Problem:
Topological Sort   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. 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). 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$  Sample Input 6 6
0 1
1 2
3 1
3 4
4 5
5 2 Sample Output 0
3
1
4
5
2

Solution (Python):

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



"""
from heapq import heappush, heappop
def dijkstra(num, start):
    dist = [float("inf") for i in range(num)]
    dist[start] = 0
    q = [[dist[start], start]]
    while q:
        du, u = heappop(q)
        for j, k in adj[u]:
            if dist[j] > du + k:
                dist[j] = du + k
                heappush(q, [dist[j], j])
                print(dist, q)
    return dist

v,e,r = map(int, input().split(" "))
adj = [[] for i in range(v)]
for i in range(e):
    s,t,d = map(int, input().split(" "))
    adj[s].append([t, d])
lis = dijkstra(v, r)
print(lis)
for i in lis:
    print(str(i).upper())
"""


"""
def bellman_ford(num, start):
    dist = [float("inf") for i in range(num)]
    dist[start] = 0
    for i in range(num):
        update = False
        for j, k, l in adj:
                if dist[k] > dist[j] + l:
                    dist[k] = dist[j] + l
                    update = True
                    if i == num-1:
                        return False
        if not update:
            break
    return dist

v,e,r = map(int, input().split(" "))
adj = []
for i in range(e):
    s,t,d = map(int, input().split(" "))
    adj.append([s, t, d])
lis = bellman_ford(v, r)
if not lis:
    print("NEGATIVE CYCLE")
else:
    for i in lis:
        print(str(i).upper())
"""


"""
def warshallfloyd(n):
    for i in range(n):
        for j in range(n):
            for k in range(n):
                d[j][k] = min(d[j][k], d[j][i]+d[i][k])
v,e = map(int, input().split())
d = [[float("inf") for j in range(v)] for i in range(v)]
for i in range(v):
    d[i][i] = 0
for i in range(e):
    s, t, c = map(int, input().split())
    d[s][t] = c
warshallfloyd(v)
for i in range(v):
    if d[i][i] < 0:
        print("NEGATIVE CYCLE")
        quit()
for i in d:
    for j in range(v):
        if j < v-1:
            print(str(i[j]).upper(), end = " ")
        else:
            print(str(i[j]).upper())
"""



"""
def root(x):
    if par[x] == x:
        return x
    par[x] = root(par[x])
    return par[x]

def same(x,y):
    return root(x) == root(y)

def unite(x,y):
    x = root(x)
    y = root(y)
    if rank[x] < rank[y]:
        par[x] = y
    else:
        par[y] = x
        if rank[x] == rank[y]:
            rank[x] += 1
v,e = LI()
c = LIR(e)
c.sort(key = lambda x:x[2])
par = [i for i in range(v)]
rank = [0 for i in range(v)]
k = 0
ans = 0
for a,b,w in c:
    if not same(a,b):
        k += 1
        unite(a,b)
        ans += w
    if k == v-1:
        break
print(ans)
"""


"""
def root(x):
    if par[x] == x:
        return x
    par[x] = root(par[x])
    return par[x]

def same(x,y):
    return root(x) == root(y)

def unite(x,y):
    x = root(x)
    y = root(y)
    if rank(x) < rank(y):
        par[x] = y
    else:
        par[y] = x
        if rank(x) == rank(y):
            rank[x] += 1
"""











"""
def bellman_ford(num, start):
    dist = [float("inf") for i in range(num)]
    dist[start] = 0
    for i in range(num):
        update = False
        for j, k, l in adj:
            if dist[k] > dist[j] + l:
                dist[k] = dist[j] + l
                update = True
                if i == num-1:
                    return False
        if not update:
            break
    return True

v, e = map(int, input().split(" "))
adj = []
for i in range(e):
    s,t = map(int, input().split(" "))
    adj.append([s, t, -1])
for i in range(v):
    if not bellman_ford(v,i):
        print(1)
        quit()
print(0)
"""


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 heapq import heappush, heappop
def dijkstra(num, start):
    dist = [float("inf") for i in range(num)]
    dist[start]  = 0
    q = [[dist[start], start]]
    while q:
        du, u = heappop(q)
        for j, k in adj[u]:
            if dist[j] > du + k:
                dist[j] = du + k
                heappush(q, [dist[j], j])
    return dist

n = II()
adj = [[] for i in range(n)]
for i in range(n-1):
    s,t,w = LI()
    adj[s].append([t, w])
    adj[t].append([s, w])
d = dijkstra(n,0)
i = d.index(max(d))
d2 = dijkstra(n,i)
print(max(d2))
"""


"""
from heapq import heappush, heappop
def dijkstra(num, start):
    dist = [float("inf") for i in range(num)]
    dist[start]  = 0
    q = [[dist[start], start]]
    while q:
        du, u = heappop(q)
        for j, k in adj[u]:
            if dist[j] > du + k:
                dist[j] = du + k
                heappush(q, [dist[j], j])
    return dist

n = int(input())
adj = [[] for i in range(n)]
for i in range(n-1):
    s, t, w = map(int, input().split(" "))
    adj[s].append([t, w])
    adj[t].append([s, w])
for i in range(n):
    s = dijkstra(n,i)
    print(max(s))
"""









"""
def bfs(s,g,n):
    bfs_map = [-1 for i in range(n)]
    bfs_map[s] = 0
    q = deque()
    q.append(s)
    fin = False
    while q:
        x = q.popleft()
        for y in range(n):
            if c[x][y] > 0 and bfs_map[y] < 0:
                bfs_map[y] = bfs_map[x]+1
                if y == g:
                    fin = True
                    break
                q.append(y)
        if fin:
            break

    if bfs_map[g] == -1:
        return [None,0]
    path = [None for i in range(bfs_map[g]+1)]
    m = float("inf")
    path[bfs_map[g]] = g
    y = g
    for i in range(bfs_map[g])[::-1]:
        for x in range(n+1):
            if c[x][y] > 0 and bfs_map[x] == bfs_map[y]-1:
                path[i] = x
                if c[x][y] < m:
                    m = c[x][y]
                y = x
                break
    return [path,m]

def ford_fulkerson(s,g,c,n):
    while 1:
        p,m = bfs(s,g,n)
        if not m:break
        for i in range(len(p)-1):
            c[p[i]][p[i+1]] -= m
            c[p[i+1]][p[i]] += m
    return sum(c[g])

n,e = LI()
c = [[0 for i in range(n)] for j in range(n)]
for i in range(e):
    a,b,w = LI()
    if a != n-1:
        c[a][b] = w
print(ford_fulkerson(0,n-1,c,n))
"""





"""
def bfs(s,g,n):
    bfs_map = [-1 for i in range(n)]
    bfs_map[s] = 0
    q = deque()
    q.append(s)
    fin = False
    while q:
        x = q.popleft()
        for y in range(n):
            if c[x][y] > 0 and bfs_map[y] < 0:
                bfs_map[y] = bfs_map[x]+1
                if y == g:
                    fin = True
                    break
                q.append(y)
        if fin:
            break

    if bfs_map[g] == -1:
        return [None,0]
    path = [None for i in range(bfs_map[g]+1)]
    m = float("inf")
    path[bfs_map[g]] = g
    y = g
    for i in range(bfs_map[g])[::-1]:
        for x in range(n+1):
            if c[x][y] > 0 and bfs_map[x] == bfs_map[y]-1:
                path[i] = x
                if c[x][y] < m:
                    m = c[x][y]
                y = x
                break
    return [path,m]

def ford_fulkerson(s,g,c,n):
    while 1:
        p,m = bfs(s,g,n)
        if not m:break
        for i in range(len(p)-1):
            c[p[i]][p[i+1]] -= m
            c[p[i+1]][p[i]] += m
    return sum(c[g])

x,y,e = LI()
c = [[0 for i in range(x+y+2)] for j in range(x+y+2)]
for i in range(x):
    c[0][i+1] = 1
for i in range(y):
    c[x+i+1][x+y+1] = 1
for i in range(e):
    a,b = LI()
    c[a+1][x+b+1] = 1
print(ford_fulkerson(0,x+y+1,c,x+y+2))
"""

Solution (Python):
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])

Solution (Python):
import sys

sys.setrecursionlimit(int(1e6))

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())

Solution (Python):
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)

Solution (Python):
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)

Solution (Python):
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]


if __name__ == '__main__':
    main()

Solution (Python):
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 = 0.000000001


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)

Solution (Python):
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)


if __name__ == '__main__':
    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)