但是会超时
#include <bits/stdc++.h>
using namespace std;
const int maxn=2e6+10;
int t,n,m,f,q;
vector<int>vec[maxn];
struct edge{ int to,nxt; }d[maxn];
int head[maxn],cnt=1;
void add(int u,int v){ d[++cnt]=(edge){v,head[u]},head[u]=cnt; }
void ins(int u,int v){ vec[u].push_back(v); }
int low[maxn],dfn[maxn],stac[maxn],iid,top;
void tarjan(int u)
{
low[u]=dfn[u]=++iid,stac[++top]=u;
for(int i=head[u];i;i=d[i].nxt )
{
int v=d[i].to;
if( !dfn[v] )
{
tarjan(v),low[u]=min(low[u],low[v]);
if( low[v]>=dfn[u] )
{
++f;//发现割点
while( 1 )
{
ins(f,stac[top]); ins(stac[top],f);
if( stac[top--]==v ) break;
}
ins(f,u); ins(u,f);
}
}
else low[u]=min( low[u],dfn[v] );
}
}
int id[maxn],fa[maxn][22],dis[maxn],num,deep[maxn],s[maxn];
void dfs(int u,int father)
{
id[u]=++num,deep[u]=deep[father]+1;
fa[u][0]=father, dis[u]=dis[father]+( u<=n );
for(int i=1;i<=20;i++)
fa[u][i]=fa[ fa[u][i-1] ][i-1];
for(int i=0;i<vec[u].size();i++)
if( vec[u][i]!=father ) dfs( vec[u][i],u );
}
int lca(int x,int y)
{
if( deep[x]<deep[y] ) swap(x,y);
// for(int i=log(deep[x]);i>=0;i--)
// if( deep[fa[x][i]]>=deep[y] ) x=fa[x][i];
for(int j=0,d=deep[x]-deep[y];d;j++,d>>=1)
if( d&1 ) x=fa[x][j];
if( x==y ) return x;
for(int i=18;i>=0;i--)
if( fa[x][i]!=fa[y][i] )
x=fa[x][i],y=fa[y][i];
return fa[x][0];
}
bool com(int a,int b){ return id[a]<id[b]; }
void init()
{
iid=0,num=0,cnt=1,top=0;
for(int i=1;i<=f;i++)
{
vec[i].clear(),head[i]=0;
dfn[i]=low[i]=0;
id[i]=dis[i]=deep[i]=0;
for(int j=0;j<=20;j++) fa[i][j]=0;
}
}
int main()
{
ios::sync_with_stdio(false);
// cin.tie(0),cout.tie(0);
cin >> t;
while( t-- )
{
cin >> n >> m;
f=n;
for(int i=1;i<=m;i++)
{
int l,r; cin >> l >> r;
add(l,r); add(r,l);
}
tarjan(1),top--;
dfs(1,0);
cin >> q;
while( q-- )
{
int shu,ans=0; cin >> shu;
ans=-2*shu;
for(int i=1;i<=shu;i++) cin >> s[i];
sort(s+1,s+1+shu,com);
for(int i=1;i<shu;i++)
{
int u=s[i],v=s[i+1];
ans+=dis[u]+dis[v]-2*dis[lca(u,v)];
}
ans+=dis[s[1]]+dis[s[shu]]-2*dis[lca(s[1],s[shu])];
if( lca(s[1],s[shu])<=n ) ans+=2;
cout << ans/2 << '\n';
}
init();
}
}