This problem consists of two subproblems: for solving subproblem E1 you will receive 11 points, and for solving subproblem E2 you will receive 13 points.

A tree is an undirected connected graph containing no cycles. The distance between two nodes in an unweighted tree is the minimum number of edges that have to be traversed to get from one node to another.

You are given 3 trees that have to be united into a single tree by adding two edges between these trees. Each of these edges can connect any pair of nodes from two trees. After the trees are connected, the distances between all unordered pairs of nodes in the united tree should be computed. What is the maximum possible value of the sum of these distances?

Input

The first line contains three space-separated integers n1, n2, n3 — the number of vertices in the first, second, and third trees, respectively. The following n1 - 1 lines describe the first tree. Each of these lines describes an edge in the first tree and contains a pair of integers separated by a single space — the numeric labels of vertices connected by the edge. The following n2 - 1 lines describe the second tree in the same fashion, and the n3 - 1 lines after that similarly describe the third tree. The vertices in each tree are numbered with consecutive integers starting with 1.

The problem consists of two subproblems. The subproblems have different constraints on the input. You will get some score for the correct submission of the subproblem. The description of the subproblems follows.

  * In subproblem E1 (11 points), the number of vertices in each tree will be between 1 and 1000, inclusive. 
  * In subproblem E2 (13 points), the number of vertices in each tree will be between 1 and 100000, inclusive. 

Output

Print a single integer number — the maximum possible sum of distances between all pairs of nodes in the united tree.

Examples

Input

2 2 3
1 2
1 2
1 2
2 3


Output

56


Input

5 1 4
1 2
2 5
3 4
4 2
1 2
1 3
1 4


Output

151

Note

Consider the first test case. There are two trees composed of two nodes, and one tree with three nodes. The maximum possible answer is obtained if the trees are connected in a single chain of 7 vertices.

In the second test case, a possible choice of new edges to obtain the maximum answer is the following: 

  * Connect node 3 from the first tree to node 1 from the second tree; 
  * Connect node 2 from the third tree to node 1 from the second tree. 
#include <bits/stdc++.h>
using namespace std;
template <class T>
inline void gmax(T &a, T b) {
  if (a < b) a = b;
}
long long ans, n[3];
struct TREE {
  long long dist[100010], node[100010], pos, n, SUM, f[100010], sum[100010],
      maxd;
  struct EDGE {
    int pnt;
    EDGE *pre;
    EDGE() {}
    EDGE(int _pnt, EDGE *_pre) : pnt(_pnt), pre(_pre) {}
  } Edge[200010], *SP, *edge[100010];
  void addedge(int a, int b) {
    edge[a] = new (++SP) EDGE(b, edge[a]);
    edge[b] = new (++SP) EDGE(a, edge[b]);
  }
  void build(int nn) {
    int a, b;
    SP = Edge;
    n = nn;
    for (int i = 1; i < n; i++) {
      cin >> a >> b;
      addedge(a, b);
    }
  }
  void dfs0(int cur, int fa) {
    dist[cur] = dist[fa] + 1;
    for (EDGE *j = edge[cur]; j; j = j->pre)
      if (j->pnt != fa) {
        dfs0(j->pnt, cur);
      }
  }
  void dfs1(int cur, int fa) {
    node[cur] = 1;
    sum[cur] = 0;
    for (EDGE *j = edge[cur]; j; j = j->pre)
      if (j->pnt != fa) {
        dfs1(j->pnt, cur);
        node[cur] += node[j->pnt];
        sum[cur] += sum[j->pnt] + node[j->pnt];
      }
  }
  void dfs2(int cur, int fa, long long val) {
    f[cur] = sum[cur] + val;
    for (EDGE *j = edge[cur]; j; j = j->pre)
      if (j->pnt != fa)
        dfs2(j->pnt, cur,
             val + sum[cur] - sum[j->pnt] - node[j->pnt] + n - node[j->pnt]);
  }
  void solve() {
    dfs1(1, 0);
    dfs2(1, 0, 0);
    for (int i = 1; i <= n; i++) {
      SUM += f[i];
      if (f[i] > maxd) {
        maxd = f[i];
        pos = i;
      }
    }
    dist[0] = -1;
    dfs0(pos, 0);
  }
} T[3];
long long calc(TREE &TL, TREE &TM, TREE &TR) {
  long long res, ans = 0;
  int i = TM.pos;
  for (int j = 1; j <= TM.n; j++) {
    res = (TL.SUM + TM.SUM + TR.SUM) / 2;
    res += TL.maxd * (TM.n + TR.n) + TM.n * TR.n;
    res += TR.maxd * (TL.n + TM.n) + TM.n * TL.n;
    res += (TM.dist[j] + 2) * TL.n * TR.n + TL.n * TM.f[i] + TR.n * TM.f[j];
    gmax(ans, res);
  }
  return ans;
}
int main() {
  cin >> n[0] >> n[1] >> n[2];
  for (int i = 0; i < 3; i++) {
    T[i].build(n[i]);
    T[i].solve();
  }
  for (int i = 0; i < 3; i++)
    for (int j = 0; j < 3; j++)
      if (i != j) gmax(ans, calc(T[i], T[j], T[3 - i - j]));
  cout << ans << endl;
}
