#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vi;
typedef pair<ll,ll> pi;
typedef vector<pi> vp;
typedef set<ll> si;
typedef map<string, ll> msi;
#define REP(i,a,b) \
for(ll i=ll(a);i<=ll(b);i++)
#define DEP(i,a,b) \
for(ll i=ll(a);i>=ll(b);i--)
#define TR(c, it) \
for (auto it = (c).begin(); it != (c).end(); it++)
#define mp make_pair
#define pb push_back
#define F first
#define S second
ll mod = 1e9+7;
void dtob(vector<ll> &bin,ll n){
  ll k=bin.size();
  REP(i,0,k-1){
    ll t=pow(2,i);
    t=t&n;
    if(t)bin[i]=1;
  }
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  
  int T;
  T=1;
  while(T--)
  {
      ll n,i,j,k,l,m;
      cin>>n>>m;
      vector<pair<ll,ll> > v,b;
      REP(i,0,m-1){
        cin>>j>>k;
        v.push_back(make_pair(j,k));
      }
      cin>>k;

      REP(i,0,k-1){
        cin>>j>>l;
        b.push_back(make_pair(j,l));
      }
      ll ans=0;
      REP(i,0,pow(2,k)-1){
        vector<ll> bin(k,0);
        dtob(bin,i);
        ll a[101]={0};
        REP(j,0,k-1){
          if(bin[j])a[b[j].S]++;
          else a[b[j].F]++;
        }
        ll temp=0;
        REP(j,0,m-1){
          if(a[v[j].F]>=1&&a[v[j].S]>=1)temp++;
        }
        ans=max(ans,temp);
      }
      cout<<ans;
  }
  return 0;
}
#include "bits/stdc++.h"
#include "ext/pb_ds/tree_policy.hpp"
#include "ext/pb_ds/assoc_container.hpp"
using namespace std;
////////////// Prewritten code follows. Look down for solution. ////////////////
#define x first
#define y second
#define LEN(x) ((int)(x).size())
#define ALL(x) x.begin(), x.end()
using ll = long long;
using llu = long long unsigned;
using ld = long double;
using pii = pair<int, int>;
using vi = vector<int>;
using vpii = vector<pii>;

template<typename T>
const T INF = (is_same<T, int>::value ? 1e9 : 1e18);
const ld EPS = 1e-9;
const int MOD = 1;

inline int fcmp (ld x, ld y = 0, ld tol = EPS) {
	return (x <= y + tol) ? (x + tol < y) ? -1 : 0 : 1;
}

inline int mod (ll x, int m = MOD) {
	int ret = (int)x%m;
	if (ret < 0)
		ret += m;
	return ret;
}

template<typename T, typename M = __gnu_pbds::null_type>
using ordered_set = __gnu_pbds::tree<T, M, less<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;

////////////////////////// Solution starts below. //////////////////////////////



int main () {
	// freopen("FILE_NAME_INPUT.EXTENSION", "r", stdin);
	// freopen("FILE_NAME_OUTPUT.EXTENSION", "w", stdout);
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.precision(10);

	int n, m;
	cin >> n >> m;
	vpii conditions(m);
	for (auto &[x, y] : conditions)
		cin >> x >> y;

	int k;
	cin >> k;
	vpii people(k);
	for (auto &[x, y] : people)
		cin >> x >> y;
	
	int ans = 0;
	vi dishs(n+1);
	for (int msk = 0; msk < (1<<k); msk++) {
		dishs.assign(n+1, 0);
		for (int i = 0; i < k; i++)
			if (msk&(1<<i))
				dishs[people[i].x]++;
			else
				dishs[people[i].y]++;
		int now = 0;
		for (auto [x, y] : conditions)
			now += (dishs[x] and dishs[y]);
		ans = max(ans, now);
	}
	cout << ans << '\n';

	return 0;
}
