#include<stdio.h>
#include<stdlib.h>
#define N 100001
#define M 200001
FILE *f1=fopen("ctc.in","r");
FILE *f2=fopen("ctc.out","w");
typedef struct nod
{long info;
struct nod *leg;}Nod,*list;
typedef struct stack
{long st[N],sp;};
stack s;
list q=NULL;
long n,m,deg[N]={0},*g[N],k,i,j,t,ind=0,c[N]={0},l[N],nr,a[M],b[M],u,p,r;
void add(list &q,long x)
{Nod *p=new Nod;
p->info=x;
p->leg=q;
q=p;}
int contine(list &q,long x)
{Nod *p;
for(p=q;p!=NULL;p=p->leg)
if(p->info==x)
return 1;
return 0;}
long del(list &q)
{Nod *p=q->leg;
long x=q->info;
free(q);
q=p;
return x;}
void push(stack &s,long x)
{s.st[++s.sp]=x;}
long pop(stack &s)
{return s.st[s.sp--];}
int apartine(stack &s,long x)
{long i;
for(i=1;i<=s.sp;i++)
if(s.st[i]==x)
return 1;
return 0;}
void tarjan(long i,long *nr,long *ind)
{long j,r;
push(s,i);
c[i]=(*ind);
l[i]=(*ind)++;
for(j=0;j<deg[i];j++)
if(c[g[i][j]]==0)
{tarjan(g[i][j],nr,ind);
if(l[i]>l[g[i][j]])
l[i]=l[g[i][j]];}
else
if(apartine(s,g[i][j])==1&&l[i]>c[g[i][j]])
l[i]=c[g[i][j]];
if(c[i]==l[i])
{(*nr)++;
while(s.sp!=0)
{r=pop(s);
if(contine(q,r)==0&&r!=i)
{add(q,r);
fprintf(f2,"%ld ",r);}
else
break;}
if(contine(q,i)==0)
{add(q,i);
fprintf(f2,"%ld ",i);}
r=del(q);
if(r==0)
(*nr)--;
else
{add(q,r);
fprintf(f2,"\n");}
add(q,0);}}
int main()
{fscanf(f1,"%ld%ld\n",&n,&m);
for(k=1;k<=m;k++)
{fscanf(f1,"%ld%ld\n",&a[k],&b[k]);
deg[a[k]]++;}
for(i=1;i<=n;deg[i++]=0)
g[i]=(long*)malloc(deg[i]*sizeof(long));
for(j=1;j<=m;j++)
g[a[j]][deg[a[j]]++]=b[j];
ind=0;
nr=0;
s.sp=0;
add(q,0);
fprintf(f2,"\n");
for(u=1;u<=n;u++)
if(c[u]==0)
tarjan(u,&nr,&ind);
fseek(f2,0,SEEK_SET);
fprintf(f2,"%ld",nr);
fclose(f1);
fclose(f2);
return 0;}