int cor[nMax],dfn[nMax],low[nMax],instack[nMax],st[nMax];
int top,scc,cnt;
void tarjan_dfs(int cur)
{
    dfn[cur] = low[cur] = ++cnt;
    st[++top] = cur;
    instack[cur] = 1;
    for(int i = g[cur]; i ;i = edge[i].nxt){
        int v = edge[i].v;
        if( !instack[v] ){
            tarjan_dfs(v);
            low[cur] = min(low[cur],low[v]);
        }
        else if( instack[v] == 1 )
            low[cur] = min(low[cur],dfn[v]);
    }
    if( low[cur] == dfn[cur] ){
        ++scc;
        for(;;){
            int tmp = st[top];
            top--;
            cor[tmp] = scc;
            cor_tot[scc]++;
            instack[tmp] = 2;
            if( tmp == cur )
                break;
        }
    }
}
void tarjan()
{
    memset(instack,0,sizeof(instack));
    memset(cor_tot,0,sizeof(cor_tot));
    scc = cnt = 0;
    top = 0;
    for(int i = 1;i <= n;i++)
        if( !instack[i] )
            tarjan_dfs(i);
}