import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class C {
	static int max(char c) {
		c -= 'a';
		return Math.max(26 - c, c);
	}

	public static void main(String[] args) throws IOException {
		Reader.init(System.in);
		PrintWriter pw=new PrintWriter(System.out);
		int n = Reader.nextInt();
		int k = Reader.nextInt();
		char c, d;
		int maxdist;
		String line = Reader.nextLine();
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < n; i++) {
			maxdist = max(line.charAt(i));
			if (k - maxdist >= 0) {
				k -= maxdist;
				c = (char) (line.charAt(i) + maxdist-1);
				d = (char) (line.charAt(i) - maxdist+1);
				if (Character.isLowerCase(c)) {
					sb.append(c);
				} else{
					sb.append(d);
				}
			} else {
				c = (char) (line.charAt(i) + k);
				d = (char) (line.charAt(i) - k);
				if (Character.isLowerCase(c)) {
					sb.append(c);
				} else
					sb.append(d);
				k=0;
			}
		}
		if(k!=0)
			System.out.println("-1");
		else {
			pw.println(sb.toString());
			pw.flush();
		}
		pw.close();
	}
}

class Reader {
	static BufferedReader reader;
	static StringTokenizer tokenizer;

	/** call this method to initialize reader for InputStream */
	static void init(InputStream input) {
		reader = new BufferedReader(new InputStreamReader(input));
		tokenizer = new StringTokenizer("");
	}

	/** get next word */
	static String next() throws IOException {
		while (!tokenizer.hasMoreTokens()) {
			// TODO add check for eof if necessary
			tokenizer = new StringTokenizer(reader.readLine());
		}
		return tokenizer.nextToken();
	}

	static int nextInt() throws IOException {
		return Integer.parseInt(next());
	}

	static String nextLine() throws IOException {
		return reader.readLine();
	}

	static double nextDouble() throws IOException {
		return Double.parseDouble(next());
	}
}


import java.util.Scanner;
public class BearAndStringDistance {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		long k = in.nextLong();
		in.nextLine();
		String s = in.nextLine();
		char[] ar = new char[n];
		char c;
		int max;
		boolean nearZ = false;
		boolean nearA = false;
		for (int i = 0; i < n; i++) {
			nearA = false;
			nearZ = false;
			c = s.charAt(i);
			if ('z' - c > c - 'a') {
				max = 'z' - c;
				nearZ = true;
			}
			else {
				max = c - 'a';
				nearA = true;
			}
			if (k >= max) {
				if (nearA) {
					ar[i] = 'a';
				}
				else if (nearZ) {
					ar[i] = 'z';
				}
				k = k - max;
			}
			else {
				if (c + k <= 'z') {
					ar[i] = (char) (c + k);
				}
				else if (c - k >= 'a') {
					ar[i] = (char) (c - k);
				}
				k = k - k;
			}
		}
		if (k > 0) {
			System.out.println(-1);
		}
		else {
			StringBuilder str = new StringBuilder("");
			for (int i = 0; i < n; i++) {
				str.append(ar[i]);
			}
			System.out.println(str);
		}
	}
}


import java.util.Scanner;

public class C {
	public static void main(String[] args){
		Scanner in = new Scanner(System.in);
		int len = in.nextInt();
		int dist = in.nextInt();
		char[] ch = in.next().toCharArray();
		StringBuilder sb = new StringBuilder();
		for(int i = 0; i<ch.length; i++){
		//	System.out.println(dist);
			if(dist==0){
				sb.append(ch[i]);
			}
			else{
				int top = ch[i]-'a';
				int bot = 'z'-ch[i];
				if(top>bot){
					if(dist>=top){
						sb.append("a");
						dist-=top;
					}
					else{
						char now = (char)(ch[i]-dist);
						sb.append(now);
						dist = 0;
					}
				}
				else{
					if(dist>=bot){
						sb.append("z");
						dist-=bot;
					}
					else{
						char now = (char)(ch[i]+dist);
						dist = 0;
						sb.append(now);
					}
				}
			}
		}
		if(dist>0){
			System.out.println(-1);
		}
		else{
			System.out.println(sb.toString());
		}
	}
}


import java.util.*;
import java.io.*;
import java.math.*;

public class Limak {

	public static Integer[] parse(String st) {
		String[] a = st.split(" ");
		Integer[] ar = new Integer[a.length];
		for (int i = 0; i < a.length; i++)
			ar[i] = Integer.parseInt(a[i]);
		return ar;
	}

	public static void solve(String s, int k) {
		StringBuffer out = new StringBuffer();
		for (int i = 0; i < s.length(); i++) {
			char c = s.charAt(i);
			int dmax = dmax(c);
			if (dmax > k) {
				out.append(shift(c, k));
				k = k - k;
			} else {
				out.append(shift(c, dmax));
				k = k - dmax;
			}
		}
		if (k == 0) {
			System.out.println(out.toString());
		} else {
			System.out.println(-1);
		}
	}

	public static char shift(char c, int d) {
		char mid = ('a' + 'z') / 2;
		if (c > mid) {
			return (char) (c - d);
		} else {
			return (char) (c + d);
		}
	}

	public static int dmax(char c) {
		return Math.max( (c - 'a'), ('z' - c) );
	}

	public static void main(String[] args) {
		try {
			InputStreamReader is = new InputStreamReader(System.in);
			BufferedReader br = new BufferedReader(is);
			Integer[] p = parse(br.readLine());
			solve(br.readLine(), p[1]);
		} catch (Exception e) {e.printStackTrace();}
	}

}


import java.util.Scanner;

public class CodeforcesD {

	public static void main(String[] args){
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		int b = in.nextInt();
		String c = in.next();
		char[] s = c.toCharArray();
		for(int i=0; i<s.length; i++){
			if(s[i]-'a'>=b){
				s[i]=(char) (s[i]-b);
				System.out.println(s);
				return;
			}
			if('z'-s[i]>=b){
				s[i]=(char) (s[i]+b);
				System.out.println(s);
				return;
			}
			if(s[i]<='m'){
				b-='z'-s[i];
				s[i]='z';
			}
			else{
				b-=s[i]-'a';
				s[i]='a';
			}
		}
		System.out.println(-1);

	}

}


import java.io.*;
import java.util.*;
public final class string_dis
{
    static FastScanner sc=new FastScanner(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter out=new PrintWriter(System.out);

    public static void main(String args[]) throws Exception
    {
		int n=sc.nextInt(),k=sc.nextInt();
		char[] a=sc.next().toCharArray(),b=a;
		for(int i=0;i<a.length;i++)
		{
			//out.println(k);
			if(k==0)
			{
				break;
			}
			int maxdiff=-1,maxpos=-1;
			for(int j=97;j<=122;j++)
			{
				if(Math.abs(j-a[i])>maxdiff)
				{
					maxdiff=Math.abs(j-a[i]);
					maxpos=j;
				}
			}
			if(maxdiff>=0 && k>=maxdiff)
			{
				b[i]=(char)maxpos;
				k-=maxdiff;
			}
			else if(maxdiff>=0)
			{
				int val1=a[i]+k,val2=a[i]-k;
				if(val1>=97 && val1<=122)
				{
					b[i]=(char)val1;
					k-=k;
				}
				else if(val2>=97 && val2<=122)
				{
					b[i]=(char)val2;
					k-=k;
				}
				else
				{
					continue;
				}
			}
		}
		if(k==0)
		{
			out.println(new String(b));
		}
		else
		{
			out.println("-1");
		}
		out.close();
    }
}
class FastScanner
{
    BufferedReader in;
    StringTokenizer st;

    public FastScanner(BufferedReader in) {
        this.in = in;
    }

    public String nextToken() throws Exception {
        while (st == null || !st.hasMoreTokens()) {
            st = new StringTokenizer(in.readLine());
        }
        return st.nextToken();
    }

	public String next() throws Exception {
		return nextToken().toString();
	}

    public int nextInt() throws Exception {
        return Integer.parseInt(nextToken());
    }

    public long nextLong() throws Exception {
        return Long.parseLong(nextToken());
    }

    public double nextDouble() throws Exception {
        return Double.parseDouble(nextToken());
    }
}


import java.io.InputStreamReader;
import java.io.IOException;
import java.util.InputMismatchException;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		QuickScanner in = new QuickScanner(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskC solver = new TaskC();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskC {
    public void solve(int testNumber, QuickScanner in, PrintWriter out) {
        int n=in.nextInt();
        int k=in.nextInt();
        char s[]=in.next().toCharArray();

        char r[]=new char[n];
        for(int i=0;i<n;i++)
        {
            char to='a';
            int dc=-1;
            int df=Math.abs(to-s[i]);
            if(Math.abs('z'-s[i])>df)
            {
                to='z';
                dc=1;
                df=Math.abs(to-s[i]);
            }
            df=Math.min(df, k);
            r[i]= (char) (s[i]+dc*df);
            k-=df;
        }
        if(k>0)
            out.println(-1);
        else
            out.println(new String(r));

    }
}

class QuickScanner {
    BufferedReader in;
    StringTokenizer token;
    String delim;
    public QuickScanner(InputStream inputStream)
    {
        this.in=new BufferedReader(new InputStreamReader(inputStream));
        this.delim=" \n\t";
        this.token=new StringTokenizer("",delim);
    }

    public boolean hasNext()
    {
        while(!token.hasMoreTokens())
        {
            try {
                String s=in.readLine();
                if(s==null) return false;
                token=new StringTokenizer(s,delim);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
        }
        return true;
    }

    public String next()
    {
        hasNext();
        return token.nextToken();
    }

    public int nextInt()
    {
        return Integer.parseInt(next());
    }

}


import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n=in.nextInt();
		int k=in.nextInt();
		int a[]=new int [n];
		String s=in.next();
		int max1=0;
		for(int i=0;i<n;i++){
			a[i]=s.charAt(i)-'a';
		max1+=Math.max(25-a[i], a[i]-0);
		}
		if(k>max1)System.out.println(-1);
		else{int i=0;
			while(k>0){
				int max=Math.max(25-a[i], a[i]-0);
				if(k>=max){a[i]=(25-a[i]>a[i])?25:0;
				k-=max;
			}
				else {
					if(a[i]+k<=25){a[i]+=k;k=0;}
					else if(a[i]-k>0){
						a[i]-=k;
						k=0;
				}

			}
				i++;
		}
			for(int q:a)System.out.print((char)(q+'a'));
			System.out.println();

	}

}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class ProblemC {

	public static void main(String[] args) {
		InputReader in = new InputReader();
		PrintWriter out = new PrintWriter(System.out);

		new ProblemC().solve(in, out);

		out.close();
	}

	public void solve(InputReader in, PrintWriter out) {
		int n = in.nextInt();
		int k = in.nextInt();

		String s = in.next();

		long max = 0l;
		for (int i = 0; i < n; i++) {
			int d1 = Math.abs(s.charAt(i) - 'a');
			int d2 = Math.abs(s.charAt(i) - 'z');

			max += Math.max(d1, d2);
		}

		if (k > max) {
			out.println(-1);

			return;
		}

		StringBuilder sb = new StringBuilder();

		for (int i = 0; i < n; i++) {
			int d1 = Math.abs(s.charAt(i) - 'a');
			int d2 = Math.abs(s.charAt(i) - 'z');

			char c;
			int m;
			if (d1 >= d2) {
				m = d1;
				c = 'a';
			} else {
				m = d2;
				c = 'z';
			}

			if (k >= m) {
				k -= m;

				sb.append(c);
			} else if (k == 0) {
				sb.append(s.charAt(i));
			} else {
				if (s.charAt(i) - 'a' - k >= 0) {
					sb.append((char)(s.charAt(i) - k));
				} else {
					sb.append((char)(s.charAt(i) + k));
				}

				k = 0;
			}

		}

		out.println(sb.toString());
	}

	static class InputReader {
		public BufferedReader br;
		public StringTokenizer st;

		public InputReader() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		public String next() {
			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
			return st.nextToken();
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}

		long nextLong() {
			return Long.parseLong(next());
		}

		double nextDouble() {
			return Double.parseDouble(next());
		}

		String nextLine() {
			String str = "";
			try {
				str = br.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return str;
		}
	}
}


#include<bits/stdc++.h>
#define int ll
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define Rep(i,a,b) for(register int i=(a);i<=int(b);++i)
#define Dep(i,a,b) for(register int i=(a);i>=int(b);--i)
#define rep(i,a,b) for(register int i=(a);i<int(b);++i)
#define mem(x,v) memset(x,v,sizeof(x))
#define gc getchar
#define pc putchar
inline ll rd(){
    ll x=0,f=1;char c=gc();
    for(;!isdigit(c);c=gc())if(c=='-')f=-1;
    for(;isdigit(c);c=gc())x=(x<<1)+(x<<3)+(c^48);
    return x*f;
}
void write(ll x){if(x<0)x=-x,pc('-');if(x>=10)write(x/10);putchar(x%10+'0');}
void writeln(ll x){write(x);puts("");}
const int mod = 998244353;
const int maxn = 4005;
const int maxk = 45;
int C[88][88];
int k;
void initC(){
	C[0][0] = 1;
	Rep(i,1,2*k){
		C[i][0] = 1;
		Rep(j,1,i){
			C[i][j] = (C[i-1][j-1] + C[i-1][j]) % mod;
		}
	}
}
struct Tree{
	int n;
	vector<int> edge[maxn];
	int fa[maxn],f[maxn],v[maxn];
	int vson[maxn][maxk],vfa[maxn][maxk];
	void read(int _n){
		n = _n;
		Rep(i,1,n) edge[i] . clear();
		rep(i,1,n){
			int x = rd(),y = rd();
			edge[x] . push_back(y);
			edge[y] . push_back(x);
		}
	}
	void dfs(int u){
		for(auto v : edge[u])if(v!=fa[u]){fa[v]=u;dfs(v);}
	}
	void dfs1(int u){
		for(auto v : edge[u])if(v!=fa[u]) dfs1(v);
		vson[u][0] = 1;
		Rep(i,1,k){
			for(auto v : edge[u]){
				if(v != fa[u]){
					Rep(j,0,i-1){
						vson[u][i] = (vson[u][i] + 1ll * vson[u][j] * vson[v][i-j-1] % mod) % mod;
					}
				}
			}
		}
	}
	void dfs2(int u){
		for(auto v : edge[u])if(v!=fa[u])vfa[v][0] = 1;
		Rep(i,1,k){
			static int tmp[maxk];memset(tmp,0,sizeof(tmp));
			Rep(j,0,i-1)tmp[j]=vfa[u][j];
			for(auto v:edge[u])if(v!=fa[u])
				Rep(j,0,i-1) tmp[j]=(tmp[j]+vson[v][j])%mod;
			for(auto v:edge[u])if(v!=fa[u])
				Rep(j,0,i-1) vfa[v][i] = (vfa[v][i] + 1ll * (tmp[j]-vson[v][j]+mod) * vfa[v][i-j-1] % mod) % mod;
		}
		for(auto v : edge[u])if(v!=fa[u]) dfs2(v);
	}
	void init(){
		dfs(1);
		dfs1(1);//sub tree
		dfs2(1);
		Rep(u,1,n){
			memset(f,0,sizeof(f));f[0] = 1;
			Rep(i,1,k){
//				printf("[%d %d]\n",vfa[u][i],vson[u][i]);
				Rep(j,0,i-1){
					f[i] = (f[i] + 1ll * f[j] * vfa[u][i-j-1] % mod) % mod;
				}
				for(auto v : edge[u])if(v!=fa[u]){
					Rep(j,0,i-1){
						f[i] = (f[i] + 1ll * f[j] * vson[v][i-j-1] % mod) % mod;
					}
				}
			}
			Rep(i,0,k) v[i] = (v[i] + f[i]) % mod;
		}
	}
}T1,T2;
signed main(){
//	freopen("1.in","r",stdin);
	int n1,n2;
	n1 = rd(),n2 = rd(),k = rd();
	if(k&1){
		puts("0");
		return 0;
	}k/=2;
	initC();
	T1.read(n1),T2.read(n2);
	T1.init(),T2.init();
	int ans = 0;
	Rep(i,0,k){
//		printf("%lld %lld %lld\n",T1.v[i],T2.v[k-i],C[k*2][i*2]);
		ans = (ans + 1ll * T1.v[i] * T2.v[k-i] % mod * C[k*2][i*2] % mod) % mod;
	}writeln(ans);
	return 0;
}


/*#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")*/
#include<bits/stdc++.h>
#define ll long long
#define N 4005
#define inf 1000000005
#define mod 998244353
#define put putchar('\n')
#define F(i,a,b) for (int i=(a);i<=(b);i++)
#define D(i,a,b) for (int i=(a);i>=(b);i--)
#define go(i,t) for (int i=head[t];i;i=Next[i])
#define sqr(x) ((x)*(x))
#define re register
#define mp make_pair
#define fi first
#define se second
#define int ll
using namespace std;
inline int read(){char c=getchar();int tot=1;while ((c<'0'|| c>'9')&&c!='-') c=getchar();if (c=='-'){tot=-1;c=getchar();}
int sum=0;while (c>='0'&&c<='9'){sum=sum*10+c-'0';c=getchar();}return sum*tot;}
inline void wr(int x){if (x<0) {putchar('-');wr(-x);return;}if(x>=10)wr(x/10);putchar(x%10+'0');}
inline void wrn(int x){wr(x);put;}inline void wri(int x){wr(x);putchar(' ');}
inline void wrn(int x,int y){wri(x);wrn(y);}inline void wrn(int a,int b,int c){wri(a);wrn(b,c);}
int n,m,k,ans,fac[200],inv[200];
inline void tadd(int &x,int k){x+=k;x-=(x>=mod)?mod:0;}
struct xx{
	int n,ans[76],x,y,nedge,Next[N*2],head[N],to[N*2],f[N][76],g[N][76],fa[N],dp[N][76];
	#define V to[i]
	void add(int a,int b){Next[++nedge]=head[a];head[a]=nedge;to[nedge]=b;}
	void dfs(int x){
		g[x][0]=1;
		go(i,x){
			if (V==fa[x]) continue;
			fa[V]=x;dfs(V);
			F(j,0,k) F(j2,0,j-1) tadd(g[x][j],g[V][j-j2-1]);
		}
	}
	void dfs2(int x){
		int z[76];
		F(i,1,k){
			memset(z,0,sizeof(z));
			F(j,0,i-1) z[j]=dp[x][j];
			go(p,x) if (to[p]!=fa[x])
			F(j,0,i-1) tadd(z[j],g[to[p]][j]);
			go(p,x) if (to[p]!=fa[x])
			F(j,0,i-1) tadd(dp[to[p]][i],1LL*dp[to[p]][i-j-1]*((z[j]-g[to[p]][j]+mod)%mod)%mod);
		}
		go(i,x) if (V!=fa[x]) dfs2(V);
	}
	void dp1(){
		F(i,1,n) f[i][0]=1;
		F(i,1,k){
			F(o,1,n){
				F(j,0,i-1) tadd(f[o][i],1LL*f[o][i-j-1]*dp[o][j]%mod);
				go(p,o) if (to[p]!=fa[o])
					F(j,0,i-1){
						tadd(f[o][i],1LL*f[o][i-j-1]*g[to[p]][j]%mod);
					}
			}
		}
		F(i,1,n) F(j,0,k) tadd(ans[j],f[i][j]);
	}
	void init(){
		F(i,1,n-1){x=read();y=read();add(x,y);add(y,x);}
		dfs(1);
		F(i,2,n) dp[i][0]=1;
		dfs2(1);
		dp1();
	}
}a,b;
int ksm(ll x,int k){
	int sum=1;
	while (k){
		if (k&1) sum=sum*x%mod;
		x=x*x%mod;k>>=1;
	}
	return sum;
}
int C(int n,int m){return 1LL*fac[n]*inv[m]%mod*inv[n-m]%mod;}
signed main(){
	a.n=read();b.n=read();k=read();
	if (k&1) return puts("0"),0;
	fac[0]=1;
	F(i,1,k) fac[i]=1LL*fac[i-1]*i%mod;inv[k]=ksm(fac[k],mod-2);
	D(i,k-1,0) inv[i]=1LL*inv[i+1]*(i+1)%mod;
	k/=2;
	a.init();b.init();
	F(i,0,k) tadd(ans,1LL*a.ans[i]*b.ans[k-i]%mod*C(k*2,i*2));
	wrn(ans);
	return 0;
}


#define DEBUG 0

#include <bits/stdc++.h>
using namespace std;

#if DEBUG
// basic debugging macros
int __i__,__j__;
#define printLine(l) for(__i__=0;__i__<l;__i__++){cout<<"-";}cout<<endl
#define printLine2(l,c) for(__i__=0;__i__<l;__i__++){cout<<c;}cout<<endl
#define printVar(n) cout<<#n<<": "<<n<<endl
#define printArr(a,l) cout<<#a<<": ";for(__i__=0;__i__<l;__i__++){cout<<a[__i__]<<" ";}cout<<endl
#define print2dArr(a,r,c) cout<<#a<<":\n";for(__i__=0;__i__<r;__i__++){for(__j__=0;__j__<c;__j__++){cout<<a[__i__][__j__]<<" ";}cout<<endl;}
#define print2dArr2(a,r,c,l) cout<<#a<<":\n";for(__i__=0;__i__<r;__i__++){for(__j__=0;__j__<c;__j__++){cout<<setw(l)<<setfill(' ')<<a[__i__][__j__]<<" ";}cout<<endl;}

// advanced debugging class
// debug 1,2,'A',"test";
class _Debug {
    public:
        template<typename T>
        _Debug& operator,(T val) {
            cout << val << endl;
            return *this;
        }
};
#define debug _Debug(),
#else
#define printLine(l)
#define printLine2(l,c)
#define printVar(n)
#define printArr(a,l)
#define print2dArr(a,r,c)
#define print2dArr2(a,r,c,l)
#define debug
#endif

// define
#define MAX_VAL 999999999
#define MAX_VAL_2 999999999999999999LL
#define EPS 1e-6
#define mp make_pair
#define pb push_back

// typedef
typedef unsigned int UI;
typedef long long int LLI;
typedef unsigned long long int ULLI;
typedef unsigned short int US;
typedef pair<int,int> pii;
typedef pair<LLI,LLI> plli;
typedef vector<int> vi;
typedef vector<LLI> vlli;
typedef vector<pii> vpii;
typedef vector<plli> vplli;

// ---------- END OF TEMPLATE ----------
#define MOD 998244353

int k;
vi adjList1[4000],adjList2[4000];
int ways1[76],ways2[76];
vi dp[4000][4001];
vi sum[4000];
int pp[4000];
int doDFS(int u,int p) {
    if (!dp[u][p].empty()) return 0;
    int i,j;
    if (sum[u].empty()) {
        sum[u].resize(k+1);
        //fill(sum[u].begin(),sum[u].end(),0);
        for (i = 0; i < adjList1[u].size(); i++) {
            int v = adjList1[u][i];
            if (v != p) {
                doDFS(v,u);
                for (j = 0; j <= k; j++) {
                    sum[u][j] += dp[v][u][j];
                    if (sum[u][j] >= MOD) sum[u][j] -= MOD;
                }
            }
        }
        pp[u] = p;
    }
    vi c = sum[u];
    for (i = 0; i < adjList1[u].size(); i++) {
        int v = adjList1[u][i];
        if (v == p) {
            if (v != pp[u]) {
                for (j = 0; j <= k; j++) {
                    c[j] -= dp[v][u][j];
                    if (c[j] < 0) c[j] += MOD;
                }
            }
        }
        else if (v == pp[u]) {
            doDFS(v,u);
            for (j = 0; j <= k; j++) {
                c[j] += dp[v][u][j];
                if (c[j] >= MOD) c[j] -= MOD;
            }
        }
    }
    dp[u][p].resize(k+1);
    dp[u][p][0] = 1;
    for (i = 2; i <= k; i += 2) {
        LLI x = 0;
        for (j = 0; j < i; j += 2) x += ((LLI) c[j]*dp[u][p][i-j-2]) % MOD;
        dp[u][p][i] = x % MOD;
    }
    //cout<<u<<","<<p<<": ";
    //for (i = 0; i <= k; i++) cout << dp[u][p][i]<<" ";
    //cout<<endl;
    return 0;
}
int C[100][100];
int main() {
    int i;
    int n1,n2;
    int u,v;
    scanf("%d %d %d",&n1,&n2,&k);
    for (i = 0; i < n1-1; i++) {
        scanf("%d %d",&u,&v);
        u--,v--;
        adjList1[u].pb(v);
        adjList1[v].pb(u);
    }
    for (i = 0; i < n2-1; i++) {
        scanf("%d %d",&u,&v);
        u--,v--;
        adjList2[u].pb(v);
        adjList2[v].pb(u);
    }
    if (k & 1) {
        printf("0\n");
        return 0;
    }

    int j;
    for (i = 0; i < n1; i++) {
        doDFS(i,n1);
        for (j = 0; j <= k; j++) {
            ways1[j] += dp[i][n1][j];
            if (ways1[j] >= MOD) ways1[j] -= MOD;
        }
    }
    for (i = 0; i < n1; i++) {
        for (j = 0; j <= n1; j++) dp[i][j].clear();
        sum[i].clear();
    }
    for (i = 0; i < 4000; i++) swap(adjList1[i],adjList2[i]);
    swap(n1,n2);
    for (i = 0; i < n1; i++) {
        doDFS(i,n1);
        for (j = 0; j <= k; j++) {
            ways2[j] += dp[i][n1][j];
            if (ways2[j] >= MOD) ways2[j] -= MOD;
        }
    }
    for (i = 0; i < 100; i++) {
        C[i][0] = 1;
        for (j = 1; j <= i; j++) C[i][j] = (C[i-1][j-1]+C[i-1][j]) % MOD;
    }
    LLI ans = 0;
    for (i = 0; i <= k; i += 2) {
        ans += (((LLI) ways1[i]*ways2[k-i]) % MOD)*C[k][i];
        ans %= MOD;
    }
    printf("%I64d\n",ans);

    return 0;
}


#define DEBUG 0

#include <bits/stdc++.h>
using namespace std;

#if DEBUG
// basic debugging macros
int __i__,__j__;
#define printLine(l) for(__i__=0;__i__<l;__i__++){cout<<"-";}cout<<endl
#define printLine2(l,c) for(__i__=0;__i__<l;__i__++){cout<<c;}cout<<endl
#define printVar(n) cout<<#n<<": "<<n<<endl
#define printArr(a,l) cout<<#a<<": ";for(__i__=0;__i__<l;__i__++){cout<<a[__i__]<<" ";}cout<<endl
#define print2dArr(a,r,c) cout<<#a<<":\n";for(__i__=0;__i__<r;__i__++){for(__j__=0;__j__<c;__j__++){cout<<a[__i__][__j__]<<" ";}cout<<endl;}
#define print2dArr2(a,r,c,l) cout<<#a<<":\n";for(__i__=0;__i__<r;__i__++){for(__j__=0;__j__<c;__j__++){cout<<setw(l)<<setfill(' ')<<a[__i__][__j__]<<" ";}cout<<endl;}

// advanced debugging class
// debug 1,2,'A',"test";
class _Debug {
    public:
        template<typename T>
        _Debug& operator,(T val) {
            cout << val << endl;
            return *this;
        }
};
#define debug _Debug(),
#else
#define printLine(l)
#define printLine2(l,c)
#define printVar(n)
#define printArr(a,l)
#define print2dArr(a,r,c)
#define print2dArr2(a,r,c,l)
#define debug
#endif

// define
#define MAX_VAL 999999999
#define MAX_VAL_2 999999999999999999LL
#define EPS 1e-6
#define mp make_pair
#define pb push_back

// typedef
typedef unsigned int UI;
typedef long long int LLI;
typedef unsigned long long int ULLI;
typedef unsigned short int US;
typedef pair<int,int> pii;
typedef pair<LLI,LLI> plli;
typedef vector<int> vi;
typedef vector<LLI> vlli;
typedef vector<pii> vpii;
typedef vector<plli> vplli;

// ---------- END OF TEMPLATE ----------
#define MOD 998244353

int k;
vi adjList1[4000],adjList2[4000];
int ways1[76],ways2[76];
vi dp[4000][4001];
vi sum[4000];
int pp[4000];
int doDFS(int u,int p) {
    if (!dp[u][p].empty()) return 0;
    int i,j;
    if (sum[u].empty()) {
        sum[u].resize(k+1);
        for (i = 0; i < adjList1[u].size(); i++) {
            int v = adjList1[u][i];
            if (v != p) {
                doDFS(v,u);
                for (j = 0; j <= k; j++) {
                    sum[u][j] += dp[v][u][j];
                    if (sum[u][j] >= MOD) sum[u][j] -= MOD;
                }
            }
        }
        pp[u] = p;
    }
    vi c = sum[u];
    for (i = 0; i < adjList1[u].size(); i++) {
        int v = adjList1[u][i];
        if (v == p) {
            if (v != pp[u]) {
                for (j = 0; j <= k; j++) {
                    c[j] -= dp[v][u][j];
                    if (c[j] < 0) c[j] += MOD;
                }
            }
        }
        else if (v == pp[u]) {
            doDFS(v,u);
            for (j = 0; j <= k; j++) {
                c[j] += dp[v][u][j];
                if (c[j] >= MOD) c[j] -= MOD;
            }
        }
    }
    dp[u][p].resize(k+1);
    dp[u][p][0] = 1;
    for (i = 2; i <= k; i += 2) {
        LLI x = 0;
        for (j = 0; j < i; j += 2) x += ((LLI) c[j]*dp[u][p][i-j-2]) % MOD;
        dp[u][p][i] = x % MOD;
    }
    return 0;
}
int C[100][100];
int main() {
    int i;
    int n1,n2;
    int u,v;
    scanf("%d %d %d",&n1,&n2,&k);
    for (i = 0; i < n1-1; i++) {
        scanf("%d %d",&u,&v);
        u--,v--;
        adjList1[u].pb(v);
        adjList1[v].pb(u);
    }
    for (i = 0; i < n2-1; i++) {
        scanf("%d %d",&u,&v);
        u--,v--;
        adjList2[u].pb(v);
        adjList2[v].pb(u);
    }
    if (k & 1) {
        printf("0\n");
        return 0;
    }

    int j;
    for (i = 0; i < n1; i++) {
        doDFS(i,n1);
        for (j = 0; j <= k; j++) {
            ways1[j] += dp[i][n1][j];
            if (ways1[j] >= MOD) ways1[j] -= MOD;
        }
    }
    for (i = 0; i < n1; i++) {
        for (j = 0; j <= n1; j++) dp[i][j].clear();
        sum[i].clear();
    }
    for (i = 0; i < 4000; i++) swap(adjList1[i],adjList2[i]);
    swap(n1,n2);
    for (i = 0; i < n1; i++) {
        doDFS(i,n1);
        for (j = 0; j <= k; j++) {
            ways2[j] += dp[i][n1][j];
            if (ways2[j] >= MOD) ways2[j] -= MOD;
        }
    }
    for (i = 0; i < 100; i++) {
        C[i][0] = 1;
        for (j = 1; j <= i; j++) C[i][j] = (C[i-1][j-1]+C[i-1][j]) % MOD;
    }
    LLI ans = 0;
    for (i = 0; i <= k; i += 2) {
        ans += (((LLI) ways1[i]*ways2[i]) % MOD)*C[k][i];
        ans %= MOD;
    }
    printf("%I64d\n",ans);

    return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
const int MX=4005,MXK=81;
const int md=998244353;

int n1,n2,k;
int f[3][MXK];
vector<int>G[MX];

int fa[MX],g[MX][MXK],gs[MX][MXK],gf[MX][MXK];

#define A(x,y) ((x)=((x)+(ll)(y))%md)

void dfs(int i,int f){
	fa[i]=f;
	for(auto j:G[i])if(j!=f)dfs(j,i);
}
void dfsgs(int i){
	for(auto j:G[i])if(j!=fa[i])dfsgs(j);
	gs[i][0]=1;
	for(int t=2;t<=k;t+=2){
		for(auto j:G[i])if(j!=fa[i])
			for(int l=0;l<=t-2;l+=2)
				A(gs[i][t],(ll)gs[j][l]*gs[i][t-l-2]);
	}
}
void dfsgf(int i){
	for(auto j:G[i])if(j!=fa[i])gf[j][0]=1;
	for(int t=2;t<=k;t+=2){
		static int tmp[MXK];
		memset(tmp,0,sizeof(int)*(k+1));
		for(int q=0;q<=t-2;q+=2)A(tmp[q],gf[i][q]);
		for(auto j:G[i])if(j!=fa[i])
			for(int q=0;q<=t-2;q+=2)
				A(tmp[q],gs[j][q]);
		for(auto j:G[i])if(j!=fa[i]){
			for(int q=0;q<=t-2;q+=2)
				A(tmp[q],md-gs[j][q]);
			for(int q=0;q<=t-2;q+=2)
				A(gf[j][t],(ll)tmp[q]*gf[j][t-q-2]);
			for(int q=0;q<=t-2;q+=2)
				A(tmp[q],gs[j][q]);
		}
	}
	for(auto j:G[i])if(j!=fa[i])dfsgf(j);
}
void solve(int n,int k,int ans[]){
	for(int i=1;i<=n;i++)G[i].clear();
	for(int i=1;i<n;i++){
		int u,v;cin>>u>>v;
		G[u].push_back(v),G[v].push_back(u);
	}
	dfs(1,0);
	memset(g,0,sizeof(g));
	memset(gs,0,sizeof(gs));
	memset(gf,0,sizeof(gf));
	dfsgs(1);
	dfsgf(1);
	for(int i=1;i<=n;i++){
		g[i][0]=1;
		for(int t=2;t<=k;t+=2){
			for(int q=0;q<=t-2;q+=2)
				A(g[i][t],(ll)gf[i][q]*g[i][t-q-2]);
			for(auto j:G[i])if(j!=fa[i]){
				for(int q=0;q<=t-2;q+=2)
					A(g[i][t],(ll)gs[j][q]*g[i][t-q-2]);
			}
		}
		for(int j=0;j<=k;j+=2)A(ans[j],g[i][j]);
	}
}
int C[MXK][MXK];
void ini(){
	for(int i=0;i<MXK;i++)
		for(int j=(C[i][0]=C[i][i]=1);j<i;j++)
			A(C[i][j],C[i-1][j]+C[i-1][j-1]);
}
int main(){
	ios::sync_with_stdio(false);
	cin>>n1>>n2>>k;
	ini();
	solve(n1,k,f[1]);
	solve(n2,k,f[2]);
	int ans=0;
	for(int i=0;i<=k;i+=2){
		A(ans,(ll)f[1][i]*f[2][k-i]%md*C[k][i]);
	}
	cout<<ans<<endl;
	return 0;
}
// r-l=max-min

// f[i][j]:过 i 的长为 j 的环个数
// f[i][j](枚举第一条边...)


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<set>
#include<map>
#include<queue>
using namespace std;
typedef long long ll;
#define sqr(x) ((x)*(x))
#define mp make_pair
inline char gc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
#define gc getchar
inline int read(){
	int x = 0; char ch = gc(); bool positive = 1;
	for (; !isdigit(ch); ch = gc())	if (ch == '-')	positive = 0;
	for (; isdigit(ch); ch = gc())	x = x * 10 + ch - '0';
	return positive ? x : -x;
}
inline void write(int a){
    if(a>=10)write(a/10);
    putchar('0'+a%10);
}
inline void writeln(int a){
    if(a<0){
    	a=-a; putchar('-');
	}
	write(a); puts("");
}
const int N=4005,K=80,mod=998244353;
const ll mod2=(ll)mod*mod;
int n1,n2,k,f[2][N][K],g[2][N][K],ans[2][K],c[K][K],tot;
vector<int> v[N];
void cal(int *g,int *f){
	g[0]=1;
	for(int i=1;i<=k;i++){
		ll jb=0;
		for(int j=1;j<=i;j++){jb+=(ll)f[j]*g[i-j]; if(jb>=mod2)jb-=mod2;}
		g[i]=jb%mod;
		//cout<<g[i]<<" "<<f[1]<<endl;
	}
}
void dfs1(int p,int fa,int id){
	f[id][p][0]=1;
	for(unsigned i=0;i<v[p].size();i++)if(v[p][i]!=fa){
		dfs1(v[p][i],p,id);
		for(int j=1;j<=k;j++)f[id][p][j]=(f[id][p][j]+g[id][v[p][i]][j-1])%mod;
	}
	cal(g[id][p],f[id][p]);
}
void dfs2(int p,int fa,int id){
	cal(g[id][p],f[id][p]);
	//for(int i=1;i<=k;i++)cout<<f[id][p][i]<<" "; puts("");
	//for(int i=1;i<=k;i++)cout<<g[id][p][i]<<" "; puts("");
	//cout<<g[id][p][0]<<" "<<g[id][p][1]<<" "<<g[id][p][2]<<" "<<g[id][p][3]<<endl;
	for(int i=0;i<=k;i++)ans[id][i]=(ans[id][i]+g[id][p][i])%mod;
	for(unsigned i=0;i<v[p].size();i++)if(v[p][i]!=fa){
		for(int j=1;j<=k;j++)f[id][p][j]=(f[id][p][j]-g[id][v[p][i]][j-1])%mod;
		cal(g[id][p],f[id][p]);
		for(int j=1;j<=k;j++)f[id][v[p][i]][j]=(f[id][v[p][i]][j]+g[id][p][j-1])%mod;
		dfs2(v[p][i],p,id);
		for(int j=1;j<=k;j++)f[id][v[p][i]][j]=(f[id][v[p][i]][j]-g[id][p][j-1])%mod;
		cal(g[id][v[p][i]],f[id][v[p][i]]);
		for(int j=1;j<=k;j++)f[id][p][j]=(f[id][p][j]+g[id][v[p][i]][j-1])%mod;
	}
	//cal(g[id][p],f[id][p]);
}
signed main(){
	n1=read(); n2=read(); k=read();
	if(k%2){puts("0"); return 0;}else k/=2;
	for(int i=1;i<n1;i++){
		int s=read(),t=read();
		v[s].push_back(t); v[t].push_back(s);
	}
	dfs1(1,0,0);
	dfs2(1,0,0);
	for(int i=1;i<=n2;i++)v[i].clear();
	for(int i=1;i<n2;i++){
		int s=read(),t=read();
		v[s].push_back(t); v[t].push_back(s);
	}
	dfs1(1,0,1);
	dfs2(1,0,1);
	for(int i=0;i<=k*2;i++){
		c[i][0]=1; for(int j=1;j<=i;j++)c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
	}
	for(int i=0;i<=k;i++)tot=(tot+(ll)c[k*2][i*2]*ans[0][i]%mod*ans[1][k-i])%mod;
	cout<<(tot+mod)%mod<<endl;
}


#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int Mod=998244353;
int k;
struct Edge{
	int v,nxt;
}e[8010];int tot;
int first[4010];
void build(int u,int v)
{
	e[++tot]=(Edge){v,first[u]};
	first[u]=tot;return ;
}
bool book[4010];
int siz[4010];
void getsiz(int u,int lst)
{
	siz[u]=1;
	for(int i=first[u];i;i=e[i].nxt)
	{
		int v=e[i].v;
		if(v==lst||book[v])continue;
		getsiz(v,u);
		siz[u]+=siz[v];
	}
	return ;
}
void getmn(int u,int lst,int S,int& mn,int& rt)
{
	int mx=S-siz[u];
	for(int i=first[u];i;i=e[i].nxt)
	{
		int v=e[i].v;
		if(v==lst||book[v])continue;
		getmn(v,u,S,mn,rt);
		mx=max(mx,siz[v]);
	}
	if(mx<mn){
		mn=mx;
		rt=u;
	}
	return ;
}
int getroot(int u)
{
	getsiz(u,0);
	int rt=0,mn=1e9;
	getmn(u,0,siz[u],mn,rt);
	return rt;
}
int f[4010][81],g[4010][81];
void dfs(int u,int lst,int c)
{
	f[u][c]=g[u][c]=0;
	if(c){
		for(int i=first[u];i;i=e[i].nxt)
		{
			int v=e[i].v;
			if(book[v])continue;
			g[u][c]=(g[u][c]+g[v][c-1])%Mod;
			if(lst)f[u][c]=(f[u][c]+f[v][c-1])%Mod;
		}
	}
	for(int i=first[u];i;i=e[i].nxt)
	{
		int v=e[i].v;
		if(v==lst||book[v])continue;
		dfs(v,u,c);
	}
	return ;
}
int sum[81];
void work(int u,int lst)
{
	for(int i=0;i<=k;i++)
		for(int j=0;j<=i;j++)
			sum[i]=(sum[i]+1ll*f[u][j]*g[u][i-j])%Mod;
	for(int i=first[u];i;i=e[i].nxt)
	{
		int v=e[i].v;
		if(v==lst||book[v])continue;
		work(v,u);
	}
	return ;
}
void divide(int u)
{
	u=getroot(u);
	dfs(u,0,0);
	f[u][0]=g[u][0]=1;
	for(int c=1;c<=k;c++)
		dfs(u,0,c);
	work(u,0);
	book[u]=true;
	for(int i=first[u];i;i=e[i].nxt)
	{
		int v=e[i].v;
		if(book[v])continue;
		divide(v);
	}
	return ;
}
void solve(int n,int* res)
{
	for(int i=1;i<n;i++)
	{
		int u,v;
		scanf("%d %d",&u,&v);
		build(u,v);
		build(v,u);
	}
	divide(1);
	for(int i=0;i<=k;i++)
		res[i]=sum[i];
	memset(first,0,sizeof(first));
	memset(sum,0,sizeof(sum));
	memset(book,0,sizeof(book));
	tot=0;
	return ;
}
int F[81],G[81];
int C[81][81];
int main()
{
	int n1,n2;
	scanf("%d %d %d",&n1,&n2,&k);
	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]=(C[i-1][j-1]+C[i-1][j])%Mod;
	}
	solve(n1,F);
	solve(n2,G);
	int ans=0;
	for(int i=0;i<=k;i++)
		ans=(ans+1ll*F[i]*G[k-i]%Mod*C[k][i])%Mod;
	printf("%d\n",ans);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define mp make_pair
const int maxn=4000,mod=998244353;
int k;
int ans;
int C[80][80];
void inc(int &a,int b)
{
    a=(a+b)%mod;
}
struct wjmzbmr
{
    int n;
    vector<int> g[maxn+5];
    vector<int> dp[80][maxn+5];
    int sum[80][maxn+5];
    int ans[maxn+5],sz[maxn+5];
    map<pair<int,int>,int> s;
    void init()
    {
        for(int i=1;i<n;++i)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            g[u].push_back(v),g[v].push_back(u);
        }
        for(int i=1;i<=n;++i)
            for(int j=0;j<g[i].size();++j)
                s[mp(i,g[i][j])]=j;
        for(int i=1;i<=n;++i) sz[i]=g[i].size(),g[i].push_back(0);
        for(int t=0;t<=k;++t)
            for(int i=0;i<=n;++i)
                dp[t][i].resize(sz[i]+1,0);
    }
    void work()
    {
        for(int i=1;i<=n;++i)
            for(int j=0;j<=sz[i];++j)
            {

                dp[0][i][j]=1;
                inc(sum[0][g[i][j]],1);
            }
        for(int i=2;i<=k;++i)
            for(int u=1;u<=n;++u)
                for(int j=0;j<=sz[u];++j)
                {
                    int v;
                    if(j<sz[u]) v=g[u][j];else v=0;
                    int id;
                    if(v==0) id=0;
                    else
                        id=s[mp(v,u)];
                    for(int t=0;t<=i-2;++t)
                        dp[i][u][j]=((dp[i][u][j]+1LL*dp[i-t-2][u][j]*(sum[t][u]-dp[t][v][id])%mod)%mod+mod)%mod;
                    inc(sum[i][v],dp[i][u][j]);
                }
        for(int i=0;i<=k;i+=2)
            for(int u=1;u<=n;++u)
                inc(ans[i],dp[i][u][sz[u]]);
    }
}tree[2];
int main()
{
    scanf("%d%d%d",&tree[0].n,&tree[1].n,&k);
    tree[0].init(),tree[1].init();
    tree[0].work();
    tree[1].work();
    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]=(C[i-1][j]+C[i-1][j-1])%mod;
    }
    for(int i=0;i<=k;++i)
        inc(ans,int(1LL*tree[0].ans[i]*tree[1].ans[k-i]%mod*C[k][i]%mod));
    printf("%d\n",ans);
    return 0;
}


#include<bits/stdc++.h>
#define nn 4002
#define mod 998244353
#define ll long long
using namespace std;
#define pii pair<int,int>
int nk;
void add(int &x,int y)
{
	x+=y;
	if(x>=mod) x-=mod;
}
struct tree{
	int n;vector<int> v[nn],rev[nn];

	int tot[78];
	vector<int> dp[78][nn];
	vector<int> vis[78][nn];
	vector<int>  sum[78][nn];
	int tql[nn][78];
	void getin()
	{
		for(int i=1;i<n;i++)
		{
			int x,y;scanf("%d%d",&x,&y);
			rev[x].push_back(v[y].size());
			rev[y].push_back(v[x].size());
			v[x].push_back(y);v[y].push_back(x);
		}
		for(int i=1;i<=n;i++)
			for(int j=0;j<78;j++)
				for(int k=0;k<v[i].size();k++)
					dp[j][i].push_back(0),vis[j][i].push_back(0),
						sum[j][i].push_back(j==0),tql[0][i]=1;
	}
	int ctrl;
	int dfs(int x,int p,int ck)
	{
		if(ck==0) return 1;
		if(ck%2) return 0;
		if(vis[ck][x][p]) return dp[ck][x][p];
		vis[ck][x][p]=1;
		dp[ck][x][p]=sum[ck][x][p];
		dp[ck][x][p]%=mod;
		return dp[ck][x][p];
	}

	void solve()
	{
		for(int i=0;i<=nk;i+=2)
		{
			for(int j=1;j<=n;j++)
			{
				int hl=0;
				for(int k=2;k<=i;k+=2)
				{
					int ctot=0;
					for(int l=0;l<v[j].size();l++)
						add(ctot,dfs(v[j][l],rev[j][l],k-2));
					for(int l=0;l<v[j].size();l++)
					{
						add(
						sum[i][j][l],1ll*(mod+ctot-dfs(v[j][l],rev[j][l],k-2))*sum[i-k][j][l]%mod);
					}
					add(
						tql[i][j],1ll*(ctot)*tql[i-k][j]%mod);
				}
				add(tot[i],tql[i][j]);
			}

		}
	}
}t1,t2;
ll f[nn],rf[nn];
ll c(ll x,ll y)
{
	if(x>y) return 0;
	return f[y]*rf[y-x]%mod*rf[x]%mod;
}
ll qpow(ll x,ll y)
{
	ll res=1;
	while(y)
	{
		if(y&1) res=res*x%mod;
		x=x*x%mod;y=y/2;
	}
	return res;
}
int main()
{
	f[0]=1;for(int i=1;i<nn;i++) f[i]=f[i-1]*i%mod;
	rf[nn-1]=qpow(f[nn-1],mod-2);
	for(int i=nn-2;i>=0;i--) rf[i]=rf[i+1]*(i+1)%mod;
	scanf("%d%d%d",&t1.n,&t2.n,&nk);
	t1.getin();t2.getin();
	t1.solve();t2.solve();

	ll ans=0;
	for(int i=0;i<=nk;i++)
	{
		ans+=t1.tot[i]*1ll*t2.tot[nk-i]%mod*c(i,nk)%mod;
		ans%=mod;
	}
	ans+=mod;
	cout<<ans%mod;

	return 0;
}


#include<bits/stdc++.h>
#define nn 4002
#define mod 998244353
#define ll long long
using namespace std;
#define pii pair<int,int>
int nk;
void add(int &x,int y)
{
	x+=y;
	if(x>=mod) x-=mod;
}
struct tree{
	int n;vector<int> v[nn],rev[nn];

	int tot[78];
	vector<int> dp[78][nn];
	vector<int> vis[78][nn];
	vector<int>  sum[78][nn];
	int tql[78][nn];
	void getin()
	{
		for(int i=1;i<n;i++)
		{
			int x,y;scanf("%d%d",&x,&y);
			rev[x].push_back(v[y].size());
			rev[y].push_back(v[x].size());
			v[x].push_back(y);v[y].push_back(x);
		}
		for(int i=1;i<=n;i++)
			for(int j=0;j<77;j++)
				for(int k=0;k<v[i].size();k++)
					dp[j][i].push_back(0),vis[j][i].push_back(0),
						sum[j][i].push_back(j==0),tql[0][i]=1;
	}
	int ctrl;
	int dfs(int x,int p,int ck)
	{
		if(ck==0) return 1;
		if(ck%2) return 0;
		if(vis[ck][x][p]) return dp[ck][x][p];
		vis[ck][x][p]=1;
		dp[ck][x][p]=sum[ck][x][p];
		dp[ck][x][p]%=mod;
		return dp[ck][x][p];
	}

	void solve()
	{
		for(int i=0;i<=nk;i+=2)
		{
			for(int j=1;j<=n;j++)
			{
				int hl=0;
				for(int k=2;k<=i;k+=2)
				{
					int ctot=0;
					for(int l=0;l<v[j].size();l++)
						add(ctot,dfs(v[j][l],rev[j][l],k-2));
					for(int l=0;l<v[j].size();l++)
					{
						add(
						sum[i][j][l],1ll*(mod+ctot-dfs(v[j][l],rev[j][l],k-2))*sum[i-k][j][l]%mod);
					}
					add(
						tql[i][j],1ll*(ctot)*tql[i-k][j]%mod);
				}
				add(tot[i],tql[i][j]);
			}

		}
	}
}t1,t2;
ll f[nn],rf[nn];
ll c(ll x,ll y)
{
	if(x>y) return 0;
	return f[y]*rf[y-x]%mod*rf[x]%mod;
}
ll qpow(ll x,ll y)
{
	ll res=1;
	while(y)
	{
		if(y&1) res=res*x%mod;
		x=x*x%mod;y=y/2;
	}
	return res;
}
int main()
{
	f[0]=1;for(int i=1;i<nn;i++) f[i]=f[i-1]*i%mod;
	rf[nn-1]=qpow(f[nn-1],mod-2);
	for(int i=nn-2;i>=0;i--) rf[i]=rf[i+1]*(i+1)%mod;
	scanf("%d%d%d",&t1.n,&t2.n,&nk);
	t1.getin();t2.getin();
	t1.solve();t2.solve();

	ll ans=0;
	for(int i=0;i<=nk;i++)
	{
		ans+=t1.tot[i]*1ll*t2.tot[nk-i]%mod*c(i,nk)%mod;
		ans%=mod;
	}
	ans+=mod;
	cout<<ans%mod;

	return 0;
}


#include<bits/stdc++.h>
#define nn 4002
#define mod 998244353
#define ll long long
using namespace std;
#define pii pair<int,int>
int nk;
void add(int &x,int y)
{
	x+=y;
	if(x>=mod) x-=mod;
}
struct tree{
	int n;vector<int> v[nn],rev[nn];

	int tot[76];
	vector<int> dp[76][nn];
	vector<int> vis[76][nn];
	int sum[76][nn];
	void getin()
	{
		for(int i=1;i<n;i++)
		{
			int x,y;scanf("%d%d",&x,&y);
			rev[x].push_back(v[y].size());
			rev[y].push_back(v[x].size());
			v[x].push_back(y);v[y].push_back(x);
		}
		for(int i=1;i<=n;i++)
			for(int j=0;j<76;j++)
				for(int k=0;k<v[i].size();k++)
					dp[j][i].push_back(0),vis[j][i].push_back(0);
	}

	int dfs(int x,int p,int ck)
	{
		if(ck==0) return 1;
		if(p==-1) return sum[ck][x];
		if(ck%2) return 0;
		if(vis[ck][x][p]) return dp[ck][x][p];
		vis[ck][x][p]=1;dp[ck][x][p]=sum[ck][x];
		for(int i=2;i<=ck;i++)
			add(dp[ck][x][p],mod-1ll*dfs(v[x][p],rev[x][p],i-2)*dfs(x,p,ck-i)%mod);
		dp[ck][x][p]%=mod;
		return dp[ck][x][p];
	}

	void solve()
	{
		for(int i=0;i<=nk;i++)
		{
			for(int j=1;j<=n;j++)
				for(int k=0;k<v[j].size();k++)
					for(int l=2;l<=i;l++)
						add(sum[i][j],1ll*sum[i-l][j]*dfs(v[j][k],rev[j][k],l-2)%mod);

			for(int j=1;j<=n;j++) sum[0][j]=1,add(tot[i],sum[i][j]);
					//this is wherever i go is ok
		}
	}
}t1,t2;
ll f[nn],rf[nn];
ll c(ll x,ll y)
{
	if(x>y) return 0;
	return f[y]*rf[y-x]%mod*rf[x]%mod;
}
ll qpow(ll x,ll y)
{
	ll res=1;
	while(y)
	{
		if(y&1) res=res*x%mod;
		x=x*x%mod;y=y/2;
	}
	return res;
}
int main()
{
	f[0]=1;for(int i=1;i<nn;i++) f[i]=f[i-1]*i%mod;
	rf[nn-1]=qpow(f[nn-1],mod-2);
	for(int i=nn-2;i>=0;i--) rf[i]=rf[i+1]*(i+1)%mod;
	scanf("%d%d%d",&t1.n,&t2.n,&nk);
	t1.getin();t2.getin();
	t1.solve();t2.solve();

	ll ans=0;
	for(int i=0;i<=nk;i++)
	{
		ans+=t1.tot[i]*1ll*t2.tot[nk-i]%mod*c(i,nk)%mod;
		ans%=mod;
	}
	cout<<ans;

	return 0;
}


#include<bits/stdc++.h>
#define nn 4002
#define mod 998244353
#define ll long long
using namespace std;
#define pii pair<int,int>
int nk;
void add(int &x,int y)
{
	x+=y;
	if(x>=mod) x-=mod;
}
struct tree{
	int n;vector<int> v[nn],rev[nn];

	int tot[78];
	vector<int> dp[78][nn];
	vector<int> vis[78][nn];
	int sum[78][nn];
	void getin()
	{
		for(int i=1;i<n;i++)
		{
			int x,y;scanf("%d%d",&x,&y);
			rev[x].push_back(v[y].size());
			rev[y].push_back(v[x].size());
			v[x].push_back(y);v[y].push_back(x);
		}
		for(int i=1;i<=n;i++)
			for(int j=0;j<78;j++)
				for(int k=0;k<v[i].size();k++)
					dp[j][i].push_back(0),vis[j][i].push_back(0);
	}
	int ctrl;
	int dfs(int x,int p,int ck)
	{
		if(ck==0) return 1;
		if(p==-1) return sum[ck][x];
		if(ck%2) return 0;
		if(vis[ck][x][p]) return dp[ck][x][p];
		vis[ck][x][p]=1;dp[ck][x][p]=sum[ck][x];
		for(int i=2;i<=ck;i+=2)
			add(dp[ck][x][p],mod-1ll*sum[i-2][v[x][p]]*dfs(x,p,ck-i)%mod);
			//if(ctrl) cout<<dp[ck][x][p];
		dp[ck][x][p]%=mod;
		return dp[ck][x][p];
	}

	void solve()
	{
		for(int i=0;i<=nk;i++)
		{
			for(int j=1;j<=n;j++)
				for(int k=0;k<v[j].size();k++)
					for(int l=2;l<=i;l+=2)
						add(sum[i][j],1ll*sum[i-l][j]*dfs(v[j][k],rev[j][k],l-2)%mod);

			for(int j=1;j<=n;j++) sum[0][j]=1,add(tot[i],sum[i][j]);
					//this is wherever i go is ok
		}
	//	cout<<sum[4][1]<<"  ";
	//ctrl=1;vis[4][1][0]=0;
	//	cout<<dfs(1,0,4);ctrl=0;
	//	cout<<sum[6][1]<<" ";
	}
}t1,t2;
ll f[nn],rf[nn];
ll c(ll x,ll y)
{
	if(x>y) return 0;
	return f[y]*rf[y-x]%mod*rf[x]%mod;
}
ll qpow(ll x,ll y)
{
	ll res=1;
	while(y)
	{
		if(y&1) res=res*x%mod;
		x=x*x%mod;y=y/2;
	}
	return res;
}
int main()
{
	f[0]=1;for(int i=1;i<nn;i++) f[i]=f[i-1]*i%mod;
	rf[nn-1]=qpow(f[nn-1],mod-2);
	for(int i=nn-2;i>=0;i--) rf[i]=rf[i+1]*(i+1)%mod;
	scanf("%d%d%d",&t1.n,&t2.n,&nk);
	t1.getin();t2.getin();
	t1.solve();t2.solve();

	ll ans=0;
	for(int i=0;i<=nk;i++)
	{
		ans+=t1.tot[i]*1ll*t2.tot[nk-i]%mod*c(i,nk)%mod;
		ans%=mod;
	}
	cout<<ans;

	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define Rep(i,a,b) for(register int i=(a);i<=int(b);++i)
#define Dep(i,a,b) for(register int i=(a);i>=int(b);--i)
#define rep(i,a,b) for(register int i=(a);i<int(b);++i)
#define mem(x,v) memset(x,v,sizeof(x))
#define gc getchar
#define pc putchar
inline ll rd(){
    ll x=0,f=1;char c=gc();
    for(;!isdigit(c);c=gc())if(c=='-')f=-1;
    for(;isdigit(c);c=gc())x=(x<<1)+(x<<3)+(c^48);
    return x*f;
}
void write(ll x){if(x<0)x=-x,pc('-');if(x>=10)write(x/10);putchar(x%10+'0');}
void writeln(ll x){write(x);puts("");}
const int mod = 998244353;
const int maxn = 4005;
const int maxk = 45;
int C[88][88];
int k;
void initC(){
	C[0][0] = 1;
	Rep(i,1,2*k){
		C[i][0] = 1;
		Rep(j,1,i){
			C[i][j] = C[i-1][j-1] + C[i-1][j];
		}
	}
}
struct Tree{
	int n;
	vector<int> edge[maxn];
	int fa[maxn],f[maxn],v[maxn];
	int vson[maxn][maxk],vfa[maxn][maxk];
	void read(int _n){
		n = _n;
		Rep(i,1,n) edge[i] . clear();
		rep(i,1,n){
			int x = rd(),y = rd();
			edge[x] . push_back(y);
			edge[y] . push_back(x);
		}
	}
	void dfs(int u){
		for(auto v : edge[u])if(v!=fa[u]){fa[v]=u;dfs(v);}
	}
	void dfs1(int u){
		for(auto v : edge[u])if(v!=fa[u]) dfs1(v);
		vson[u][0] = 1;
		Rep(i,1,k){
			for(auto v : edge[u]){
				if(v != fa[u]){
					Rep(j,0,i-1){
						vson[u][i] = (vson[u][i] + 1ll * vson[u][j] * vson[v][i-j-1] % mod) % mod;
					}
				}
			}
		}
	}
	void dfs2(int u){
		for(auto v : edge[u])if(v!=fa[u])vfa[v][0] = 1;
		Rep(i,1,k){
			static int tmp[maxk];memset(tmp,0,sizeof(tmp));
			Rep(j,0,i-1)tmp[j]=vfa[u][j];
			for(auto v:edge[u])if(v!=fa[u])
				Rep(j,0,i-1) tmp[j]=(tmp[j]+vson[v][j])%mod;233
			for(auto v:edge[u])if(v!=fa[u])
				Rep(j,0,i-1) vfa[v][i] = (vfa[v][i] + 1ll * (tmp[j]-vson[v][j]+mod) * vfa[v][i-j-1] % mod) % mod;
		}
		for(auto v : edge[u])if(v!=fa[u]) dfs2(v);
	}
	void init(){
		dfs(1);
		dfs1(1);//sub tree
		dfs2(1);
		Rep(u,1,n){
			memset(f,0,sizeof(f));f[0] = 1;
			Rep(i,1,k){
//				printf("[%d %d]\n",vfa[u][i],vson[u][i]);
				Rep(j,0,i-1){
					f[i] = (f[i] + 1ll * f[j] * vfa[u][i-j-1] % mod) % mod;
				}
				for(auto v : edge[u])if(v!=fa[u]){
					Rep(j,0,i-1){
						f[i] = (f[i] + 1ll * f[j] * vson[v][i-j-1] % mod) % mod;
					}
				}
			}
			Rep(i,0,k) v[i] = (v[i] + f[i]) % mod;
		}
	}
}T1,T2;
int main(){
//	freopen("1.in","r",stdin);
	int n1,n2;
	n1 = rd(),n2 = rd(),k = rd();
	if(k&1){
		puts("0");
		return 0;
	}k/=2;
	initC();
	T1.read(n1),T2.read(n2);
	T1.init(),T2.init();
	int ans = 0;
	Rep(i,0,k){
		ans = (ans + 1ll * T1.v[i] * T2.v[k-i] % mod * C[k*2][i*2] % mod) % mod;
	}writeln(ans);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define Rep(i,a,b) for(register int i=(a);i<=int(b);++i)
#define Dep(i,a,b) for(register int i=(a);i>=int(b);--i)
#define rep(i,a,b) for(register int i=(a);i<int(b);++i)
#define mem(x,v) memset(x,v,sizeof(x))
#define gc getchar
#define pc putchar
inline ll rd(){
    ll x=0,f=1;char c=gc();
    for(;!isdigit(c);c=gc())if(c=='-')f=-1;
    for(;isdigit(c);c=gc())x=(x<<1)+(x<<3)+(c^48);
    return x*f;
}
void write(ll x){if(x<0)x=-x,pc('-');if(x>=10)write(x/10);putchar(x%10+'0');}
void writeln(ll x){write(x);puts("");}
const int mod = 998244353;
const int maxn = 4005;
const int maxk = 45;
int C[88][88];
int k;
void initC(){
	C[0][0] = 1;
	Rep(i,1,2*k){
		C[i][0] = 1;
		Rep(j,1,i){
			C[i][j] = C[i-1][j-1] + C[i-1][j];
		}
	}
}
struct Tree{
	int n;
	vector<int> edge[maxn];
	int fa[maxn],f[maxn],v[maxn];
	int vson[maxn][maxk],vfa[maxn][maxk];
	void read(int _n){
		n = _n;
		Rep(i,1,n) edge[i] . clear();
		rep(i,1,n){
			int x = rd(),y = rd();
			edge[x] . push_back(y);
			edge[y] . push_back(x);
		}
	}
	void dfs(int u){
		for(auto v : edge[u])if(v!=fa[u]){fa[v]=u;dfs(v);}
	}
	void dfs1(int u){
		for(auto v : edge[u])if(v!=fa[u]) dfs1(v);
		vson[u][0] = 1;
		Rep(i,1,k){
			for(auto v : edge[u]){
				if(v != fa[u]){
					Rep(j,0,i-1){
						vson[u][i] = (vson[u][i] + 1ll * vson[u][j] * vson[v][i-j-1] % mod) % mod;
					}
				}
			}
		}
	}
	void dfs2(int u){
		for(auto v : edge[u])if(v!=fa[u])vfa[v][0] = 1;
		Rep(i,1,k){
			static int tmp[maxk];memset(tmp,0,sizeof(tmp));
			Rep(j,0,i-1)tmp[j]=vfa[u][j];
			for(auto v:edge[u])if(v!=fa[u])
				Rep(j,0,i-1) tmp[j]=(tmp[j]+vson[v][j])%mod;
			for(auto v:edge[u])if(v!=fa[u])
				Rep(j,0,i-1) vfa[v][i] = (vfa[v][i] + 1ll * (tmp[j]-vson[v][j]+mod) * vfa[v][i-j-1] % mod) % mod;
		}
		for(auto v : edge[u])if(v!=fa[u]) dfs2(v);
	}
	void init(){
		dfs(1);
		dfs1(1);//sub tree
		dfs2(1);
		Rep(u,1,n){
			memset(f,0,sizeof(f));f[0] = 1;
			Rep(i,1,k){
//				printf("[%d %d]\n",vfa[u][i],vson[u][i]);
				Rep(j,0,i-1){
					f[i] = (f[i] + 1ll * f[j] * vfa[u][i-j-1] % mod) % mod;
				}
				for(auto v : edge[u])if(v!=fa[u]){
					Rep(j,0,i-1){
						f[i] = (f[i] + 1ll * f[j] * vson[v][i-j-1] % mod) % mod;
					}
				}
			}
			Rep(i,0,k) v[i] = (v[i] + f[i]) % mod;
		}
	}
}T1,T2;
int main(){
//	freopen("1.in","r",stdin);
	int n1,n2;
	n1 = rd(),n2 = rd(),k = rd();
	if(k&1){
		puts("0");
		return 0;
	}k/=2;
	initC();
	T1.read(n1),T2.read(n2);
	T1.init(),T2.init();
	int ans = 0;
	Rep(i,0,k){
		ans = (ans + 1ll * T1.v[i] * T2.v[k-i] % mod * C[k*2][i*2] % mod) % mod;
	}writeln(ans);
	return 0;
}


#include <iostream>
#include <vector>
using namespace std;
int N, M, K;
vector <int> G[2][4005];
vector <int> V;
const int MOD = 998244353;
int Res[2][80];
int Sz[4005];
bool Blocked[4005];
int DP[4005][80], DP2[4005][80], C[4005][80];
int Comb[205][205];
void Read()
{
    cin >> N >> M >> K;
    for(int i = 1; i < N; i++)
    {
        int x, y;
        cin >> x >> y;
        G[0][x].push_back(y);
        G[0][y].push_back(x);
    }
    for(int i = 1; i < M; i++)
    {
        int x, y;
        cin >> x >> y;
        G[1][x].push_back(y);
        G[1][y].push_back(x);
    }
}

void DFS(int ind, int node, int father)
{
    Sz[node] = 1;
    V.push_back(node);
    for(int i = 0; i < G[ind][node].size(); i++)
    {
        int neighb = G[ind][node][i];
        if(neighb == father || Blocked[neighb] == 1)
            continue;
        DFS(ind, neighb, node);
        Sz[node] += Sz[neighb];
    }
}

int findCentroid(int ind, int node, int father, int sz)
{
    for(int i = 0; i < G[ind][node].size(); i++)
    {
        int neighb = G[ind][node][i];
        if(neighb == father || Blocked[neighb] == 1)
            continue;
        if(Sz[neighb] > sz / 2)
            return findCentroid(ind, neighb, node, sz);
    }
    return node;
}
inline void Add(int& x, int y)
{
    x += y;
    if(x >= MOD)
        x -= MOD;
}
void Decomposition(int ind, int root, int father)
{
    V.clear();
    DFS(ind, root, 0);
    int centroid = findCentroid(ind, root, 0, Sz[root]);
    for(int i = 0; i < V.size(); i++)
    {
        for(int j = 0; j <= K; j++)
            DP[V[i]][j] = DP2[V[i]][j] = C[V[i]][j] = 0;
    }
    DP[centroid][0] = 1;
    for(int i = 0; i < G[ind][centroid].size(); i++)
    {
        int neighb = G[ind][centroid][i];
        if(Blocked[neighb] == 1)
            continue;
        DP2[neighb][1] = 1;
    }
    for(int k = 1; k <= K; k++)
    {
        for(int i = 0; i < V.size(); i++)
        {
            int node = V[i];
            for(int j = 0; j < G[ind][node].size(); j++)
            {
                int neighb = G[ind][node][j];
                if(Blocked[neighb] == 1)
                    continue;
                Add(DP[node][k], DP[neighb][k - 1]);
                if(k >= 2 && neighb != centroid)
                    Add(DP2[node][k], DP2[neighb][k - 1]);
            }
        }
    }
    for(int i = 0; i < V.size(); i++)
    {
        int node = V[i];
        if(node == centroid)
            continue;
        for(int k = 1; k <= K; k++)
        {
            for(int j = 1; j + k <= K; j++)
            {
                Add(C[node][j + k], (1LL * DP2[node][j] * DP2[node][k]) % MOD);
            }
        }
        for(int j = 1; j <= K; j++)
            for(int k = 0; k +j <= K; k++)
                Add(Res[ind][k + j], (1LL * C[node][j] * DP[centroid][k]) % MOD);
    }
    for(int i = 1; i <= K; i++)
        Add(Res[ind][i], DP[centroid][i]);
    Blocked[centroid] = 1;
    for(int i = 0; i < G[ind][centroid].size(); i++)
    {
        int neighb = G[ind][centroid][i];
        if(Blocked[neighb] == 1)
            continue;
        Decomposition(ind, neighb, centroid);
    }
}
void precalcComb()
{
    for(int i = 0; i <= 200; i++)
        Comb[i][0] = 1;
    for(int i = 1; i <= 200; i++)
    {
        for(int j = 1; j <= i; j++)
        {
            Comb[i][j] = Comb[i - 1][j];
            Add(Comb[i][j], Comb[i - 1][j - 1]);
        }
    }
}

void Solve()
{
    Decomposition(0, 1, 0);
     for(int i = 1; i <= N; i++)
        Blocked[i] = 0;
    Decomposition(1, 1, 0);
    Res[0][0] = N;
    Res[1][0] = M;
    int ans = 0;
    for(int i = 0; i <= K; i++)
    {
        int aux = 0;
        aux = (1LL * Res[0][i] * Res[1][K - i]) % MOD;
        aux = (1LL * aux * Comb[K][i]) % MOD;
        Add(ans, aux);
    }
    cout << ans << "\n";
}
int main()
{
    Read();
    precalcComb();
    Solve();
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

const int MOD = 998244353;
const int K = 80;
const int N = 4010;

int n, m, k, C[K][K], vtx[2 * N], v_cyc[K][N], e_cyc[K][2 * N], trip[2][K], ans;
vector<int> g[N];

int main() {
  cin >> n >> m >> k;
  if (k & 1) {
    cout << "0\n";
    return 0;
  }

  // pascal's triangle
  for (int a = 0; a <= k; a++) {
    C[a][0] = 1;
    for (int b = 1; b <= a; b++) {
      C[a][b] = C[a - 1][b - 1] + C[a - 1][b];
      if (C[a][b] >= MOD) C[a][b] -= MOD;
    }
  }

  // count k-cycles in each tree
  for (int it = 0; it < 2; it++, swap(n, m)) {
    for (int i = 0; i < n; i++) g[i].clear();
    for (int i = 0; i < n - 1; i++) {
      int u, v; cin >> u >> v; u--; v--;
      g[u].push_back(i * 2); vtx[i * 2] = v;
      g[v].push_back(i * 2 + 1); vtx[i * 2 + 1] = u;
    }
    fill(*e_cyc, *e_cyc + 2 * K * N, 0);
    fill(e_cyc[0], e_cyc[0] + 2 * N, 1);
    fill(e_cyc[2], e_cyc[2] + 2 * N, 1);
    for (int i = 4; i <= k; i += 2) {
      for (int j = 2; j < i; j += 2) {
        for (int u = 0; u < n; u++) {
          int sum = 0;
          for (int e : g[u]) {
            sum += e_cyc[j][e];
            if (sum >= MOD) sum -= MOD;
          }
          for (int e : g[u]) {
            e_cyc[i][e ^ 1] += 1LL * (sum + MOD - e_cyc[j][e]) * e_cyc[i - j][e ^ 1] % MOD;
            if (e_cyc[i][e ^ 1] >= MOD) e_cyc[i][e ^ 1] -= MOD;
          }
        }
      }
    }
    fill(*v_cyc, *v_cyc + K * N, 0);
    fill(v_cyc[0], v_cyc[0] + n, 1);
    for (int i = 2; i <= k; i += 2) {
      for (int j = 2; j <= i; j += 2) {
        for (int u = 0; u < n; u++) {
          for (int e : g[u]) {
            v_cyc[i][u] += 1LL * e_cyc[j][e] * v_cyc[i - j][u] % MOD;
            if (v_cyc[i][u] >= MOD) v_cyc[i][u] -= MOD;
          }
        }
      }
    }
    for (int i = 0; i <= k; i++) {
      for (int u = 0; u < n; u++) {
        trip[it][i] += v_cyc[i][u];
        if (trip[it][i] >= MOD) trip[it][i] -= MOD;
      }
    }
  }
  for (int i = 0; i <= k; i += 2) {
    ans += 1LL * trip[0][i] * trip[1][k - i] % MOD * C[k][i] % MOD;
    if (ans >= MOD) ans -= MOD;
  }
  cout << ans << '\n';
}


#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

int readint(){
	int x=0,f=1; char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}

const int cys=998244353;

int mod(int x){return x>=cys?x-cys:x;}

ll qpow(ll x,ll p){
	ll ret=1;
	for(;p;p>>=1,x=x*x%cys) if(p&1) ret=ret*x%cys;
	return ret;
}

struct Graph{
	int n,k,tot;
	int v[8005],nxt[8005],rev[8005],h[4005];
	ll dv[8005][80],adv[8005][80],dp[4005][80],adp[4005][80],res[80];
	void addedge(int x,int y){
		v[++tot]=y; rev[tot]=tot+1; nxt[tot]=h[x]; h[x]=tot;
		v[++tot]=x; rev[tot]=tot-1; nxt[tot]=h[y]; h[y]=tot;
	}
	void solve(){
		for(int i=1;i<=n;i++){
			dp[i][0]=adp[i][0]=1;
			for(int p=h[i];p;p=nxt[p]) dv[p][0]=adv[p][0]=1;
		}
		res[0]+=n;
		for(int i=2;i<=k;i+=2){
			for(int j=1;j<=n;j++){
				dp[j][i]=adp[j][i]=0;
				for(int p=h[j];p;p=nxt[p]) dp[j][i]=mod(dp[j][i]+adv[p][i-2]);
				for(int l=2;l<=i;l+=2) adp[j][i]=mod(adp[j][i]+dp[j][l]*adp[j][i-l]%cys);
				res[i]=mod(res[i]+adp[j][i]);
			}
			for(int j=1;j<=n;j++){
				for(int p=h[j];p;p=nxt[p]){
					dv[p][i]=mod(dp[v[p]][i]+cys-adv[rev[p]][i-2]),adv[p][i]=0;
					for(int l=2;l<=i;l+=2) adv[p][i]=mod(adv[p][i]+dv[p][l]*adv[p][i-l]%cys);
				}
			}
		}
	}
}G1,G2;

ll fac[4005],inv[4005];

int main(){
	G1.n=readint(); G2.n=readint(); G1.k=G2.k=readint();
	fac[0]=inv[0]=1;
	for(int i=1;i<=G1.k;i++) fac[i]=fac[i-1]*i%cys;
	inv[G1.k]=qpow(fac[G1.k],cys-2);
	for(int i=G1.k-1;i>=1;i--) inv[i]=inv[i+1]*(i+1)%cys;
	for(int i=1;i<=G1.n-1;i++) G1.addedge(readint(),readint());
	for(int i=1;i<=G2.n-1;i++) G2.addedge(readint(),readint());
	G1.solve(); G2.solve();
	ll ans=0;
	for(int i=0;i<=G1.k;i++) ans=mod(ans+G1.res[i]*G2.res[G1.k-i]%cys*fac[G1.k]%cys*inv[i]%cys*inv[G1.k-i]%cys);
	cout<<ans<<endl;
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint ungigned
#define db double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pli pair<ll,int>
#define vi vector<int>
#define vpi vector<pii >
#define IT iterator

#define PB push_back
#define MK make_pair
#define LB lower_bound
#define UB upper_bound
#define y1 wzpakking
#define fi first
#define se second
#define BG begin
#define ED end

#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define UPD(x,y) (((x)+=(y))>=mo?(x)-=mo:233)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));

#define LS3 k*2,l,mid
#define RS3 k*2+1,mid+1,r
#define LS5 k*2,l,mid,x,y
#define RS5 k*2+1,mid+1,r,x,y
#define GET pushdown(k);int mid=(l+r)/2

#define INF (1ll<<60)
using namespace std;

const int mo=998244353;
const int N=4005;
const int M=40;
int n1,n2,k;
struct tree{
	vi e[N];
	int vson[N][M];
	int vfa[N][M];
	int f[M],v[M],fa[N];
	void dfs(int x){
		for (auto to:e[x]) if (to!=fa[x])
			fa[to]=x,dfs(to);
	}
	void dfs1(int x){
		for (auto to:e[x]) if (to!=fa[x]) dfs1(to);
		vson[x][0]=1;
		For(i,1,k) for (auto to:e[x]) if(to!=fa[x])
			For(j,0,i-1) UPD(vson[x][i],1ll*vson[x][j]*vson[to][i-j-1]%mo);
	}
	void dfs2(int x){
		for (auto to:e[x]) if (to!=fa[x]) vfa[to][0]=1;
		For(i,1,k){
			static int tmp[M]; CLR(tmp,0);
			For(j,0,i-1) UPD(tmp[j],vfa[x][j]);
			for (auto to:e[x]) if (to!=fa[x])
				For(j,0,i-1) UPD(tmp[j],vson[to][j]);
			for (auto to:e[x]) if (to!=fa[x]){
				For(j,0,i-1) UPD(tmp[j],mo-vson[to][j]);
				For(j,0,i-1) UPD(vfa[to][i],1ll*tmp[j]*vfa[to][i-j-1]);
				For(j,0,i-1) UPD(tmp[j],vson[to][j]);
			}
		}
		for (auto to:e[x]) if (to!=fa[x]) dfs2(to);
	}
	void init(int n){
		For(i,1,n-1){
			int x,y;
			scanf("%d%d",&x,&y);
			e[x].PB(y); e[y].PB(x);
		}
		dfs(1); dfs1(1); dfs2(1);
		For(id,1,n){
			CLR(f,0); f[0]=1;
			For(i,1,k){
				For(j,0,i-1) UPD(f[i],1ll*f[j]*vfa[id][i-j-1]);
				for (auto to:e[id]) if (to!=fa[id])
					For(j,0,i-1) UPD(f[i],1ll*f[j]*vson[to][i-j-1]);
			}
			For(i,0,k)
				UPD(v[i],f[i]);
		}
	}
}T1,T2;
int c[80][80],ans;
int main(){
	For(i,0,75) c[i][0]=1;
	For(i,1,75) For(j,1,i) c[i][j]=(c[i-1][j]+c[i-1][j-1])%mo;
	scanf("%d%d%d",&n1,&n2,&k);
	if (k&1) return puts("0"),0;
	k/=2; T1.init(n1); T2.init(n2);
	For(i,0,k) UPD(ans,1ll*T1.v[i]*T2.v[k-i]%mo*c[k*2][i*2]%mo);
	printf("%d\n",ans);
}


#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint ungigned
#define db double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pli pair<ll,int>
#define vi vector<int>
#define vpi vector<pii >
#define IT iterator

#define PB push_back
#define MK make_pair
#define LB lower_bound
#define UB upper_bound
#define y1 wzpakking
#define fi first
#define se second
#define BG begin
#define ED end

#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define UPD(x,y) (((x)+=(y))>=mo?(x)-=mo:233)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));

#define LS3 k*2,l,mid
#define RS3 k*2+1,mid+1,r
#define LS5 k*2,l,mid,x,y
#define RS5 k*2+1,mid+1,r,x,y
#define GET pushdown(k);int mid=(l+r)/2

#define INF (1ll<<60)
using namespace std;

const int mo=998244353;
struct edge{
	int to,next;
};
const int N=4005;
struct tree{
	edge e[N*2];
	int head[N],tot;
	int f[2][N],v[80];
	void add(int x,int y){
		e[++tot]=(edge){y,head[x]};
		head[x]=tot;
	}
	void init(int n,int k){
		For(i,1,n-1){
			int x,y; scanf("%d%d",&x,&y);
			add(x,y); add(y,x);
		}
		CLR(v,0);
		For(id,1,n){
			CLR(f,0); f[0][id]=1; v[0]++;
			For(T,1,k){
				For(i,1,n) if (f[(T&1)^1][i]){
					int v=f[(T&1)^1][i]; f[(T&1)^1][i]=0;
					for (int j=head[i];j;j=e[j].next) UPD(f[T&1][e[j].to],v);
				}
				UPD(v[T],f[T&1][id]);
			}
		}
		For(i,1,k) For(j,2,k/i) UPD(v[i*j],mo-v[i]);
		Rep(i,k,1) For(j,2,k/i) UPD(v[i*j],v[i]);
	}
}T1,T2;
int c[80][80];
int n1,n2,k,ans;
int main(){
	For(i,0,75) c[i][0]=1;
	For(i,1,75) For(j,1,i) c[i][j]=(c[i-1][j]+c[i-1][j-1])%mo;
	scanf("%d%d%d",&n1,&n2,&k);
	T1.init(n1,k); T2.init(n2,k);
	For(i,0,k) UPD(ans,1ll*T1.v[i]*T2.v[k-i]%mo*c[k][i]%mo);
	printf("%d\n",ans);
}


#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint ungigned
#define db double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pli pair<ll,int>
#define vi vector<int>
#define vpi vector<pii >
#define IT iterator

#define PB push_back
#define MK make_pair
#define LB lower_bound
#define UB upper_bound
#define y1 wzpakking
#define fi first
#define se second
#define BG begin
#define ED end

#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define UPD(x,y) (((x)+=(y))>=mo?(x)-=mo:233)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));

#define LS3 k*2,l,mid
#define RS3 k*2+1,mid+1,r
#define LS5 k*2,l,mid,x,y
#define RS5 k*2+1,mid+1,r,x,y
#define GET pushdown(k);int mid=(l+r)/2

#define INF (1ll<<60)
using namespace std;

const int mo=998244353;
struct edge{
	int to,next;
};
const int N=4005;
struct tree{
	edge e[N*2];
	int head[N],tot;
	int f[2][N],v[80];
	void add(int x,int y){
		e[++tot]=(edge){y,head[x]};
		head[x]=tot;
	}
	void init(int n,int k){
		For(i,1,n-1){
			int x,y; scanf("%d%d",&x,&y);
			add(x,y); add(y,x);
		}
		CLR(v,0);
		For(id,1,n){
			CLR(f,0); f[0][id]=1; v[0]++;
			For(T,1,(k+1)/2){
				CLR(f[T&1],0);
				For(i,1,n) if (f[(T&1)^1][i]){
					int v=f[(T&1)^1][i];
					for (int j=head[i];j;j=e[j].next) UPD(f[T&1][e[j].to],v);
				}
				For(i,1,n){
					UPD(v[T*2-1],1ll*f[T&1][i]*f[(T&1)^1][i]);
					UPD(v[T*2],1ll*f[T&1][i]*f[T&1][i]);
				}
			}
		}
		//For(i,1,k) v[i]=1ll*v[i]*i%mo;
		For(i,1,k) For(j,2,k/i) UPD(v[i*j],mo-v[i]);
		Rep(i,k,1) For(j,2,k/i) UPD(v[i*j],v[i]);
	}
}T1,T2;
int c[80][80];
int n1,n2,k,ans;
int main(){
	For(i,0,75) c[i][0]=1;
	For(i,1,75) For(j,1,i) c[i][j]=(c[i-1][j]+c[i-1][j-1])%mo;
	scanf("%d%d%d",&n1,&n2,&k);
	T1.init(n1,k); T2.init(n2,k);
	For(i,0,k) UPD(ans,1ll*T1.v[i]*T2.v[k-i]%mo*c[k][i]%mo);
	printf("%d\n",ans);
}


#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint ungigned
#define db double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pli pair<ll,int>
#define vi vector<int>
#define vpi vector<pii >
#define IT iterator

#define PB push_back
#define MK make_pair
#define LB lower_bound
#define UB upper_bound
#define y1 wzpakking
#define fi first
#define se second
#define BG begin
#define ED end

#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define UPD(x,y) (((x)+=(y))>=mo?(x)-=mo:233)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));

#define LS3 k*2,l,mid
#define RS3 k*2+1,mid+1,r
#define LS5 k*2,l,mid,x,y
#define RS5 k*2+1,mid+1,r,x,y
#define GET pushdown(k);int mid=(l+r)/2

#define INF (1ll<<60)
using namespace std;

const int mo=998244353;
struct edge{
	int to,next;
};
const int N=4005;
int vis[N];
struct tree{
	edge e[N*2];
	int head[N],tot;
	int f[2][N],v[80];
	void add(int x,int y){
		e[++tot]=(edge){y,head[x]};
		head[x]=tot;
	}
	void init(int n,int k){
		For(i,1,n-1){
			int x,y; scanf("%d%d",&x,&y);
			add(x,y); add(y,x);
		}
		CLR(v,0);
		For(id,1,n){
			CLR(f,0); CLR(vis,0);
			f[0][id]=1; v[0]++;
			For(T,1,k/2){
				For(i,1,n) if (vis[i]==T-1){
					int &v=f[(T&1)^1][i];
					for (int j=head[i];j;j=e[j].next) UPD(f[T&1][e[j].to],v);
					v=0;
				}
				For(i,1,n)
					if (f[T&1][i])
						UPD(v[T*2],1ll*f[T&1][i]*f[T&1][i]%mo),vis[i]=T;
			}
		}
		For(i,1,k) For(j,2,k/i) UPD(v[i*j],mo-v[i]);
		Rep(i,k,1) For(j,2,k/i) UPD(v[i*j],v[i]);
	}
}T1,T2;
int c[80][80];
int n1,n2,k,ans;
int main(){
	For(i,0,75) c[i][0]=1;
	For(i,1,75) For(j,1,i) c[i][j]=(c[i-1][j]+c[i-1][j-1])%mo;
	scanf("%d%d%d",&n1,&n2,&k);
	if (k&1) return puts("0"),0;
	T1.init(n1,k);
	T2.init(n2,k);
	For(i,0,k) UPD(ans,1ll*T1.v[i]*T2.v[k-i]%mo*c[k][i]%mo);
	printf("%d\n",ans);
}


#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint ungigned
#define db double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pli pair<ll,int>
#define vi vector<int>
#define vpi vector<pii >
#define IT iterator

#define PB push_back
#define MK make_pair
#define LB lower_bound
#define UB upper_bound
#define y1 wzpakking
#define fi first
#define se second
#define BG begin
#define ED end

#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define UPD(x,y) (((x)+=(y))>=mo?(x)-=mo:233)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));

#define LS3 k*2,l,mid
#define RS3 k*2+1,mid+1,r
#define LS5 k*2,l,mid,x,y
#define RS5 k*2+1,mid+1,r,x,y
#define GET pushdown(k);int mid=(l+r)/2

#define INF (1ll<<60)
using namespace std;

const int mo=998244353;
struct edge{
	int to,next;
};
const int N=4005;
struct tree{
	edge e[N*2];
	int head[N],tot;
	int f[2][N],v[80];
	int v1[80],v2[80];
	void add(int x,int y){
		e[++tot]=(edge){y,head[x]};
		head[x]=tot;
	}
	void init(int n,int k){
		For(i,1,n-1){
			int x,y; scanf("%d%d",&x,&y);
			add(x,y); add(y,x);
		}
		CLR(v,0);
		For(id,1,n){
			CLR(f,0); CLR(v1,0);
			f[0][id]=1; v[0]++;
			For(T,1,k){
				For(i,id,n) if (f[(T&1)^1][i]){
					int &v=f[(T&1)^1][i];
					for (int j=head[i];j;j=e[j].next) UPD(f[T&1][e[j].to],v);
					v=0;
				}
				For(i,id,n)
					UPD(v1[T],1ll*f[T&1][i]*f[T&1][i]%mo);
			}
			CPY(v2,v1);
			For(i,2,k) For(j,1,i-1) UPD(v1[i],mo-1ll*v1[j]*v2[i-j]%mo);
			CLR(v2,0); v2[0]=1;
			For(i,1,k) For(j,0,i-1) UPD(v2[i],1ll*v2[j]*v1[i-j]%mo);
			For(i,1,k) UPD(v[i],v2[i]);
		}
		For(i,1,k) v[i]=1ll*v[i]*i*2%mo;
		For(i,1,k) For(j,2,k/i) UPD(v[i*j],mo-1ll*v[i]*j%mo);
		Rep(i,k,1) For(j,2,k/i) UPD(v[i*j],v[i]);
	}
}T1,T2;
int c[80][80];
int n1,n2,k,ans;
int main(){
	For(i,0,75) c[i][0]=1;
	For(i,1,75) For(j,1,i) c[i][j]=(c[i-1][j]+c[i-1][j-1])%mo;
	scanf("%d%d%d",&n1,&n2,&k);
	if (k&1) return puts("0"),0; k/=2;
	T1.init(n1,k); T2.init(n2,k);
	For(i,0,k) UPD(ans,1ll*T1.v[i]*T2.v[k-i]%mo*c[2*k][2*i]%mo);
	printf("%d\n",ans);
	//1->A->B
}


#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint ungigned
#define db double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pli pair<ll,int>
#define vi vector<int>
#define vpi vector<pii >
#define IT iterator

#define PB push_back
#define MK make_pair
#define LB lower_bound
#define UB upper_bound
#define y1 wzpakking
#define fi first
#define se second
#define BG begin
#define ED end

#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define UPD(x,y) (((x)+=(y))>=mo?(x)-=mo:233)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));

#define LS3 k*2,l,mid
#define RS3 k*2+1,mid+1,r
#define LS5 k*2,l,mid,x,y
#define RS5 k*2+1,mid+1,r,x,y
#define GET pushdown(k);int mid=(l+r)/2

#define INF (1ll<<60)
using namespace std;

const int mo=998244353;
struct edge{
	int to,next;
};
const int N=4005;
struct tree{
	edge e[N*2];
	int head[N],tot;
	int f[2][N],v[80];
	void add(int x,int y){
		e[++tot]=(edge){y,head[x]};
		head[x]=tot;
	}
	void init(int n,int k){
		For(i,1,n-1){
			int x,y; scanf("%d%d",&x,&y);
			add(x,y); add(y,x);
		}
		CLR(v,0);
		For(id,1,n){
			CLR(f,0); f[0][id]=1; v[0]++;
			For(T,1,k/2){
				CLR(f[T&1],0);
				For(i,1,n) if (f[(T&1)^1][i]){
					int v=f[(T&1)^1][i];
					for (int j=head[i];j;j=e[j].next) UPD(f[T&1][e[j].to],v);
				}
				For(i,1,n)
					UPD(v[T*2],1ll*f[T&1][i]*f[T&1][i]);
			}
		}
		For(i,1,k) For(j,2,k/i) UPD(v[i*j],mo-v[i]);
		Rep(i,k,1) For(j,2,k/i) UPD(v[i*j],v[i]);
	}
}T1,T2;
int c[80][80];
int n1,n2,k,ans;
int main(){
	For(i,0,75) c[i][0]=1;
	For(i,1,75) For(j,1,i) c[i][j]=(c[i-1][j]+c[i-1][j-1])%mo;
	scanf("%d%d%d",&n1,&n2,&k);
	if (k&1) return puts("0"),0;
	T1.init(n1,k); T2.init(n2,k);
	For(i,0,k) UPD(ans,1ll*T1.v[i]*T2.v[k-i]%mo*c[k][i]%mo);
	printf("%d\n",ans);
}


#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint ungigned
#define db double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pli pair<ll,int>
#define vi vector<int>
#define vpi vector<pii >
#define IT iterator

#define PB push_back
#define MK make_pair
#define LB lower_bound
#define UB upper_bound
#define y1 wzpakking
#define fi first
#define se second
#define BG begin
#define ED end

#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define UPD(x,y) (((x)+=(y))>=mo?(x)-=mo:233)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));

#define LS3 k*2,l,mid
#define RS3 k*2+1,mid+1,r
#define LS5 k*2,l,mid,x,y
#define RS5 k*2+1,mid+1,r,x,y
#define GET pushdown(k);int mid=(l+r)/2

#define INF (1ll<<60)
using namespace std;

const int mo=998244353;
struct edge{
	int to,next;
};
const int N=4005;
struct tree{
	edge e[N*2];
	int head[N],tot;
	int f[2][N],v[80];
	void add(int x,int y){
		e[++tot]=(edge){y,head[x]};
		head[x]=tot;
	}
	void init(int n,int k){
		For(i,1,n-1){
			int x,y; scanf("%d%d",&x,&y);
			add(x,y); add(y,x);
		}
		CLR(v,0);
		For(id,1,n){
			CLR(f,0); f[0][id]=1; v[0]++;
			For(T,1,k/2){
				CLR(f[T&1],0);
				For(i,1,n) if (f[(T&1)^1][i]){
					int v=f[(T&1)^1][i];
					for (int j=head[i];j;j=e[j].next) UPD(f[T&1][e[j].to],v);
				}
				For(i,1,n)
					UPD(v[T*2],1ll*f[T&1][i]*f[T&1][i]%mo);
			}
		}
		For(i,1,k) For(j,2,k/i) UPD(v[i*j],mo-v[i]);
		Rep(i,k,1) For(j,2,k/i) UPD(v[i*j],v[i]);
	}
}T1,T2;
int c[80][80];
int n1,n2,k,ans;
int main(){
	For(i,0,75) c[i][0]=1;
	For(i,1,75) For(j,1,i) c[i][j]=(c[i-1][j]+c[i-1][j-1])%mo;
	scanf("%d%d%d",&n1,&n2,&k);
	if (k&1) return puts("0"),0;
	T1.init(n1,k); T2.init(n2,k);
	For(i,0,k) UPD(ans,1ll*T1.v[i]*T2.v[k-i]%mo*c[k][i]%mo);
	printf("%d\n",ans);
}


#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint ungigned
#define db double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pli pair<ll,int>
#define vi vector<int>
#define vpi vector<pii >
#define IT iterator

#define PB push_back
#define MK make_pair
#define LB lower_bound
#define UB upper_bound
#define y1 wzpakking
#define fi first
#define se second
#define BG begin
#define ED end

#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define UPD(x,y) (((x)+=(y))>=mo?(x)-=mo:233)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));

#define LS3 k*2,l,mid
#define RS3 k*2+1,mid+1,r
#define LS5 k*2,l,mid,x,y
#define RS5 k*2+1,mid+1,r,x,y
#define GET pushdown(k);int mid=(l+r)/2

#define INF (1ll<<60)
using namespace std;

const int mo=998244353;
struct edge{
	int to,next;
};
const int N=4005;
struct tree{
	edge e[N*2];
	int head[N],tot;
	int f[2][N],v[80];
	void add(int x,int y){
		e[++tot]=(edge){y,head[x]};
		head[x]=tot;
	}
	void init(int n,int k){
		For(i,1,n-1){
			int x,y; scanf("%d%d",&x,&y);
			add(x,y); add(y,x);
		}
		CLR(v,0);
		For(id,1,n){
			CLR(f,0); f[0][id]=1; v[0]++;
			For(T,1,k/2){
				For(i,1,n) if (f[(T&1)^1][i]){
					int v=f[(T&1)^1][i];
					for (int j=head[i];j;j=e[j].next) UPD(f[T&1][e[j].to],v);
				}
				if (k/2%T==0)
					For(i,1,n)
						UPD(v[T*2],1ll*f[T&1][i]*f[T&1][i]%mo);
			}
		}
		For(i,1,k) For(j,2,k/i) UPD(v[i*j],mo-v[i]);
		Rep(i,k,1) For(j,2,k/i) UPD(v[i*j],v[i]);
	}
}T1,T2;
int c[80][80];
int n1,n2,k,ans;
int main(){
	For(i,0,75) c[i][0]=1;
	For(i,1,75) For(j,1,i) c[i][j]=(c[i-1][j]+c[i-1][j-1])%mo;
	scanf("%d%d%d",&n1,&n2,&k);
	if (k&1) return puts("0"),0;
	T1.init(n1,k);	T2.init(n2,k);
	For(i,0,k) UPD(ans,1ll*T1.v[i]*T2.v[k-i]%mo*c[k][i]%mo);
	printf("%d\n",ans);
}


#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint ungigned
#define db double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pli pair<ll,int>
#define vi vector<int>
#define vpi vector<pii >
#define IT iterator

#define PB push_back
#define MK make_pair
#define LB lower_bound
#define UB upper_bound
#define y1 wzpakking
#define fi first
#define se second
#define BG begin
#define ED end

#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define UPD(x,y) (((x)+=(y))>=mo?(x)-=mo:233)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));

#define LS3 k*2,l,mid
#define RS3 k*2+1,mid+1,r
#define LS5 k*2,l,mid,x,y
#define RS5 k*2+1,mid+1,r,x,y
#define GET pushdown(k);int mid=(l+r)/2

#define INF (1ll<<60)
using namespace std;

const int mo=998244353;
struct edge{
	int to,next;
};
const int N=4005;
struct tree{
	edge e[N*2];
	int head[N],tot;
	int f[2][N],v[80];
	void add(int x,int y){
		e[++tot]=(edge){y,head[x]};
		head[x]=tot;
	}
	void init(int n,int k){
		For(i,1,n-1){
			int x,y; scanf("%d%d",&x,&y);
			add(x,y); add(y,x);
		}
		CLR(v,0);
		For(id,1,n){
			CLR(f,0); f[0][id]=1; v[0]++;
			For(T,1,k/2){
				CLR(f[T&1],0);
				For(i,1,n){
					for (int j=head[i];j;j=e[j].next)
						UPD(f[T&1][i],f[(T&1)^1][e[j].to]);
					UPD(v[T*2],1ll*f[T&1][i]*f[T&1][i]%mo);
				}
			}
		}
		For(i,1,k) For(j,2,k/i) UPD(v[i*j],mo-v[i]);
		Rep(i,k,1) For(j,2,k/i) UPD(v[i*j],v[i]);
	}
}T1,T2;
int c[80][80];
int n1,n2,k,ans;
int main(){
	For(i,0,75) c[i][0]=1;
	For(i,1,75) For(j,1,i) c[i][j]=(c[i-1][j]+c[i-1][j-1])%mo;
	scanf("%d%d%d",&n1,&n2,&k);
	if (k&1) return puts("0"),0;
	T1.init(n1,k); T2.init(n2,k);
	For(i,0,k) UPD(ans,1ll*T1.v[i]*T2.v[k-i]%mo*c[k][i]%mo);
	printf("%d\n",ans);
}


#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint ungigned
#define db double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pli pair<ll,int>
#define vi vector<int>
#define vpi vector<pii >
#define IT iterator

#define PB push_back
#define MK make_pair
#define LB lower_bound
#define UB upper_bound
#define y1 wzpakking
#define fi first
#define se second
#define BG begin
#define ED end

#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define UPD(x,y) (((x)+=(y))>=mo?(x)-=mo:233)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));

#define LS3 k*2,l,mid
#define RS3 k*2+1,mid+1,r
#define LS5 k*2,l,mid,x,y
#define RS5 k*2+1,mid+1,r,x,y
#define GET pushdown(k);int mid=(l+r)/2

#define INF (1ll<<60)
using namespace std;

const int mo=998244353;
struct edge{
	int to,next;
};
const int N=4005;
struct tree{
	edge e[N*2];
	int head[N],tot;
	int f[2][N],v[80];
	void add(int x,int y){
		e[++tot]=(edge){y,head[x]};
		head[x]=tot;
	}
	void init(int n,int k){
		For(i,1,n-1){
			int x,y; scanf("%d%d",&x,&y);
			add(x,y); add(y,x);
		}
		CLR(v,0);
		For(id,1,n){
			CLR(f,0); f[0][id]=1; v[0]++;
			For(T,1,k){
				For(i,id,n) if (f[(T&1)^1][i]){
					int v=f[(T&1)^1][i]; f[(T&1)^1][i]=0;
					for (int j=head[i];j;j=e[j].next) UPD(f[T&1][e[j].to],v);
				}
				UPD(v[T],f[T&1][id]);
			}
		}
		For(i,1,k) v[i]=1ll*v[i]*i%mo;
		For(i,1,k) For(j,2,k/i) UPD(v[i*j],mo-v[i]);
		Rep(i,k,1) For(j,2,k/i) UPD(v[i*j],v[i]);
	}
}T1,T2;
int c[80][80];
int n1,n2,k,ans;
int main(){
	For(i,0,75) c[i][0]=1;
	For(i,1,75) For(j,1,i) c[i][j]=(c[i-1][j]+c[i-1][j-1])%mo;
	scanf("%d%d%d",&n1,&n2,&k);
	T1.init(n1,k); T2.init(n2,k);
	For(i,0,k) UPD(ans,1ll*T1.v[i]*T2.v[k-i]%mo*c[k][i]%mo);
	printf("%d\n",ans);
}


#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint ungigned
#define db double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pli pair<ll,int>
#define vi vector<int>
#define vpi vector<pii >
#define IT iterator

#define PB push_back
#define MK make_pair
#define LB lower_bound
#define UB upper_bound
#define y1 wzpakking
#define fi first
#define se second
#define BG begin
#define ED end

#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define UPD(x,y) (((x)+=(y))>=mo?(x)-=mo:233)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));

#define LS3 k*2,l,mid
#define RS3 k*2+1,mid+1,r
#define LS5 k*2,l,mid,x,y
#define RS5 k*2+1,mid+1,r,x,y
#define GET pushdown(k);int mid=(l+r)/2

#define INF (1ll<<60)
using namespace std;

const int mo=998244353;
const int N=4005;
const int M=40;
int n1,n2,k;
struct tree{
	vi e[N];
	int vson[N][M];
	int vfa[N][M];
	int f[M],v[M],fa[N];
	void dfs(int x){
		for (auto to:e[x]) if (to!=fa[x])
			fa[to]=x,dfs(to);
	}
	void dfs1(int x){
		for (auto to:e[x]) if (to!=fa[x]) dfs1(to);
		vson[x][0]=1;
		For(i,1,k) for (auto to:e[x]) if(to!=fa[x])
			For(j,0,i-1) UPD(vson[x][i],1ll*vson[x][j]*vson[to][i-j-1]%mo);
	}
	void dfs2(int x){
		for (auto to:e[x]) if (to!=fa[x]) vfa[to][0]=1;
		For(i,1,k){
			static int tmp[M]; CLR(tmp,0);
			For(j,0,i-1) UPD(tmp[j],vfa[x][j]);
			for (auto to:e[x]) if (to!=fa[x])
				For(j,0,i-1) UPD(tmp[j],vson[to][j]);
			for (auto to:e[x]) if (to!=fa[x]){
				For(j,0,i-1) UPD(tmp[j],mo-vson[to][j]);
				For(j,0,i-1) UPD(vfa[to][i],1ll*tmp[j]*vfa[to][i-j-1]%mo);
				For(j,0,i-1) UPD(tmp[j],vson[to][j]);
			}
		}
		for (auto to:e[x]) if (to!=fa[x]) dfs2(to);
	}
	void init(int n){
		For(i,1,n-1){
			int x,y;
			scanf("%d%d",&x,&y);
			e[x].PB(y); e[y].PB(x);
		}
		dfs(1); dfs1(1); dfs2(1);
		For(id,1,n){
			CLR(f,0); f[0]=1;
			For(i,1,k){
				For(j,0,i-1) UPD(f[i],1ll*f[j]*vfa[id][i-j-1]%mo);
				for (auto to:e[id]) if (to!=fa[id])
					For(j,0,i-1) UPD(f[i],1ll*f[j]*vson[to][i-j-1]%mo);
			}
			For(i,0,k)
				UPD(v[i],f[i]);
		}
	}
}T1,T2;
int c[80][80],ans;
int main(){
	For(i,0,75) c[i][0]=1;
	For(i,1,75) For(j,1,i) c[i][j]=(c[i-1][j]+c[i-1][j-1])%mo;
	scanf("%d%d%d",&n1,&n2,&k);
	if (k&1) return puts("0"),0;
	k/=2; T1.init(n1); T2.init(n2);
	For(i,0,k) UPD(ans,1ll*T1.v[i]*T2.v[k-i]%mo*c[k*2][i*2]%mo);
	printf("%d\n",ans);
}


#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint ungigned
#define db double
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pli pair<ll,int>
#define vi vector<int>
#define vpi vector<pii >
#define IT iterator

#define PB push_back
#define MK make_pair
#define LB lower_bound
#define UB upper_bound
#define y1 wzpakking
#define fi first
#define se second
#define BG begin
#define ED end

#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define UPD(x,y) (((x)+=(y))>=mo?(x)-=mo:233)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));

#define LS3 k*2,l,mid
#define RS3 k*2+1,mid+1,r
#define LS5 k*2,l,mid,x,y
#define RS5 k*2+1,mid+1,r,x,y
#define GET pushdown(k);int mid=(l+r)/2

#define INF (1ll<<60)
using namespace std;

const int mo=998244353;
const int N=4005;
const int M=40;
int n1,n2,k;
struct tree{
	vi e[N];
	int vson[N][M];
	int vfa[N][M];
	int f[M],v[M],fa[N];
	void dfs(int x){
		for (auto to:e[x]) if (to!=fa[x])
			fa[to]=x,dfs(to);
	}
	void dfs1(int x){
		for (auto to:e[x]) if (to!=fa[x]) dfs1(to);
		vson[x][0]=1;
		For(i,1,k) for (auto to:e[x]) if(to!=fa[x])
			For(j,0,i-1) UPD(vson[x][i],1ll*vson[x][j]*vson[to][i-j-1]%mo);
	}
	void dfs2(int x){
		for (auto to:e[x]) if (to!=fa[x]) vfa[to][0]=1;
		For(i,1,k){
			static int tmp[M]; CLR(tmp,0);
			For(j,0,i-1) UPD(tmp[j],vfa[x][j]);
			for (auto to:e[x]) if (to!=fa[x])
				For(j,0,i-1) UPD(tmp[j],vson[to][j]);
			for (auto to:e[x]) if (to!=fa[x])
				For(j,0,i-1) UPD(vfa[to][i],1ll*(tmp[j]+mo-vson[to][j])*vfa[to][i-j-1]%mo);
		}
		for (auto to:e[x]) if (to!=fa[x]) dfs2(to);
	}
	void init(int n){
		For(i,1,n-1){
			int x,y;
			scanf("%d%d",&x,&y);
			e[x].PB(y); e[y].PB(x);
		}
		dfs(1); dfs1(1); dfs2(1);
		For(id,1,n){
			CLR(f,0); f[0]=1;
			For(i,1,k){
				For(j,0,i-1) UPD(f[i],1ll*f[j]*vfa[id][i-j-1]%mo);
				for (auto to:e[id]) if (to!=fa[id])
					For(j,0,i-1) UPD(f[i],1ll*f[j]*vson[to][i-j-1]%mo);
			}
			For(i,0,k)
				UPD(v[i],f[i]);
		}
	}
}T1,T2;
int c[80][80],ans;
int main(){
	For(i,0,75) c[i][0]=1;
	For(i,1,75) For(j,1,i) c[i][j]=(c[i-1][j]+c[i-1][j-1])%mo;
	scanf("%d%d%d",&n1,&n2,&k);
	if (k&1) return puts("0"),0;
	k/=2; T1.init(n1); T2.init(n2);
	For(i,0,k) UPD(ans,1ll*T1.v[i]*T2.v[k-i]%mo*c[k*2][i*2]%mo);
	printf("%d\n",ans);
}


#include <bits/stdc++.h>
using namespace std;
int main()
{
    string s;
    int cnt=0;
    for(int i=0;i<10;++i)
    {
        cout<<i<<endl;
        cout.flush();
        getline(cin,s);
        if(s == "no")
            break;
        ++cnt;
        if(cnt>3)
        {
            cout<<"normal"<<endl;
            cout.flush();
            return 0;
        }
    }
    if(s == "great!" || s == "don't think so" || s == "don't touch me!" || s == "not bad" || s == "cool")
        cout<<"normal"<<endl;
    else cout<<"grumpy"<<endl;
    cout.flush();
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
int main()
{
    string s;
    int cnt=0;
    for(int i=0;i<10;++i)
    {
        cout<<i<<endl;
        cout.flush();
        getline(cin,s);
        if(s != "no")
            break;
        ++cnt;
        if(0&&cnt>3)
        {
            cout<<"normal"<<endl;
            cout.flush();
            return 0;
        }
    }
    if(s == "great!" || s == "don't think so" || s == "don't touch me!" || s == "not bad" || s == "cool")
        cout<<"normal"<<endl;
    else cout<<"grumpy"<<endl;
    cout.flush();
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
int main()
{
    string s;
    int cnt=0;
    for(int i=0;i<10;++i)
    {
        cout<<i<<endl;
        cout.flush();
        getline(cin,s);
        if(s != "no")
            break;
        ++cnt;
        if(cnt>3)
        {
            cout<<"normal"<<endl;
            cout.flush();
            return 0;
        }
    }
    if(s == "great!" || s == "don't think so" || s == "don't touch me!" || s == "not bad" || s == "cool")
        cout<<"normal"<<endl;
    else cout<<"grumpy"<<endl;
    cout.flush();
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
int main()
{
    char s[100];
    int cnt=0;
    for(int i=0;i<10;++i)
    {
        printf("%d\n",i);
        fflush(stdout);
        gets(s);
        if(strcmp(s,"no"))
            break;
        ++cnt;
        if(cnt>3)
        {
            puts("normal");
            fflush(stdout);
            return 0;
        }
    }
    string res = string(s);
    if(res == "great!" || res == "don't think so" || res == "don't touch me!" || res == "not bad" || res == "cool")
        puts("normal");
    else puts("grumpy");
    fflush(stdout);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
int main()
{
    char s[100];
    int ans=-1;
    for(int i=0;i<10;++i)
    {
        printf("%d\n",i);
        fflush(stdout);
        gets(s);
        if(strcmp(s,"no"))
            break;
    }
    string res = string(s);
    if(res == "great!" || res == "don't think so" || res == "don't touch me!" || res == "not bad" || res == "cool")
        puts("normal");
    else puts("grumpy");
    fflush(stdout);
    return 0;
}


#include <iostream>
#include <sstream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cctype>
#include <string>
#include <vector>
#include <list>
#include <set>
#include <map>
// #include <unordered_map>
#include <limits.h>
#include <cassert>
#include <queue>
#include <stack>
#include <algorithm>
#include <functional>
#include <iomanip>
using namespace std;
//////////////////
// Aditya Kumar //
//  BITS H      //
//////////////////
#define mod 1000000007
#define ll long long
#define ss second
#define ff first
// #define endl '\n'
#define FastIO ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define int long long
#define pb push_back

#define FOR(i,a,b) for(int i=a;i<b;i++)

int32_t main()
{
        FastIO;
        #ifndef ONLINE_JUDGE
        freopen("input.txt","r",stdin);
        freopen("output.txt","w",stdout);
        #endif
        int gl= 0;
        // string s;
        // cin >> s;
        int noc = 0;//
        int a[10];
        for(int i=0;i<10;i++) a[i] = i;
        srand(time(NULL));
	random_shuffle(a,a+10);
        for(int i = 0 ;i <= 9 ; i++)
        {
        	cout << a[i] << endl;
        	fflush(stdout);
        	string s;
        	cin >> s;

        	if(s == "no") {
        		noc++;
        		if(noc >= 4)
        		{
        			cout << "normal" << endl;
	        		fflush(stdout);
	        		return 0;
        		}
        		continue;
        	}
        	if(s == "worse" || s == "are you serious?" || s == "no way" || s=="go die in a hole" || s == "terrible" || s == "don't even")
        	{
        		cout  << "grumpy" << endl;
        		fflush(stdout);
        		return 0;
        	}
        	else
        	{
        		if( s== "don't think so" || s== "don't touch me!" || s== "not bad" || s== "cool" || s== "great!"  ){
	        		cout << "normal" << endl;
	        		fflush(stdout);
	        		return 0;

        		}
        	}
        }
        	fflush(stdout);
        return 0;
}


#include <iostream>
#include <sstream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cctype>
#include <string>
#include <vector>
#include <list>
#include <set>
#include <map>
// #include <unordered_map>
#include <limits.h>
#include <cassert>
#include <queue>
#include <stack>
#include <algorithm>
#include <functional>
#include <iomanip>
using namespace std;
//////////////////
// Aditya Kumar //
//  BITS H      //
//////////////////
#define mod 1000000007
#define ll long long
#define ss second
#define ff first
// #define endl '\n'
#define FastIO ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define int long long
#define pb push_back

#define FOR(i,a,b) for(int i=a;i<b;i++)

int32_t main()
{
        FastIO;
        #ifndef ONLINE_JUDGE
        freopen("input.txt","r",stdin);
        freopen("output.txt","w",stdout);
        #endif
        int gl= 0;
        // string s;
        // cin >> s;
        int noc = 0;
        int a[10];
        for(int i=0;i<10;i++) a[i] = i;
        srand(time(NULL));
	// random_shuffle(a,a+10);
        for(int i = 0 ;i <= 9 ; i++)
        {
        	cout << a[i] << endl;
        	fflush(stdout);
        	string s;

        	getline(cin, s);

        	if(s == "no") {
        		noc++;
        		if(noc >= 4)
        		{
        			cout << "normal" << endl;
	        		fflush(stdout);
	        		return 0;
        		}
        		continue;
        	}

        	if(s == "worse" || s == "are you serious?" || s == "no way" || s=="go die in a hole" || s == "terrible" || s == "don't even")
        	{
        		cout  << "grumpy" << endl;
        		fflush(stdout);
        		return 0;
        	}
        	else
        	{
        		if( s== "don't think so" || s== "don't touch me!" || s== "not bad" || s== "cool" || s== "great!"  ){
	        		cout << "normal" << endl;
	        		fflush(stdout);
	        		return 0;

        		}
        	}
        }
	fflush(stdout);
        return 0;
}


#include <iostream>
#include <sstream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cctype>
#include <string>
#include <vector>
#include <list>
#include <set>
#include <map>
// #include <unordered_map>
#include <limits.h>
#include <cassert>
#include <queue>
#include <stack>
#include <algorithm>
#include <functional>
#include <iomanip>
using namespace std;
//////////////////
// Aditya Kumar //
//  BITS H      //
//////////////////
#define mod 1000000007
#define ll long long
#define ss second
#define ff first
// #define endl '\n'
#define FastIO ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define int long long
#define pb push_back

#define FOR(i,a,b) for(int i=a;i<b;i++)

int32_t main()
{
        FastIO;
        #ifndef ONLINE_JUDGE
        freopen("input.txt","r",stdin);
        freopen("output.txt","w",stdout);
        #endif
        int gl= 0;
        // string s;
        // cin >> s;
        int noc = 0;
        int a[10];
        for(int i=0;i<10;i++) a[i] = i;
        srand(time(NULL));
	// random_shuffle(a,a+10);
        for(int i = 0 ;i <= 9 ; i++)
        {
        	cout << a[i] << endl;
        	fflush(stdout);
        	string s;
        	cin >> s;

        	if(s == "no") {
        		noc++;
        		if(noc >= 1)
        		{
        			cout << "normal" << endl;
	        		fflush(stdout);
	        		return 0;
        		}
        		continue;
        	}
        	if(s == "NO") {
        		noc++;
        		if(noc >= 1)
        		{
        			cout << "grumpy" << endl;
	        		fflush(stdout);
	        		return 0;
        		}
        		continue;
        	}
        	if(s == "Worse" || s == "Are you serious?" || s == "no way" || s=="Go die in a hole" || s == "Terrible" || s == "DON'T EVEN")
        	{
        		cout  << "grumpy" << endl;
        		fflush(stdout);
        		return 0;
        	}
        	else
        	{
        		if( s== "don't think so" || s== "don't touch me!" || s== "not bad" || s== "cool" || s== "great!"  ){
	        		cout << "normal" << endl;
	        		fflush(stdout);
	        		return 0;

        		}
        	}
        }
        	fflush(stdout);
        return 0;
}


	#include <iostream>
	#include <sstream>
	#include <cstdio>
	#include <cmath>
	#include <cstring>
	#include <string>
	#include <cctype>
	#include <string>
	#include <vector>
	#include <list>
	#include <set>
	#include <map>
	// #include <unordered_map>
	#include <limits.h>
	#include <cassert>
	#include <queue>
	#include <stack>
	#include <algorithm>
	#include <functional>
	#include <iomanip>
	using namespace std;
	//////////////////
	// Aditya Kumar //
	//  BITS H      //
	//////////////////
	#define mod 1000000007
	#define ll long long
	#define ss second
	#define ff first
	// #define endl '\n'
	#define FastIO ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	#define int long long
	#define pb push_back

	#define FOR(i,a,b) for(int i=a;i<b;i++)

	int32_t main()
	{
	        FastIO;
	        #ifndef ONLINE_JUDGE
	        freopen("input.txt","r",stdin);
	        freopen("output.txt","w",stdout);
	        #endif
	        int gl= 0;
	        for(int i = 0 ;i <= 9 ; i++)
	        {
	        	cout << i << endl;
	        	string s;
	        	cin >> s;
	        	if(s == "worse")
	        	{
	        		gl = 1;
	        	}
	        }
	        if(gl == 1)
	        	cout  << "grumpy" << endl;
	        else
	        cout << "normal" << endl;
	        return 0;
	}


#include <iostream>
#include <sstream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cctype>
#include <string>
#include <vector>
#include <list>
#include <set>
#include <map>
// #include <unordered_map>
#include <limits.h>
#include <cassert>
#include <queue>
#include <stack>
#include <algorithm>
#include <functional>
#include <iomanip>
using namespace std;
//////////////////
// Aditya Kumar //
//  BITS H      //
//////////////////
#define mod 1000000007
#define ll long long
#define ss second
#define ff first
// #define endl '\n'
#define FastIO ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define int long long
#define pb push_back

#define FOR(i,a,b) for(int i=a;i<b;i++)

int32_t main()
{
        FastIO;
        #ifndef ONLINE_JUDGE
        freopen("input.txt","r",stdin);
        freopen("output.txt","w",stdout);
        #endif
        int gl= 0;
        // string s;
        // cin >> s;
        for(int i = 0 ;i <= 9 ; i++)
        {
        	cout << i << endl;
        	fflush(stdout);
        	string s;
        	cin >> s;
        	if(s == "no")
        		continue;
        	if(s == "worse" || s == "are you serious?" || s == "no way" || s=="go die in a hole" || s == "terrible" || s == "don't even")
        	{
        		cout  << "grumpy" << endl;
        		fflush(stdout);
        		return 0;
        	}
        	else{
        		cout << "normal" << endl;
        		fflush(stdout);
        		return 0;
        	}
        }
        	fflush(stdout);
        return 0;
}


#include <iostream>
#include <sstream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cctype>
#include <string>
#include <vector>
#include <list>
#include <set>
#include <map>
// #include <unordered_map>
#include <limits.h>
#include <cassert>
#include <queue>
#include <stack>
#include <algorithm>
#include <functional>
#include <iomanip>
using namespace std;
//////////////////
// Aditya Kumar //
//  BITS H      //
//////////////////
#define mod 1000000007
#define ll long long
#define ss second
#define ff first
// #define endl '\n'
#define FastIO ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define int long long
#define pb push_back

#define FOR(i,a,b) for(int i=a;i<b;i++)

int32_t main()
{
        FastIO;
        #ifndef ONLINE_JUDGE
        freopen("input.txt","r",stdin);
        freopen("output.txt","w",stdout);
        #endif
        int gl= 0;
        // string s;
        // cin >> s;
        for(int i = 0 ;i <= 9 ; i++)
        {
        	cout << i << endl;
        	fflush(stdout);
        	string s;
        	cin >> s;
        	if(s == "worse")
        	{
        		gl = 1;
        	}
        }
        if(gl == 1)
        	cout  << "grumpy" << endl;
        else
        	cout << "normal" << endl;

        	fflush(stdout);
        return 0;
}


#include <iostream>
#include <sstream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cctype>
#include <string>
#include <vector>
#include <list>
#include <set>
#include <map>
// #include <unordered_map>
#include <limits.h>
#include <cassert>
#include <queue>
#include <stack>
#include <algorithm>
#include <functional>
#include <iomanip>
using namespace std;
//////////////////
// Aditya Kumar //
//  BITS H      //
//////////////////
#define mod 1000000007
#define ll long long
#define ss second
#define ff first
// #define endl '\n'
#define FastIO ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define int long long
#define pb push_back

#define FOR(i,a,b) for(int i=a;i<b;i++)

int32_t main()
{
        FastIO;
        #ifndef ONLINE_JUDGE
        freopen("input.txt","r",stdin);
        freopen("output.txt","w",stdout);
        #endif
        int gl= 0;
        string s;
        cin >> s;
        for(int i = 0 ;i <= 9 ; i++)
        {
        	cout << i << endl;
        	fflush(stdout);
        	string s;
        	cin >> s;
        	if(s == "worse")
        	{
        		gl = 1;
        	}
        }
        if(gl == 1)
        	cout  << "grumpy" << endl;
        else
        	cout << "normal" << endl;

        	fflush(stdout);
        return 0;
}


#include <iostream>
#include <sstream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cctype>
#include <string>
#include <vector>
#include <list>
#include <set>
#include <map>
// #include <unordered_map>
#include <limits.h>
#include <cassert>
#include <queue>
#include <stack>
#include <algorithm>
#include <functional>
#include <iomanip>
using namespace std;
//////////////////
// Aditya Kumar //
//  BITS H      //
//////////////////
#define mod 1000000007
#define ll long long
#define ss second
#define ff first
// #define endl '\n'
#define FastIO ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define int long long
#define pb push_back

#define FOR(i,a,b) for(int i=a;i<b;i++)

int32_t main()
{
        FastIO;
        #ifndef ONLINE_JUDGE
        freopen("input.txt","r",stdin);
        freopen("output.txt","w",stdout);
        #endif
        int gl= 0;
        // string s;
        // cin >> s;
        int noc = 0;
        for(int i = 0 ;i <= 9 ; i++)
        {
        	cout << i << endl;
        	fflush(stdout);
        	string s;
        	cin >> s;

        	if(s == "no") {
        		noc++;
        		if(noc >= 4)
        		{
        			cout << "normal" << endl;
	        		fflush(stdout);
	        		return 0;
        		}
        		continue;
        	}
        	if(s == "worse" || s == "are you serious?" || s == "no way" || s=="go die in a hole" || s == "terrible" || s == "don't even")
        	{
        		cout  << "grumpy" << endl;
        		fflush(stdout);
        		return 0;
        	}
        	else
        	{
        		if( s== "don't think so" || s== "don't touch me!" || s== "not bad" || s== "cool" || s== "great"  ){
	        		cout << "normal" << endl;
	        		fflush(stdout);
	        		return 0;

        		}
        	}
        }
        	fflush(stdout);
        return 0;
}


#include <iostream>
#include <sstream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cctype>
#include <string>
#include <vector>
#include <list>
#include <set>
#include <map>
// #include <unordered_map>
#include <limits.h>
#include <cassert>
#include <queue>
#include <stack>
#include <algorithm>
#include <functional>
#include <iomanip>
using namespace std;
//////////////////
// Aditya Kumar //
//  BITS H      //
//////////////////
#define mod 1000000007
#define ll long long
#define ss second
#define ff first
// #define endl '\n'
#define FastIO ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define int long long
#define pb push_back

#define FOR(i,a,b) for(int i=a;i<b;i++)

int32_t main()
{
        FastIO;
        #ifndef ONLINE_JUDGE
        freopen("input.txt","r",stdin);
        freopen("output.txt","w",stdout);
        #endif
        int gl= 0;
        // string s;
        // cin >> s;
        for(int i = 0 ;i <= 9 ; i++)
        {
        	cout << i << endl;
        	fflush(stdout);
        	string s;
        	cin >> s;
        	if(s == "no") continue;
        	if(s == "worse" || s == "are you serious?" || s == "no way" || s=="go die in a hole" || s == "terrible" || s == "don't even")
        	{
        		cout  << "grumpy" << endl;
        		return 0;
        	}
        	else{
        		cout << "normal" << endl; return 0;
        	}
        }
        if(gl == 0)
        	cout  << "grumpy" << endl;
        else
        	cout << "normal" << endl;

        	fflush(stdout);
        return 0;
}