/* ---------- STL Libraries ---------- */ // IO library #include #include #include #include #include // algorithm library #include #include #include #include #include // container library #include #include #include #include #include #include #include #include #include #include #include /* ---------- Namespace ---------- */ using namespace std; /* ---------- Type ---------- */ using ll = long long; #define int ll #define P pair /* ---------- Constants */ const double PI = 3.141592653589793238462643383279; const ll MOD = 1e9 + 7; const int INF = 1LL << 55; class UnionFind { public: vector par, rank; vector forest_size; int forest_cnt; int N; UnionFind(int n) : forest_cnt(n), N(N) { par = vector(n); iota(par.begin(), par.end(), 0); rank = vector(n, 0); forest_size.resize(n, 1); } int root(int x) { if (par[x] == x) { return x; } else { return par[x] = root(par[x]); } } void unite(int x, int y) { x = root(x); y = root(y); if (x == y) return; int fsz = forest_size[x] + forest_size[y]; if (rank[x] < rank[y]) { par[x] = y; forest_size[y] = fsz; } else { par[y] = x; forest_size[x] = fsz; if (rank[x] == rank[y]) rank[x]++; } forest_cnt--; } bool same(int x, int y) { return root(x) == root(y); } int get_forest_size(int x) { return forest_size[root(x)]; } }; signed main() { int N, M; cin >> N >> M; vector table[N]; UnionFind uf = UnionFind(N); for (int i = 0; i < M; i++) { int s, t; cin >> s >> t; s--; t--; table[s].push_back(t); table[t].push_back(s); uf.unite(s, t); } int Q; cin >> Q; for (int q = 0; q < Q; q++) { int a; cin >> a; a--; vector visited(N, false); visited[a] = true; queue que; que.push(a); int dis = 0; vector dis_v(N, 0); while (!que.empty()) { int node = que.front(); que.pop(); for (int next : table[node]) { if (visited[next]) continue; dis = max(dis, dis_v[node] + 1); dis_v[next] = dis_v[node] + 1; que.push(next); visited[next] = true; } } cout << uf.get_forest_size(a) - 1 << " " << max(0LL, (int) ceil(log2(dis))) << endl; } return 0; }