
//SCC板子
void tarjan(int u){
dfn[u]=low[u]=++cnt;
stk[++top]=u;
ins[u]=1;
for(int i=hed[u];i;i=nxt[i]){
int v=ver[i];
if(!dfn[v]){
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(ins[v]){
low[u]=min(low[u],dfn[v]);
}
}
if(dfn[u]==low[u]){
int v;
cntt++;
do{
v=stk[top--];
ins[v]=0;
scc[cntt].push_back(v);
blg[v]=cntt;
}while(u!=v);
}
}

//点双连通分量板子
void tarjan(int x){
dfn[x]=low[x]=++cnt;
ins[x]=1;
s.push(x);
if(!siz[x]){
dcc[++cntt].push_back(x);
return ;
}
int ch=0;
for(int i=hed[x];i;i=nxt[i]){
int y=ver[i];
if(!dfn[y]){
tarjan(y);
low[x]=min(low[x],low[y]);
if(low[y]>=dfn[x]){
ch++;
if(rt!=x||ch>1){
cut[x]=1;
}
cntt++;
int z;
do{
z=s.top();
ins[z]=0;
s.pop();
dcc[cntt].push_back(z);
}while(y!=z);
dcc[cntt].push_back(x);
}
}
else{
low[x]=min(low[x],dfn[y]);
}
}
}
//边双连通分量板子
void tarjan(int u,int in_edg){
dfn[u]=low[u]=++cnt;
for(int i=hed[u];i;i=nxt[i]){
int v=ver[i];
if(!dfn[v]){
tarjan(v,i);
low[u]=min(low[u],low[v]);
if(low[v]>dfn[u]){
brg[i]=brg[i^1]=1;
}
}
else if(i!=(in_edg^1)){
low[u]=min(low[u],dfn[v]);
}
}
}