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

//#define MOD 1000000007
#define MOD 998244353

class mint {
	public:
		int i;

		mint() : i(0) {}

		template<class T>
			mint(T x) {
				i = int(x % MOD);
				if (i < 0) i += MOD;
			}

		mint operator+(mint x) {
			return i + x.i;
		}

		mint operator-(mint x) {
			return i - x.i;
		}

		mint operator*(mint x) {
			return (long long)i * x.i;
		}

		mint operator/(mint x) {
			return (long long)i * x.pow(MOD - 2).i;
		}

		mint inv() {
			return pow(MOD - 2);
		}

		template<class T>
			mint pow(T p) {
				long long r = 1;
				long long t = i;
				for(; p > 0; p >>= 1) {
					if (p & 1) r = r * t % MOD;
					t = t * t % MOD;
				}
				return r;
			}

		template<class T1, class T2>
			static mint pow(T1 a, T2 b) {
				long long r = 1;
				long long t = (long long)(a % MOD);
				for(; b > 0; b >>= 1) {
					if (b & 1) r = r * t % MOD;
					t = t * t % MOD;
				}
				return r;
			}

		mint& operator+=(mint x) {
			i = (i + x.i) % MOD;
			return *this;
		}

		mint& operator-=(mint x) {
			i = i - x.i;
			if (i < 0) i += MOD;
			return *this;
		}

		mint& operator*=(mint x) {
			i = (int)((long long)i * x.i % MOD);
			return *this;
		}

		mint& operator/=(mint x) {
			i = (long long)i * x.pow(MOD - 2).i % MOD;
			return *this;
		}
};

std::ostream& operator<<(std::ostream& os, const mint& m) {
	return os << m.i;
}

std::vector<std::vector<int>> iig(int vn, int en) { 
        std::vector<std::vector<int>> res(vn); 
        for(int i = 0; i < en; i++) { 
                int s, t; 
                std::cin >> s >> t; 
                s--; t--; 
		if (s > t) swap(s, t);
                res[t].push_back(s); 
        } 
        return res; 
}

std::vector<int> assign_grundy(std::vector<std::vector<int>>& dg) {
	int gsize = dg.size();
	std::vector<int> incomings(gsize);
	for(int i = 0; i < gsize; i++) {
		for(int j: dg[i]) {
			incomings[j]++;
		}
	}
	std::vector<int> vs_ready;
	for(int i = 0; i < gsize; i++) {
		if (incomings[i] == 0) vs_ready.push_back(i);
	}
	std::vector<std::set<int>> prohibited_grundy(gsize);
	std::vector<int> grundy(gsize);
	while(!vs_ready.empty()) {
		int i = vs_ready.back();
		vs_ready.pop_back();
		int g = 0;
		for(int pg: prohibited_grundy[i]) {
			if (g == pg) g++;
			else break;
		}
		grundy[i] = g;
		for(int j: dg[i]) {
			prohibited_grundy[j].insert(g);
			if ((--incomings[j]) == 0) vs_ready.push_back(j);
		}
	}
	return grundy;
}

int main() {
	int n, m;
	cin >> n;
	cin >> m;
	auto g1 = iig(n, m);
	cin >> m;
	auto g2 = iig(n, m);
	cin >> m;
	auto g3 = iig(n, m);
	// assume that each edge direction is reversed
	auto grn1 = assign_grundy(g1);
	auto grn2 = assign_grundy(g2);
	auto grn3 = assign_grundy(g3);	
	// gmax * (gmax + 1) <= E * 2

	vector<mint> w(n + 1);
	mint step = mint::pow(10, 18);
	w[0] = 1;
	for(int i = 1; i <= n; i++) {
		w[i] = w[i-1] * step;
	}

	vector<mint> gcount1(500), gcount2(500), gcount3(500);
	for(int i = 0; i < n; i++) {
		gcount1[grn1[i]] += w[i+1];
		gcount2[grn2[i]] += w[i+1];
		gcount3[grn3[i]] += w[i+1];
	}

	mint res = 0;

	for(int i = 0; i < 500; i++)
		for(int j = 0; j < 500; j++) {
			int k = i ^ j;
			if (k >= 500) continue;
			res += gcount1[i] * gcount2[j] * gcount3[k];
		}

	cout << res << endl;
}


Measured memory_bytes: 22648