#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 15;
int u, v;
long long res;
long long n[3], h[3][N], child[3][N];
long long down[3][N], up[3][N], s[3][N], r[3];
vector<int> G[3][N];
struct Task {
  int L, R, M;
  long long toL[N], toR[N];
  long long ans;
  long long addL, addR, addM;
  void solve(int _L, int _M, int _R) {
    memset(toL, 0, sizeof(toL));
    memset(toR, 0, sizeof(toR));
    addL = addM = addR = ans = 0;
    L = _L, M = _M, R = _R;
    ans += r[L] + r[M] + r[R];
    ans += n[L] * (n[M] + n[R]) + n[R] * (n[L] + n[M]);
    for (int i = 1; i <= n[L]; ++i) addL = max(addL, s[L][i] * (n[M] + n[R]));
    for (int i = 1; i <= n[R]; ++i) addR = max(addR, s[R][i] * (n[L] + n[M]));
    ans += addL + addR;
    dfs(1, 1);
    ans += addM;
    res = max(res, ans);
  }
  void dfs(int u, int p) {
    toL[u] = s[M][u] * n[L] + h[M][u] * n[L] * n[R];
    toR[u] = s[M][u] * n[R] + h[M][u] * n[L] * n[R];
    int p1, p2, p3, p4;
    p1 = p2 = p3 = p4 = 0;
    for (int i = 0; i < G[M][u].size(); ++i) {
      int v = G[M][u][i];
      if (v == p) continue;
      dfs(v, u);
      if (!p1 || toL[p1] < toL[v]) {
        p2 = p1;
        p1 = v;
      } else if (!p2 || toL[p2] < toL[v]) {
        p2 = v;
      }
      if (!p3 || toR[p3] < toR[v]) {
        p4 = p3;
        p3 = v;
      } else if (!p4 || toR[p4] < toR[v]) {
        p4 = v;
      }
    }
    addM = max(addM, toL[u] + toR[u] - 2 * h[M][u] * n[L] * n[R]);
    addM = max(addM, toL[u] + toR[p3] - 2 * h[M][u] * n[L] * n[R]);
    addM = max(addM, toR[u] + toL[p1] - 2 * h[M][u] * n[L] * n[R]);
    if (p1 != p3)
      addM = max(addM, toL[p1] + toR[p3] - 2 * h[M][u] * n[L] * n[R]);
    else {
      addM = max(addM, toL[p1] + toR[p4] - 2 * h[M][u] * n[L] * n[R]);
      addM = max(addM, toR[p3] + toL[p2] - 2 * h[M][u] * n[L] * n[R]);
    }
    toL[u] = max(toL[u], toL[p1]);
    toR[u] = max(toR[u], toR[p3]);
  }
} AOME;
void downdfs(int u, int p, int t) {
  child[t][u] = 1;
  for (int i = 0; i < G[t][u].size(); ++i) {
    int v = G[t][u][i];
    if (v == p) continue;
    h[t][v] = h[t][u] + 1;
    downdfs(v, u, t);
    down[t][u] += down[t][v] + child[t][v];
    child[t][u] += child[t][v];
  }
}
void updfs(int u, int p, int t) {
  s[t][u] = up[t][u] + down[t][u];
  for (int i = 0; i < G[t][u].size(); ++i) {
    int v = G[t][u][i];
    if (v == p) continue;
    up[t][v] =
        up[t][u] + down[t][u] - down[t][v] - child[t][v] + n[t] - child[t][v];
    updfs(v, u, t);
  }
}
int main() {
  ios::sync_with_stdio(false);
  for (int i = 0; i <= 2; ++i) cin >> n[i];
  for (int i = 0; i <= 2; ++i) {
    for (int j = 1; j < n[i]; ++j) {
      cin >> u >> v;
      G[i][u].push_back(v);
      G[i][v].push_back(u);
    }
  }
  for (int i = 0; i <= 2; ++i) downdfs(1, 1, i), updfs(1, 1, i);
  for (int i = 0; i <= 2; ++i) {
    for (int j = 1; j <= n[i]; ++j) {
      r[i] += s[i][j];
    }
    r[i] /= 2;
  }
  AOME.solve(2, 1, 0);
  AOME.solve(0, 2, 1);
  AOME.solve(1, 0, 2);
  cout << res;
}
