#include <stdio.h>          // printf(), scanf()
#include <stdlib.h>         // exit()
#include <stdbool.h>

#define MAX_V 10000
#define QUE_SIZE 100

int G[MAX_V][MAX_V];
int nG[MAX_V];
bool visited[MAX_V];
int indeg[MAX_V];
int V;
int n_out;

int queue[QUE_SIZE];
int que_in;
int que_out;

void
cleanup(int ecode)
{
	exit(ecode);
}

int
que_size()
{
	if (que_in >= que_out)
		return que_in - que_out;

	return que_in + QUE_SIZE - que_out;
}

int
que_empty()
{
	return que_in == que_out;
}

void
que_push(int x)
{
	queue[que_in] = x;
	que_in = (que_in + 1) % QUE_SIZE;
	if (que_in == que_out)
	{
		fprintf(stderr, "Queue overflow. size:%d\n", QUE_SIZE);
		cleanup(1);
	}
}

void
que_pop()
{
	if (que_out == que_in)
	{
		fprintf(stderr, "Queue underflow\n");
		cleanup(1);
	}

	que_out = (que_out + 1) % QUE_SIZE;
}

int
que_front()
{
	return queue[que_out];
}

void
bfs(int s)
{
	int i;

	que_push(s);
	visited[s] = true;
	while (!que_empty())
	{
		int u = que_front(); que_pop();
		printf("%d\n", u);
		for (i = 0; i < nG[u]; ++i)
		{
			int v = G[u][i];
			indeg[v]--;

			if (indeg[v] == 0 && !visited[v])
			{
				visited[v] = true;
				que_push(v);
			}
		}
	}
}

void
tsort()
{
	int u;
	int i;

	for (i = 0; i < V; ++i)
		indeg[i] = 0;

	for (u = 0; u < V; ++u)
	{
		for (i = 0; i < nG[u]; ++i)
		{
			int v = G[u][i];
			indeg[v]++;
		}
	}

	for (u = 0; u < V; ++u)
	{
		if (indeg[u] == 0 && !visited[u])
			bfs(u);
	}
}

int
main(int argc, char** argv)
{
	int E;
	int s, t;
	int i;

	que_in = 0;
	que_out = 0;

	scanf("%d %d", &V, &E);
	for (i = 0; i < V; ++i)
	{
		nG[i] = 0;
		visited[i] = false;

	}

	for (i = 0; i < E; ++i)
	{
		scanf("%d %d", &s, &t);
		G[s][nG[s]++] = t;
	}

	tsort();
	return 0;
}