#include<stdio.h>
#define M 200001
#define N 100001
struct nod{ int inf;nod *urm;};
nod *p[N];
int n,m,i,a[M],b[M],viz[N],niv[N],ret[N],dad[N],nsol,dc,ee,x[N],y[N];
void readd(),solve(),add_edge(),df(int nc),sortare(),numarare(),afisare(),
hd(int ic,int nr),sw(int i1,int i2);
int main()
{
readd();
solve();
return 0;
}
void readd()
{
freopen("biconex.in","rt",stdin);
freopen("biconex.out","wt",stdout);
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++){scanf("%d%d",&a[i],&b[i]);add_edge();}
}
void add_edge()
{
nod *paux;
paux=new nod;
paux->inf=i;
paux->urm=p[b[i]];
p[b[i]]=paux;
paux=new nod;
paux->inf=i;
paux->urm=p[a[i]];
p[a[i]]=paux;
}
void solve()
{
df(1);
sortare();
numarare();
afisare();
}
void df(int nc)
{ int e,v;
nod *paux;
ret[nc]=nc;niv[nc]=niv[dad[nc]]+1;
for(paux=p[nc];paux;paux=paux->urm)
{ e=paux->inf;
v=a[e]+b[e]-nc;
if(v==dad[nc])continue;
if(ret[v])
{ if(niv[v]<niv[ret[nc]])ret[nc]=v;continue;}
dad[v]=nc;
df(v);
if(niv[ret[v]]<niv[ret[nc]])ret[nc]=ret[v];
}
}
void sortare()
{
for(i=1;i<=n;i++)x[i]=i;
for(i=n/2;i>=1;i--)hd(i,n);
for(i=n;i>=1;i--){sw(1,i);hd(1,i-1);}
}
void hd(int ii,int nn)
{
int jj=ii<<1;
if(jj>nn)return;
if(jj<nn)if(niv[x[jj]]<niv[x[jj+1]])jj++;
if(niv[x[ii]]<niv[x[jj]]){sw(ii,jj);hd(jj,nn);}
}
void sw(int i1,int i2)
{ int aux=x[i1];x[i1]=x[i2];x[i2]=aux;}
void numarare()
{ int jj;
for(i=1;i<=n;i++)y[x[i]]=i;
for(i=n;i>1;i--)
{
if(viz[x[i]])continue;
nsol++;
if(ret[x[i]]==x[i])continue;
jj=x[i];
while(jj-ret[jj])
{ viz[jj]=1;jj=dad[jj];}
}
}
void afisare()
{ int jj;
printf("%d\n",nsol);
for(i=1;i<=n;i++)viz[i]=0;
for(i=n;i>1;i--)
{ if(viz[x[i]])continue;
jj=x[i];
if(ret[jj]==jj){printf("%d %d\n",jj,dad[jj]);continue;}
while(jj-ret[jj]){printf("%d ",jj);viz[jj]=1;jj=dad[jj];}
printf("%d\n",jj);
}
}