#include <stdio.h>
#include <stdlib.h>
typedef enum {false, true} bool;
#define MaxVertexNum 10 /* maximum number of vertices */
typedef int Vertex; /* vertices are numbered from 0 to MaxVertexNum-1 */
typedef struct AdjVNode *PtrToAdjVNode;
struct AdjVNode{
Vertex AdjV;
PtrToAdjVNode Next;
};
typedef struct Vnode{
PtrToAdjVNode FirstEdge;
} AdjList[MaxVertexNum];
typedef struct GNode *PtrToGNode;
struct GNode{
int Nv;
int Ne;
AdjList G;
};
typedef PtrToGNode LGraph;
bool visit[MaxVertexNum];
int front,rear;
int indegree[MaxVertexNum];
int queue[MaxVertexNum];
void enqueue(int x)
{
rear=(rear+1)%MaxVertexNum;
queue[rear]=x;
}
int dequeue()
{
front=(front+1)%MaxVertexNum;
return queue[front];
}
bool dfs(LGraph Graph,int v)
{
static int count=0;
count++;
visit[v]=true;
PtrToAdjVNode p=Graph->G[v].FirstEdge;
while(p){
if(visit[p->AdjV])return false;
else if(!visit[p->AdjV]&&!dfs(Graph,p->AdjV))return false;
p=p->Next;
}
return true;
}
bool TopSort( LGraph Graph, Vertex TopOrder[] )
{
front=rear=0;
int i;
int cnt=0;
for(i=0;i<Graph->Nv;i++){
visit[i]=false;
}
if(!dfs(Graph,0))return false;;
for(i=0;i<Graph->Nv;i++){
indegree[i]=0;
}
for(i=0;i<Graph->Nv;i++){
PtrToAdjVNode p=Graph->G[i].FirstEdge;
while(p){
int j=p->AdjV;
indegree[j]++;
p=p->Next;
}
}
for(i=0;i<Graph->Nv;i++){
if(indegree[i]==0)enqueue(i);
}
while(front!=rear){
int v=dequeue();
TopOrder[cnt++]=v;
PtrToAdjVNode p=Graph->G[v].FirstEdge;
while(p){
int j=p->AdjV;
indegree[j]--;
if(indegree[j]==0){
enqueue(j);
}
p=p->Next;
}
}
return true;
}
PtrToAdjVNode Insert(PtrToAdjVNode p,int x)
{
PtrToAdjVNode q;
q=(PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
p->Next=q;
q->AdjV=x;
q->Next=NULL;
return q;
}
LGraph ReadG()
{
int i;
LGraph p=(LGraph)malloc(sizeof(struct GNode));
scanf("%d%d",&p->Nv,&p->Ne);
PtrToAdjVNode rear[MaxVertexNum];
for(i=0;i<p->Nv;i++){
p->G[i].FirstEdge=(PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
rear[i]=p->G[i].FirstEdge;
rear[i]->Next=NULL;
}
for(i=0;i<p->Ne;i++){
int x,y;
scanf("%d%d",&x,&y);
rear[x]=Insert(rear[x],y);
}
for(i=0;i<p->Nv;i++){
PtrToAdjVNode tmp=p->G[i].FirstEdge;
p->G[i].FirstEdge=p->G[i].FirstEdge->Next;
free(tmp);
}
return p;
}
int main()
{
//freopen("test.txt","r",stdin);
int i;
Vertex TopOrder[MaxVertexNum];
LGraph G = ReadG();
if ( TopSort(G, TopOrder)==true )
for ( i=0; i<G->Nv; i++ )
printf("%d ", TopOrder[i]);
else
printf("ERROR");
printf("\n");
return 0;
}