#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> l_l;
ll N1, M1;
ll N2;
bool visited[350000];
set<ll> valid;
ll dist[2][350000];
vector<ll> pathes[350000];
l_l HASH[350000][2];
ll base[2];
ll mod[2];
ll R[350000];
random_device seed_gen;
default_random_engine engine(seed_gen());
uniform_int_distribution<> disti(2, 9e8);
void DFS(int index, int now, int from) {
    visited[now] = true;
    valid.insert(now);
    for(int i = 0; i < pathes[now].size(); i++) {
        int to = pathes[now][i];
        if(to == from) continue;
        dist[index][to] = dist[index][now] + 1;
        DFS(index, to, now);
    }
}

l_l Hash(ll now, ll from, ll depth) {
    l_l hashnow = {1, 1};
    for(int i = 0; i < pathes[now].size(); i++) {
        ll to = pathes[now][i];
        if(to == from) continue;
        l_l newhash = Hash(to, now, depth + 1);
        hashnow.first = hashnow.first * (newhash.first + R[depth]) % mod[0];
        hashnow.second = hashnow.second * (newhash.second + R[depth]) % mod[1];
    }
    return hashnow;
    /*
    vector<l_l> hashes;
    for(int i = 0; i < pathes[now].size(); i++) {
        ll to = pathes[now][i];
        if(to == from) continue;
        hashes.push_back(Hash(to, now));
    }
    sort(hashes.begin(), hashes.end());
    l_l childhash = {0, 0};
    for(int i = 0; i < hashes.size(); i++) {
        childhash.first *= base[0];
        childhash.first %= mod[0];
        childhash.first += hashes[i].first;
        childhash.first %= mod[0];
        childhash.second *= base[1];
        childhash.second %= mod[1];
        childhash.second += hashes[i].second;
        childhash.second %= mod[1];
    }
    childhash.first = (childhash.first * base[0]) % mod[0];
    childhash.second = (childhash.second * base[1]) % mod[1];
    childhash.first = (childhash.first + 1) % mod[0];
    childhash.second = (childhash.second + 1) % mod[1];
    return childhash;
    */
}

void f(int now) {
    valid.clear();
    dist[0][now] = 0;
    DFS(0, now, -1);
    int worst[2];
    worst[0] = now;
    for(auto itr = valid.begin(); itr != valid.end(); itr++) {
        if(dist[0][worst[0]] < dist[0][*itr]) worst[0] = *itr;
    }
    dist[0][worst[0]] = 0;
    DFS(0, worst[0], -1);
    worst[1] = now;
    for(auto itr = valid.begin(); itr != valid.end(); itr++) {
        //cerr << "TWICE: " << *itr << " " << dist[0][*itr] << endl;
        if(dist[0][worst[1]] < dist[0][*itr]) worst[1] = *itr;
    }
    //cerr << "WORST: " << worst[0] << " " << worst[1] << endl;
    ll minimum = 1e9;
    dist[1][worst[1]] = 0;
    DFS(1, worst[1], -1);
    for(auto itr = valid.begin(); itr != valid.end(); itr++) {
        minimum = min(minimum, max(dist[0][*itr], dist[1][*itr]));
        //cerr << "DIST: " << *itr << " " << dist[0][*itr] << " " << dist[1][*itr] << endl;
    }
    l_l centers = {0, 0};
    for(auto itr = valid.begin(); itr != valid.end(); itr++) {
        if(minimum == max(dist[0][*itr], dist[1][*itr])) {
            if(centers.first == 0) centers.first = *itr;
            centers.second = *itr;
        }
    }
    //cerr << now << " " << centers.first << " " << centers.second << endl;
    HASH[now][0] = Hash(centers.first, -1, 0);
    HASH[now][1] = Hash(centers.second, -1, 0);
    /*
    cerr << "----" << now << "----" << endl;
    cerr << HASH[now][0].first << " " << HASH[now][0].second << endl;
    cerr << HASH[now][1].first << " " << HASH[now][1].second  << endl;
    */
}
int main() {
    for(int i = 0; i <= 320000; i++) R[i] = disti(engine);
    base[0] = 65434674;
    base[1] = 54643547;
    mod[0] = 1e9 + 7;
    mod[1] = 998244353;
    cin >> N1 >> M1;
    while(M1--) {
        ll u, v;
        cin >> u >> v;
        pathes[u].push_back(v);
        pathes[v].push_back(u);
    }
    cin >> N2;
    for(int i = 1; i < N2; i++) {
        ll u, v;
        cin >> u >> v;
        pathes[u+N1].push_back(v+N1);
        pathes[v+N1].push_back(u+N1);
    }
    int counter = 0;
    for(int i = 1; i <= N1 + 1; i++) {
        if(visited[i]) continue;
        counter++;
        f(i);
    }
    ll ans = 0;
    for(int i = 1; i <= N1; i++) {
        if(HASH[i][0] == HASH[N1+1][0]) ans++;
        else if(HASH[i][1] == HASH[N1+1][0]) ans++;
        else if(HASH[i][0] == HASH[N1+1][1]) ans++;
        else if(HASH[i][1] == HASH[N1+1][1]) ans++;
    }
    //cerr << "COUNTER: " << counter << endl;
    cout << ans << endl;
    return 0;
}


Measured memory_bytes: 71848