// Words are flowing out like endless rain into a paper cup
// They slither while they pass they slip away across the universe
// Pools of sorrow, waves of joy are drifting through my open mind
// Possessing and caressing me

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

using LL = long long;

namespace _buff {

const size_t BUFF = 1 << 19;
char ibuf[BUFF], *ib = ibuf, *ie = ibuf;
char getc() {
    if (ib == ie) {
        ib = ibuf;
        ie = ibuf + fread(ibuf, 1, BUFF, stdin);
    }
    return ib == ie ? -1 : *ib++;
}

}

LL read() {
    using namespace _buff;
    LL ret = 0;
    bool pos = true;
    char c = getc();
    for (; (c < '0' || c > '9') && c != '-'; c = getc()) {
        assert(~c);
    }
    if (c == '-') {
        pos = false;
        c = getc();
    }
    for (; c >= '0' && c <= '9'; c = getc()) {
        ret = (ret << 3) + (ret << 1) + (c ^ 48);
    }
    return pos ? ret : -ret;
}

using uint = unsigned;
const uint MOD = 998244353;
struct Z {
    uint v;

    Z(uint v = 0) : v(v) {}

    Z& operator += (const Z &z) {
        v += z.v;
        if (v >= MOD) v -= MOD;
        return *this;
    }

    Z& operator -= (const Z &z) {
        if (v < z.v) v += MOD;
        v -= z.v;
        return *this;
    }

    Z& operator *= (const Z &z) {
        v = static_cast<uint64_t>(v) * z.v % MOD;
        return *this;
    }

    void div2() {
        if (v & 1) v += MOD;
        v >>= 1;
    }
};

ostream& operator << (ostream &os, const Z &z) {
    return os << z.v;
}

Z operator + (const Z &x, const Z &y) {
    return Z(x.v + y.v >= MOD ? x.v + y.v - MOD : x.v + y.v);
}

Z operator - (const Z &x, const Z &y) {
    return Z(x.v < y.v ? x.v + MOD - y.v : x.v - y.v);
}

Z operator * (const Z &x, const Z &y) {
    return Z(static_cast<uint64_t>(x.v) * y.v % MOD);
}

Z qpow(Z base, uint e) {
    Z ret(1);
    for (; e; e >>= 1) {
        if (e & 1) {
            ret *= base;
        }
        base *= base;
    }
    return ret;
}

const size_t N = 1 << 17;
const size_t M = 1 << 10;

vector<int> g[3][N];
int sg[3][N];
Z pw[N];

void dfs(int id, int u) {
    if (~sg[id][u]) return;
    sg[id][u] = 0;
    for (int v : g[id][u]) {
        dfs(id, v);
    }
    static int lst[N], tot = 0;
    ++tot;
    for (int v : g[id][u]) {
        lst[sg[id][v]] = tot;
    }
    while (lst[sg[id][u]] == tot) {
        ++sg[id][u];
    }
}

void fwt_xor(Z a[], int n, int flag) {
    for (int m = 1, l = 2; m < n; m <<= 1, l <<= 1) {
        Z *x = a, *y = a + m;
        for (int i = 0; i < n; i += l) {
            for (int j = 0; j < m; ++j, ++x, ++y) {
                Z tmp = *y;
                *y = *x;
                *x += tmp;
                *y -= tmp;
                if (flag == 2) {
                    x->div2();
                    y->div2();
                }
            }
            x += m;
            y += m;
        }
    }
}

int main() {
    memset(sg, -1, sizeof sg);
    int n = read();
    for (int i = 0; i < 3; ++i) {
        for (int m = read(); m--; ) {
            int u = read(), v = read();
            if (u > v) swap(u, v);
            g[i][u].emplace_back(v);
        }
        for (int j = 1; j <= n; ++j) {
            dfs(i, j);
        }
    }

    pw[0] = 1;
    Z mul = (LL) 1E18 % MOD;
    for (int i = 1; i <= n; ++i) {
        pw[i] = pw[i - 1] * mul;
    }

    static Z f[3][M];
    for (int i = 0; i < 3; ++i) {
        for (int j = 1; j <= n; ++j) {
            f[i][sg[i][j]] += pw[j];
        }
    }
    fwt_xor(f[0], M, 1);
    fwt_xor(f[1], M, 1);
    for (uint i = 0; i < M; ++i) {
        f[0][i] *= f[1][i];
    }
    fwt_xor(f[0], M, 2);
    Z ans = 0;
    for (uint i = 0; i < M; ++i) {
        ans += f[0][i] * f[2][i];
    }
    cout << ans;
    return 0;
}


Measured memory_bytes: 17920