<image>


A directed acyclic graph (DAG) can be used to represent the ordering of tasks. Tasks are represented by vertices and constraints where one task can begin before another, are represented by edges. For example, in the above example, you can undertake task B after both task A and task B are finished. You can obtain the proper sequence of all the tasks by a topological sort.

Given a DAG $G$, print the order of vertices after the topological sort.

Constraints

* $1 \leq |V| \leq 10,000$
* $0 \leq |E| \leq 100,000$
* There are no parallel edges in $G$
* There are no self loops in $G$

Input

A directed graph $G$ is given in the following format:
$|V|\;|E|$
$s_0 \; t_0$
$s_1 \; t_1$
:
$s_{|E|-1} \; t_{|E|-1}$



$|V|$ is the number of vertices and $|E|$ is the number of edges in the graph. The graph vertices are named with the numbers $0, 1,..., |V|-1$ respectively.

$s_i$ and $t_i$ represent source and target nodes of $i$-th edge (directed).

Output

Print the vertices numbers in order. Print a number in a line.

If there are multiple possible solutions, print any one of them (the solution is judged by a special validator).

Example

Input

6 6
0 1
1 2
3 1
3 4
4 5
5 2


Output

0
3
1
4
5
2

Source: aizu | Difficulty: UNKNOWN_DIFFICULTY


Solutions:
from collections import deque
from typing import List, Optional

def topological_sort(graph: List[List[int]], in_degrees: List[int], first_index: int=0) -> Optional[List[int]]:
	V = len(graph) + first_index
	order = [i for i in range(first_index, V) if not in_degrees[i]]
	queue = deque(order)
	while queue:
		u = queue.popleft()
		for v in graph[u]:
			in_degrees[v] -= 1
			if not in_degrees[v]:
				(queue.append(v), order.append(v))
	return order if len(order) + first_index == V else None

def grl_4_b():
	(V, _, *ST) = map(int, open(0).read().split())
	graph = [[] for _ in range(V)]
	in_degrees = [0] * V
	for (s, t) in zip(*[iter(ST)] * 2):
		graph[s].append(t)
		in_degrees[t] += 1
	res = topological_sort(graph, in_degrees)
	print('\n'.join(map(str, res)))
grl_4_b()


from collections import deque
(n, m) = [int(s) for s in input().split()]
E = [set() for _ in range(n)]
for _ in range(m):
	(s, t) = [int(s) for s in input().split(' ')]
	E[s].add(t)
color = [0] * n
indeg = [0] * n
for s in range(n):
	for t in E[s]:
		indeg[t] += 1
Q = deque()
out = []

def bfs(s):
	Q.append(s)
	color[s] = 1
	while Q:
		u = Q.popleft()
		out.append(u)
		for v in E[u]:
			indeg[v] -= 1
			if indeg[v] == 0 and color[v] == 0:
				color[v] = 1
				Q.append(v)
for u in range(n):
	if indeg[u] == 0 and color[u] == 0:
		bfs(u)
print('\n'.join(map(str, out)))


from collections import deque
(V, E) = map(int, input().split())
G = [[] for _ in range(V)]
reached = [False] * V
indeg = [0] * V
for _ in range(E):
	(s, t) = map(int, input().split())
	G[s].append(t)
	indeg[t] += 1
out = []

def bfs(s):
	Q = deque()
	Q.append(s)
	reached[s] = True
	while Q:
		u = Q.popleft()
		out.append(u)
		for v in G[u]:
			indeg[v] -= 1
			if indeg[v] == 0 and reached[v] == False:
				reached[v] = True
				Q.append(v)

def topologicalSort():
	for u in range(V):
		if indeg[u] == 0 and reached[u] == False:
			bfs(u)
topologicalSort()
for i in out:
	print(i)


(N, M) = map(int, input().split())
G = [[] for i in range(N)]
for i in range(M):
	(s, t) = map(int, input().split())
	G[s].append(t)
ans = []
V = set()

def dfs(n):
	for e in G[n]:
		if e not in V:
			dfs(e)
	ans.append(n)
	V.add(n)
for i in range(N):
	if i not in V:
		if i not in V:
			dfs(i)
			print()
print(*ans[::-1], sep='\n')


from sys import stdin
from collections import deque
(UNVISITED, VISITED_IN_QUEUE, POPPED_OUT) = (0, 1, 2)

def generate_adj_matrix(_v_info, _input_adj_table, _in_deg_list):
	for v_detail in _v_info:
		(v_from, v_to) = map(int, v_detail)
		_input_adj_table[v_from].append(v_to)
		_in_deg_list[v_to] += 1
	return (_input_adj_table, _in_deg_list)

def topological_sort():
	for v in range(vertices):
		if not in_deg_list[v] and status[v] is UNVISITED:
			bfs(v)
	return ans

def bfs(v):
	v_queue.append(v)
	status[v] = VISITED_IN_QUEUE
	while v_queue:
		current = v_queue.popleft()
		ans.append(current)
		for v_adj in adj_table[current]:
			in_deg_list[v_adj] -= 1
			if not in_deg_list[v_adj] and status[v_adj] is UNVISITED:
				status[v_adj] = VISITED_IN_QUEUE
				v_queue.appendleft(v_adj)
		status[current] = POPPED_OUT
	return None
_input = stdin.readlines()
(vertices, edges) = map(int, _input[0].split())
v_info = map(lambda x: x.split(), _input[1:])
status = [UNVISITED] * vertices
v_queue = deque()
init_adj_table = tuple(([] for _ in range(vertices)))
init_in_deg_list = [0] * vertices
ans = []
(adj_table, in_deg_list) = generate_adj_matrix(v_info, init_adj_table, init_in_deg_list)
print(*topological_sort())


from sys import stdin
from collections import deque
(UNVISITED, VISITED_IN_QUEUE, POPPED_OUT) = (0, 1, 2)

def generate_adj_matrix(_v_info):
	for v_detail in _v_info:
		(v_from, v_to) = map(int, v_detail)
		init_adj_table[v_from].append(v_to)
		init_in_deg_list[v_to] += 1
	return (init_adj_table, init_in_deg_list)

def topological_sort():
	for v in range(vertices):
		if not in_deg_list[v] and status[v] is UNVISITED:
			bfs(v)
	return ans

def bfs(v):
	queue = deque()
	queue.append(v)
	status[v] = VISITED_IN_QUEUE
	while queue:
		current = queue.popleft()
		ans.append(current)
		for v_adj in adj_table[current]:
			in_deg_list[v_adj] -= 1
			if not in_deg_list[v_adj] and status[v_adj] is UNVISITED:
				status[v_adj] = VISITED_IN_QUEUE
				queue.appendleft(v_adj)
		status[current] = POPPED_OUT
	return None
_input = stdin.readlines()
(vertices, edges) = map(int, _input[0].split())
v_info = map(lambda x: x.split(), _input[1:])
status = [UNVISITED] * vertices
init_adj_table = tuple(([] for _ in range(vertices)))
init_in_deg_list = [0] * vertices
ans = []
(adj_table, in_deg_list) = generate_adj_matrix(v_info)
print(*topological_sort(), sep='\n')


from collections import defaultdict, deque
(V, E) = map(int, input().split())
G = defaultdict(list)
for i in range(E):
	(s, t) = map(int, input().split())
	G[s].append(t)
ans = deque([])
visited = defaultdict(bool)

def visit(v):
	if visited[v]:
		return
	visited[v] = True
	for k in G[v]:
		visit(k)
	ans.appendleft(v)
for v in range(V):
	visit(v)
print('\n'.join(map(str, ans)))


import sys
input = sys.stdin.readline
from operator import itemgetter
INF = 10 ** 30
sys.setrecursionlimit(10000000)
from collections import deque
G = []
into = []

def topological_sort(n):
	global into
	ans = []
	unvisited = [True] * n
	for i in range(n):
		if into[i] == 0 and unvisited[i]:
			q = deque()
			q.append(i)
			while len(q) > 0:
				node = q.popleft()
				ans.append(node)
				unvisited[node] = False
				for v in G[node]:
					into[v] -= 1
					if into[v] == 0:
						q.append(v)
	return ans
visited = []
answer = deque()

def rec(v):
	global visited
	visited[v] = True
	for node in G[v]:
		if not visited[node]:
			rec(node)
	answer.appendleft(v)

def dfs_topolo(n):
	for i in range(n):
		if not visited[i]:
			rec(i)

def main():
	global G, into, visited
	(v, e) = list(map(int, input().strip().split()))
	G = [[] for _ in range(v)]
	visited = [False] * v
	into = [0] * v
	for i in range(e):
		(s, t) = list(map(int, input().strip().split()))
		G[s].append(t)
		into[t] += 1
	dfs_topolo(v)
	for p in answer:
		print(p)
main()


from sys import stdin
from collections import deque

def read_graph(n, k):
	A = [[] for _ in range(n)]
	for _ in range(k):
		line = stdin.readline().strip().split()
		A[int(line[0])].append(int(line[1]))
	return A

def topological_sort(n, A):
	color = ['WHITE'] * n
	Q = deque([])
	out = []
	indeg = [0] * n
	for i in range(n):
		for j in A[i]:
			indeg[j] = indeg[j] + 1

	def bfs(s):
		nonlocal color
		nonlocal indeg
		nonlocal Q
		color[s] = 'GRAY'
		Q.append(s)
		while Q:
			u = Q.popleft()
			out.append(u)
			for v in A[u]:
				indeg[v] = indeg[v] - 1
				if indeg[v] == 0 and color[v] == 'WHITE':
					color[v] = 'GRAY'
					Q.append(v)
	for i in range(n):
		if indeg[i] == 0 and color[i] == 'WHITE':
			bfs(i)
	return out
(n, k) = [int(i) for i in input().split()]
A = read_graph(n, k)
B = topological_sort(n, A)
for i in B:
	print(i)


from heapq import heappush, heappop, heapify
from collections import deque, defaultdict, Counter
import itertools
from itertools import permutations, combinations, accumulate, product, combinations_with_replacement
import sys
import bisect
import string
import math
import time

def I():
	return int(input())

def S():
	return input()

def MI():
	return map(int, input().split())

def MS():
	return map(str, input().split())

def LI():
	return [int(i) for i in input().split()]

def LI_():
	return [int(i) - 1 for i in input().split()]

def StoI():
	return [ord(i) - 97 for i in input()]

def ItoS(nn):
	return chr(nn + 97)

def input():
	return sys.stdin.readline().rstrip()

def list2d(a, b, c):
	return [[c] * b for i in range(a)]

def list3d(a, b, c, d):
	return [[[d] * c for j in range(b)] for i in range(a)]

def list4d(a, b, c, d, e):
	return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)]
yn = {False: 'No', True: 'Yes'}
YN = {False: 'NO', True: 'YES'}
MOD = 10 ** 9 + 7
inf = float('inf')
IINF = 10 ** 19
l_alp = string.ascii_lowercase
u_alp = string.ascii_uppercase
ts = time.time()
sys.setrecursionlimit(10 ** 6)
nums = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']
show_flg = False

def main():
	(V, E) = MI()
	edges = []
	for i in range(E):
		edges.append(tuple(MI()))
	in_cnt = defaultdict(int)
	outs = defaultdict(list)
	for (a, b) in edges:
		in_cnt[b] += 1
		outs[a].append(b)
	res = []
	queue = deque([i for i in range(V) if in_cnt[i] == 0])
	while len(queue) != 0:
		v = queue.popleft()
		res.append(v)
		for nxt_v in outs[v]:
			in_cnt[nxt_v] -= 1
			if in_cnt[nxt_v] == 0:
				queue.append(nxt_v)
	for i in range(V):
		print(res[i])
main()


from collections import deque
(V, E) = list(map(int, input().split()))
edge = [[] for i in range(V)]
in_num = [0] * V
for i in range(E):
	(s, t) = list(map(int, input().split()))
	edge[s].append(t)
	in_num[t] += 1
q = deque()
for i in range(V):
	if in_num[i] == 0:
		q.append(i)
ans = deque()
while q:
	v = q.popleft()
	ans.append(v)
	for u in edge[v]:
		in_num[u] -= 1
		if in_num[u] == 0:
			q.append(u)
for a in ans:
	print(a)


import os
import sys

def main():
	sys.setrecursionlimit(100000)
	(V, E) = read_ints()
	G = [set() for _ in range(V)]
	for _ in range(E):
		(s, t) = read_ints()
		G[s].add(t)
	print(*solve(V, E, G), sep='\n')

def solve(V, E, G):
	topo = []
	done = [False] * V

	def dfs(i):
		if done[i]:
			return
		for j in G[i]:
			dfs(j)
		done[i] = True
		topo.append(i)
	for i in range(V):
		if not done[i]:
			dfs(i)
	topo.reverse()
	return topo
DEBUG = 'DEBUG' in os.environ

def inp():
	return sys.stdin.readline().rstrip()

def read_int():
	return int(inp())

def read_ints():
	return [int(e) for e in inp().split()]

def dprint(*value, sep=' ', end='\n'):
	if DEBUG:
		print(*value, sep=sep, end=end)
main()


from collections import defaultdict
from collections import deque
from heapq import heappush, heappop
import sys
import math
import bisect
import random

def LI():
	return list(map(int, sys.stdin.readline().split()))

def I():
	return int(sys.stdin.readline())

def LS():
	return list(map(list, sys.stdin.readline().split()))

def S():
	return list(sys.stdin.readline())[:-1]

def IR(n):
	l = [None for i in range(n)]
	for i in range(n):
		l[i] = I()
	return l

def LIR(n):
	l = [None for i in range(n)]
	for i in range(n):
		l[i] = LI()
	return l

def SR(n):
	l = [None for i in range(n)]
	for i in range(n):
		l[i] = S()
	return l

def LSR(n):
	l = [None for i in range(n)]
	for i in range(n):
		l[i] = SR()
	return l
mod = 1000000007

def visit(s):
	if f[s]:
		f[s] = 0
		for t in v[s]:
			visit(t)
		l.append(s)
(n, e) = LI()
v = [[] for i in range(n)]
for i in range(e):
	(s, t) = LI()
	v[s].append(t)
l = []
f = [1 for i in range(n)]
for i in range(n):
	visit(i)
l = l[::-1]
for i in l:
	print(i)


from collections import deque
(v, e) = map(int, input().split())
edges = [[] for _ in range(v)]
in_num = [0 for _ in range(v)]
for _ in range(e):
	(s, t) = map(int, input().split())
	edges[s].append(t)
	in_num[t] += 1
q = deque()
for i in range(len(in_num)):
	if in_num[i] == 0:
		q.append(i)
ans = []
while q:
	node = q.popleft()
	ans.append(node)
	for v in edges[node]:
		in_num[v] -= 1
		if in_num[v] == 0:
			q.append(v)
for i in ans:
	print(i)


import queue
(V, E) = map(int, input().split())
G = [[] for _ in range(V)]
visited = [False] * V
indeg = [0] * V
out = []
for _ in range(E):
	(s, t) = map(int, input().split())
	G[s].append(t)
for i in range(V):
	for j in range(len(G[i])):
		indeg[G[i][j]] += 1
q = queue.Queue()
for i in range(V):
	if indeg[i] == 0 and (not visited[i]):
		q.put(i)
		visited[i] = True
		while not q.empty():
			u = q.get()
			out.append(u)
			for j in range(len(G[u])):
				v = G[u][j]
				indeg[v] -= 1
				if indeg[v] == 0 and (not visited[v]):
					visited[v] = True
					q.put(v)
for el in out:
	print(el)


from collections import deque

def topological_sort(indeg, tonodes, v):
	nodes = deque([])
	visited = deque([])
	for i in range(v):
		if indeg[i] == 0:
			nodes.append(i)
	while len(nodes) > 0:
		i = nodes.popleft()
		visited.append(i)
		for j in tonodes[i]:
			indeg[j] -= 1
			if indeg[j] == 0:
				nodes.append(j)
	return visited

def main():
	ve = input().split()
	(v, e) = tuple(map(int, ve))
	indeg = [0 for _ in range(v)]
	tonodes = [[] for _ in range(v)]
	for _ in range(e):
		st = input().split()
		(s, t) = tuple(map(int, st))
		indeg[t] += 1
		tonodes[s].append(t)
	visited = topological_sort(indeg, tonodes, v)
	while len(visited) > 0:
		print(visited.popleft())
main()


from collections import defaultdict

def topological_sort(N, edges):

	def dfs(u):
		used[u] = True
		for v in edges[u]:
			if not used[v]:
				dfs(v)
		result.append(u)
	used = [False] * N
	result = []
	for i in range(N):
		if not used[i]:
			dfs(i)
	return result[::-1]

def main():
	(N, M) = map(int, input().split())
	edges = defaultdict(list)
	for _ in range(M):
		(s, t) = map(int, input().split())
		edges[s].append(t)
	ans = topological_sort(N, edges)
	print(*ans)
main()


from collections import deque

def topological(N, LIST):
	incnt = [0] * N
	CHILD = [set() for _ in range(N)]
	for (a, b) in LIST:
		CHILD[a].add(b)
		incnt[b] += 1
	TPLGSORT = []
	que = deque([i for (i, num) in enumerate(incnt) if num == 0])
	while len(que) > 0:
		q = que.popleft()
		for i in CHILD[q]:
			incnt[i] -= 1
			if incnt[i] == 0:
				que.append(i)
		TPLGSORT.append(q)
	return TPLGSORT
(n, m) = map(int, input().split())
ab = [list(map(int, input().split())) for _ in range(m)]
tplg = topological(n, ab)
print(*tplg, sep='\n')


from collections import deque

def topologicalSort(v, e):
	global color, out, indeg
	color = ['white' for _ in range(v)]
	indeg = [[0, []] for _ in range(v)]
	out = []
	for i in range(e):
		(s, t) = map(int, input().split())
		indeg[s][0] += 1
		indeg[t][1] += [s]
	for i in range(v):
		if indeg[i][0] == 0 and color[i] == 'white':
			BFS(i)
	return out[::-1]

def BFS(s):
	Q = deque([])
	Q.append(s)
	color[s] = 'gray'
	while len(Q) != 0:
		u = Q.popleft()
		out.append(u)
		for i in indeg[u][1]:
			indeg[i][0] -= 1
			if indeg[i][0] == 0 and color[i] == 'white':
				color[i] = 'gray'
				Q.append(i)
(v, e) = map(int, input().split())
for i in topologicalSort(v, e):
	print(i)


from sys import stdin
from collections import deque
(V, E) = map(int, stdin.readline().split())
adj_list = deque([[] for _ in [0] * V])
is_visited = [False] * V
for _ in [0] * E:
	(s, t) = map(int, stdin.readline().split())
	adj_list[s].append(t)
out = deque()

def dfs(u):
	is_visited[u] = True
	for v in adj_list[u]:
		if not is_visited[v]:
			dfs(v)
	out.appendleft(u)
for s in range(V):
	if not is_visited[s]:
		dfs(s)
print(*out, sep='\n')


Vnum = 0
Enum = 0
Edge = {}
L = []
V = []

def visit(n):
	if V[n] == 1:
		sys.exit()
	elif V[n] == 0:
		V[n] = 1
		if n in Edge.keys():
			for m in Edge[n]:
				visit(m)
		V[n] = 2
		L.append(n)
		return True
(Vnum, Enum) = map(int, input().split())
V = [0 for v in range(Vnum)]
for _ in range(Enum):
	(s, t) = map(int, input().split())
	if s in Edge.keys():
		Edge[s].append(t)
	else:
		Edge[s] = [t]
for n in range(Vnum):
	if V[n] == 0:
		visit(n)
L.reverse()
for a in L:
	print(a)


from collections import deque
from collections import defaultdict
(V, E) = map(int, input().split())
d = [0] * V
G = defaultdict(list)
for i in range(E):
	(s, t) = map(int, input().split())
	d[t] += 1
	G[s].append(t)
q = deque([])
for i in range(V):
	if d[i] == 0:
		q.append(i)
ans = []
while q:
	s = q.popleft()
	ans.append(s)
	for t in G[s]:
		d[t] -= 1
		if d[t] == 0:
			q.append(t)
for x in ans:
	print(x)


from sys import stdin
input = stdin.readline
from collections import deque, defaultdict

def bfs(s):
	Q.append(s)
	color[s] = 1
	while Q:
		u = Q.popleft()
		out.append(u)
		for edge in range(e):
			(s, t) = list(map(int, lines[edge + 1].split()))
			if s == u:
				indeg[t] -= 1
				if indeg[t] == 0 and color == 0:
					color[t] = 1
					Q.append(t)
lines = stdin.readlines()
(v, e) = list(map(int, lines[0].split()))
out = []
outs = defaultdict(list)
color = [0] * v
indeg = [0] * v
for i in range(e):
	(s, t) = list(map(int, lines[i + 1].split()))
	outs[s].append(t)
	indeg[t] += 1
Q = deque((v1 for v1 in range(v) if indeg[v1] == 0))
while Q:
	v1 = Q.popleft()
	out.append(v1)
	for v2 in outs[v1]:
		indeg[v2] -= 1
		if indeg[v2] == 0:
			Q.append(v2)
for i in out:
	print(i)


from collections import defaultdict

def dfs(u, used, edges, result):
	used[u] = True
	for v in edges[u]:
		if not used[v]:
			dfs(v, used, edges, result)
	result.append(u)

def main():
	(N, M) = map(int, input().split())
	used = [False] * N
	edges = defaultdict(list)
	for _ in range(M):
		(s, t) = map(int, input().split())
		edges[s].append(t)
	result = []
	for i in range(N):
		if not used[i]:
			dfs(i, used, edges, result)
	print(*result[::-1])
main()


from collections import deque
(N, M) = map(int, input().split())
G = [[] for _ in range(N)]
deg = [0] * N
for i in range(M):
	(a, b) = map(int, input().split())
	G[b].append(a)
	deg[a] += 1
que = deque()
for i in range(N):
	if deg[i] == 0:
		que.append(i)
order = []
while len(que) != 0:
	v = que.popleft()
	order.append(v)
	for nv in G[v]:
		deg[nv] -= 1
		if deg[nv] == 0:
			que.append(nv)
order.reverse()
for i in order:
	print(i)


import sys
sys.setrecursionlimit(2147483647)
INF = float('inf')
MOD = 10 ** 9 + 7
input = lambda : sys.stdin.readline().rstrip()
res = []

def recursion(v, E, state) -> bool:
	if state[v]:
		return state[v] == 1
	state[v] = -1
	flag = all((recursion(nv, E, state) for nv in E[v]))
	if flag:
		state[v] = 1
		res.append(v)
	return flag

def resolve():
	(n, m) = map(int, input().split())
	E = [[] for _ in range(n)]
	for _ in range(m):
		(u, v) = map(int, input().split())
		E[u].append(v)
	state = [0] * n
	for v in range(n):
		recursion(v, E, state)
	print(*res[::-1], sep='\n')
resolve()


(V, E) = list(map(int, input().split()))
visit = []
no_visit = list(range(V))
enter = [0] * V
ad_list = [[] for _ in range(V)]
for e in range(E):
	(start, end) = list(map(int, input().split()))
	ad_list[start].append(end)
	enter[end] += 1
(enter, ad_list)
while True:
	if len(visit) == V:
		break
	for (n_v_idx, n_v) in enumerate(no_visit):
		e = enter[n_v]
		if e == 0:
			v = no_visit.pop(n_v_idx)
			visit.append(v)
			for a in ad_list[n_v]:
				enter[a] = enter[a] - 1
for v in visit:
	print(v)


import heapq

def topologicalsort(N, E):
	V = [0] * N
	for i in range(N):
		for y in E[i]:
			V[y] += 1
	S = [i for i in range(N) if V[i] == 0]
	SORTED = []
	while S:
		s = S.pop(0)
		SORTED.append(s)
		for t in E[s]:
			V[t] -= 1
			if V[t] == 0:
				S.append(t)
	return SORTED
(N, M) = map(int, input().split())
E = [[] for _ in range(N)]
for _ in range(M):
	(x, y) = map(int, input().split())
	E[x].append(y)
ANS = topologicalsort(N, E)
for i in range(N):
	print(ANS[i])


def main():
	(nvertices, nedges) = map(int, input().split())
	Adj = [[] * nvertices for i in range(nvertices)]
	for i in range(nedges):
		(u, v) = map(int, input().split())
		Adj[u].append(v)
	visited = [False] * nvertices
	ordering = []
	for u in range(nvertices):
		if not visited[u]:
			dfs(Adj, u, visited, ordering)
	for u in reversed(ordering):
		print(u)

def dfs(Adj, u, visited, ordering):
	visited[u] = True
	for v in Adj[u]:
		if not visited[v]:
			dfs(Adj, v, visited, ordering)
	ordering.append(u)
main()


import sys
sys.setrecursionlimit(200000)

def dfs(i):
	global visited, edges, counter, finish_order
	visited[i] = True
	for edge in edges[i]:
		if visited[edge]:
			continue
		dfs(edge)
	finish_order[i] = (counter, i)
	counter += 1
(n, m) = map(int, input().split())
edges = [set() for _ in range(n)]
for _ in range(m):
	(s, t) = map(int, input().split())
	edges[s].add(t)
visited = [False] * n
finish_order = [None] * n
counter = 0
for i in range(n):
	if not visited[i]:
		dfs(i)
for (d, i) in sorted(finish_order, reverse=True):
	print(i)


import sys
sys.setrecursionlimit(10 ** 6)
input = sys.stdin.readline
from math import floor, ceil, sqrt, factorial, log
from heapq import heappop, heappush, heappushpop
from collections import Counter, defaultdict, deque
from itertools import accumulate, permutations, combinations, product, combinations_with_replacement
from bisect import bisect_left, bisect_right
from copy import deepcopy
inf = float('inf')
mod = 10 ** 9 + 7

def pprint(*A):
	for a in A:
		print(*a, sep='\n')

def INT_(n):
	return int(n) - 1

def MI():
	return map(int, input().split())

def MF():
	return map(float, input().split())

def MI_():
	return map(INT_, input().split())

def LI():
	return list(MI())

def LI_():
	return [int(x) - 1 for x in input().split()]

def LF():
	return list(MF())

def LIN(n: int):
	return [I() for _ in range(n)]

def LLIN(n: int):
	return [LI() for _ in range(n)]

def LLIN_(n: int):
	return [LI_() for _ in range(n)]

def LLI():
	return [list(map(int, l.split())) for l in input()]

def I():
	return int(input())

def F():
	return float(input())

def ST():
	return input().replace('\n', '')

def main():
	(N, M) = MI()
	edge = [[] for _ in range(N)]
	indegree = [0] * N
	for _ in range(M):
		(a, b) = MI()
		edge[a].append(b)
		indegree[b] += 1
	queue = deque()
	for (i, x) in enumerate(indegree):
		if not x:
			queue.append(i)
	pop = queue.popleft
	topological_index = []
	while queue:
		v = pop()
		topological_index.append(v)
		for to in edge[v]:
			indegree[to] -= 1
			if not indegree[to]:
				queue.append(to)
	if tuple((1 for i in indegree if i != 0)):
		print('loop')
	print(*topological_index, sep='\n')
main()


from collections import deque

def topological_sort(graph: list) -> list:
	n = len(graph)
	degree = [0] * n
	for g in graph:
		for next_pos in g:
			degree[next_pos] += 1
	ans = [i for i in range(n) if degree[i] == 0]
	q = deque(ans)
	while q:
		pos = q.popleft()
		for next_pos in graph[pos]:
			degree[next_pos] -= 1
			if degree[next_pos] == 0:
				q.append(next_pos)
				ans.append(next_pos)
	return ans
(n, m) = map(int, input().split())
info = [list(map(int, input().split())) for i in range(m)]
graph = [[] for i in range(n)]
for i in range(m):
	(a, b) = info[i]
	graph[a].append(b)
ans = topological_sort(graph)
for pos in ans:
	print(pos)


from collections import deque

def topologicalSortBfs(n):
	for i in range(n):
		color[i] = WHITE
	for i in range(0, n):
		if indeg[i] == 0 and color[i] == WHITE:
			bfs(i)

def bfs(s):
	Q.appendleft(s)
	color[s] = GRAY
	while Q:
		u = Q.popleft()
		out.append(u)
		for v in G[u]:
			indeg[v] -= 1
			if indeg[v] == 0 and color[v] == WHITE:
				color[v] = GRAY
				Q.append(v)

def topologicalSortDfs(n):
	for i in range(n):
		color[i] = WHITE
	for s in range(0, n):
		if color[s] == WHITE:
			dfs(s)

def dfs(u):
	color[u] = GRAY
	for v in G[u]:
		if color[v] == WHITE:
			dfs(v)
	out.appendleft(u)
(n, e) = map(int, input().split())
G = {}
for i in range(n):
	G[i] = []
indeg = [0] * n
for i in range(e):
	(s, t) = map(int, input().split())
	indeg[t] += 1
	G[s].append(t)
color = [None] * n
out = deque([])
WHITE = 0
GRAY = 1
Q = deque([])
topologicalSortDfs(n)
print(*out)


import sys
sys.setrecursionlimit(10 ** 9)

def input():
	return sys.stdin.readline().strip()

def INT():
	return int(input())

def MAP():
	return map(int, input().split())

def LIST():
	return list(map(int, input().split()))
INF = float('inf')

def topological_sort(N: int, edges: list) -> list:
	incnts = [0] * N
	outnodes = [[] for i in range(N)]
	for i in range(len(edges)):
		incnts[edges[i][1]] += 1
		outnodes[edges[i][0]].append(edges[i][1])
	S = set()
	for i in range(N):
		if incnts[i] == 0:
			S.add(i)
	L = []
	while S:
		L.append(S.pop())
		for node in outnodes[L[-1]]:
			incnts[node] -= 1
			if incnts[node] == 0:
				S.add(node)
	return L
(N, M) = MAP()
edges = [None] * M
for i in range(M):
	(s, t) = MAP()
	edges[i] = (s, t)
ans = topological_sort(N, edges)
for i in range(N):
	print(ans[i])


from collections import deque
import sys
input = sys.stdin.readline
(N, M) = map(int, input().split())
G = [[] for _ in [0] * N]
deg = [0] * N
for _ in [0] * M:
	(a, b) = map(int, input().split())
	G[a].append(b)
	deg[b] += 1
q = deque()
for (v, d) in enumerate(deg):
	if d == 0:
		print(v)
		q.append(v)
while q:
	v = q.popleft()
	for u in G[v]:
		deg[u] -= 1
		if deg[u] == 0:
			print(u)
			q.append(u)


from collections import deque

def sts():
	for i in g:
		for j in i:
			incnt[j] += 1
	for i in range(v):
		if incnt[i] == 0:
			q.append(i)
	while q:
		e = q.popleft()
		ans.append(e)
		for i in g[e]:
			incnt[i] -= 1
			if incnt[i] == 0:
				q.append(i)
	for i in ans:
		print(i)
(v, e) = map(int, input().split())
g = [[] for i in range(v)]
incnt = [0] * v
q = deque()
ans = []
for i in range(e):
	(x, y) = map(int, input().split())
	g[x].append(y)
sts()


(v, e) = map(int, input().split())
from collections import defaultdict
incnt = defaultdict(int)
edges = [[] for i in range(0 + v)]
for i in range(e):
	(_, __) = map(int, input().split())
	edges[_].append(__)
	incnt[__] += 1
from collections import deque
dq = deque([])
topo = []
for i in range(v):
	if incnt[i] == 0:
		dq.append(i)
while dq:
	a = dq.popleft()
	for to in edges[a]:
		incnt[to] -= 1
		if incnt[to] == 0:
			dq.append(to)
	topo.append(a)
print(*topo, sep='\n')


(V, E) = map(int, input().split())
L = []
visited = [0 for i in range(V)]
edges = [[] for i in range(V)]
flag = 0

def visit(x):
	if visited[x] == 1:
		flag = 1
	elif not visited[x]:
		visited[x] = 1
		for e in edges[x]:
			visit(e)
		visited[x] = 2
		L.insert(0, x)
for i in range(E):
	(s, t) = map(int, input().split())
	edges[s].append(t)
for i in range(V):
	if not visited[i]:
		visit(i)
for i in L:
	print(i)


import queue
WHITE = 0
GRAY = 1
BLACK = 2

def topologicalSort(s):
	Q.put(s)
	color[s] = GRAY
	while not Q.empty():
		u = Q.get()
		out.append(u)
		for v in G[u]:
			indeg[v] -= 1
			if indeg[v] == 0 and color[v] == WHITE:
				color[v] = GRAY
				Q.put(v)
nums = list(map(int, input().split()))
n = nums[0]
e = nums[1]
color = [WHITE] * n
G = [[] for i in range(n)]
indeg = [0] * n
for i in range(e):
	nums = list(map(int, input().split()))
	G[nums[0]].append(nums[1])
	indeg[nums[1]] += 1
Q = queue.Queue()
out = []
for i in range(n):
	if indeg[i] == 0 and color[i] == WHITE:
		topologicalSort(i)
for i in range(n):
	print(out[i])


from sys import stdin
from collections import deque
(UNVISITED, VISITED_IN_QUEUE, POPPED_OUT) = (0, 1, 2)

def generate_adj_matrix(_v_info):
	for v_detail in _v_info:
		(v_from, v_to) = map(int, v_detail)
		init_adj_table[v_from].append(v_to)
		init_in_deg_list[v_to] += 1
	return (init_adj_table, init_in_deg_list)

def topological_sort():
	for v in range(vertices):
		if not in_deg_list[v] and status[v] is UNVISITED:
			bfs(v)
	return ans

def bfs(v):
	v_queue.append(v)
	status[v] = VISITED_IN_QUEUE
	while v_queue:
		current = v_queue.popleft()
		ans.append(current)
		for v_adj in adj_table[current]:
			in_deg_list[v_adj] -= 1
			if not in_deg_list[v_adj] and status[v_adj] is UNVISITED:
				status[v_adj] = VISITED_IN_QUEUE
				v_queue.appendleft(v_adj)
		status[current] = POPPED_OUT
	return None
_input = stdin.readlines()
(vertices, edges) = map(int, _input[0].split())
v_info = map(lambda x: x.split(), _input[1:])
status = [UNVISITED] * vertices
v_queue = deque()
init_adj_table = tuple(([] for _ in range(vertices)))
init_in_deg_list = [0] * vertices
ans = []
(adj_table, in_deg_list) = generate_adj_matrix(v_info)
print(*topological_sort())


def topological_sort(nodes, edges) -> []:
	visited = set()
	result = []

	def dfs(v):
		if v not in visited:
			visited.add(v)
			for u in edges[v]:
				dfs(u)
			result.append(v)
	for s in nodes:
		dfs(s)
	return result

def aoj_system_test():
	(V, E) = map(int, input().split())
	nodes = []
	edges = []
	for i in range(V):
		nodes.append(i)
		edges.append([])
	for _ in range(E):
		(a, b) = map(int, input().split())
		edges[b].append(a)
	ret = topological_sort(nodes, edges)
	for v in ret:
		print(v)
aoj_system_test()


(n, m) = map(int, input().split())
G = [[] for i in range(n)]
deg = [0 for _ in range(n)]
for i in range(m):
	(a, b) = map(int, input().split())
	G[b].append(a)
	deg[a] += 1
from collections import deque
q = deque()
(add, pop) = (q.append, q.popleft)
for i in range(n):
	if deg[i] == 0:
		add(i)
order = []
while q:
	v = pop()
	order.append(v)
	for nv in G[v]:
		deg[nv] -= 1
		if deg[nv] == 0:
			add(nv)
for i in order[::-1]:
	print(i)


import array
import heapq

def topological_sort(num_vs, adj_vs):
	in_deg = array.array('L', (0 for _ in range(num_vs)))
	for dests in adj_vs:
		for dest in dests:
			in_deg[dest] += 1
	sorted_vs = array.array('L')
	pq = []
	for s in range(num_vs):
		if in_deg[s] == 0:
			heapq.heappush(pq, s)
	while pq:
		u = heapq.heappop(pq)
		sorted_vs.append(u)
		for v in adj_vs[u]:
			in_deg[v] -= 1
			if in_deg[v] == 0:
				heapq.heappush(pq, v)
	if all((x == 0 for x in in_deg)):
		return sorted_vs
	else:
		raise TopologicalSortError('The graph has a cycle')

def main():
	(v, e) = map(int, input().split())
	adj_vs = [set() for _ in range(v)]
	for _ in range(e):
		(s, t) = map(int, input().split())
		adj_vs[s].add(t)
	for u in topological_sort(v, adj_vs):
		print(u)
main()


(V, E) = map(int, input().split())
adj = [[] for _ in range(V)]
for _ in range(E):
	(s, t) = map(int, input().split())
	adj[s].append(t)
color = [0 for _ in range(V)]
topo = []

def topo_dfs(s):
	color[s] = 1
	if adj[s]:
		for next in adj[s]:
			if color[next] == 0:
				topo_dfs(next)
	topo.append(s)
	return
for i in range(V):
	if color[i] == 0:
		topo_dfs(i)
print('\n'.join(map(str, topo[::-1])))


from collections import deque
ans = deque()
(V, E) = map(int, input().split())
C = [[] for _ in range(V)]
for _ in range(E):
	tmp = list(map(int, input().split()))
	C[tmp[0]].append(tmp[1])
visited = [False] * V

def DFS(node):
	visited[node] = True
	for adj in C[node]:
		if not visited[adj]:
			DFS(adj)
	ans.appendleft(node)
for i in range(V):
	if not visited[i]:
		DFS(i)
for node in ans:
	print(node)


from collections import deque

def inpl():
	return tuple(map(int, input().split()))
(V, E) = inpl()
indeg = [0] * V
adj = {k: [] for k in range(V)}
for _ in range(E):
	(s, t) = inpl()
	adj[s].append(t)
	indeg[t] += 1
Q = deque([i for (i, ind) in enumerate(indeg) if ind == 0])
res = []
while Q:
	q = Q.popleft()
	for i in adj[q]:
		indeg[i] -= 1
		if indeg[i] == 0:
			Q.append(i)
	res.append(q)
for r in res:
	print(r)


import sys, collections as cl, bisect as bs
sys.setrecursionlimit(100000)
Max = sys.maxsize

def l():
	return list(map(int, input().split()))

def m():
	return map(int, input().split())

def onem():
	return int(input())

def s(x):
	a = []
	aa = x[0]
	su = 1
	for i in range(len(x) - 1):
		if aa == x[i + 1]:
			a.append([aa, su])
			aa = x[i + 1]
			su = 1
		else:
			su += 1
	a.append([aa, su])
	return a

def jo(x):
	return ' '.join(map(str, x))

def max2(x):
	return max(map(max, x))

def Topo_sort(x, y):
	co = cl.Counter((n for m in x.values() for n in m))
	S = cl.deque([i for i in range(y) if co[i] == 0])
	while S:
		n = S.popleft()
		yield n
		for i in x[n]:
			co[i] -= 1
			if co[i] <= 0:
				S.append(i)
(v, e) = m()
g = cl.defaultdict(set)
for i in range(e):
	(s, t) = m()
	g[s] |= {t}
a = Topo_sort(g, v)
for i in Topo_sort(g, v):
	print(i)


from collections import Counter
from collections import deque

def topological_sort(g, v):
	in_count = Counter((y for x in g.values() for y in x))
	s = deque([i for i in range(v) if in_count[i] == 0])
	while s:
		n = s.popleft()
		yield n
		for m in g[n]:
			in_count[m] -= 1
			if in_count[m] <= 0:
				s.append(m)
from sys import stdin
from collections import defaultdict
readline = stdin.readline
(v, e) = map(int, readline().split())
g = defaultdict(set)
for _ in range(e):
	(s, t) = map(int, readline().split())
	g[s] |= {t}
for i in topological_sort(g, v):
	print(i)


import array
import collections

class TopologicalSortError(Exception):
	pass

def topological_sort(num_vs, adj_vs):
	in_deg = array.array('L', (0 for _ in range(num_vs)))
	for dests in adj_vs:
		for dest in dests:
			in_deg[dest] += 1
	visited = array.array('B', (False for _ in range(num_vs)))
	sorted_vs = array.array('L')
	for s in range(num_vs):
		if in_deg[s] == 0 and (not visited[s]):
			q = collections.deque()
			q.append(s)
			visited[s] = True
			while q:
				u = q.popleft()
				sorted_vs.append(u)
				for v in adj_vs[u]:
					in_deg[v] -= 1
					if in_deg[v] == 0 and (not visited[v]):
						visited[v] = True
						q.append(v)
	if all((x == 0 for x in in_deg)):
		return sorted_vs
	else:
		raise TopologicalSortError('The graph has a cycle')

def main():
	(v, e) = map(int, input().split())
	adj_vs = [set() for _ in range(v)]
	for _ in range(e):
		(s, t) = map(int, input().split())
		adj_vs[s].add(t)
	for u in topological_sort(v, adj_vs):
		print(u)
main()


from sys import stdin
from collections import deque
(UNVISITED, VISITED_IN_QUEUE, POPPED_OUT) = (0, 1, 2)

def generate_adj_matrix(_v_info):
	for v_detail in _v_info:
		(v_from, v_to) = map(int, v_detail)
		init_adj_table[v_from].append(v_to)
		init_in_deg_list[v_to] += 1
	return (init_adj_table, init_in_deg_list)

def topological_sort():
	for v in range(vertices):
		if not in_deg_list[v] and status[v] is UNVISITED:
			bfs(v)
	return ans

def bfs(v):
	v_queue.append(v)
	status[v] = VISITED_IN_QUEUE
	while v_queue:
		current = v_queue.popleft()
		ans.append(current)
		for v_adj in adj_table[current]:
			in_deg_list[v_adj] -= 1
			if not in_deg_list[v_adj] and status[v_adj] is UNVISITED:
				status[v_adj] = VISITED_IN_QUEUE
				v_queue.appendleft(v_adj)
		status[current] = POPPED_OUT
	return None
_input = stdin.readlines()
(vertices, edges) = map(int, _input[0].split())
v_info = map(lambda x: x.split(), _input[1:])
status = [UNVISITED] * vertices
v_queue = deque()
init_adj_table = tuple(([] for _ in range(vertices)))
init_in_deg_list = [0] * vertices
ans = []
(adj_table, in_deg_list) = generate_adj_matrix(v_info)
print(*topological_sort(), sep='\n')


from collections import defaultdict, deque
(V, E) = map(int, input().split())
se_list = [list(map(int, input().split())) for _ in range(E)]
s_dic = {}
e_list = [0 for _ in range(V)]
for (s, e) in se_list:
	if s in s_dic:
		s_dic[s].append(e)
	else:
		s_dic[s] = [e]
	e_list[e] += 1
dfs_q = deque()
for v in range(V):
	if e_list[v] == 0:
		dfs_q.append(v)
topological_sort = []
while dfs_q:
	v_from = dfs_q.pop()
	topological_sort.append(v_from)
	if v_from in s_dic:
		for v_to in s_dic[v_from]:
			e_list[v_to] -= 1
			if e_list[v_to] == 0:
				dfs_q.append(v_to)
for v in topological_sort:
	print(v)


from collections import deque

def bfs(s, g, color, indeg, out):
	q = deque()
	q.append(s)
	color[s] = True
	while len(q) != 0:
		u = q.popleft()
		out.append(u)
		for i in range(len(g[u])):
			v = g[u][i]
			indeg[v] -= 1
			if indeg[v] == 0 and (not color[v]):
				color[v] = True
				q.append(v)

def tsort(n, g):
	color = [False] * n
	indeg = [0] * n
	for u in range(n):
		for i in range(len(g[u])):
			v = g[u][i]
			indeg[v] += 1
	out = []
	for u in range(n):
		if indeg[u] == 0 and (not color[u]):
			bfs(u, g, color, indeg, out)
	for line in out:
		print(line)
(n, m) = [int(v) for v in input().split()]
g = [[] for i in range(n)]
for i in range(m):
	(s, t) = [int(v) for v in input().split()]
	g[s].append(t)
tsort(n, g)


(nv, ne) = map(int, input().split(' '))
in_degs = [0] * nv
q = []
outs = {}
o = []
for _ in range(ne):
	(s, t) = map(int, input().split(' '))
	if s in outs:
		outs[s].append(t)
	else:
		outs[s] = [t]
	in_degs[t] += 1
for i in range(nv):
	if in_degs[i] == 0:
		q.append(i)
while len(q) > 0:
	v = q.pop(0)
	o.append(v)
	if v in outs:
		for out in outs[v]:
			in_degs[out] -= 1
			if in_degs[out] == 0:
				q.append(out)
[print(v) for v in o]


def topological_sort(G):
	d = {}
	nodes = set()
	for i in G:
		if i not in d:
			d[i] = set()
		for j in G[i]:
			if j not in d:
				d[j] = set()
			d[j].add(i)
	for i in d:
		if len(d[i]) == 0:
			nodes.add(i)
	visited = set()
	ret = []
	while len(visited) < len(G):
		n = nodes.pop()
		if n not in visited:
			for j in G[n]:
				d[j].discard(n)
				if len(d[j]) == 0 and j not in visited:
					nodes.add(j)
			ret.append(n)
			visited.add(n)
	return ret
(n, m) = list(map(int, input().split(' ')))
G = {}
for i in range(n):
	G[i] = set()
for _ in range(m):
	(s, t) = list(map(int, input().split(' ')))
	G[s].add(t)
L = topological_sort(G)
for n in L:
	print(n)


from collections import deque
(n, k) = map(int, input().split())
a = [[] for i in range(n)]
in_num = [0] * n
for _ in range(k):
	(p, q) = map(int, input().split())
	a[p] += [q]
	in_num[q] += 1
color = [0] * n
result = deque()
aa = deque()

def topologicalSort_w(s):
	aa.append(s)
	color[s] = 1
	while aa:
		u = aa.popleft()
		result.append(u)
		for v in a[u]:
			in_num[v] -= 1
			if in_num[v] == 0 and color[v] == 0:
				color[v] = 1
				aa.append(v)
for i in range(n):
	if in_num[i] == 0 and color[i] == 0:
		topologicalSort_w(i)
for i in range(len(result)):
	print(result.popleft())


def main():
	(nvertices, nedges) = map(int, input().split())
	indegrees = [0 for i in range(nvertices)]
	adj = [[] for i in range(nvertices)]
	for i in range(nedges):
		(s, t) = map(int, input().split())
		adj[s].append(t)
		indegrees[t] += 1
	S = []
	for i in range(nvertices):
		if indegrees[i] == 0:
			S.append(i)
	ordering = []
	while S:
		u = S.pop(0)
		ordering.append(u)
		for v in adj[u]:
			indegrees[v] -= 1
			if indegrees[v] == 0:
				S.append(v)
	for v in ordering:
		print(v)
main()


import sys
sys.setrecursionlimit(int(1000000.0))
(n, m) = map(int, input().split())
edges = {}
for i in range(m):
	(s, t) = map(int, input().split())
	if s not in edges:
		edges[s] = set()
	edges[s].add(t)
stack = []
visited = set()

def visit(v):
	if v in visited:
		return
	visited.add(v)
	if v in edges:
		for t in edges[v]:
			visit(t)
	stack.append(v)
for i in range(n):
	visit(i)
while len(stack) > 0:
	print(stack.pop())


import sys
sys.setrecursionlimit(200000)

def dfs(i: int) -> None:
	global visited, edges, counter, finish_order
	visited[i] = True
	for edge in edges[i]:
		if visited[edge]:
			continue
		dfs(edge)
	finish_order[i] = (counter, i)
	counter += 1
(V, E) = map(int, input().split())
edges = [set() for _ in range(V)]
for _ in range(E):
	(s, t) = map(lambda x: int(x), input().split())
	edges[s].add(t)
visited = [False] * V
finish_order = [(0, 0)] * V
counter = 0
for i in range(V):
	if not visited[i]:
		dfs(i)
for (d, i) in sorted(finish_order, reverse=True):
	print(i)


class Node:

	def __init__(self, id):
		self.id = id
		self.adj = []
		self.indeg = 0
		self.passed = False

	def is_start(self):
		return self.indeg == 0

	def __repr__(self):
		return 'Node({},{},{},{})'.format(self.id, self.passed, [v.id for v in self.adj], [v.id for v in self.radj])

def read_edges(ne, V):
	for _ in range(ne):
		(s, t) = [int(x) for x in input().split()]
		V[s].adj.append(V[t])
		V[t].indeg += 1

def sort(V):
	W = []

	def visit(v):
		S = []
		S.append(v)
		while S:
			v = S.pop()
			v.passed = True
			W.append(v)
			for a in v.adj:
				a.indeg -= 1
				if a.is_start():
					S.append(a)
	for v in V:
		if v.is_start() and (not v.passed):
			visit(v)
	return W

def main():
	(nv, ne) = [int(x) for x in input().split()]
	V = [Node(id) for id in range(nv)]
	read_edges(ne, V)
	W = sort(V)
	[print(v.id) for v in W]
main()


from sys import stdin
from collections import deque
(n, e) = map(int, stdin.readline().split())
G = [[] for _ in [0] * n]
indeg = [0] * n
out = []
V = [False] * n

def bfs(s):
	dq = deque([s])
	V[s] = True
	while dq:
		u = dq.popleft()
		out.append(u)
		for i in range(len(G[u])):
			v = G[u][i]
			indeg[v] -= 1
			if indeg[v] == 0 and (not V[v]):
				V[v] = True
				dq.append(v)

def tsort():
	for u in range(n):
		for i in range(len(G[u])):
			indeg[G[u][i]] += 1
	for u in range(n):
		if indeg[u] == 0 and (not V[u]):
			bfs(u)
	for i in range(len(out)):
		print(out[i])
for _ in [0] * e:
	(s, t) = map(int, stdin.readline().split())
	G[s].append(t)
tsort()


from sys import exit
import queue
(V, E) = [int(n) for n in input().split()]
ans = []
graph = [[] for _ in range(V)]
indeg = [0] * V
yet = [True] * V

def bfs(s):
	q = queue.Queue()
	q.put(s)
	while not q.empty():
		u = q.get()
		ans.append(u)
		yet[u] = False
		for v in graph[u]:
			indeg[v] -= 1
			if indeg[v] == 0:
				q.put(v)
for i in range(E):
	(s, t) = [int(n) for n in input().split()]
	graph[s].append(t)
	indeg[t] += 1
for i in range(V):
	if indeg[i] == 0 and yet[i]:
		bfs(i)
for a in ans:
	print(a)


from collections import deque
(v, e) = map(int, input().split())
L = []
ins = [0] * v
DAG = [[] for i in range(v)]
ans = []
for i in range(e):
	(a, b) = map(int, input().split())
	DAG[a].append(b)
	ins[b] += 1
start = 0
S = deque([])
for i in range(v):
	if ins[i] == 0:
		S.append(i)
while len(S) > 0:
	cur = S.popleft()
	ans.append(cur)
	for e in DAG[cur]:
		ins[e] -= 1
		if ins[e] == 0:
			S.append(e)
for i in range(v):
	print(ans[i])


from collections import defaultdict
(vertice, edge) = (int(n) for n in input().split(' '))
connect = defaultdict(list)
indegree = [0 for n in range(vertice)]
for _ in range(edge):
	(s, t) = (int(n) for n in input().split(' '))
	connect[s].append(t)
	indegree[t] += 1
answer = []
zeroin = []
for (i, n) in enumerate(indegree):
	if n == 0:
		zeroin.append(i)
while len(zeroin) > 0:
	next_v = zeroin.pop()
	indegree[next_v] -= 1
	answer.append(next_v)
	for c in connect[next_v]:
		indegree[c] -= 1
		if indegree[c] == 0:
			zeroin.append(c)
for a in answer:
	print(a)


(N, M) = map(int, input().split())
G = [[] for i in range(N)]
for i in range(M):
	(s, t) = map(int, input().split())
	G[s].append(t)
ans = []
V = set()

def dfs(n):
	for e in G[n]:
		if e not in V:
			dfs(e)
	if n not in V:
		ans.append(n)
		V.add(n)
for i in range(N):
	if i not in V:
		if i not in V:
			dfs(i)
			print()
print(*ans[::-1], sep='\n')


def zadanie_2():
	[n, m] = list(map(int, input().strip().split(' ')))
	sasiedzi = [[] for _ in range(n)]
	stopnie = [0 for _ in range(n)]
	kolejka = []
	kolejnosc = []
	for i in range(m):
		luk = list(map(int, input().strip().split(' ')))
		sasiedzi[luk[0]].append(luk[1])
		stopnie[luk[1]] += 1
	for i in range(n):
		if stopnie[i] == 0:
			kolejka.append(i)
	while len(kolejka) > 0:
		wierzcholek = kolejka.pop(0)
		kolejnosc.append(wierzcholek)
		for sasiad in sasiedzi[wierzcholek]:
			stopnie[sasiad] -= 1
			if stopnie[sasiad] == 0:
				kolejka.append(sasiad)
	for i in range(len(kolejnosc)):
		print(str(kolejnosc[i]), end='')
		if i < len(kolejnosc) - 1:
			print('')
zadanie_2()


import sys
from collections import deque

def bfs(u, result, out_edge, in_degree, processed):
	q = deque()
	q.append(u)
	processed[u] = True
	while q:
		u = q.popleft()
		result.append(u)
		for e in out_edge[u]:
			in_degree[e] -= 1
			if in_degree[e] == 0 and processed[e] == False:
				processed[e] = True
				q.append(e)

def solve(V, in_degree, out_edge):
	result = []
	processed = [False for _ in range(V)]
	for (i, u) in enumerate(in_degree):
		if u == 0 and processed[i] == False:
			bfs(i, result, out_edge, in_degree, processed)
	return result

def main(args):
	(V, E) = [int(x) for x in input().split(' ')]
	in_degree = [0 for _ in range(V)]
	out_edge = [[] for _ in range(V)]
	for _ in range(E):
		(s, t) = [int(x) for x in input().split(' ')]
		out_edge[s].append(t)
		in_degree[t] += 1
	result = solve(V, in_degree, out_edge)
	print('\n'.join(map(str, result)))
main(sys.argv[1:])


import sys
from collections import deque
sys.setrecursionlimit(10 ** 7)
(V, E) = map(int, input().split())
G = [[] for _ in range(V)]
for _ in range(E):
	(s, t) = map(int, input().split())
	G[s].append(t)
visited = [0] * V
ans = deque([])

def dfs(u):
	visited[u] = 1
	for i in G[u]:
		if visited[i] == 0:
			dfs(i)
	ans.appendleft(u)
for s in range(V):
	if visited[s] == 0:
		dfs(s)
for a in ans:
	print(a)


from collections import deque

class Graph:

	def __init__(self, n, edge, indexed=1):
		self.n = n
		self.graph = [[] for _ in range(n)]
		self.rev = [[] for _ in range(n)]
		self.deg = [0 for _ in range(n)]
		for e in edge:
			self.graph[e[0] - indexed].append(e[1] - indexed)
			self.rev[e[1] - indexed].append(e[0] - indexed)
			self.deg[e[1] - indexed] += 1

	def topological_sort(self):
		deg = self.deg[:]
		res = [i for i in range(self.n) if deg[i] == 0]
		queue = deque(res)
		used = [False for _ in range(self.n)]
		while queue:
			node = queue.popleft()
			for adj in self.graph[node]:
				deg[adj] -= 1
				if deg[adj] == 0:
					queue.append(adj)
					res.append(adj)
		return res
import sys
input = sys.stdin.readline
(N, M) = map(int, input().split())
E = [tuple(map(int, input().split())) for _ in range(M)]
g = Graph(N, E, 0)
print('\n'.join(map(str, g.topological_sort())))


from sys import stdin
from collections import deque
(n, e) = map(int, stdin.readline().split())
G = [[] for _ in [0] * n]
indeg = [0] * n
out = []
V = [False] * n

def bfs(s):
	dq = deque([s])
	V[s] = True
	while dq:
		u = dq.popleft()
		out.append(u)
		for i in range(len(G[u])):
			v = G[u][i]
			indeg[v] -= 1
			if indeg[v] == 0 and (not V[v]):
				V[v] = True
				dq.append(v)

def tsort():
	for u in range(n):
		for i in range(len(G[u])):
			indeg[G[u][i]] += 1
	for u in range(n):
		if indeg[u] == 0 and (not V[u]):
			bfs(u)
	print(*out, sep='\n')
for _ in [0] * e:
	(s, t) = map(int, stdin.readline().split())
	G[s].append(t)
tsort()


(V, E) = map(int, input().split())
EDGE = [list(map(int, input().split())) for i in range(E)]
from collections import deque
QUE = deque(list(range(V)))
EDGEOUTLIST = [[] for i in range(V)]
for (x, y) in EDGE:
	EDGEOUTLIST[x].append(y)
check = [0] * V
TOP_SORT = []

def dfs(x):
	if check[x] == 1:
		return
	for to in EDGEOUTLIST[x]:
		if check[to] == 0:
			dfs(to)
	TOP_SORT.append(x)
	check[x] = 1
while QUE:
	x = QUE.pop()
	dfs(x)
TOP_SORT.reverse()
for v in TOP_SORT:
	print(v)


from sys import stdin
from collections import deque
(V, E) = map(int, stdin.readline().split())
adj_list = [[] for _ in [0] * V]
is_visited = [False] * V
for _ in [0] * E:
	(s, t) = map(int, stdin.readline().split())
	adj_list[s].append(t)
out = deque()

def dfs(u):
	is_visited[u] = True
	for v in adj_list[u]:
		if not is_visited[v]:
			dfs(v)
	out.appendleft(u)
for s in range(V):
	if not is_visited[s]:
		dfs(s)
print(*out, sep='\n')


from collections import deque
(v, e) = map(int, input().split())
Edg = [[] for _ in range(v)]
inDeg = [0 for _ in range(v)]
Done = [0 for _ in range(v)]
for _ in range(e):
	(s, t) = map(int, input().split())
	Edg[s].append(t)
	inDeg[t] += 1
Q = deque()
ans = []
for u in range(v):
	if not inDeg[u]:
		Q.append(u)
while Q:
	u = Q.popleft()
	ans.append(u)
	for t in Edg[u]:
		inDeg[t] -= 1
		if inDeg[t] == 0 and (not Done[t]):
			Q.append(t)
			Done[t] = 1
for i in ans:
	print(i)


from collections import namedtuple
DirectedEdge = namedtuple('DirectedEdge', ('src', 'dest'))

def revert(edge):
	return edge._replace(src=edge.dest, dest=edge.src)

class Digraph:

	def __init__(self, v):
		self.v = v
		self._edges = [[] for _ in range(v)]

	def add(self, edge):
		self._edges[edge.src].append(edge)

	def adj(self, v):
		return self._edges[v]

	def edges(self):
		for es in self._edges:
			for e in es:
				yield e

	def reversed(self):
		g = self.__class__(self.v)
		for e in self.edges():
			g.add(revert(e))
		return g

def sorted_topological(graph):
	return reversed(list(reverse_post(graph.reversed())))

def reverse_post(graph):

	def visit(v):
		if not visited[v]:
			visited[v] = True
			return True
		else:
			return False

	def leave(v):
		if not left[v]:
			left[v] = True
			vs.append(v)
		return False
	visited = [False] * graph.v
	left = [False] * graph.v
	vs = []
	for i in range(graph.v):
		if not visited[i]:
			stack = [(i, leave)]
			stack.extend(((e.dest, visit) for e in graph.adj(i)))
			while stack:
				(v, f) = stack.pop()
				if f(v):
					stack.append((v, leave))
					for e in graph.adj(v):
						stack.append((e.dest, visit))
	return reversed(vs)

def run():
	(v, e) = [int(i) for i in input().split()]
	g = Digraph(v)
	for _ in range(e):
		(s, t) = [int(i) for i in input().split()]
		g.add(DirectedEdge(s, t))
	for v in sorted_topological(g):
		print(v)
run()


def topological_sort(G, revG):
	n = len(revG)
	S = set()
	for u in revG:
		if len(revG[u]) == 0:
			S.add(u)
	L = []
	while len(S) > 0:
		u = S.pop()
		L.append(u)
		for v in G[u]:
			revG[v].remove(u)
			if len(revG[v]) == 0:
				S.add(v)
	return L
(n, m) = [int(i) for i in input().strip().split(' ')]
G = {}
revG = {}
for i in range(n):
	G[i] = set()
	revG[i] = set()
for _ in range(m):
	(s, t) = [int(i) for i in input().strip().split(' ')]
	G[s].add(t)
	revG[t].add(s)
L = topological_sort(G, revG)
for n in L:
	print(n)


import os
import sys
if os.getenv('LOCAL'):
	sys.stdin = open('_in.txt', 'r')
sys.setrecursionlimit(2147483647)
INF = float('inf')
IINF = 10 ** 18
MOD = 10 ** 9 + 7

def topological_sort(graph):
	ins = [0] * len(graph)
	for vs in graph:
		for v in vs:
			ins[v] += 1
	zeros = []
	for (v, cnt) in enumerate(ins):
		if cnt == 0:
			zeros.append(v)
	ret = []
	while zeros:
		v = zeros.pop()
		ret.append(v)
		for u in graph[v]:
			ins[u] -= 1
			if ins[u] == 0:
				zeros.append(u)
	return ret
(V, E) = list(map(int, sys.stdin.readline().split()))
ST = [list(map(int, sys.stdin.readline().split())) for _ in range(E)]
graph = [[] for _ in range(V)]
for (s, t) in ST:
	graph[s].append(t)
ans = topological_sort(graph)
print(*ans, sep='\n')


import os
import sys

def main():
	(v, e) = map(int, input().split())
	path_list = [[] for _ in range(v)]
	to_there = [0] * v
	for _ in range(e):
		(s, t) = map(int, input().split())
		path_list[s].append(t)
		to_there[t] += 1
	stack_list = [i for (i, x) in enumerate(to_there) if x == 0]
	while stack_list:
		u = stack_list.pop()
		for v in path_list[u]:
			to_there[v] -= 1
			if to_there[v] == 0:
				stack_list.append(v)
		print(u)
main()


import sys
import os
import pprint
from queue import Queue
(V, E) = list(map(int, input().split()))
G = [[] for i in range(V)]
indig = [0] * V
for i in range(E):
	(s, t) = list(map(int, input().split()))
	G[s].append(t)
	indig[t] += 1
q = Queue()
out = []

def bfs(node_index):
	q.put(node_index)
	while not q.empty():
		u = q.get()
		out.append(u)
		for index in G[u]:
			indig[index] -= 1
			if indig[index] == 0:
				q.put(index)
indig_copy = indig[:]
for i in range(V):
	if indig_copy[i] == 0:
		bfs(node_index=i)
for v in out:
	print(v)


(v, e) = map(int, input().split())
indeg = [0] * v
uv = [[] for _ in range(v)]
for i in range(e):
	(s, t) = map(int, input().split())
	uv[s].append(t)
	indeg[t] += 1
visited = [False] * v
ans = []
for i in range(v):
	if indeg[i] == 0 and (not visited[i]):
		q = [i]
		visited[i] = True
		while len(q) > 0:
			u = q.pop(0)
			ans.append(u)
			for v in uv[u]:
				indeg[v] -= 1
				if indeg[v] == 0 and (not visited[v]):
					visited[v] = True
					q.append(v)
for v in ans:
	print(v)


from collections import deque

def bfs(s):
	q = deque()
	q.append(s)
	while len(q) > 0:
		u = q.popleft()
		searched[u] = True
		res.append(u)
		for v in adj[u]:
			indeg[v] -= 1
			if indeg[v] == 0 and (not searched[v]):
				q.append(v)
(V, E) = map(int, input().split())
adj = [[] for i in range(V)]
indeg = [0 for i in range(V)]
for i in range(E):
	(u, v) = map(int, input().split())
	adj[u].append(v)
	indeg[v] += 1
searched = [False for i in range(V)]
res = []
for u in range(V):
	if indeg[u] == 0 and (not searched[u]):
		bfs(u)
for u in res:
	print(u)


import sys
(v, e) = map(int, sys.stdin.readline().strip().split())
G = [[] for _ in range(v)]
indeg = [0] * v
for i in range(e):
	(s, t) = map(int, sys.stdin.readline().strip().split())
	G[s].append(t)
	indeg[t] += 1
ans = []

def dfs(u):
	if indeg[u] == 0:
		ans.append(u)
		for i in G[u]:
			indeg[i] -= 1
			dfs(i)
indeg_start = indeg.copy()
for i in range(v):
	if indeg_start[i] == 0:
		dfs(i)
for i in ans:
	print(i)


from collections import deque
from collections import defaultdict
adj = defaultdict(lambda : [])
(n_V, n_E) = list(map(int, input().split()))
indeg = [0] * n_V
for _ in range(n_E):
	(s, t) = list(map(int, input().split()))
	indeg[t] += 1
	adj[s].append(t)

def topological_sort(dag, indeg):
	is_visited = [False] * len(indeg)
	ret = []
	perm = [-1] * len(indeg)
	que = deque()
	for (i, deg) in enumerate(indeg):
		if deg == 0:
			que.append((i, 0))
			is_visited[i] = True
	while que:
		(u, cnt) = que.popleft()
		ret.append(u)
		perm[u] = cnt
		for to in dag[u]:
			indeg[to] -= 1
			if indeg[to] or is_visited[to]:
				continue
			que.append((to, cnt + 1))
			is_visited[to] = True
	if False in is_visited:
		print(is_visited)
		raise ValueError('inputted graph is not DAG')
	return (ret, perm)
(ans, _) = topological_sort(adj, indeg)
print(*ans, sep='\n')


import queue

def bfs(u):
	q = queue.Queue()
	q.put(u)
	while not q.empty():
		v = q.get()
		color[v] = 'black'
		ans.append(v)
		for w in Adj[v]:
			indeg[w] -= 1
			if indeg[w] == 0 and color[w] == 'white':
				q.put(w)
	return
(n, m) = map(int, input().split())
color = ['white' for _ in range(n)]
Adj = [[] for _ in range(n)]
indeg = [0] * n
ans = []
for i in range(m):
	(s, t) = map(int, input().split())
	Adj[s].append(t)
	indeg[t] += 1
for i in range(n):
	if indeg[i] == 0 and color[i] == 'white':
		bfs(i)
for i in range(n):
	print(ans[i])


(N, M) = map(int, input().split())
G = [[] for i in range(N)]
for i in range(M):
	(s, t) = map(int, input().split())
	G[s].append(t)

def topological_sort(g):
	topological_list = []
	visited = set()

	def dfs(n):
		for e in g[n]:
			if e not in visited:
				dfs(e)
		topological_list.append(n)
		visited.add(n)
	for i in range(len(g)):
		if i not in visited:
			dfs(i)
	return topological_list[::-1]
print(*topological_sort(G), sep='\n')


from collections import defaultdict, deque
(v, n) = map(int, input().split())
es = [[int(x) for x in input().split()] for _ in range(n)]
outs = defaultdict(list)
ins = defaultdict(int)
for (v1, v2) in es:
	outs[v1].append(v2)
	ins[v2] += 1
q = deque((v1 for v1 in range(v) if ins[v1] == 0))
res = []
while q:
	v1 = q.popleft()
	res.append(v1)
	for v2 in outs[v1]:
		ins[v2] -= 1
		if ins[v2] == 0:
			q.append(v2)
for i in res:
	print(i)


(v, e) = map(int, input().split())
adjacency_list = [[] for i in range(v)]
queue = []
deg = [0] * v
for _ in range(e):
	(s, t) = map(int, input().split())
	adjacency_list[s].append(t)
	deg[t] += 1
for i in range(v):
	if deg[i] == 0:
		queue.append(i)
		print(i)
while queue:
	vertex = queue.pop(0)
	for v in adjacency_list[vertex]:
		deg[v] -= 1
		if deg[v] == 0:
			queue.append(v)
			print(v)


def main():
	(nvertices, nedges) = map(int, input().split())
	Adj = [[] for i in range(nvertices)]
	for i in range(nedges):
		(s, t) = map(int, input().split())
		Adj[s].append(t)
	visited = [False] * nvertices
	ordering = []
	for u in range(nvertices):
		if not visited[u]:
			dfs(u, Adj, visited, ordering)
	for v in reversed(ordering):
		print(v)

def dfs(u, Adj, visited, ordering):
	visited[u] = True
	for v in Adj[u]:
		if not visited[v]:
			dfs(v, Adj, visited, ordering)
	ordering.append(u)
main()


import sys, re
from collections import deque, defaultdict, Counter
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, tan, asin, acos, atan, radians, degrees, log2, gcd
from itertools import accumulate, permutations, combinations, combinations_with_replacement, product, groupby
from operator import itemgetter, mul
from copy import deepcopy
from string import ascii_lowercase, ascii_uppercase, digits
from bisect import bisect, bisect_left, insort, insort_left
from heapq import heappush, heappop
from functools import reduce

def input():
	return sys.stdin.readline().strip()

def INT():
	return int(input())

def MAP():
	return map(int, input().split())

def LIST():
	return list(map(int, input().split()))

def ZIP(n):
	return zip(*(MAP() for _ in range(n)))
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
mod = 10 ** 9 + 7
from decimal import *
(V, E) = MAP()
st = [LIST() for _ in range(E)]
graph = [[] for _ in range(V)]
dag = [0] * V
for (s, t) in st:
	graph[s].append(t)
	dag[t] += 1
ans = [i for (i, x) in enumerate(dag) if x == 0]
q = deque([i for (i, x) in enumerate(dag) if x == 0])
while q:
	S = q.popleft()
	for node in graph[S]:
		dag[node] -= 1
		if dag[node] == 0:
			ans.append(node)
			q.append(node)
if sum(dag):
	print(-1)
else:
	print(*ans, sep='\n')


def topologicalSort(g: list, deg: list):
	ret = []
	q = []
	for (i, d) in enumerate(deg):
		if not d:
			ret.append(i)
			q.append(i)
	while q:
		cur = q.pop(0)
		for nxt in g[cur]:
			deg[nxt] -= 1
			if not deg[nxt]:
				ret.append(nxt)
				q.append(nxt)
	return ret

def main():
	(v, e, *L) = map(int, open(0).read().split())
	g = [[] for _ in range(v)]
	deg = [0] * v
	for (s, t) in zip(*[iter(L)] * 2):
		g[s].append(t)
		deg[t] += 1
	print('\n'.join(map(str, topologicalSort(g, deg))))
main()


(nv, ne) = map(int, input().split(' '))
in_degs = [0] * nv
q = []
outs = {}
o = []
for _ in range(ne):
	(s, t) = map(int, input().split(' '))
	if s in outs:
		outs[s].append(t)
	else:
		outs[s] = [t]
	in_degs[t] += 1
for i in range(nv):
	if in_degs[i] == 0:
		q.append(i)
while q:
	v = q.pop(0)
	o.append(v)
	if v in outs:
		for out in outs[v]:
			in_degs[out] -= 1
			if in_degs[out] == 0:
				q.append(out)
[print(v) for v in o]


from collections import defaultdict, deque
(v, n) = map(int, input().split())
es = [[int(x) for x in input().split()] for _ in range(n)]
outs = defaultdict(list)
ins = defaultdict(int)
for (v1, v2) in es:
	outs[v1].append(v2)
	ins[v2] += 1
q = deque((v1 for v1 in range(v) if ins[v1] == 0))
res = []
while q:
	v1 = q.popleft()
	res.append(v1)
	for v2 in outs[v1]:
		ins[v2] -= 1
		if ins[v2] == 0:
			q.append(v2)
for i in res:
	print(i)


from collections import defaultdict, deque
import sys, heapq, bisect, math, itertools, string, queue, copy, time
sys.setrecursionlimit(10 ** 8)
INF = float('inf')
mod = 10 ** 9 + 7
eps = 10 ** (-7)

def inp():
	return int(input())

def inpl():
	return list(map(int, input().split()))

def inpl_str():
	return list(input().split())
(N, M) = inpl()
lines = defaultdict(set)
hh = [0] * N
for _ in range(M):
	(x, y) = inpl()
	lines[x].add(y)
	hh[y] += 1
q = queue.Queue()
for t in range(N):
	if hh[t] == 0:
		q.put(t)
topological = []
while not q.empty():
	s = q.get()
	topological.append(s)
	for t in lines[s]:
		hh[t] -= 1
		if hh[t] == 0:
			q.put(t)
for x in topological:
	print(x)


from collections import deque
(V, E) = map(int, input().split())
g = [[] for _ in range(V)]
in_E = [0 for _ in range(V)]
for _ in range(E):
	(s, t) = map(int, input().split())
	g[s].append(t)
	in_E[t] += 1
d = deque()
for i in range(V):
	if in_E[i] == 0:
		d.append(i)
ans = []
while d:
	v = d.popleft()
	for u in g[v]:
		in_E[u] -= 1
		if in_E[u] == 0:
			d.append(u)
	ans.append(v)
for i in ans:
	print(i)


from collections import deque
(V, E) = map(int, input().split())
dic = {}
pnum = [0] * V
for i in range(E):
	(s, t) = map(int, input().split())
	pnum[t] += 1
	if s not in dic:
		dic[s] = []
	dic[s].append(t)
q = deque([])
ans = []
for i in range(V):
	if pnum[i] == 0:
		q.append(i)
		ans.append(i)
while len(q) > 0:
	now = q.popleft()
	if now not in dic:
		continue
	for i in dic[now]:
		pnum[i] -= 1
		if pnum[i] == 0:
			q.append(i)
			ans.append(i)
for i in range(V):
	print(ans[i])


from collections import deque
(v, e) = map(int, input().split())
adj = [[] for _ in range(v)]
inflow = [0] * v
for _ in range(e):
	(s, t) = map(int, input().split())
	inflow[t] += 1
	adj[s].append(t)

def topological_sort(adj, inflow):
	is_visited = [False] * len(inflow)
	res = []

	def bfs(s):
		q = deque([s])
		is_visited[s] = True
		res.append(s)
		while q:
			p = q.popleft()
			for r in adj[p]:
				inflow[r] -= 1
				if inflow[r] == 0 and (not is_visited[r]):
					q.append(r)
					is_visited[r] = True
					res.append(r)
	for x in range(len(inflow)):
		if inflow[x] == 0 and (not is_visited[x]):
			bfs(x)
	return res
for i in topological_sort(adj, inflow):
	print(i)


import queue
(nv, ne) = map(int, input().split(' '))
in_degs = [0] * nv
q = queue.Queue()
outs = {}
o = []
for _ in range(ne):
	(s, t) = map(int, input().split(' '))
	if s in outs:
		outs[s].append(t)
	else:
		outs[s] = [t]
	in_degs[t] += 1
for i in range(nv):
	if in_degs[i] == 0:
		q.put(i)
while not q.empty():
	v = q.get()
	o.append(v)
	if v in outs:
		for out in outs[v]:
			in_degs[out] -= 1
			if in_degs[out] == 0:
				q.put(out)
[print(v) for v in o]


(V, E) = map(int, input().split())
adjacents = []
for i in range(V):
	adjacents.append([])
for i in range(E):
	(s, t) = map(int, input().split())
	adjacents[t].append(s)

def topological_sort(num, adjacents):
	colors = ['white'] * num
	result = []

	def dfs(u):
		if colors[u] == 'black':
			return
		colors[u] = 'black'
		for a in adjacents[u]:
			if colors[a] != 'black':
				dfs(a)
		result.append(u)
	for n in range(num):
		dfs(n)
	return result
for i in topological_sort(V, adjacents):
	print(i)


from collections import deque

def topological_sort(n, G):
	seq_sorted = []
	st = deque()
	ct_to_edges = [0] * n
	for edges in G:
		for node in edges:
			ct_to_edges[node] += 1
	for (i, ct) in enumerate(ct_to_edges):
		if ct == 0:
			st.append(i)
	while st:
		node = st.pop()
		seq_sorted.append(node)
		for node in G[node]:
			ct_to_edges[node] -= 1
			if ct_to_edges[node] == 0:
				st.append(node)
	return seq_sorted

def main():
	(n, m) = map(int, input().split())
	G = [[] for _ in range(n)]
	for _ in range(m):
		(s, t) = map(int, input().split())
		G[s].append(t)
	topo_seq = topological_sort(n, G)
	for i in topo_seq:
		print(i)
main()


from collections import defaultdict
import sys
re = sys.stdin
(vertice, edge) = (int(n) for n in re.readline().split(' '))
connect = defaultdict(list)
indegree = [0 for n in range(vertice)]
for _ in range(edge):
	(s, t) = (int(n) for n in re.readline().split(' '))
	connect[s].append(t)
	indegree[t] += 1
answer = []
zeroin = []
for (i, n) in enumerate(indegree):
	if n == 0:
		zeroin.append(i)
while len(zeroin) > 0:
	next_v = zeroin.pop()
	indegree[next_v] -= 1
	answer.append(next_v)
	for c in connect[next_v]:
		indegree[c] -= 1
		if indegree[c] == 0:
			zeroin.append(c)
for a in answer:
	print(a)


import sys
f_i = sys.stdin
(V, E) = map(int, f_i.readline().split())
adj_list = [[] for i in range(V)]
is_visited = [False] * V
indeg = [0] * V
for l_i in f_i:
	(s, t) = map(int, l_i.split())
	adj_list[s].append(t)
	indeg[t] += 1
import collections
Q = collections.deque()
out = collections.deque()

def bfs(s):
	Q.append(s)
	is_visited[s] = True
	while Q:
		u = Q.popleft()
		out.append(u)
		for v in adj_list[u]:
			indeg[v] -= 1
			if indeg[v] == 0 and is_visited[v] == False:
				is_visited[v] = True
				Q.append(v)
for u in range(V):
	if indeg[u] == 0 and is_visited[u] == False:
		bfs(u)
print(*out, sep='\n')


import sys, collections
(V, E) = tuple(map(int, sys.stdin.readline().split()))
INF = float('inf')
st = tuple((tuple(map(int, sys.stdin.readline().rstrip().split())) for _ in range(E)))
G = [[] for _ in range(V)]
for (s, t) in st:
	G[s].append(t)
visited = set()
indeg = [0] * V
ret = []

def bfs(s):
	q = collections.deque([s])
	visited.add(s)
	while q:
		u = q.popleft()
		ret.append(u)
		for v in G[u]:
			indeg[v] -= 1
			if indeg[v] == 0 and (not v in visited):
				visited.add(v)
				q.append(v)

def topologicalSort_bfs():
	for a in G:
		for t in a:
			indeg[t] += 1
	for i in range(V):
		if indeg[i] == 0 and (not i in visited):
			bfs(i)

def dfs(s):
	if s in visited:
		return
	for e in G[s]:
		dfs(e)
	ret.append(s)
	visited.add(s)

def topologicalSort_dfs():
	for i in range(V):
		dfs(i)
	ret.reverse()
topologicalSort_bfs()
print(*ret, sep='\n')


import heapq

class TopologicalSortError(Exception):
	pass

def topological_sort(num_vs, adj_vs):
	in_deg = [0 for _ in range(num_vs)]
	for dests in adj_vs:
		for dest in dests:
			in_deg[dest] += 1
	sorted_vs = []
	pq = []
	for s in range(num_vs):
		if in_deg[s] == 0:
			heapq.heappush(pq, s)
	while pq:
		u = heapq.heappop(pq)
		sorted_vs.append(u)
		for v in adj_vs[u]:
			in_deg[v] -= 1
			if in_deg[v] == 0:
				heapq.heappush(pq, v)
	if all((x == 0 for x in in_deg)):
		return sorted_vs
	else:
		raise TopologicalSortError('The graph has a cycle')

def main():
	(v, e) = map(int, input().split())
	adj_vs = [set() for _ in range(v)]
	for _ in range(e):
		(s, t) = map(int, input().split())
		adj_vs[s].add(t)
	for u in topological_sort(v, adj_vs):
		print(u)
main()


from collections import deque
(N, E) = map(int, input().split())
G = [[] for i in range(N)]
In = [0] * N
for i in range(E):
	(s, t) = map(int, input().split())
	G[s].append(t)
	In[t] += 1
S = deque([i for i in range(N) if In[i] == 0])
res = []
while S:
	b = S.popleft()
	for nv in G[b]:
		In[nv] -= 1
		if In[nv] == 0:
			S.append(nv)
	res.append(b)
print(*res, sep='\n')


from typing import List, Tuple

def topological_sort(n: int, m: int, G: List[List[int]]) -> List[int]:
	for u in range(n):
		if color[u] == 'WHITE':
			dfs(u)
	return L[::-1]

def dfs(u: int) -> None:
	if color[u] == 'GRAY':
		print('Graph is not DAG')
		exit()
	if color[u] == 'BLACK':
		return
	color[u] = 'GRAY'
	for v in G[u]:
		dfs(v)
	color[u] = 'BLACK'
	L.append(u)
(n, m) = map(int, input().split())
G = [[] for _ in range(n)]
color: List[str] = ['WHITE' for _ in range(n)]
L: List[int] = []
for _ in range(m):
	(s, t) = map(int, input().split())
	G[s].append(t)
L = topological_sort(n, m, G)
for v in L:
	print(v)


from collections import deque, defaultdict

def topological_sort(V, E):
	indeg = {v: 0 for v in V}
	for ends in E.values():
		for v in ends:
			indeg[v] += 1
	q = deque([v for v in V if indeg[v] == 0])
	top_sorted = []
	while q:
		v = q.popleft()
		top_sorted.append(v)
		for u in E[v]:
			indeg[u] -= 1
			if indeg[u] == 0:
				q.append(u)
	if len(top_sorted) == len(V):
		return top_sorted
	else:
		return None
(N, M) = map(int, input().split())
V = range(N)
E = defaultdict(list)
for _ in range(M):
	(s, t) = map(int, input().split())
	E[s].append(t)
print(*topological_sort(V, E), sep='\n')


import collections
(V, E) = map(int, input().split())
Adj_list = [[] for _ in range(V)]
Indeg = [0] * V
isVisited = [False] * V
ans = []
for i in range(E):
	(u, v) = map(int, input().split())
	Adj_list[u].append(v)
	Indeg[v] += 1

def BFS(u):
	dq = collections.deque()
	dq.append(u)
	isVisited[u] = True
	while dq:
		v = dq.popleft()
		ans.append(v)
		for s in Adj_list[v]:
			Indeg[s] -= 1
			if Indeg[s] == 0 and isVisited[s] != True:
				isVisited[s] = True
				dq.append(s)
	return ans
for i in range(V):
	if Indeg[i] == 0 and isVisited[i] != True:
		BFS(i)
for i in ans:
	print(i)


import sys
f_i = sys.stdin
(V, E) = map(int, f_i.readline().split())
adj_list = [[] for i in range(V)]
is_visited = [False] * V
for l_i in f_i:
	(s, t) = map(int, l_i.split())
	adj_list[s].append(t)
import collections
out = collections.deque()

def dfs(u):
	is_visited[u] = True
	for v in adj_list[u]:
		if not is_visited[v]:
			dfs(v)
	out.appendleft(u)
for s in range(V):
	if not is_visited[s]:
		dfs(s)
print(*out, sep='\n')


def main():
	(N, M) = (int(i) for i in input().split())
	G = [[] for _ in range(N)]
	deg = [0] * N
	for _ in range(M):
		(a, b) = (int(i) for i in input().split())
		G[a].append(b)
		deg[b] += 1
	from collections import deque

	def topological_sort():
		que = deque()
		ans = [] * N
		for i in range(N):
			if deg[i] == 0:
				que.append(i)
				ans.append(i)
		while que:
			u = que.popleft()
			for v in G[u]:
				deg[v] -= 1
				if deg[v] == 0:
					que.append(v)
					ans.append(v)
		return ans
	print(*topological_sort(), sep='\n')
main()


import collections
(V, E) = map(int, input().split())
Adj_list = [[] for _ in range(V)]
isVisited = [False] * V
for i in range(E):
	(u, v) = map(int, input().split())
	Adj_list[u].append(v)
Out = collections.deque()

def DFS(u):
	isVisited[u] = True
	for v in Adj_list[u]:
		if isVisited[v] != True:
			DFS(v)
	Out.appendleft(u)
for i in range(V):
	if isVisited[i] != True:
		DFS(i)
print(*Out, sep='\n')


import heapq
from collections import deque
from enum import Enum
import sys
import math
from _heapq import heappush, heappop
BIG_NUM = 2000000000
MOD = 1000000007
EPS = 1e-09
(V, E) = map(int, input().split())
in_num = [0] * V
G = [[] for i in range(V)]
for loop in range(E):
	(tmp_from, tmp_to) = map(int, input().split())
	G[tmp_from].append(tmp_to)
	in_num[tmp_to] += 1
Q = deque()
for i in range(V):
	if in_num[i] == 0:
		Q.append(i)
while len(Q) > 0:
	node_id = Q.popleft()
	print('%d' % node_id)
	for adj in G[node_id]:
		in_num[adj] -= 1
		if in_num[adj] == 0:
			Q.append(adj)


from collections import namedtuple
DirectedEdge = namedtuple('DirectedEdge', ('src', 'dest'))

def revert(edge):
	return edge._replace(src=edge.dest, dest=edge.src)

class Digraph:

	def __init__(self, v):
		self.v = v
		self._edges = [[] for _ in range(v)]

	def add(self, edge):
		self._edges[edge.src].append(edge)

	def adj(self, v):
		return self._edges[v]

	def edges(self):
		for es in self._edges:
			for e in es:
				yield e

	def reversed(self):
		g = self.__class__(self.v)
		for e in self.edges():
			g.add(revert(e))
		return g

def sorted_topological(graph):
	return reverse_post(graph)

def reverse_post(graph):

	def visit(v):
		if not visited[v]:
			visited[v] = True
			return True
		else:
			return False

	def leave(v):
		if not left[v]:
			left[v] = True
			vs.append(v)
		return False
	visited = [False] * graph.v
	left = [False] * graph.v
	vs = []
	for i in range(graph.v):
		if not visited[i]:
			stack = [(i, leave)]
			stack.extend(((e.dest, visit) for e in graph.adj(i)))
			while stack:
				(v, f) = stack.pop()
				if f(v):
					stack.append((v, leave))
					for e in graph.adj(v):
						stack.append((e.dest, visit))
	return reversed(vs)

def run():
	(v, e) = [int(i) for i in input().split()]
	g = Digraph(v)
	for _ in range(e):
		(s, t) = [int(i) for i in input().split()]
		g.add(DirectedEdge(s, t))
	for v in sorted_topological(g):
		print(v)
run()


import sys
from collections import deque

def topologicalSort():
	input = sys.stdin.readline
	(V, E) = map(int, input().split())
	Parent_node = [0 for _ in range(V)]
	Son_node = [set() for _ in range(V)]
	for _ in range(E):
		(a, b) = map(int, input().split())
		Son_node[a] |= {b}
		Parent_node[b] += 1
	stack = deque()
	for (i, p) in enumerate(Parent_node):
		if p == 0:
			stack.append(i)
	sortedArray = []
	while stack:
		nowNode = stack.popleft()
		sortedArray.append(nowNode)
		for nextNode in Son_node[nowNode]:
			Parent_node[nextNode] -= 1
			if Parent_node[nextNode] == 0:
				stack.append(nextNode)
	for a in sortedArray:
		print(a)
	return len(sortedArray) == V
topologicalSort()