#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int **Next,
*numNext,
n, m;
} Graph;
typedef struct {
int post, i;
} PostNode;
inline void initGraph(Graph *G, int n, int m) {
G->n = n;
G->m = m;
G->Next = (int**)calloc(n, sizeof(int*));
G->numNext = (int*)calloc(n, sizeof(int));
}
void freeGraph(Graph *G) {
int i;
for (i = 0; i < G->n; ++ i)
free(G->Next[i]);
free(G->Next);
free(G->numNext);
}
inline void addEdge(Graph *G, int a, int b) {
G->Next[a] = (int*)realloc(G->Next[a], (G->numNext[a] + 1) * sizeof(int));
G->Next[a][G->numNext[a] ++] = b;
}
int t;
int *Order, numOrder;
void depthFirstPost(Graph G, int a, int *Used, PostNode *Post) {
Used[a] = 1;
int i, next;
for (i = 0; i < G.numNext[a]; ++ i) {
next = G.Next[a][i];
if (!Used[next]) {
t ++;
depthFirstPost(G, next, Used, Post);
}
}
Post[a].post = ++ t;
Post[a].i = a;
Order[numOrder ++] = a;
}
void depthFirst(Graph G, int a, int label, int *Used) {
Used[a] = label;
int i, next;
for (i = 0; i < G.numNext[a]; ++ i) {
next = G.Next[a][i];
if (!Used[next])
depthFirst(G, next, label, Used);
}
}
int postCmp(const void *a, const void *b) {
return ( (PostNode*)b )->post - ( (PostNode*)a )->post;
}
int main() {
FILE *in = fopen("ctc.in", "r");
freopen("ctc.out", "w", stdout);
int n, m, i, a, b;
fscanf(in, "%d%d", &n, &m);
Graph G, GT;
initGraph(&G, n, m), initGraph(>, n, m);
for (i = 0; i < m; ++ i) {
fscanf(in, "%d%d", &a, &b);
-- a, --b;
addEdge(&G, a, b);
addEdge(>, b, a);
}
fclose(in);
int *Used = (int*)calloc(n, sizeof(int));
PostNode *Post = (PostNode*)calloc(n, sizeof(PostNode));
Order = (int*)calloc(n, sizeof(int));
numOrder = 0;
t = 1;
for (i = 0; i < n; ++ i) {
if (!Used[i])
depthFirstPost(G, i, Used, Post);
}
//qsort(Post, n, sizeof(PostNode), postCmp);
/*for (i = n - 1; i >= 0; -- i)
printf("(%d %d) ", Post[Order[i]].i, Post[Order[i]].post);
printf("\n");*/
memset(Used, 0, n * sizeof(int));
int label, j;
for (i = 0, label = 1; i < n; ++ i)
if (!Used[Post[i].i])
depthFirst(GT, Post[i].i, label ++, Used);
printf("%d\n", label - 1);
for (i = 1; i < label; ++ i) {
for (j = 0; j < n; ++ j)
if (Used[j] == i)
printf("%d ", j + 1);
printf("\n");
}
free(Order);
free(Post);
free(Used);
freeGraph(&G);
freeGraph(>);
return 0;
}