1 #include<cstdio>
2 #include<iostream>
3
4 using namespace std;
5
6 const int maxn = 400010;
7
8 int k, m, n, tot;
9 int head[maxn], ans[maxn], broken[maxn], f[maxn];
10 bool flag[maxn];
11
12 struct node{
13 int next, to, from;
14 } h[maxn];
15
16 inline void add(int u, int v){
17 h[++tot].from = u;
18 h[tot].next = head[u];
19 head[u] = tot;
20 h[tot].to = v;
21 }
22
23 inline int find(int x){
24 if(f[x] != x) f[x] = find(f[x]);
25 return f[x];
26 }
27
28 inline void unionn(int u, int v){
29 u = find(u), v = find(v);
30 if(u != v) f[v] = u;
31 }
32
33 int main(){
34 scanf("%d%d", &n, &m);
35 for(int i = 0; i <= n; i++){
36 f[i] = i;
37 head[i] = -1;
38 }//初始化
39 for(int i = 1; i <= m; i++){
40 int x, y;
41 scanf("%d%d", &x, &y);
42 add(x, y);
43 add(y, x);
44 }//储存图
45 scanf("%d", &k);
46 for(int i = 1; i <= k; i++){
47 scanf("%d", &broken[i]);
48 flag[broken[i]] = 1;
49 }
50 int sum = n - k;//初始化所有点都是单独存在的
51 for(int i = 1; i <= 2 * m; i++){
52 if(!flag[h[i].from] && !flag[h[i].to] && find(h[i].from) != find(h[i].to)){//要是起点、终点都没毁坏,并且他们没有连通
53 sum--;//连一条边 减一个连通块
54 unionn(h[i].from, h[i].to);
55 }
56 }
57 ans[k + 1] = sum;
58 for(int i = k; i >= 1; i--){
59 sum++;
60 flag[broken[i]] = 0;//修复,连通块+1
61 for(int j = head[broken[i]]; j != -1; j = h[j].next){
62 if(!flag[h[j].to] && find(broken[i]) != find(h[j].to)){//枚举子点
63 sum--;//连一边减一个
64 unionn(broken[i], h[j].to);
65 }
66 }
67 ans[i] = sum;
68 }
69 for(int i = 1; i <= k + 1; i++)
70 printf("%d
", ans[i]);
71 return 0;
72 }