#include <bits/stdc++.h>
using namespace std;
const int maxn = 4010, maxk = 110, maxc = 100100, mod = 998244353;
inline int ksm(int a, int b) {
  int res = 1;
  for (; b; b >>= 1, a = 1ll * a * a % mod)
    if (b & 1) res = 1ll * res * a % mod;
  return res;
}
inline void Add(int &a, int b) { a = a + b >= mod ? a + b - mod : a + b; }
int fac[maxc], facinv[maxc];
int k;
inline int C(int n, int m) {
  return 1ll * fac[n] * facinv[n - m] % mod * facinv[m] % mod;
}
int n, head[maxn], nxt[maxn << 1], ver[maxn << 1], tot;
inline void clear() {
  memset(head, 0, sizeof(head));
  tot = 0;
}
inline void addedge(int a, int b) {
  nxt[++tot] = head[a];
  ver[tot] = b;
  head[a] = tot;
  nxt[++tot] = head[b];
  ver[tot] = a;
  head[b] = tot;
}
int tmp[maxk];
bool vis[maxn];
int size[maxn], ms, rt, allsize;
vector<int> v;
unordered_map<int, int> id;
int f[maxn][maxk], g[maxn][maxk];
inline void treedp(int x) {
  for (int i = 0; i <= k; i++)
    for (int j = 0; j < (int)v.size(); j++) f[j][i] = g[j][i] = 0;
  f[id[x]][0] = g[id[x]][0] = 1;
  for (int i = 1; i <= k; i++)
    for (int j = 0; j < (int)v.size(); j++) {
      int now = j;
      for (int ppp = head[v[j]]; ppp; ppp = nxt[ppp])
        if (id.count(ver[ppp])) {
          int lst = id[ver[ppp]];
          if (ver[ppp] != x || i == 1) Add(f[now][i], f[lst][i - 1]);
          Add(g[now][i], g[lst][i - 1]);
        }
    }
  for (int i = 0; i <= k; i++) Add(tmp[i], g[id[x]][i]);
  for (int tot = 0; tot <= k; tot++)
    for (int a = 0; a <= tot; a++) {
      int b = tot - a;
      for (int i = 0; i < (int)v.size(); i++)
        if (v[i] != x) Add(tmp[tot], 1ll * f[i][a] * g[i][b] % mod);
    }
}
inline void getroot(int x, int fat) {
  size[x] = 1;
  int mx = 0;
  for (int i = head[x]; i; i = nxt[i]) {
    int y = ver[i];
    if (y == fat || vis[y]) continue;
    getroot(y, x);
    mx = max(mx, size[y]);
    size[x] += size[y];
  }
  mx = max(mx, allsize - size[x]);
  if (mx < ms) ms = mx, rt = x;
}
inline void getvector(int x, int fat) {
  id[x] = v.size();
  v.push_back(x);
  for (int i = head[x]; i; i = nxt[i]) {
    int y = ver[i];
    if (y == fat || vis[y]) continue;
    getvector(y, x);
  }
}
inline int getroot(int RT) {
  allsize = v.size();
  ms = 1000000000;
  rt = 0;
  getroot(RT, 0);
  return rt;
}
inline void dfs(int x) {
  v.clear();
  id.clear();
  getvector(x, 0);
  x = getroot(x);
  treedp(x);
  vis[x] = 1;
  for (int i = head[x]; i; i = nxt[i])
    if (vis[ver[i]] == 0) dfs(ver[i]);
}
inline void solve_tree() {
  memset(vis, 0, sizeof(vis));
  memset(tmp, 0, sizeof(tmp));
  dfs(1);
}
int l1[maxk], l2[maxk];
int main() {
  fac[0] = 1;
  for (int i = 1; i < maxc; i++) fac[i] = 1ll * fac[i - 1] * i % mod;
  facinv[maxc - 1] = ksm(fac[maxc - 1], mod - 2);
  for (int i = maxc - 2; i >= 0; i--)
    facinv[i] = 1ll * facinv[i + 1] * (i + 1) % mod;
  int n1, n2, ans = 0;
  scanf("%d%d%d", &n1, &n2, &k);
  for (int i = 1, a, b; i < n1; i++) scanf("%d%d", &a, &b), addedge(a, b);
  n = n1;
  solve_tree();
  for (int i = 0; i <= k; i++) l1[i] = tmp[i];
  clear();
  for (int i = 1, a, b; i < n2; i++) scanf("%d%d", &a, &b), addedge(a, b);
  n = n2;
  solve_tree();
  for (int i = 0; i <= k; i++) l2[i] = tmp[i];
  for (int i = 0; i <= k; i++)
    Add(ans, 1ll * l1[i] * l2[k - i] % mod * C(k, i) % mod);
  printf("%d", ans);
}
