int From[maxn], Laxt[maxn], To[maxn << 2], Next[maxn << 2], cnt;

int low[maxn], dfn[maxn], times, q[maxn], head, scc_cnt, scc[maxn];

bool inst[maxn];

vectorG[maxn];

void add(int u, int v)

{

Next[++cnt] = Laxt[u]; From[cnt] = u;

Laxt[u] = cnt; To[cnt] = v;

}

void tarjan(int u)

{

dfn[u] = low[u] = ++times;

q[++head] = u;

inst[u] = 1;

for (int i = Laxt[u]; i; i = Next[i]) {

if (!dfn[To[i]]) {

tarjan(To[i]);

low[u] = min(low[u], low[To[i]]);

} else if (inst[To[i]]) {

low[u] = min(low[u], dfn[To[i]]);

}

}

if (low[u] == dfn[u]) {

scc_cnt++;

while (true) {

int x = q[head--];

scc[x] = scc_cnt;

inst[x] = 0;

if (x == u) { break; }

}

}