#include <algorithm>
#include <iostream>
#include <vector>
#include <math.h>
#include <set>
#include <map>
#include <string>
#include <stack>
#include <queue>
#include <iomanip>
#include <numeric>
#include <tuple>
#include <bitset>
#include <complex>
#include <unistd.h>
#include <cassert>
#include <cctype>
#include <random>
#include <time.h>
#define _USE_MATH_DEFINES
#define _GLIBCXX_DEBUG
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> plglg;
typedef pair<double, ll> pdlg;
typedef tuple<int, int, int> tiii;
typedef tuple<ll, ll, ll> tlglglg;
typedef tuple<double, double, double> tddd;
typedef complex<double> xy_t;
typedef vector<ll> vll;
typedef vector< vector<ll> > matrix;
template <class T> using V = vector<T>;
template <class T> using VV = V<V<T>>;
template <class T> using VVV = V<VV<T>>;
#define REP(i, x, y) for(ll i = (ll)x; i < (ll)y; i++)
#define DREP(i, x, y, d) for(ll i = (ll)x; i < (ll)y; i += (ll)d)
#define PER(i, x, y) for(ll i = (ll)x; i > (ll)y; i--)
#define DPER(i, x, y, d) for(ll i = (ll)x; i > (ll)y; i -= (ll)d)
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
double pi = 3.141592653589793;
ll mod = 998244353;
int intmax = 2147483647;
int intmin = -2147483648;
ll llmax = 9223372036854775807;
ll llmin = -9223372036854775807;
int iinf = intmax / 8;
ll inf = llmax / 8;
double eps = 1e-12;
void yesno(bool ok, string yes = "Yes", string no = "No") {
    if (ok) {
        cout << yes << endl;
    } else {
        cout << no << endl;
    }
}

ll modadd(ll x, ll y) {
    return ((x + y) % mod + mod) % mod;
}

ll modminus(ll x, ll y) {
    return (x - y + mod) % mod;
}

ll multiply(ll x, ll y) {
    return (x % mod) * (y % mod) % mod;
}

ll modpower(ll x, ll y) {
    if (y == 0) {
        return 1;
    } else if (y == 1) {
        return x % mod;
    } else if (y % 2 == 0) {
        ll p = modpower(x, y / 2);
        return p * p % mod;
    } else {
        ll p = modpower (x, y / 2);
        return (p * p) % mod * (x % mod) % mod;
    }
}

struct edge {
    ll to, cost;
};

VVV<edge> G(3, VV<edge>(200000));
VV<ll> grundy(3, V<ll>(200000, 0));

void addedge(VV<edge>& G, int st, int ed, ll co) {
    edge e;
    e.to = ed;
    e.cost = co;
    G[st].push_back(e);
}

ll N;
void setvalue() {
    REP(p, 0, 3) {
        V<ll> used(N, -1);
        PER(i, N - 1, -1) {
            REP(j, 0, G[p][i].size()) {
                edge e = G[p][i][j];
                used[grundy[p][e.to]] = i;
            }
            while (used[grundy[p][i]] == i) {
                grundy[p][i]++;
            }
        }
    }
}

ll ten[2000000];

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cin >> N;
    ten[0] = 1;
    REP(i, 1, 2000000) {
        ten[i] = multiply(ten[i - 1], 10);
    }
    ll M[3];
    REP(p, 0, 3) {
        cin >> M[p];
        REP(i, 0, M[p]) {
            ll a, b;
            cin >> a >> b;
            a--;
            b--;
            if (a > b) {
                swap(a, b);
            }
            addedge(G[p], a, b, 0);
        }
    }
    // cout << "aaa" << endl;
    setvalue();
    // cout << "bbb" << endl;
    VV<ll> sum(3);
    REP(p, 0, 3) {
        REP(i, 0, N) {
            while ((ll)sum[p].size() <= grundy[p][i]) {
                sum[p].push_back(0);
            }
            sum[p][grundy[p][i]] = modadd(sum[p][grundy[p][i]], ten[18 * (i + 1)]);
        }
    }
    ll ans = 0;
    REP(i, 0, sum[0].size()) {
        REP(j, 0, sum[1].size()) {
            ll k = i ^ j;
            if (k < (ll)sum[2].size()) {
                ans = modadd(ans, multiply(sum[0][i], multiply(sum[1][j], sum[2][k])));
            }
        }
    }
    // REP(p, 0, 3) {
    //     REP(i, 0, N) {
    //         cout << grundy[p][i] << " ";
    //     }
    //     cout << endl;
    // }
    // cout << "aaa" << endl;
    // REP(p, 0, 3) {
    //     REP(i, 0, sum[p].size()) {
    //         cout << sum[p][i] << " ";
    //     }
    //     cout << endl;
    // }
    cout << ans << endl;
}


Measured memory_bytes: 43312