#include <bits/stdc++.h>
using namespace std;
const int mod = 998244353;
const int M = 80;
const int N = 4100;
long long c[M][M], m;
struct Tree {
  struct Node {
    int ne, to;
  } e[2 * N];
  int vis[N], tot = 0, he[N], sz[N], mx[N], q[N], n, rp, mn;
  long long step[M], f[N][M], g[N][M], tmp[M], ans[M];
  void add(int x, int y) {
    e[++tot].ne = he[x];
    he[x] = tot;
    e[tot].to = y;
  }
  void addedge(int x, int y) {
    add(x, y);
    add(y, x);
  }
  void dfs1(int x, int fa) {
    int i, y;
    sz[x] = 1;
    mx[x] = 0;
    for (i = he[x]; i; i = e[i].ne) {
      y = e[i].to;
      if ((!vis[y]) && (y != fa)) {
        dfs1(y, x);
        sz[x] += sz[y];
        if (sz[y] > mx[x]) mx[x] = sz[y];
      }
    }
  }
  void dfsrt(int now, int x, int fa, int &rt) {
    int i, y;
    mx[x] = max(mx[x], sz[now] - sz[x]);
    if (mx[x] < mn) {
      mn = mx[x];
      rt = x;
    }
    for (i = he[x]; i; i = e[i].ne) {
      y = e[i].to;
      if ((!vis[y]) && (y != fa)) dfsrt(now, y, x, rt);
    }
  }
  void dfs2(int x, int fa) {
    int i, y;
    q[++rp] = x;
    for (i = he[x]; i; i = e[i].ne) {
      y = e[i].to;
      if ((!vis[y]) && (y != fa)) dfs2(y, x);
    }
  }
  void divide(int x) {
    int rt, i, j, k, y;
    mn = n;
    dfs1(x, 0);
    dfsrt(x, x, 0, rt);
    vis[rt] = 1;
    for (i = he[rt]; i; i = e[i].ne)
      if (!vis[e[i].to]) divide(e[i].to);
    vis[rt] = 0;
    rp = 0;
    dfs2(rt, 0);
    memset(step, 0, sizeof(step));
    for (i = he[rt]; i; i = e[i].ne) {
      y = e[i].to;
      if (!vis[y])
        for (j = 0; j <= m - 2; j++)
          step[j + 2] = (step[j + 2] + f[y][j]) % mod;
    }
    memset(f[rt], 0, sizeof(f[rt]));
    f[rt][0] = 1;
    for (i = 1; i <= m; i++)
      for (j = 2; j <= i; j++)
        f[rt][i] = (f[rt][i] + f[rt][i - j] * step[j]) % mod;
    for (i = 2; i <= rp; i++) {
      memset(tmp, 0, sizeof(tmp));
      for (j = 2; j <= m; j++)
        for (k = 0; k <= j - 2; k++)
          tmp[j] = (tmp[j] + g[q[i]][k] * f[rt][j - k - 2]) % mod;
      for (j = 2; j <= m; j++)
        for (k = 0; k <= j - 2; k++)
          f[q[i]][j] = (f[q[i]][j] + g[q[i]][k] * tmp[j - k]) % mod;
    }
    for (i = 1; i <= rp; i++) memset(g[q[i]], 0, sizeof(g[q[i]]));
    g[x][0] = 1;
    for (i = 1; i <= m; i++)
      for (j = 1; j <= rp; j++)
        for (k = he[q[j]]; k; k = e[k].ne) {
          y = e[k].to;
          if (!vis[y]) g[q[j]][i] = (g[q[j]][i] + g[y][i - 1]) % mod;
        }
  }
  void solve() {
    divide(1);
    for (int i = 0; i <= m; i++)
      for (int j = 1; j <= n; j++) ans[i] = (ans[i] + f[j][i]) % mod;
  }
} tr1, tr2;
int main() {
  int i, j, k, x, y;
  long long out;
  scanf("%d%d%d", &tr1.n, &tr2.n, &m);
  for (i = 1; i < tr1.n; i++) {
    scanf("%d%d", &x, &y);
    tr1.addedge(x, y);
  }
  for (i = 1; i < tr2.n; i++) {
    scanf("%d%d", &x, &y);
    tr2.addedge(x, y);
  }
  for (i = 0; i <= m; i++) c[i][0] = 1;
  for (i = 1; i <= m; i++)
    for (j = 1; j <= i; j++) c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % mod;
  tr1.solve();
  tr2.solve();
  out = 0;
  for (i = 0; i <= m; i++)
    out = (out + (c[m][i] * tr1.ans[i]) % mod * tr2.ans[m - i]) % mod;
  printf("%I64d\n", out);
  return 0;
}
