
#define SVR "CreatedBySmitRami"

///////////////////////Loading Payloads.......////////////////////////////
#include<bits/stdc++.h>
#define f(i,a,b) for(int i = a; i < b; i++)
#define fd(i,a,b) for(int i = a; i > b;i--)
#define ll long long
#define fl(i,a,b) for(ll i = a; i < b; i++)
#define VI vector<int>
#define VP vector<pair<int,int>>
#define VS vector<string>
#define VL vector<long long>
#define VC vector<char>
#define VF vector<float>
#define PB push_back
#define F first
#define S second
#define fa(i,skill) for(auto i : skill)
#define fr(i,skill) for(VI :: reverse_iterator i = skill.rbegin(); i != skill.rend(); i++)
#define PI pair<int,int>
#define mi map<int,int>
#define mci map<char,int>
#define all(x) x.begin(),x.end()
#define MAX 1000000001
using namespace std;

///////////////////////Engine Check.......////////////////////////////
void edit(VI &skill,int n)
{
    f(i,0,n)
        {
            int x;
            cin >> x;
            skill.PB(x);
        }
}
void editl(VL &skill,ll n)
{
    fl(i,0,n)
        {
            ll x;
            cin >> x;
            skill.PB(x);
        }
}


void achilles()
{
    int n,m;cin >> n >> m;
    VP p(m);
    f(i,0,m)
    {
        cin >> p[i].F >> p[i].S;
        
    }   
    int k;cin >> k;
    VP q(k);
    f(i,0,k)
    {
        cin >> q[i].F >> q[i].S;
    }
    int x = 1;
    f(i,0,k) x *= 2;
    VI ans;
    f(j,0,x)
    {
        string  u = bitset<16>(j).to_string();
        string s = "";
        fd(i,15,15-k)
        s += u[i];
        set<int> sss;
        f(i,0,k)
        {
            if(s[i]=='0')sss.insert(q[i].F);
            else sss.insert(q[i].S);
        }
        int y =0;
        f(i,0,m)
        {
            if(sss.count(p[i].F) && sss.count(p[i].S))y++;
        }
        ans.PB(y);
    }

    cout << *max_element(all(ans)) << "\n";
}

///////////////////////3....2....1...Ignition////////////////////////////

int main()
{
    ios :: sync_with_stdio(0);
    cin.tie(0);
    //freopen("out.txt","w",stdin);
    /*int t;cin >>t ;
    while(t--)*/
    {achilles();}
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define gcd(m,n) __gcd(m,n)
#define lcm(m,n) m*(n/gcd(m,n))
#define fast std::ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define pi acos(-1.0)
#define endl '\n'
#define MOD 1000000007
#define ull unsigned long long
#define ll long long
#define ld long double
#define pb push_back
#define dbg(x) cout << #x << "  " << x << endl;
ll power(ll base, ll exp) 
{ll res=1;while(exp>0) {if(exp%2==1) res=(res*base);base=(base*base);exp/=2;}return res;}
ll mod(ll a, ll b) {return (a % b + b) % b;}
ll powerm(ll base,ll exp,ll mod) 
{ll ans=1;while(exp){if(exp&1) ans=(ans*base)%mod;exp>>=1,base=(base*base)%mod;}return ans;}
/*{{ x | (1 << k) sets the kth bit of x to one
x & ~(1 << k) sets the kth bit of x to zero
x ^ (1 << k) inverts the kth bit of x.
x & (x-1) sets the last one bit of x to zero
x & -x sets all the one bits to zero, except for the last one bit. 
x | (x-1) inverts all the bits after the last one bit.}} SOME BIT MANIPULATION*/
//__builtin_clz(x): the number of zeros at the beginning of the number
//__builtin_ctz(x): the number of zeros at the end of the number
//__builtin_popcount(x): the number of ones in the number
//__builtin_parity(x): the parity (even or odd) of the number of ones 
struct custom_hash 
{
    static uint64_t splitmix64(uint64_t x) 
	{
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }
    size_t operator()(uint64_t x) const 
	{
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};
/*//DSU 
int parent[200005];
int rankr[200005];
int find_set(int v) {
    if (v == parent[v])
        return v;
    return parent[v] = find_set(parent[v]);
}
void make_set(int v) {
    parent[v] = v;
    rankr[v] = 0;
}
void union_sets(int a, int b) {
    a = find_set(a);
    b = find_set(b);
    if (a != b) {
        if (rankr[a] < rankr[b])
            swap(a, b);
        parent[b] = a;
        if (rankr[a] == rankr[b])
            rankr[a]++;
    }
} */
vector<vector<ll>>arr,v;
unordered_map<ll,ll>mp;
ll solve(ll idx)
{
	if(idx == arr.size())
	{
		ll res = 0;
		for(ll i = 0; i < v.size(); i++)
		{
			ll a = v[i][0]; ll b = v[i][1];
			if(mp[a] > 0 && mp[b] > 0)
			{
				res++;
			}
		}
		return res;
	}
	mp[arr[idx][0]]++;
	ll c1 = solve(idx+1);
	mp[arr[idx][0]]--;
	mp[arr[idx][1]]++;
	ll c2 = solve(idx+1);
	mp[arr[idx][1]]--;
	ll ans = max(c1,c2);
	return ans;
}
int main() 
{
    fast;
   	ll n,m; cin>>n>>m;
   	for(ll i = 0; i < m; i++)
   	{
   		ll x,y; cin>>x>>y; x--; y--;
   		v.push_back({x,y});
	}
	ll res = 0; ll k; cin>>k;
	for(ll i = 0; i < k; i++)
	{
		ll x,y; cin>>x>>y; x--; y--;
		arr.push_back({x,y});
	}
	cout << solve(0) << endl;
	return 0;
}