#include <bits/stdc++.h>
using namespace std;
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
long long power(long long x, long long p, long long MOD) {
  if (p == 0) return 1 % MOD;
  if (p == 1) return x % MOD;
  long long res = power(x, p / 2, MOD);
  res = (long long)res * res % MOD;
  if (p & 1) res = (long long)res * x % MOD;
  return res;
}
const long long MOD = 998244353LL;
const long long N = 1e4;
const long long KK = 80;
long long fat[N], ifat[N], inv[N];
long long inve(long long x) { return power(x, MOD - 2, MOD); }
void precompute() {
  for (long long i = 0; i <= 1; i++) {
    fat[i] = 1;
    ifat[i] = 1;
    inv[i] = 1;
  }
  for (long long i = 2; i < N; i++) {
    fat[i] = fat[i - 1] * i % MOD;
    inv[i] = MOD - MOD / i * inv[MOD % i] % MOD;
    ifat[i] = ifat[i - 1] * inv[i] % MOD;
  }
}
long long nCr(long long n, long long r) {
  if (r > n) return 0;
  return fat[n] * ifat[r] % MOD * ifat[n - r] % MOD;
}
vector<long long> edges;
vector<long long> adj[N];
long long dp[2 * N][KK], sum[N][KK];
long long dp2[N][KK];
long long go(long long r, long long ed, long long K) {
  if (K == 0) return 1;
  long long &res = ed != -1 ? dp[ed][K] : dp2[r][K];
  if (res != -1) return res;
  long long u = r;
  if (ed != -1) {
    u = edges[ed];
    assert(binary_search(adj[u].begin(), adj[u].end(), ed ^ 1));
  }
  res = 0;
  if (ed == -1) {
    for (long long ed2 : adj[u]) {
      for (long long i = 0; i <= K - 2; i++) {
        res = (res + go(r, ed2, i) * go(r, -1, K - i - 2)) % MOD;
      }
    }
  } else {
    for (long long i = 0; i <= K - 2; i++) {
      if (sum[u][i] == -1) {
        sum[u][i] = 0;
        for (long long ed2 : adj[u]) {
          sum[u][i] = (sum[u][i] + go(r, ed2, i)) % MOD;
        }
      }
      long long acc = sum[u][i] * go(r, ed, K - i - 2) % MOD;
      acc = (acc - go(r, ed ^ 1, i) * go(r, ed, K - i - 2)) % MOD;
      res = (res + acc) % MOD;
      if (res < 0) res += MOD;
    }
  }
  assert(res >= 0);
  return res;
}
void add_edge(long long u, long long v) {
  adj[u].push_back(edges.size());
  edges.push_back(v);
  adj[v].push_back(edges.size());
  edges.push_back(u);
}
int32_t main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  precompute();
  memset((sum), (-1), sizeof(sum));
  memset((dp), (-1), sizeof(dp));
  memset((dp2), (-1), sizeof(dp2));
  long long n1, n2, K;
  cin >> n1 >> n2 >> K;
  for (long long i = 1; i < n1; i++) {
    long long x, y;
    cin >> x >> y;
    x--, y--;
    add_edge(x, y);
  }
  for (long long i = 1; i < n2; i++) {
    long long x, y;
    cin >> x >> y;
    x--, y--;
    x += n1, y += n1;
    add_edge(x, y);
  }
  vector<long long> a(K + 1), b(K + 1);
  for (long long i = 0; i < n1; i++) {
    for (long long j = 0; j <= K; j++) {
      a[j] = (a[j] + go(i, -1, j)) % MOD;
    }
  }
  for (long long i = 0; i < n2; i++) {
    for (long long j = 0; j <= K; j++) {
      b[j] = (b[j] + go(i + n1, -1, j)) % MOD;
    }
  }
  long long ans = 0;
  for (long long i = 0; i <= K; i++) {
    ans += nCr(K, i) * a[i] % MOD * b[K - i] % MOD;
    ans %= MOD;
  }
  cout << ans << endl;
}
