#include <bits/stdc++.h>
#include <unordered_set>
#include <cmath>

// URL: https://atcoder.jp/contests/abc190/tasks/abc190_c

using namespace std;

using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using vi = vector<int>;
using vll = vector<ll>;
using vs = vector<string>;

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define reps(i, s, n) for (int i = (int)(s); i < (int)(n); i++)

#define repll(i, n) for (ll i = 0; i < (ll)(n); i++)
#define repsll(i, s, n) for (ll i = (ll)(s); i < (ll)(n); i++)

#define ALL(a) (a).begin(), (a).end()

#define pb push_back
#define optimize_cin() cin.tie(0); ios::sync_with_stdio(false)

template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return 1; } return 0; }

const ll INFL = 1e18;
const int INF = 1e9;

const int dx[4] = {1, 0, 0, -1};
const int dy[4] = {0, 1, -1, 0};



int main(){
    optimize_cin();

    int N, M;
    cin >> N >> M;
    vi A(M), B(M);
    rep(i, M){
        cin >> A.at(i) >> B.at(i); 
    }


    int K;
    cin >> K;
    vi C(K), D(K);
    rep(i, K){
        cin >> C.at(i) >> D.at(i); 
    }

    ll pattern = 1, diff = 0;
    rep(i, K) pattern *= 2;
    diff = pattern;
    pattern *= 2;

    int max = 0;

    repsll(i, diff, pattern){
        int cnt = 0, ord = 0, tmp = i;
        vi dish(N, 0);
        while(tmp > 0){
            if(tmp % 2 == 0) dish[C[ord] - 1]++;
            else dish[D[ord] - 1]++;
            tmp /= 2;
            ord++;
            if(ord == K) break;
        }
        rep(j, M){
            if(dish[A[j] - 1] > 0 && dish[B[j] - 1]) cnt++;
        }
        chmax(max, cnt);
    }

    cout << max << endl;
    
    return 0;
}
# pragma GCC optimize ("O3")
# pragma GCC optimize ("Ofast")
# pragma GCC optimize ("unroll-loops")
#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
#define rep(i,a,b) for(int i = (a); i < (b); i++)
#define rep2(i,a,b) for(int i = (b) - 1; i >= (a); i--)
#define all(x) (x).begin(), (x).end()
#define sz(x) ((int)(x).size())
#define pb push_back
#define eb emplace_back
#define em emplace
#define popcount __builtin_popcount
#define popcountll __builtin_popcountll
#define x first
#define y second
using namespace std;
using ll = long long;
using ld = long double;
using pi = pair<int, int>;
using ti = tuple<int, int, int>;
using pl = pair<ll, ll>;
using tl = tuple<ll, ll, ll>;

const int MOD = 998244353;
int N, W[111], tot;
template<class T> struct mi { 
	T val;
	mi() { val = 0; }
	mi(const ll& v) {
		val = (-MOD <= v && v <= MOD) ? v : v % MOD;
		if (val < 0) val += MOD;
	}
	mi operator + (const mi& m) {
		T tmp = (val + m.val) % MOD;
		return tmp + (tmp < 0 ? MOD : 0);
	}
	mi operator - (const mi& m) {
		T tmp = (val - m.val) % MOD;
		return tmp + (tmp < 0 ? MOD : 0);
	}
	mi operator * (const mi& m) {
		T tmp = (val * m.val) % MOD;
		return tmp;
	}
	mi& operator += (const mi& m) {
		if ((val += m.val) >= MOD) val -= MOD;
		return *this;
	}
	mi& operator -= (const mi& m) {
		if ((val -= m.val) < 0) val += MOD;
		return *this;
	}
	mi& operator *= (const mi& m) {
		val = (val * m.val) % MOD;
		return *this;
	}
};
mi<ll> f[111], dp[111][11111], ans;
int main() {
    cin.tie(0) -> sync_with_stdio(false); cout.tie(0);
    cin >> N;
    rep(i, 0, N) {
        cin >> W[i];
        tot += W[i];
    }
    if(tot & 1){cout << "0\n"; return 0;}
    tot >>= 1;
    f[0] = 1;
    rep(i, 1, N + 1) f[i] = f[i - 1] * i;
    dp[0][0] = 1;
    rep(i, 0, N) rep2(j, 0, i + 1) rep(k, W[i], 100 * N + 1) {
        dp[j + 1][k] += dp[j][k - W[i]];
    }
    rep(j, 0, N + 1) ans += f[j] * f[N - j] * dp[j][tot];
    cout << ans.val << endl;
}
