#include <bits/stdc++.h>
using namespace std;
template <class T>
void debug(T a, T b) {
  ;
}
template <class T>
void chmin(T& a, const T& b) {
  if (a > b) a = b;
}
template <class T>
void chmax(T& a, const T& b) {
  if (a < b) a = b;
}
namespace std {
template <class S, class T>
ostream& operator<<(ostream& out, const pair<S, T>& a) {
  out << '(' << a.first << ',' << a.second << ')';
  return out;
}
}  // namespace std
long long int readL() {
  long long int res;
  scanf("%I64d", &res);
  return res;
}
void printL(long long int res) { printf("%I64d", res); }
const int INF = 5e8;
struct Tree {
  int e[200005], nxt[200005], begin[100005], cnt;
  int n;
  long long int totdist[100005];
  int size[100005];
  long long int sum_dist;
  void getdist(int v, int p) {
    size[v] = 1;
    for (int it = begin[v]; ~it; it = nxt[it]) {
      int to = e[it];
      if (to == p) continue;
      getdist(to, v);
      size[v] += size[to];
      totdist[v] += totdist[to];
    }
    totdist[v] += size[v] - 1;
  }
  void getdist2(int v, int p, long long int sum) {
    for (int it = begin[v]; ~it; it = nxt[it]) {
      int to = e[it];
      if (to == p) continue;
      getdist2(to, v,
               sum + totdist[v] - (totdist[to] + size[to]) + n - size[to]);
    }
    totdist[v] += sum;
  }
  long long int maxdist;
  void init(int n_) {
    n = n_;
    memset(begin, -1, sizeof(begin));
    cnt = 0;
    for (int i = 0; i < (n - 1); ++i) {
      int a, b;
      scanf("%d%d", &a, &b);
      --a;
      --b;
      e[cnt] = b;
      nxt[cnt] = begin[a];
      begin[a] = cnt++;
      e[cnt] = a;
      nxt[cnt] = begin[b];
      begin[b] = cnt++;
    }
    maxdist = sum_dist = 0;
    getdist(0, -1);
    getdist2(0, -1, 0);
    for (int i = 0; i < (n); ++i) {
      chmax(maxdist, totdist[i]);
      sum_dist += totdist[i];
    }
    debug(totdist, totdist + n);
    sum_dist /= 2;
  }
  long long int dis1, dis3;
  int n1, n3;
  int cut[100005];
  long long int res;
  pair<long long int, long long int> dfs(int v, int p, int d) {
    pair<long long int, long long int> nxtt =
        make_pair(totdist[v] * n1 + d * (long long int)n1 * n3,
                  totdist[v] * n3 + d * (long long int)n1 * n3);
    chmax(res, nxtt.first + nxtt.second - 2LL * d * n1 * n3);
    for (int it = begin[v]; ~it; it = nxt[it]) {
      int to = e[it];
      if (to == p) continue;
      pair<long long int, long long int> nxt2 = dfs(to, v, d + 1);
      chmax(res, nxtt.first + nxt2.second - 2LL * d * (long long int)n1 * n3);
      chmax(res, nxtt.second + nxt2.first - 2LL * d * (long long int)n1 * n3);
      chmax(nxtt.first, nxt2.first);
      chmax(nxtt.second, nxt2.second);
    }
    return nxtt;
  }
  long long int query(long long int A, long long int B, int n1_, int n3_) {
    ;
    ;
    dis1 = A;
    dis3 = B;
    n1 = n1_;
    n3 = n3_;
    memset((cut), 0, sizeof(cut));
    res = 0;
    dfs(0, -1, 0);
    res += (dis1 + dis3) * n;
    res += n1 * dis3;
    res += n3 * dis1;
    res += 2ll * n1 * n3;
    res += 1ll * n1 * n;
    res += 1ll * n * n3;
    return res;
  }
};
Tree T[3];
int n[3];
int main() {
  cin >> n[0] >> n[1] >> n[2];
  for (int i = 0; i < (3); ++i) {
    T[i].init(n[i]);
  }
  int perm[3] = {0, 1, 2};
  long long int res = 0, base = T[0].sum_dist + T[1].sum_dist + T[2].sum_dist;
  do {
    if (perm[0] > perm[2]) {
      chmax(res, T[perm[1]].query(T[perm[0]].maxdist, T[perm[2]].maxdist,
                                  n[perm[0]], n[perm[2]]));
    }
  } while (next_permutation(perm, perm + 3));
  res += base;
  cout << res << endl;
  return 0;
}
