#include <bits/stdc++.h>
using namespace std;
const int maxn = 4004, maxk = 101, mod = 998244353;
inline int mAdd(int x, int y) { return (x + y) % mod; }
inline int mMul(int x, int y) { return 1ll * x * y % mod; }
int n, m, k, c[maxn][maxn], ans;
class tree {
 public:
  tree(int n) : n(n) {
    memset(vis, 0, sizeof(vis)), memset(ans, 0, sizeof(ans)),
        cnt = root = minSize = sumSize = 0;
  }
  void add(int u, int v) { return nxt[u].push_back(v), nxt[v].push_back(u); }
  void findRoot(int u, int f) {
    int curSize = 0;
    siz[u] = 1;
    for (int v : nxt[u])
      if (v != f && !vis[v])
        findRoot(v, u), siz[u] += siz[v], curSize = max(curSize, siz[v]);
    curSize = max(curSize, sumSize - siz[u]);
    if (curSize < minSize) root = u, minSize = curSize;
    return;
  }
  void getDfn(int u, int f) {
    dfn[++cnt] = u, siz[u] = 1;
    for (int v : nxt[u])
      if (v != f && !vis[v]) getDfn(v, u), siz[u] += siz[v];
    return;
  }
  void calc(int u) {
    cnt = 0, getDfn(u, 0), memset(from, 0, sizeof(from)),
    memset(to, 0, sizeof(to)), to[0][u] = from[0][u] = 1;
    for (int i = 1; i <= k; i++)
      for (int x = 1; x <= cnt; x++) {
        if (dfn[x] == u) {
          for (int y : nxt[dfn[x]])
            if (!vis[y])
              from[i][dfn[x]] = mAdd(from[i][dfn[x]], from[i - 1][y]);
        } else {
          for (int y : nxt[dfn[x]])
            if (!vis[y])
              from[i][dfn[x]] = mAdd(from[i][dfn[x]], from[i - 1][y]),
              to[i][dfn[x]] = mAdd(to[i][dfn[x]], to[i - 1][y]);
        }
      }
    for (int x = 1; x <= cnt; x++) {
      if (dfn[x] == u)
        for (int i = 0; i <= k; i++) ans[i] = mAdd(ans[i], from[i][u]);
      else
        for (int i = 0; i <= k; i++)
          for (int j = 0; i + j <= k; j++)
            ans[i + j] = mAdd(ans[i + j], mMul(from[i][dfn[x]], to[j][dfn[x]]));
    }
    vis[u] = 1;
    for (int v : nxt[u])
      if (!vis[v])
        root = 0, minSize = INT32_MAX, sumSize = siz[v], findRoot(v, 0),
        calc(root);
    return;
  }
  void solve() {
    return root = 0, minSize = INT32_MAX, sumSize = n, findRoot(n, 0),
           calc(root);
  }
  int ans[maxn];

 private:
  vector<int> nxt[maxn];
  int n, vis[maxn], siz[maxn], dfn[maxn], from[maxk][maxn], to[maxk][maxn], cnt,
      root, minSize, sumSize;
};
int main() {
  cin.tie(0), cout.tie(0), ios::sync_with_stdio(0);
  cin >> n >> m >> k;
  for (int i = 0; i <= k; i++) c[i][0] = c[i][i] = 1;
  for (int i = 1; i <= k; i++)
    for (int j = 1; j < i; j++) c[i][j] = mAdd(c[i - 1][j], c[i - 1][j - 1]);
  tree p(n), q(m);
  for (int i = 1, u, v; i < n; i++) cin >> u >> v, p.add(u, v);
  for (int i = 1, u, v; i < m; i++) cin >> u >> v, q.add(u, v);
  p.solve(), q.solve();
  for (int i = 0; i <= k; i++)
    ans = mAdd(ans, mMul(c[k][i], mMul(p.ans[i], q.ans[k - i])));
  cout << ans << endl;
  return 0;
}
