#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1000 * 3 + 10, INF = 1e9 + 10;
struct UnionFind {
  int parent[MAXN], sz[MAXN];
  UnionFind(int n) {
    for (int i = 0; i < n; i++) {
      parent[i] = i;
      sz[i] = 1;
    }
  }
  int find(int v) {
    int root = v;
    while (parent[root] != root) root = parent[root];
    while (v != root) {
      int old = v;
      v = parent[v];
      parent[old] = root;
    }
    return root;
  }
  void merge(int u, int v) {
    u = find(u);
    v = find(v);
    if (u == v) return;
    if (sz[u] < sz[v]) swap(u, v);
    sz[u] += sz[v];
    parent[v] = u;
  }
};
int mark[MAXN];
vector<int> dis[MAXN];
int main() {
  ios::sync_with_stdio(false);
  int n, k, m;
  cin >> n >> k;
  UnionFind a(n);
  for (int i = 0; i < k; i++) {
    int x, y;
    cin >> x >> y;
    x--, y--;
    a.merge(x, y);
  }
  cin >> m;
  for (int i = 0; i < m; i++) {
    int x, y;
    cin >> x >> y;
    x--, y--;
    dis[x].push_back(y);
    dis[y].push_back(x);
  }
  int ans = 0;
  for (int i = 0; i < n; i++)
    if (!mark[i]) {
      vector<int> cur;
      int root = a.find(i);
      for (int j = 0; j < n; j++)
        if (a.find(j) == root) {
          cur.push_back(j);
          mark[j] = i + 1;
        }
      bool check = true;
      for (int j = 0; j < ((int)cur.size()); j++) {
        int v = cur[j];
        for (int k = 0; k < ((int)dis[v].size()); k++) {
          if (mark[dis[v][k]] == i + 1) check = false;
        }
      }
      if (!check) continue;
      ans = max(ans, ((int)cur.size()));
    }
  cout << ans << endl;
  return 0;
}
