传送门biu~
对于原图建圆方树,每次询问在圆方树上建虚树,树上的每一个圆点都符合条件,统计圆点个数即可。
#include<bits/stdc++.h>
#define N 200005
using namespace std;
int n,m,tot,top,tim,TIM,s[N];
int stac[N],dfn[N],low[N],dep[N<<1],val[N<<1],fa[N<<1][20],DFN[N<<1];
int head[N],nex[N<<1],to[N<<1],tp;
inline void add(int x,int y){
nex[++tp]=head[x];
head[x]=tp;
to[tp]=y;
}
int HEAD[N<<1],NEX[N<<3],TO[N<<3],TP;
inline void ADD(int x,int y){
NEX[++TP]=HEAD[x];
HEAD[x]=TP;
TO[TP]=y;
}
inline void init(){
top=tim=TIM=0;
memset(fa,0,sizeof fa);
memset(head,-1,sizeof head),tp=0;
memset(HEAD,-1,sizeof HEAD),TP=0;
memset(dfn,0,sizeof dfn),memset(low,0,sizeof low);
memset(dep,0,sizeof dep),memset(val,0,sizeof val);
}
void tarjan(int x){
dfn[x]=low[x]=++tim;
val[x]=1; stac[++top]=x;
for(int v,p,i=head[x];~i;i=nex[i]){
if(dfn[v=to[i]]) low[x]=min(low[x],dfn[v]);
else{
tarjan(v),low[x]=min(low[x],low[v]);
if(low[v]>=dfn[x]){
++tot;
while((p=stac[top])^v) ADD(p,tot),ADD(tot,p),--top;
p=stac[top],ADD(p,tot),ADD(tot,p),--top;
ADD(x,tot),ADD(tot,x);
}
}
}
}
void dfs(int x){
DFN[x]=++TIM;
for(int i=1;(1<<i)<=dep[x];++i) fa[x][i]=fa[fa[x][i-1]][i-1];
for(int v,i=HEAD[x];~i;i=NEX[i]){
if((v=TO[i])==fa[x][0]) continue;
dep[v]=dep[x]+1,val[v]+=val[x],fa[v][0]=x;
dfs(v);
}
}
inline int lca(int x,int y){
if(dep[x]<dep[y]) swap(x,y);
int len(dep[x]-dep[y]);
for(int i=0;(1<<i)<=len;++i)
if((1<<i)&len) x=fa[x][i];
if(x==y) return x;
for(int i=19;~i;--i)
if(fa[x][i]^fa[y][i]) x=fa[x][i],y=fa[y][i];
return fa[x][0];
}
inline bool cmp(int a,int b){return DFN[a]<DFN[b];}
inline int GetAns(){
int res(0);
sort(s+1,s+s[0]+1,cmp);
int rt=lca(s[1],s[s[0]]);
stac[top=1]=rt;
for(int i=1;i<=s[0];++i){
int LCA=lca(s[i],stac[top]);
while(1){
if(dep[stac[top-1]]<=dep[LCA]){
res+=val[stac[top]]-val[LCA],--top;
if(stac[top]^LCA) stac[++top]=LCA;
break;
}
res+=val[stac[top]]-val[stac[top-1]],--top;
}
if(s[i]^stac[top]) stac[++top]=s[i];
}
while(top>1) res+=val[stac[top]]-val[stac[top-1]],--top;
return res+(rt<=n)-s[0];
}
inline void solve(){
scanf("%d%d",&n,&m),tot=n;
for(int u,v,i=0;i<m;++i) scanf("%d%d",&u,&v),add(u,v),add(v,u);
tarjan(1),dfs(1);
int Q;scanf("%d",&Q);
while(Q--){
scanf("%d",&s[0]);
for(int i=1;i<=s[0];++i) scanf("%d",&s[i]);
printf("%d\n",GetAns());
}
}
int main(){
int T;scanf("%d",&T);
while(T--){
init();
solve();
}
return 0;
}