#include <bits/stdc++.h>
long long max(long long x, long long y) { return (x > y ? x : y); }
long long min(long long x, long long y) { return (x < y ? x : y); }
int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
using namespace ::std;
const long long maxn = 1e5 + 200;
long long seg[maxn * 4];
long long lazy[maxn * 4];
void shift(long long a, long long l, long long r, long long mid) {
  lazy[2 * a] += lazy[a];
  lazy[2 * a + 1] += lazy[a];
  seg[2 * a] += lazy[a] * (mid - l);
  seg[2 * a + 1] += lazy[a] * (r - mid);
  lazy[a] = 0;
}
void update(long long L, long long R, long long node, long long l, long long r,
            long long v) {
  if (l <= L && R <= r) {
    seg[node] += v * (R - L);
    lazy[node] += v;
    return;
  }
  if (r <= L || R <= l) {
    return;
  }
  long long mid = (L + R) / 2;
  shift(node, L, R, mid);
  update(L, mid, 2 * node, l, r, v);
  update(mid, R, 2 * node + 1, l, r, v);
  seg[node] = seg[2 * node] + seg[2 * node + 1];
}
long long find_sum() { return seg[1]; }
void shift_max(long long a) {
  lazy[2 * a] += lazy[a];
  lazy[2 * a + 1] += lazy[a];
  seg[2 * a] += lazy[a];
  seg[2 * a + 1] += lazy[a];
  lazy[a] = 0;
}
void update_max(long long L, long long R, long long node, long long l,
                long long r, long long v) {
  if (l <= L && R <= r) {
    seg[node] += v;
    lazy[node] += v;
    return;
  }
  if (r <= L || R <= l) {
    return;
  }
  long long mid = (L + R) / 2;
  shift_max(node);
  update_max(L, mid, 2 * node, l, r, v);
  update_max(mid, R, 2 * node + 1, l, r, v);
  seg[node] = max(seg[2 * node], seg[2 * node + 1]);
}
long long find_max() { return seg[1]; }
long long n[3];
vector<long long> ger[3][maxn];
long long f[3][maxn];
long long st[maxn];
long long et[maxn];
long long h[maxn];
long long tt = 0;
long long a, Y;
void dfs(long long v, long long p = -1) {
  f[a][v] = find_sum();
  for (long long i = 0; i < (long long)ger[a][v].size(); i++) {
    long long u = ger[a][v][i];
    if (u != p) {
      update(0, Y, 1, st[u], et[u] + 1, -1);
      update(0, Y, 1, 0, st[u], +1);
      update(0, Y, 1, et[u] + 1, Y, +1);
      dfs(u, v);
      update(0, Y, 1, st[u], et[u] + 1, +1);
      update(0, Y, 1, 0, st[u], -1);
      update(0, Y, 1, et[u] + 1, Y, -1);
    }
  }
}
void dfs_s(long long v, long long p = -1) {
  tt++;
  st[v] = tt;
  for (long long i = 0; i < (long long)ger[a][v].size(); i++) {
    long long u = ger[a][v][i];
    if (u != p) {
      h[u] = h[v] + 1;
      dfs_s(u, v);
    }
  }
  et[v] = tt;
}
void cal() {
  long long N = n[a];
  fill(seg, seg + maxn * 4, 0);
  fill(lazy, lazy + maxn * 4, 0);
  tt = -1;
  dfs_s(1);
  Y = et[1] + 1;
  for (long long i = 1; i <= N; i++) {
    update(0, Y, 1, st[i], st[i] + 1, h[i]);
  }
  dfs(1);
}
long long m, C, D;
void dfss(long long v, long long p = -1) {
  m = max(m, f[a][v] * C + find_max());
  for (long long i = 0; i < (long long)ger[a][v].size(); i++) {
    long long u = ger[a][v][i];
    if (u != p) {
      update_max(0, Y, 1, st[u], et[u] + 1, -C * D);
      update_max(0, Y, 1, 0, st[u], C * D);
      update_max(0, Y, 1, et[u] + 1, Y, C * D);
      dfss(u, v);
      update_max(0, Y, 1, st[u], et[u] + 1, C * D);
      update_max(0, Y, 1, 0, st[u], -C * D);
      update_max(0, Y, 1, et[u] + 1, Y, -C * D);
    }
  }
}
long long find_real_best(long long vas, long long c, long long d) {
  C = c;
  D = d;
  fill(seg, seg + maxn * 4, 0);
  fill(lazy, lazy + maxn * 4, 0);
  a = vas;
  dfs_s(1);
  Y = et[1] + 1;
  for (long long i = 1; i <= n[vas]; i++) {
    update_max(0, Y, 1, st[i], st[i] + 1, f[a][i] * d + h[i] * c * d);
  }
  m = 0;
  dfss(1);
  return m;
}
long long maxf[3];
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> n[0] >> n[1] >> n[2];
  for (long long i = 0; i < 3; i++) {
    for (long long j = 1; j < n[i]; j++) {
      long long v, u;
      cin >> v >> u;
      ger[i][v].push_back(u);
      ger[i][u].push_back(v);
    }
  }
  a = 0;
  cal();
  a = 1;
  cal();
  a = 2;
  cal();
  long long ans = 0;
  for (long long i = 0; i < 3; i++) {
    for (long long j = 1; j <= n[i]; j++) {
      ans += f[i][j];
      maxf[i] = max(maxf[i], f[i][j]);
    }
  }
  ans /= 2;
  long long anss = 0;
  for (long long vas = 0; vas <= 2; vas++) {
    long long res = 0;
    if (vas != 0) res += maxf[0] * (n[1] + n[2]);
    if (vas != 1) res += maxf[1] * (n[0] + n[2]);
    if (vas != 2) res += maxf[2] * (n[0] + n[1]);
    res += n[0] * n[1];
    res += n[1] * n[2];
    res += n[0] * n[2];
    long long c = (vas + 1) % 3;
    long long d = (vas + 2) % 3;
    res += n[c] * n[d];
    long long mx = find_real_best(vas, n[c], n[d]);
    res += mx;
    anss = max(anss, res);
  }
  cout << ans + anss;
}
