#include<iostream>
#include<fstream>
using namespace std;
ifstream fin("ctc.in");
ofstream fout("ctc.out");
int time;
enum color{white,gray,black};
struct node{
int val;
node *next;
};
typedef struct node *nod;
class lista{
public:
nod p,q;
color culoare;
int tata,d,f;
lista()
{
p=q=NULL;
}
};
void ins_p(lista &x,int val)
{
nod r=new node;
r->val=val;
r->next=NULL;
x.p=r;
x.q=x.p;
}
void ins_cs(lista &x,int val)
{
nod r=new node;
r->val=val;
r->next=NULL;
x.q->next=r;
x.q=r;
}
void ins_cf(lista &x,int val)
{
nod r=new node;
r->val=val;
r->next=x.p;
x.p=r;
}
void afisare(const lista &x)
{
nod r;
r=x.p;
while(r!=NULL)
{
cout<<r->val<<" ";
r=r->next;
}
cout<<endl;
}
void dfs_visit(lista *x,lista &u,int k,lista &topo)
{
time=time+1;
u.d=time;
u.culoare=gray;
nod r;
r=u.p;
while(r!=NULL)
{
if(x[r->val].culoare==white)
{
x[r->val].tata=k;
dfs_visit(x,x[r->val],r->val,topo);
}
r=r->next;
}
if(topo.p==NULL)
ins_p(topo,k);
else
ins_cf(topo,k);
u.culoare=black;
time=time+1;
u.f=time;
}
void dfs_visit_conexa(lista *x,lista &u,int k)
{
time=time+1;
u.d=time;
u.culoare=gray;
nod r;
r=u.p;
while(r!=NULL)
{
if(x[r->val].culoare==white)
{
fout<<r->val<<" ";
x[r->val].tata=k;
dfs_visit_conexa(x,x[r->val],r->val);
}
r=r->next;
}
u.culoare=black;
time=time+1;
u.f=time;
}
void dfs_conexa(lista *x,int n,const lista &topo)
{
for(int i=1;i<=n;i++)
{
x[i].culoare=white;
x[i].tata=0;
}
time=0;
nod r;
r=topo.p;
while(r!=NULL)
{
if(x[r->val].culoare==white)
{
fout<<r->val<<" ";
dfs_visit_conexa(x,x[r->val],r->val);
fout<<endl;
}
r=r->next;
}
}
void dfs(lista *x,int n,lista &topo)
{
for(int i=1;i<=n;i++)
{
x[i].culoare=white;
x[i].tata=0;
}
time=0;
for(int i=1;i<=n;i++)
if(x[i].culoare==white)
dfs_visit(x,x[i],i,topo);
}
void transpusa(lista *x1,int n,lista *x2)
{
nod r;
for(int i=1;i<=n;i++)
{
r=x1[i].p;
while(r!=NULL)
{
if(x2[r->val].p==NULL)
ins_p(x2[r->val],i);
else
ins_cs(x2[r->val],i);
r=r->next;
}
}
}
void comp_conexa(lista *x,int n)
{
lista *lista1;
lista topo_sort;
lista1=new lista[n+1];
dfs(x,n,topo_sort);
transpusa(x,n,lista1);
/*for(int i=1;i<=n;i++)
{
cout<<i<<" = ";
afisare(lista1[i]);
}
cout<<endl;
cout<<endl;*/
dfs_conexa(lista1,n,topo_sort);
}
int main()
{
int n,m,x,y;
lista *lista1;
fin>>n>>m;
lista1=new lista[n+1];
while(/*fin>>x>>y*/ m--)
{
if(lista1[x].p==NULL)
{
ins_p(lista1[x],y);
/*if(lista1[y].p==NULL)
ins_p(lista1[y],x);
else
ins_cs(lista1[y],x);*/
}
else
if(lista1[x].p!=NULL)
{
ins_cs(lista1[x],y);
/*if(lista1[y].p==NULL)
ins_p(lista1[y],x);
else
ins_cs(lista1[y],x);*/
}
}
/*for(int i=1;i<=n;i++)
{
cout<<i<<" = ";
afisare(lista1[i]);
}*/
comp_conexa(lista1,n);
fout<<endl;
return 0;
}