#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=20010;
const int maxm=50010;
struct edge{
int to,nxt;
}edge[maxm];
int head[maxn],tot;
int low[maxn],dfn[maxn],stack[maxn],belong[maxn];
int index,top;
int scc;
bool vis[maxn];
int num[maxn];
void addedge(int u,int v)
{
edge[tot].to=v;
edge[tot].nxt=head[u];
head[u]=tot++;
}
void tarjan(int u)
{
int v;
low[u]=dfn[u]=++index;
stack[top++]=u;
vis[u]=true;
for ( int i=head[u];i!=-1;i=edge[i].nxt ) {
v=edge[i].to;
if ( !dfn[v] ) {
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if ( vis[v] ) low[u]=min(low[u],dfn[v]);
}
if ( low[u]==dfn[u] ) {
scc++;
do {
v=stack[--top];
vis[v]=false;
belong[v]=scc;
num[scc]++;
}
while ( v!=u );
}
}
void solve(int N)
{
memset(dfn,0,sizeof(dfn));
memset(vis,false,sizeof(vis));
memset(num,0,sizeof(num));
index=scc=top=0;
for ( int i=1;i<=N;i++ ) {
if ( !dfn[i] ) tarjan(i);
}
}
void init()
{
tot=0;
memset(head,-1,sizeof(head));
}
tarjan模板