#include <bits/stdc++.h>
using namespace std;
const int N = 10000;
const int K = 80;
const int INF = 1e9;
vector<int> G[N];
bool used[N];
int msz[N], sz[N], root, rootP, tot, k;
void getroot(int v, int p = 0) {
  sz[v] = 1;
  msz[v] = 0;
  for (auto u : G[v]) {
    if (u == p || used[u]) continue;
    getroot(u, v);
    sz[v] += sz[u];
    msz[v] = max(msz[v], sz[u]);
  }
  msz[v] = max(msz[v], tot - sz[v]);
  if (msz[v] < msz[root]) root = v, rootP = p;
}
const long long Mod = 998244353;
inline long long mul(long long a, long long b) { return a * b % Mod; }
inline long long sum(long long a, long long b) { return (a + b) % Mod; }
inline void add(long long &a, long long b) { a = sum(a, b); }
long long C[K][K];
void initC() {
  C[0][0] = 1;
  for (int i = 1; i < K; i++) {
    C[i][0] = 1;
    for (int j = 1; j <= i; j++) C[i][j] = sum(C[i - 1][j - 1], C[i - 1][j]);
  }
}
long long f[N][K], g[N][K];
vector<int> vs;
void dfs(int v, int p = 0) {
  vs.push_back(v);
  for (auto u : G[v]) {
    if (u == p || used[u]) continue;
    dfs(u, v);
  }
}
void solve(int v, long long ans[]) {
  root = 0;
  getroot(v);
  v = root;
  int p = rootP, t = tot;
  for (auto x : G[v]) {
    if (used[x]) continue;
    vs.clear();
    dfs(x, v);
    for (auto u : vs) f[u][1] = 0;
    f[x][1] = 1;
    for (int i = 2; i <= k; i++) {
      for (auto u : vs) {
        f[u][i] = 0;
        for (auto w : G[u]) {
          if (!used[w] && w != v) add(f[u][i], f[w][i - 1]);
        }
      }
    }
  }
  vs.clear();
  dfs(v);
  for (auto u : vs) g[u][0] = 0;
  g[v][0] = 1;
  for (int i = 1; i <= k; i++) {
    for (auto u : vs) {
      g[u][i] = 0;
      for (auto w : G[u]) {
        if (!used[w]) add(g[u][i], g[w][i - 1]);
      }
    }
  }
  for (auto u : vs) {
    if (u == v) {
      for (int i = 1; i <= k; i++) add(ans[i], g[v][i]);
    } else {
      for (int i = 1; i <= k; i++)
        for (int j = 1; i + j <= k; j++) {
          add(ans[i + j], mul(g[u][i], f[u][j]));
        }
    }
  }
  used[v] = true;
  for (auto u : G[v]) {
    if (used[u]) continue;
    if (u == p)
      tot = t - sz[v];
    else
      tot = sz[u];
    solve(u, ans);
  }
}
long long ans1[K], ans2[K];
void solve() {
  msz[0] = INF;
  int n1, n2;
  scanf("%d%d%d", &n1, &n2, &k);
  for (int i = 1; i <= n1; i++) G[i].clear();
  for (int i = 0; i < n1 - 1; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    G[u].push_back(v);
    G[v].push_back(u);
  }
  tot = n1;
  solve(1, ans1);
  memset(used, 0, sizeof used);
  for (int i = 1; i <= n2; i++) G[i].clear();
  for (int i = 0; i < n2 - 1; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    G[u].push_back(v);
    G[v].push_back(u);
  }
  tot = n2;
  solve(1, ans2);
  ans1[0] = ans2[0] = 1;
  long long tans = 0;
  for (int i = 1; i < k; i++)
    add(tans, mul(C[k][i], mul(ans1[i], ans2[k - i])));
  add(tans, mul(n1, ans2[k]));
  add(tans, mul(n2, ans1[k]));
  printf("%lld\n", tans);
}
int main() {
  initC();
  solve();
}
