#include <vector>
#include <cstdio>
#include <string>
#include <algorithm>
#include <stack>
#include <string.h>
#define cat(c) while (c!='\n') fscanf(f,"%c",&c);
#define ct(c) while (c!='\n') scanf("%c",&c);
#define lim 100100
using namespace std;
FILE *f,*g;
vector <int> a[lim],b[lim],bt[lim];
vector <vector <int> > sol;
vector <int> con;
stack <int>S;
int ind[lim],mn[lim],in_q[lim];
int nr,n,m,i,j,cn;
int bf[lim];
int h[lim];
bool dr[255][255];
bool tk[lim]; // a fost conectat sau nu
void tare_conex(int x)
{
int i;
ind[x]=mn[x]=++nr;
in_q[x]=1; S.push(x);
for (i=0;i<a[x].size();i++)
{
if (ind[a[x][i]]==0)
{
tare_conex(a[x][i]);
mn[x]=min(mn[x],mn[a[x][i]]);
}
else
if (in_q[x])
mn[x]=min(mn[x],mn[a[x][i]]);
}
if (ind[x]==mn[x])
{
int nod;
con.clear();
cn++;
do {
nod=S.top(); S.pop();
in_q[nod]=0; con.push_back(nod);
bf[nod]=cn;
}
while (nod!=x);
sol.push_back(con);
}
}
void fa_muchii()
{
int i,j;
for (i=1;i<=n;i++)
for (j=0;j<a[i].size();j++)
if (bf[i]!=bf[a[i][j]])
if (dr[bf[i]][bf[a[i][j]]]==0)
{
dr[bf[i]][bf[a[i][j]]]=1;
b[bf[i]].push_back(bf[a[i][j]]);
bt[bf[a[i][j]]].push_back(bf[i]);
}
}
void read()
{
int i,x,y;
f=fopen("ctc.in","r");
g=fopen("ctc.out","w");
fscanf(f,"%d%d",&n,&m);
for (i=1;i<=m;i++)
{
fscanf(f,"%d%d",&x,&y);
a[x].push_back(y);
}
}
int X[260],Y[260];
int nx,ny,ax,rx,ry;
void df(int x,int r)
{
int i,y;
h[x]=r;
if (b[x].size()==0 && tk[x]==0)
ax=x;
for (i=0;i<b[x].size();i++)
if (h[b[x][i]]!=r)
df(b[x][i],r);
}
int main()
{
read();
sol.push_back(con);
nr=0;
for (i=1;i<=n;i++)
if (!ind[i])
{
tare_conex(i);
}
fprintf(g,"%d\n",cn);
for (i=1;i<=cn;i++,fprintf(g,"\n"))
for (j=0;j<sol[i].size();j++)
fprintf(g,"%d ",sol[i][j]);
/*if (cn==1)
{
fprintf(g,"0");
return 0;
}
fa_muchii();
for (i=1;i<=cn;i++)
if (bt[i].size()==0)
{
ax=-1;
df(i,i);
if (ax!=-1)
{
X[++nx]=i;
tk[i]=1;
Y[++ny]=ax;
tk[ax]=1;
}
}
rx=nx;
ry=ny;
for (i=1;i<=cn;i++)
{
if (b[i].size()==0 && tk[i]==0)
Y[++ny]=i;
if (bt[i].size()==0 && tk[i]==0)
X[++nx]=i;
}
fprintf(g,"%d\n",max(nx,ny));
for (i=1;i<rx;i++)
{
fprintf(g,"%d %d\n",sol[Y[i]][0],sol[X[i+1]][0]);
}
fprintf(g,"%d %d\n",sol[Y[rx]][0],sol[X[1]][0]);
for (i=rx+1;i<=min(nx,ny);i++)
fprintf(g,"%d %d\n",sol[Y[i]][0],sol[X[i]][0]);
if (nx>ny)
for (;i<=nx;i++)
fprintf(g,"%d %d\n",sol[X[1]][0],sol[X[i]][0]);
else
for (;i<=ny;i++)
fprintf(g,"%d %d\n",sol[Y[i]][0],sol[X[1]][0]);
*/
return 0;
}