#include <stdlib.h>
#include <stdio.h>
struct node
{
int data;
struct node *next;
};
int list_add_front(struct node **head, int val)
{
struct node *tmp;
tmp = malloc(sizeof(struct node));
tmp->data = val;
tmp->next = *head;
*head = tmp;
return 0;
}
int list_pop_front(struct node **head, int *val)
{
struct node *tmp;
*val = (*head)->data;
tmp = *head;
*head = (*head)->next;
free(tmp);
return 0;
}
int dfs(struct node **graph, int root, int *marked, int* order, int *ocount, struct node **chead)
{
if (marked[root])
return 0;
marked[root] = 1;
for(struct node* p = graph[root]; p != NULL; p = p->next)
dfs(graph, p->data, marked, order, ocount, chead);
if(order != NULL) {
order[*ocount] = root;
(*ocount)++;
return 0;
}
list_add_front(chead, root);
return 0;
}
int main()
{
FILE *infile, *outfile;
int n, m, i;
int *order, *marked;
struct node **grapht, **graph;
int count = 0;
int ocount = 0;
infile = fopen("ctc.in", "r");
outfile = fopen("ctc.out", "w");
fscanf(infile, "%d %d", &n, &m);
order = malloc((n+1) * sizeof(int));
marked = malloc((n+1) * sizeof(int));
graph = malloc((n+1) * sizeof(struct node*));
grapht = malloc((n+1) * sizeof(struct node*));
for (i = 0; i <= n; i++) {
order[i] = 0;
marked[i] = 0;
graph[i] = NULL;
grapht[i] = NULL;
}
for (i = 0; i < m; i++) {
int u, v;
fscanf(infile, "%d %d", &u, &v);
// add reverse
list_add_front(&grapht[v], u);
list_add_front(&graph[u], v);
}
for (i = 1; i <=n; i++) {
if(!marked[i]) {
count++;
dfs(grapht, i, marked, order, &ocount, NULL);
}
}
fprintf(outfile, "%d\n", count);
for (i = 1; i <=n; i++)
marked[i] = 0;
for (i = ocount - 1; i >= 0; i--) {
struct node *chead = NULL;
if(marked[order[i]])
continue;
dfs(graph, order[i], marked, NULL, NULL, &chead);
while (chead != NULL){
int val;
list_pop_front(&chead, &val);
fprintf(outfile, "%d ", val);
}
fprintf(outfile, "\n");
}
fclose(infile);
fclose(outfile);
return 0;
}