#ifndef INCLUDED_MAIN #define INCLUDED_MAIN #include __FILE__ int main(void) { ll n,m; cin>>n>>m; vector> edge; rep(i,m) { ll v,u; cin>>u>>v; u--; v--; edge.emplace_back(u,v); } ll q; cin>>q; vector col(q); rep(i,q) { ll b; cin>>b; b--; col[i]=b; } UnionFind uf(n); vector ers(m); rep(i,q) { ers[col[i]]=true; } rep(i,m) { if(!ers[i]) uf.unite(edge[i].first,edge[i].second); } ll total=n*(n-1)/2; ll reach=0; rep(i,n) { if(uf.root(i)==i){ ll sz=uf.szof(i); reach+=sz*(sz-1)/2ll; } } ll unr=total-reach; vl ans(q); irep(i,q-1,0) { ans[i]=unr; ll collap=col[i]; ll u=edge[collap].first,v=edge[collap].second; if(!uf.same(u,v)){ ll su=uf.szof(u); ll sv=uf.szof(v); uf.unite(u,v); unr-=(ll)su*(ll)sv; } } rep(i,q) { cout< using namespace std; #define rep(i,n) for(ll i=0;i=l;i--) using ll = long long; using ld = long double; const ll mod=998244353; #define vout(v) for(auto i :v) cout< #define vc vector #define pb push_back ll vecmax(vector a) { ll ans=-INF; rep(i,(ll)a.size()) { ans=max(ans,a[i]); } return ans; } struct UnionFind { vector par; vector rank; vector size; int count; UnionFind(int N):par(N),rank(N,0),count(N),size(N,1){ rep(i,N) { par[i]=i; rank[i]=0; size[i]=1; } } //経路圧縮 int root(int x){ return par[x]==x?x:par[x]=root(par[x]); } void unite(int x,int y){ int rx=root(x),ry=root(y); if(rx==ry) return; count--; if(rank[rx]0) { if (po&1) ret=(ret*fl)%mod; fl=(fl*fl)%mod; po>>=1; } } else { while (po>0) { if(po&1) ret*=fl; fl*=fl; po>>=1; } } return ret; } ll op(ll a,ll b) {return max(a,b);} ll e() {return -Winf; } template bool chmin(T& a, T b){if(a > b){a = b; return true;} return false;} template bool chmax(T& a, T b){if(a < b){a = b; return true;} return false;} void no() { cout<<"No"<