int dfn[MAXN],low[MAXN],cnt; bool isbridge[MAXN]; void tarjan(int x,int edg) { low[x]=dfn[x]=++cnt; for(int i=f(x);i;i=n(i)) if(!dfn[v(i)]) { tarjan(v(i),i); low[x]=min(low[x],low[v(i)]); if(low[v(i)]>dfn[x]) isbridge[i]=isbridge[i^1]=1; } else if(i!=(edg^1))low[x]=min(low[x],dfn[v(i)]); } int c[MAXN],dcc; void dfs(int x,int dcc) { c[x]=dcc; for(int i=f(x);i;i=n(i)) if(!c[v(i)]&&!isbridge[i]) dfs(v(i),dcc); } signed main() { for(int i=1;i<=n;i++) if(!dfn[i])tarjan(i,0); for(int i=1;i<=n;i++) if(!c[i])dcc++,dfs(i,dcc); for(int i=2;i<=num_e;i++) if(c[u(i)]!=c[v(i)]) du[c[u(i)]]++; }