#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
 
#pragma GCC optimize("Ofast")
#pragma GCC optimize("O3")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,sse4.1,sse4.2,tune=native")
 
using namespace __gnu_pbds;
using namespace std;
     
#define mp make_pair
#define sz(x) (int)((x).size())
#define all(x) (x).begin(),(x).end()
#define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
#define eb emplace_back
 
typedef pair< int, int > pii;
typedef pair< long long, long long > pll;
typedef long long ll;
typedef unsigned long long ull;
typedef vector< int > vi;
typedef vector< vi > vvi;
typedef vector< ll > vll;
typedef vector< vll > vvll;
typedef vector< pii > vpii;
typedef vector< vpii > vvpii;
typedef vector< pll > vpll;
typedef long double ld;
typedef vector< ld > vld;
typedef unsigned int uint;
 
const ll MOD2 = 1e9 + 7;
const int MOD = 1e9 + 7;
 
const ull infull = numeric_limits<unsigned long long>::max();
 
void fix(int &x, ll MOD) {
    x = (x % MOD);
    if(x < 0) x += MOD;
    return;
}
 
ll lgput(ll a, ll b, ll MOD) {
    ll ret = 1;
    a %= MOD;
    while(b) {
        if(b&1) ret = ret*a % MOD;
        a = a*a % MOD;
        b >>= 1;
    }
 
    return ret;
}
 
ll inv(ll a, ll MOD) {
    return lgput(a, MOD-2, MOD);
}

template <uint MD> struct ModInt {
    using M = ModInt;
    const static M G;
    uint v;
    ModInt(ll _v = 0) { set_v(uint(_v % MD + MD)); }
    M& set_v(uint _v) {
        v = (_v < MD) ? _v : _v - MD;
        return *this;
    }
    explicit operator bool() const { return v != 0; }
    M operator-() const { return M() - *this; }
    M operator+(const M& r) const { return M().set_v(v + r.v); }
    M operator-(const M& r) const { return M().set_v(v + MD - r.v); }
    M operator*(const M& r) const { return M().set_v(uint(ull(v) * r.v % MD)); }
    M operator/(const M& r) const { return *this * r.inv(); }
    M& operator+=(const M& r) { return *this = *this + r; }
    M& operator-=(const M& r) { return *this = *this - r; }
    M& operator*=(const M& r) { return *this = *this * r; }
    M& operator/=(const M& r) { return *this = *this / r; }
    bool operator==(const M& r) const { return v == r.v; }
    M pow(ll n) const {
        M x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    M inv() const { return pow(MD - 2); }
    friend ostream& operator<<(ostream& os, const M& r) { return os << r.v; }
};

using Mint = ModInt<998244353>;

const Mint base = Mint(1e18);

int main() { 
    #ifdef BLAT
        freopen("stdin", "r", stdin);
        freopen("stderr", "w", stderr);
    #endif
 
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cout.precision(12);
    srand(time(NULL));
        
    int n;
    cin >> n;

    vector< vector< Mint > > ans(3);
    for(int i = 0; i < 3; ++i) {
        int m;
        cin >> m;
        vvi gr(n);

        for(int j = 0; j < m; ++ j) {
            int a, b;
            cin >> a >> b;

            --a, --b;
            if(a > b) swap(a, b);

            gr[a].emplace_back(b);
        }

        vector< int > grundy(n, 0);
        vector< int > used(n, -1);

        for(int j = n-1; j >= 0; --j) {
            for(auto &x : gr[j]) {
                used[grundy[x]] = j;
            }

            while(used[grundy[j]] == j) ++grundy[j];
            while(ans[i].size() <= grundy[j]) ans[i].emplace_back(0);

            ans[i][grundy[j]] += base.pow(j + 1);
        }
    }

    Mint ret = 0;
    for(int i = 0; i < ans[0].size(); ++i) {
        for(int j = 0; j < ans[1].size(); ++j) {
            int k = i ^ j;
            if(k < ans[2].size()) ret += ans[0][i]*ans[1][j]*ans[2][k];
        }
    }

    cout << ret << '\n';
    return 0;  
}

Measured memory_bytes: 5192