#include <bits/stdc++.h>
using namespace std;
template <class T, class T2>
inline int chkmax(T &x, const T2 &y) {
  return x < y ? x = y, 1 : 0;
}
template <class T, class T2>
inline int chkmin(T &x, const T2 &y) {
  return x > y ? x = y, 1 : 0;
}
const int MAXN = 4042;
const int MAXK = 80;
const int mod = 998244353;
const double PI = acosl(-1);
int n, m, k;
inline void addmod(int &x, int y, int mod) { (x += y) >= mod && (x -= mod); }
inline int mulmod(int x, int y, int mod) { return x * 1ll * y % mod; }
struct complex_base {
  long double x, y;
  complex_base(long double _x = 0, long double _y = 0) {
    x = _x;
    y = _y;
  }
  friend complex_base operator-(const complex_base &a, const complex_base &b) {
    return complex_base(a.x - b.x, a.y - b.y);
  }
  friend complex_base operator+(const complex_base &a, const complex_base &b) {
    return complex_base(a.x + b.x, a.y + b.y);
  }
  friend complex_base operator*(const complex_base &a, const complex_base &b) {
    return complex_base(a.x * b.x - a.y * b.y, a.y * b.x + b.y * a.x);
  }
  friend void operator/=(complex_base &a, const long double &P) {
    a.x /= P;
    a.y /= P;
  }
};
int bit_rev[MAXN];
void fft(complex_base *a, int lg) {
  int n = (1 << lg);
  for (int i = 1; i < n; i++) {
    bit_rev[i] = (bit_rev[i >> 1] >> 1) | ((i & 1) << (lg - 1));
    if (bit_rev[i] < i) swap(a[i], a[bit_rev[i]]);
  }
  for (int len = 2; len <= n; len <<= 1) {
    long double ang = 2 * PI / len;
    complex_base w(1, 0), wn(cos(ang), sin(ang));
    for (int j = 0; j < (len >> 1); j++, w = w * wn)
      for (int i = 0; i < n; i += len) {
        complex_base u = a[i + j], v = w * a[i + j + (len >> 1)];
        a[i + j] = u + v;
        a[i + j + (len >> 1)] = u - v;
      }
  }
}
void inv_fft(complex_base *a, int lg) {
  int n = (1 << lg);
  for (int i = 1; i < n; i++) {
    bit_rev[i] = (bit_rev[i >> 1] >> 1) | ((i & 1) << (lg - 1));
    if (bit_rev[i] < i) swap(a[i], a[bit_rev[i]]);
  }
  for (int len = 2; len <= n; len <<= 1) {
    long double ang = -2 * PI / len;
    complex_base w(1, 0), wn(cos(ang), sin(ang));
    for (int j = 0; j < (len >> 1); j++, w = w * wn)
      for (int i = 0; i < n; i += len) {
        complex_base u = a[i + j], v = w * a[i + j + (len >> 1)];
        a[i + j] = u + v;
        a[i + j + (len >> 1)] = u - v;
      }
  }
  for (int i = 0; i < n; i++) a[i] /= n;
}
complex_base A[MAXN], B[MAXN];
vector<int> mult(const vector<int> &a, const vector<int> &b) {
  {
    vector<int> ans(a.size() + b.size(), 0);
    for (int i = 0; i < (int)a.size(); i++)
      for (int j = 0; j < (int)b.size(); j++)
        ans[i + j] = (ans[i + j] + a[i] * 1ll * b[j]) % mod;
    return ans;
  }
  int lg = 0;
  while ((1 << lg) < (int)(a.size() + b.size())) ++lg;
  for (int i = 0; i < (1 << lg); i++) A[i] = B[i] = complex_base(0, 0);
  for (int i = 0; i < (int)a.size(); i++) A[i] = complex_base(a[i], 0);
  for (int i = 0; i < (int)b.size(); i++) B[i] = complex_base(b[i], 0);
  fft(A, lg);
  fft(B, lg);
  for (int i = 0; i < (1 << lg); i++) A[i] = A[i] * B[i];
  inv_fft(A, lg);
  vector<int> ans(a.size() + b.size(), 0);
  for (int i = 0; i < (int)ans.size(); i++)
    ans[i] = (int64_t)(A[i].x + 0.5) % mod;
  return ans;
}
vector<int> mult_mod(const vector<int> &a, const vector<int> &b) {
  int base = (int)sqrtl(mod);
  vector<int> a0(a.size()), a1(a.size());
  for (int i = 0; i < (int)a.size(); i++) {
    a0[i] = a[i] % base;
    a1[i] = a[i] / base;
  }
  vector<int> b0(b.size()), b1(b.size());
  for (int i = 0; i < (int)b.size(); i++) {
    b0[i] = b[i] % base;
    b1[i] = b[i] / base;
  }
  vector<int> a01 = a0;
  for (int i = 0; i < (int)a.size(); i++) addmod(a01[i], a1[i], mod);
  vector<int> b01 = b0;
  for (int i = 0; i < (int)b.size(); i++) addmod(b01[i], b1[i], mod);
  vector<int> C = mult(a01, b01);
  vector<int> a0b0 = mult(a0, b0);
  vector<int> a1b1 = mult(a1, b1);
  vector<int> mid = C;
  for (int i = 0; i < (int)mid.size(); i++) {
    addmod(mid[i], -a0b0[i] + mod, mod);
    addmod(mid[i], -a1b1[i] + mod, mod);
  }
  vector<int> res = a0b0;
  for (int i = 0; i < (int)res.size(); i++)
    addmod(res[i], mulmod(base, mid[i], mod), mod);
  base = mulmod(base, base, mod);
  for (int i = 0; i < (int)res.size(); i++)
    addmod(res[i], mulmod(base, a1b1[i], mod), mod);
  return res;
}
struct Tree {
  int n;
  vector<int> adj[MAXN];
  int S[MAXK];
  Tree() { n = 0; }
  Tree(int _n) {
    n = _n;
    for (int i = 0; i <= n; i++) adj[i].clear();
    for (int i = 0; i <= k; i++) S[i] = 0;
  }
  void init(int _n) {
    n = _n;
    for (int i = 0; i <= n; i++) adj[i].clear();
    for (int i = 0; i <= k; i++) S[i] = 0;
  }
  void input() {
    for (int i = 0; i < n - 1; i++) {
      int u, v;
      cin >> u >> v;
      adj[u].push_back(v);
      adj[v].push_back(u);
    }
  }
  int ver_cnt, tr_sz[MAXN];
  bool used[MAXN];
  int ver_li[MAXN];
  void pre_dfs(int u, int pr) {
    ver_li[ver_cnt++] = u;
    tr_sz[u] = 1;
    for (int v : adj[u])
      if (v != pr && !used[v]) {
        pre_dfs(v, u);
        tr_sz[u] += tr_sz[v];
      }
  }
  int centroid(int u, int pr) {
    for (int v : adj[u])
      if (v != pr && !used[v] && tr_sz[v] > ver_cnt / 2) return centroid(v, u);
    return u;
  }
  int dp1[MAXN][MAXK], dp2[MAXN][MAXK];
  void decompose(int u) {
    ver_cnt = 0;
    pre_dfs(u, u);
    int cen = centroid(u, u);
    for (int i = 0; i < ver_cnt; i++) {
      int v = ver_li[i];
      dp1[v][0] = dp2[v][0] = 0;
    }
    dp1[cen][0] = dp2[cen][0] = 1;
    for (int kk = 1; kk <= k; kk++)
      for (int i = 0; i < ver_cnt; i++) {
        int v = ver_li[i];
        dp1[v][kk] = dp2[v][kk] = 0;
        for (int q : adj[v])
          if (!used[q]) {
            dp1[v][kk] += dp1[q][kk - 1];
            if (v != cen) dp2[v][kk] += dp2[q][kk - 1];
            if (dp1[v][kk] >= mod) dp1[v][kk] -= mod;
            if (dp2[v][kk] >= mod) dp2[v][kk] -= mod;
          }
      }
    for (int i = 0; i < ver_cnt; i++) {
      int v = ver_li[i];
      if (v == cen) {
        for (int j = 0; j <= k; j++) {
          S[j] += dp1[cen][j];
          if (S[j] >= mod) S[j] -= mod;
        }
      } else {
        vector<int> f(k + 1, 0);
        vector<int> s(k + 1, 0);
        vector<int> tmp;
        for (int i = 0; i <= k; i++) f[i] = dp1[v][i], s[i] = dp2[v][i];
        tmp = mult(f, s);
        for (int j = 0; j <= k; j++) {
          S[j] += tmp[j];
          if (S[j] >= mod) S[j] -= mod;
        }
      }
    }
    used[cen] = true;
    for (int v : adj[cen])
      if (!used[v]) decompose(v);
    used[cen] = false;
  }
  void compute() { decompose(1); }
};
Tree t1, t2;
void read() {
  cin >> n >> m >> k;
  t1.init(n);
  t2.init(m);
  t1.input();
  t2.input();
}
int C[MAXK][MAXK];
void solve() {
  for (int i = 0; i < MAXK; i++) {
    C[i][0] = 1;
    for (int j = 1; j <= i; j++)
      C[i][j] = (C[i - 1][j] + C[i - 1][j - 1]) % mod;
  }
  t1.compute();
  t2.compute();
  int answer = 0;
  for (int k1 = 0; k1 <= k; k1++) {
    int curr = (t1.S[k1] * 1ll * t2.S[k - k1]) % mod;
    curr = (curr * 1ll * C[k][k - k1]) % mod;
    answer = (answer + curr) % mod;
  }
  cout << answer << '\n';
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  read();
  solve();
  return 0;
}
