#include <stdio.h>
#include <stdlib.h>
#define WHITE 0
#define GRAY 1
#define BLACK 2
typedef struct nod {
int nr_copil;
int *kid;
int culoare;
} Nod;
int N, M, *S, nr_elem, **comp, nr_comp, *aux, n_glob;
FILE *in, *out;
void dfs(Nod *graf, int i)
{
int j;
graf[i].culoare = GRAY;
for (j = 0; j < graf[i].nr_copil; j++)
if (graf[graf[i].kid[j]].culoare == WHITE)
dfs(graf, graf[i].kid[j]);
S[nr_elem++] = i;
graf[i].culoare = BLACK;
}
void dfsT (Nod *transpus, int i)
{
int j, t;
transpus[i].culoare = GRAY;
aux[n_glob++] = i;
//scot din stiva
for (j = 0; j < nr_elem; j++)
if( S[j] == i) {
for (t = j ; t < nr_elem - 1; t++)
S[t] = S[t + 1];
nr_elem --;
break;
}
for (j = 0; j < transpus[i].nr_copil; j++)
if (transpus[transpus[i].kid[j]].culoare == WHITE)
dfsT(transpus, transpus[i].kid[j]);
transpus[i].culoare = BLACK;
}
void ctc (Nod *graf, Nod *transpus)
{
int i, j, cod = 1, c;
while (cod) {
for (i = 1; i <= N; i++) {
c = 0;
for (j = 0; j < nr_elem; j++)
if (S[j] == i) {
c = 1;
break;
}
if (c == 0) {//nodul nu e pe stiva
dfs(graf, i);
break;
}
if (c == 1)
cod = 0;
}
}
while (nr_elem > 0) {
i = S[nr_elem - 1];
nr_elem --;
n_glob = 0;
dfsT(transpus, i);
if (n_glob > 1) {
nr_comp++;
comp = realloc(comp, (nr_comp + 1) * sizeof(int*));
comp[nr_comp] = calloc(N, sizeof(int));
comp[nr_comp - 1][0] = n_glob;
for (j = 0; j < n_glob; j++) {
comp[nr_comp - 1][j + 1] = aux[j];
}
}
}
}
void afisare (FILE *out, Nod *graf)
{
int i,j;
for (i = 1; i <= N; i++) {
printf("%d: ", i);
for (j = 0; j < graf[i].nr_copil; j++)
printf("%d ", graf[i].kid[j]);
printf("\n");
}
}
void print()
{
int i,j ;
fprintf(out, "%d\n", nr_comp);
for(i = 0; i < nr_comp; i++) {
for (j = 0; j < comp[i][0]; j++)
fprintf(out,"%d ", comp[i][j+1]);
fprintf(out,"\n");
}
}
int main()
{
int i, x, y;
in = fopen("ctc.in","r");
out = fopen("ctc.out","w");
fscanf(in, "%d", &N); //nr de noduri
fscanf(in, "%d", &M); //nr de muchii
Nod *graf, *transpus;
graf = calloc(N + 1, sizeof(Nod));
transpus = calloc(N + 1, sizeof(Nod));
S = calloc(N + 1, sizeof(int));
nr_comp = 0;
comp = calloc(1, sizeof(int *));
comp[0] = calloc(N + 1, sizeof(Nod));
aux = calloc(N + 1, sizeof(Nod));
nr_elem = 0;
for (i = 0; i <= N; i++) {
graf[i].nr_copil = 0;
graf[i].culoare = WHITE;
transpus[i].nr_copil = 0;
transpus[i].culoare = WHITE;
}
for (i = 0; i < M; i++) {
fscanf(in, "%d", &x);
fscanf(in, "%d", &y);
graf[x].nr_copil ++;
graf[x].kid = realloc(graf[x].kid, graf[x].nr_copil * sizeof(int));
graf[x].kid[graf[x].nr_copil - 1] = y;
transpus[y].nr_copil ++;
transpus[y].kid = realloc(transpus[y].kid, transpus[y].nr_copil * sizeof(int));
transpus[y].kid[transpus[y].nr_copil - 1] = x;
}
// afisare(out, transpus);
ctc(graf, transpus);
print();
fclose(in);
fclose(out);
return 0;
}