F: If you want to hide the trees, in the forest

story

"Wood is good" Chico, who runs the coffee shop "Turtle House", has an extraordinary love for trees. Everything seems to wash my heart with the immobility of wood. .. .. In order to confirm Chico-chan's love for trees, Kokoro-chan, who works part-time at the same coffee shop, decided to play a trick on Chico-chan.

Kokoro decided to prepare a forest for Chico and hide some of the trees growing near the coffee shop in the forest to test her love for the trees. Specifically, I decided to have Chico find the hidden tree in the forest. Chico-chan, who loves trees, can tell which trees she has seen once by the difference in how her heart is washed, but because she has moved the trees, the way the trees are immovable has changed, and which tree is which? I don't know the tree near the coffee shop. What's more, even the stupid Kokoro-chan has forgotten which tree is the answer! As it is, the answer tree cannot be returned to its original place, so Kokoro-chan gets angry with Chico-chan. So, let's write a program that will teach Kokoro-chan how many answer trees there are with gentle programmers.

problem

Two graphs G_1 and G_2 are given as inputs. G_1 is a forest, that is, a graph without a cycle (not necessarily connected), and G_2 is a tree, that is, a connected graph without a cycle. At this time, find out how many connected components G_1 has the same type as G_2.

Note 1) Two vertices f (u) and f (v) in G_2 are adjacent only when u and v are adjacent to any two vertices u and v contained in the connected component H_1 with graph G_1. When there is such a bijective f, H_1 is said to be a connected component of G_1, which is isomorphic to G_2.

input

The input is given in the following format.


N_1 M_1
u_1 v_1
...
u_ {M_1} v_ {M_1}
N_2
w_1 x_1
...
w_ {N_2 --1} x_ {N_2 --1}


In the first line, the number of vertices N_1 (1 \ leq N_1 \ leq 300,000) and the number of sides M_1 (0 \ leq M_1 \ leq N_1 --1) of the forest G_1 are given. In the following M_1 line, the i-th side e_i of G_1 is given in the i-th line (1 \ leq i \ leq M_1). e_i is the edge connecting the two vertices u_i and v_i. (1 \ leq u_i, v_i \ leq N_1, u_i \ neq v_i) The next line gives the number of vertices N_2 (1 \ leq N_2 \ leq 30,000) of the tree G_2. In the following N_2 --1 line, the jth side e_j of G_2 is given on the jth line (1 \ leq j \ leq N_2 --1). e_j is the edge connecting the two vertices w_j and x_j. (1 \ leq w_j, x_j \ leq N_2, w_j \ neq x_j)

output

Output the number of connected components of G_1 that are isomorphic to G_2.

Input example 1


6 4
1 2
twenty three
twenty four
5 6
Four
twenty three
3 1
3 4


Output example 1


1

Input example 2


14 9
5 8
5 11
10 14
6 4
13 9
3 14
1 2
6 12
7 9
3
3 1
twenty one


Output example 2


Four





Example

Input

6 4
1 2
2 3
2 4
5 6
4
2 3
3 1
3 4


Output

1
//
// Writer: kurita
// states: AC
// O(N log(N))
//

#include<iostream>
#include<vector>
#include<algorithm>
#include<queue>
#include<map>
#include<cstdio>
using namespace std;
typedef pair<int, int> pii;
typedef vector<vector<int> > Graph;
map<vector<int>, int> tree_hash;

vector<Graph> ConectedComponent(Graph &f) {
  int n = f.size(), pos = 0;
  vector<bool> used(n, false);
  vector<Graph> res;
  queue<int> que;
  while(pos < n){
    vector<int> used_vertex;
    int size = 0;
    que.push(pos);
    used[pos] = true;
    while(not que.empty()){
      size++;
      int v = que.front();
      used_vertex.push_back(v);
      que.pop();
      for (int i = 0; i < f[v].size(); i++) {
        if(used[f[v][i]] == true)continue;
        que.push(f[v][i]);
        used[f[v][i]] = true;
      }
    }
    sort(used_vertex.begin(), used_vertex.end());
    Graph g(used_vertex.size());
    for (int i = 0; i < used_vertex.size(); i++) {
      for (int j = 0; j < f[used_vertex[i]].size(); j++) {
        g[i].push_back(lower_bound(used_vertex.begin(), used_vertex.end(), f[used_vertex[i]][j]) -
                       used_vertex.begin());
      }
    }
    res.push_back(g);
    while(pos < n and used[pos])pos++;
  }
  return res;
}

vector<int> BFS(const Graph &g, vector<int> &dist, int v){
  int n = g.size();
  queue<pii> que;
  vector<int> parent(n);
  for (int i = 0; i < n; i++) parent[i] = i;
  que.push(pii(v, 0));
  dist[v] = 0;
  while(not que.empty()){
    int v = que.front().first;
    int d = que.front().second;
    que.pop();
    for (int i = 0; i < g[v].size(); i++) {
      if(dist[g[v][i]] >= 0)continue;
      dist[g[v][i]] = d + 1;
      parent[g[v][i]] = v;
      que.push(pii(g[v][i], d + 1));
    }
  }
  return parent;
}

inline vector<int> CenterTree(const Graph &g, int v = 0){
  int n = g.size();
  vector<int> dist(n, -1);
  BFS(g, dist, v);
  int u, maxi = -1;
  for (int i = 0; i < n; i++) {
    if(dist[i] > maxi){
      u = i, maxi = dist[i];
    }
  }
  dist = vector<int>(n, -1);
  vector<int> parent = BFS(g, dist, u);
  int diam = 0;
  for (int i = 0; i < n; i++) {
    if(dist[i] > diam) diam = dist[i], v = i;
  }
  
  for (int i = 0; i < diam/2; i++) v = parent[v];
  
  vector<int> res;
  res.push_back(v);
  if(diam%2 != 0)res.push_back(parent[v]);
  return res;
}

int AHUHash(const Graph &t, int v, int parent = -1){
  if(t[v].size() == 1 and parent != -1)return 0;
  vector<int> res;
  for (int i = 0; i < t[v].size(); i++) {
    if(t[v][i] == parent)continue;
    res.emplace_back(AHUHash(t, t[v][i], v));
  }
  sort(res.begin(), res.end());
  if(tree_hash.count(res) == 0){
    tree_hash[res] = 0;
    tree_hash[res] = tree_hash.size();
  }
  return tree_hash[res];
}

int main() {
  int n, m;
  std::cin >> n >> m;
  Graph forest(n);
  int to, from;
  for (int i = 0; i < m; i++) {
    scanf("%d %d", &to, &from);
    to--, from--;
    forest[to].push_back(from);
    forest[from].push_back(to);
  }
  int nn;
  std::cin >> nn;
  Graph tree(nn);
  for (int i = 0; i < nn - 1; i++) {
    scanf("%d %d", &to, &from);
    to--, from--;
    tree[to].push_back(from);
    tree[from].push_back(to);
  }
  int ans = 0;
  vector<int> ct = CenterTree(tree);
  vector<int> th(ct.size());
  for (int i = 0; i < ct.size(); i++) {
    th[i] = AHUHash(tree, ct[i]);
  }
  vector<Graph> tree_set = ConectedComponent(forest);
  for (auto t: tree_set) {
    if(t.size() != nn)continue;
    vector<int> cf = CenterTree(t);
    vector<int> fh(cf.size());
    for (int j = 0; j < cf.size(); j++) {
      fh[j] = AHUHash(t, cf[j]);
    }
    for (int j = 0; j < th.size(); j++) {
      for (int k = 0; k < fh.size(); k++) {
        if(th[j] == fh[k])ans++, j = k = 1e9;
      }
    }
  }
  std::cout << ans << std::endl;
  return 0;
}