Problem:
Score : 100 points

Problem Statement

You are given a directed graph with N vertices and M edges, not necessarily simple. The i-th edge is oriented from the vertex a_i to the vertex b_i.
Divide this graph into strongly connected components and print them in their topological order.

Constraints

1 \leq N \leq 500,000

1 \leq M \leq 500,000

0 \leq a_i, b_i < N

Input

Input is given from Standard Input in the following format:

N M
a_0 b_0
a_1 b_1
:
a_{M - 1} b_{M - 1}

Output

Print 1+K lines, where K is the number of strongly connected components.
Print K on the first line.
Print the information of each strongly connected component in next K lines in the following format, where l is the number of vertices in the strongly connected component and v_i is the index of the vertex in it.

l v_0 v_1 ... v_{l-1}

Here, for each edge (a_i, b_i), b_i should not appear in earlier line than a_i.

If there are multiple correct output, print any of them.

Sample Input 1

6 7
1 4
5 2
3 0
5 5
4 1
0 3
4 2

Sample Output 1

4
1 5
2 4 1
1 2
2 3 0

Solution in C (GCC 9.2.1) (judge verdict: Accepted)

#include <stdio.h>

typedef struct List {
	struct List *next;
	int v;
} list;

list *adj[500001] = {}, *adj_inv[500001] = {}, e[1000001], *sc[500001] = {}, d[500001], *sc_adj[500001] = {}, f[500001];

void DFS1(int u, int label[], int q[])
{
	if (label[u] != 0) return;
	else label[u] = 1;
	
	list *p;
	for (p = adj[u]; p != NULL; p = p->next) DFS1(p->v, label, q);
	q[label[0]++] = u;
}

void DFS2(int u, int label[])
{
	if (label[u] != 0) return;
	else {
		label[u] = label[0];
		d[u].v = u;
		d[u].next = sc[label[0]];
		sc[label[0]] = &(d[u]);
	}
	
	list *p;
	for (p = adj_inv[u]; p != NULL; p = p->next) DFS2(p->v, label);
}

int SCC(int N, int label[], int size[], int deg[])
{
	int i, k, u, q[500001];
	for (i = 1; i <= N; i++) DFS1(i, label, q);
	for (i = 0; i <= N; i++) label[i] = 0;
	for (i = N - 1, k = 1; i >= 0; i--) {
		if (label[q[i]] == 0) {
			label[0] = k++;
			DFS2(q[i], label);
		}
	}
	
	list *p;
	for (i = 1, k--; i <= k; i++) for (p = sc[i]; p != NULL; p = p->next, size[i]++);
	for (u = 1, i = 0; u <= N; u++) {
		for (p = adj[u]; p != NULL; p = p->next) {
			if (label[p->v] == label[u]) continue;
			f[i].v = label[p->v];
			f[i].next = sc_adj[label[u]];
			sc_adj[label[u]] = &(f[i++]);
			deg[label[p->v]]++;
		}
	}
	return k;
}

int main()
{
	int i, N, M, u, w;
	scanf("%d %d", &N, &M);
	for (i = 0; i < M; i++) {
		scanf("%d %d", &u, &w);
		if (u == w) continue;
		e[i*2].v = w + 1;
		e[i*2+1].v = u + 1;
		e[i*2].next = adj[u+1];
		e[i*2+1].next = adj_inv[w+1];
		adj[u+1] = &(e[i*2]);
		adj_inv[w+1] = &(e[i*2+1]);
	}
	
	int label[500001] = {}, size[500001] = {}, deg[500001] = {}, k = SCC(N, label, size, deg), q[500001], head, tail;
	list *p;
	printf("%d\n", k);
	for (i = 1, tail = 0; i <= k; i++) if (deg[i] == 0) q[tail++] = i;
	for (head = 0; head < tail; head++) {
		i = q[head];
		printf("%d", size[i]);
		for (p = sc[i]; p != NULL; p = p->next) printf(" %d", p->v - 1);
		printf("\n");
		
		for (p = sc_adj[i]; p != NULL; p = p->next) {
			deg[p->v]--;
			if (deg[p->v] == 0) q[tail++] = p->v;
		}
	}
	fflush(stdout);
	return 0;
}