Problem:
Depth First Search Depth-first search (DFS) follows the strategy to search ”deeper” in the graph whenever possible. In DFS, edges are recursively explored out of the most recently discovered vertex $v$ that still has unexplored edges leaving it. When all of $v$'s edges have been explored, the search ”backtracks” to explore edges leaving the vertex from which $v$ was discovered. This process continues until all the vertices that are reachable from the original source vertex have been discovered. If any undiscovered vertices remain, then one of them is selected as a new source and the search is repeated from that source. DFS timestamps each vertex as follows:  $d[v]$ records when $v$ is first discovered.  $f[v]$ records when the search finishes examining $v$’s adjacency list.  Write a program which reads a directed graph $G = (V, E)$ and demonstrates DFS on the graph based on the following rules:  $G$ is given in an adjacency-list. Vertices are identified by IDs $1, 2,... n$ respectively.  IDs in the adjacency list are arranged in ascending order.  The program should report the discover time and the finish time for each vertex.  When there are several candidates to visit during DFS, the algorithm should select the vertex with the smallest ID.  The timestamp starts with 1.  Input In the first line, an integer $n$ denoting the number of vertices of $G$ is given. In the next $n$ lines, adjacency lists of $u$ are given in the following format: $u$ $k$ $v_1$ $v_2$ ... $v_k$ $u$ is ID of the vertex and $k$ denotes its degree. $v_i$ are IDs of vertices adjacent to $u$. Output For each vertex, print $id$, $d$ and $f$ separated by a space character in a line. $id$ is ID of the vertex, $d$ and $f$ is the discover time and the finish time respectively. Print in order of vertex IDs. Constraints  $1 \leq n \leq 100$  Sample Input 1 4
1 1 2
2 1 4
3 0
4 1 3 Sample Output 1 1 1 8
2 2 7
3 4 5
4 3 6 Sample Input 2 6
1 2 2 3
2 2 3 4
3 1 5
4 1 6
5 1 6
6 0 Sample Output 2 1 1 12
2 2 11
3 3 8
4 9 10
5 4 7
6 5 6   This is example for Sample Input 2 (discover/finish)  Reference Introduction to Algorithms, Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. The MIT Press.

Solution (Python):
n=int(input())
a=[[0 for i in range(n)]for j in range(n)]
for i in range(n):
    v=list(input().split())
    for j in range(len(v)):
        v[j]=int(v[j])
    x=2
    for k in range(v[1]):
        a[i][v[x+k]-1]=1


stack=[]
v=[]
d=[0]*n
f=[0]*n
t=1

while len(v)<n:
    for i in range(n):
        if i+1 not in v:
            stack.append(i+1)
            d[i]=t
            break
        else: pass
        
    while len(stack)!=0:
        for i in range(n):
            if a[stack[-1]-1][i]==1 and stack[-1]-1!=i and i+1 not in v and i+1 not in stack:
                stack.append(i+1)
                t+=1
                d[i]=t
                break
            elif i==n-1:
                t+=1
                f[stack[-1]-1]=t
                v.append(stack.pop())
            else: pass
            
            
            
    t+=1

for i in range(n):
    print(i+1,d[i],f[i])

Solution (Python):
time=1
n=int(input())

A=[[] for i in range(n)]
d=[0 for i in range(n)]
f=[0 for i in range(n)]

for i in range(n):
	a=list(map(int,input().split()))
	for j in range(a[1]):
		A[i].append(a[2+j]-1)

def dfs(q,num):
	global d,f,time
	d[num]=time
	for nx in q[num]:
		if d[nx]==0:
			time+=1
			dfs(q,nx)
	time+=1
	f[num]=time
	
for i in range(n):
	if d[i]==0:
		dfs(A,i)
		time+=1

for i in range(n):
	print(i+1,d[i],f[i])

Solution (Python):
cnt = 1
def dep(G,s_cnt,f_cnt,np):
    global cnt
    s_cnt[np] = cnt
    cnt += 1
    for i in range(n):
        if G[np][i] == 1 and s_cnt[i] == 0:
            dep(G,s_cnt,f_cnt,i)
    f_cnt[np] = cnt
    cnt += 1
    

n = int(input())
G = [[0 for i in range(n)] for j in range(n)]
s_cnt = [0 for i in range(n)]
f_cnt = [0 for i in range(n)]

for i in range(n):
    S = list(map(int, input().split()))
    tmp_n = S[1]
    for j in range(tmp_n):
        G[i][S[j+2]-1] = 1
        
for i in range(n):
    if s_cnt[i]==0:
        dep(G,s_cnt,f_cnt,i)

for i in range(n):
    print(i+1,s_cnt[i],f_cnt[i])

Solution (Python):
def dfs(v, cnt):
    D[v] = cnt
    cnt += 1
    for c in edge[v]:
        if D[c] == -1:
            cnt = dfs(c, cnt)
    F[v] = cnt
    cnt += 1
    return cnt
 
 
V = int(input())
edge = [[] for _ in range(V)]
for _ in range(V):
    u, _, *v = map(lambda x: int(x)-1, input().split())
    edge[u] = sorted(v)
D, F = [-1] * V, [-1] * V
c = 1
for i in range(V):
    if D[i] == -1:
        c = dfs(i, c)
for i, (d, f) in enumerate(zip(D, F)):
    print(i+1, d, f)

Solution (Python):
def d(u):
 global t
 C[u]=1;D[u]=t;t+=1
 for v in M[u]:v=int(v)-1;C[v]or d(v)
 F[u]=t;t+=1
N=int(input());R=range(N)
M=[input().split()[2:]for _ in R]
C,D,F=[0]*N,[0]*N,[0]*N
t=1
for i in R:C[i]or d(i)
for i in R:print(i+1,D[i],F[i])

Solution (Python):

from copy import deepcopy

n = int(input())
c = ["white" for i in range(n)]
d = [0 for i in range(n)]
f = [0 for i in range(n)]
S = []
class DFS:
    def __init__(self, key, color="white",nex=None):
        self.color = color
        self.nex = nex
        self.key = key

objListCopy = [DFS(i+1) for i in range(n)]
for i in range(n):
    data = list(map(int,input().split()))
    times = data[1]
    obj = objListCopy[i]
    for j in range(times):
        index = data[2+j] - 1
        nextobj = DFS(index+1)
        obj.nex = nextobj
        obj = obj.nex


time = 1
objList = objListCopy[:]
def check(first,time):
    obj = objList[first]
    c[first] = "gray"
    d[first] = time
    f[first] = time
    S.append(first+1)
    
    while S != []:
        index = S[-1] - 1
        u = objList[index]
        v = u.nex
        
        time += 1
        if v != None:
            if c[v.key - 1] == "white":
                objList[index] = v
                index = v.key - 1
                v = objList[index]
                c[v.key-1] = "gray"
                d[index] = time
                S.append(v.key)

            else:
                objList[index] = v
                time -= 1
                
        else:
            S.pop()
            c[u.key-1] = "black"
            f[index] = time
    return time


for i in range(n):
    if f[i] == 0:
        objList = deepcopy(objListCopy)
        time = check(i,time) + 1
        

k = 1
for i,j in zip(d,f):
    print(k,i,j)
    k += 1

Solution (Python):

from copy import deepcopy

n = int(input())
c = ["white" for i in range(n)]
d = [0 for i in range(n)]
f = [0 for i in range(n)]
S = []
class DFS:
    def __init__(self, key, color="white",nex=None):
        self.color = color
        self.nex = nex
        self.key = key

objList = [DFS(i+1) for i in range(n)]
for i in range(n):
    data = list(map(int,input().split()))
    times = data[1]
    obj = objList[i]
    for j in range(times):
        index = data[2+j] - 1
        nextobj = DFS(index+1)
        obj.nex = nextobj
        obj = obj.nex


time = 1
def check(first,time):
    obj = objList[first]
    c[first] = "gray"
    d[first] = time
    f[first] = time
    S.append(first+1)
    
    while S != []:
        index = S[-1] - 1
        u = objList[index]
        v = u.nex
    
        if v != None:
            objList[index] = v
            if c[v.key - 1] == "white":
                index = v.key - 1
                v = objList[index]
                c[v.key-1] = "gray"
                time += 1
                d[index] = time
                S.append(v.key)

           
                
        else:
            S.pop()
            c[u.key-1] = "black"
            time += 1
            f[index] = time
    return time


for i in range(n):
    if f[i] == 0:
        time = check(i,time) + 1
        

k = 1
for i,j in zip(d,f):
    print(k,i,j)
    k += 1

Solution (Python):
import sys

global stamp, counter
stamp = {}
counter=0

def dfs(key, GRAPH):
    global stamp, counter
    if stamp[key][0]==0:
        counter += 1
        stamp[key][0] = counter
    elif stamp[key][1] !=0:
        return

    for e in GRAPH[key]:
        try:
            if stamp[e][0] == 0:
                dfs(e, GRAPH)
        except:
            pass
    counter += 1
    stamp[key][1] = counter
    return

n = int(raw_input())
x = {}
for i in range(n):
    seq = map(int,raw_input().split())
    key = seq[0]
    if key != 0:
        x[key] = seq[2:]
    else:
        x[key]=[]
    stamp[key]=[0,0]

for e in x.keys():
    dfs(e, x)

for e in x.keys():
    print e, stamp[e][0],stamp[e][1]

Solution (Python):

from __future__ import division, print_function
from sys import stdin


def walk(index, tm, L, d, f):
    tm += 1
    d[index] = tm
    for i in L[index]:
        if not d[i-1]:
            tm = walk(i-1, tm, L, d, f)
    tm += 1
    f[index] = tm
    return tm


def main():
    num = int(stdin.readline())

    L = []
    for _ in xrange(num):
        L.append([int(s) for s in stdin.readline().split()[2:]])

    d = [0] * num
    f = [0] * num
    tm = 0
    for i in xrange(num):
        if not d[i]:
            tm = walk(i, tm, L, d, f)

    for i in xrange(num):
        print(i+1, d[i], f[i])


main()

Solution (Python):


from __future__ import division,print_function
import time
import sys
import io
import re
import math
start = time.clock()
i = 0
def walk(index,tm,L,d,f):
    tm+=1
    d[index]=tm
    for i in L[index]:
        if not d[i-1]:
            tm=walk(i-1,tm,L,d,f)
    tm+=1
    f[index]=tm
    return tm

def main():
    num=int(sys.stdin.readline())
    L=[]
    for _ in range(num):
        L.append([int(s) for s in sys.stdin.readline().split()[2:]])
    d=[0]*num
    f=[0]*num
    tm=0
    for i in range(num):
        if not d[i]:
            tm=walk(i,tm,L,d,f)
    for i in range(num):
        print(i+1,d[i],f[i])

main()

Solution (Python):
import sys
input = sys.stdin.readline
from collections import deque

n = int(input())
graph = {i: deque() for i in range(1, n+1)}
for _ in range(n):
    u, k, *v = [int(x) for x in input().split()]
    v.sort()
    for i in v:
        graph[u].append(i)
        

seen = [0]*(n+1)
stack = []
time = 0
seentime = [0]*(n+1)
donetime = [0]*(n+1)

def dfs(j):
    global time
    seen[j] = 1
    time += 1
    seentime[j] = time
    stack.append(j)
    while stack:
        s = stack[-1]
        if not graph[s]:
            stack.pop()
            time += 1
            donetime[s] = time
            continue
        g_NO  = graph[s].popleft()
        if seen[g_NO]:
            continue
        seen[g_NO] = 1
        stack.append(g_NO)
        time += 1
        seentime[g_NO] = time

for j in range(1, n+1):
    if seen[j]:
        continue
    dfs(j)

for k, a, b in zip(range(1, n+1), seentime[1:], donetime[1:]):
    print(k, a, b)

Solution (Python):
from sys import stdin
input = stdin.readline

def DFS(node):
    global time
    if discoveredtime[node] == -1:
        discoveredtime[node] = time
        time += 1

        for child in childlist[node]:
            DFS(child)
        
        finishedtime[node] = time
        time += 1

N = int(input())

childlist = [None]*(N+1)
for _ in range(N):
    u, k, *v = map(int, input().split())
    childlist[u] = v

discoveredtime = [-1]*(N+1)
finishedtime = [-1]*(N+1)
time = 1

for i in range(1, N+1):
    if discoveredtime[i] == -1:
        DFS(i)

for i in range(1, N+1):
    print(i, discoveredtime[i], finishedtime[i])

Solution (Python):
N = int(input())
DG = {}
node_ls = []
is_visited = {}

for _ in range(N):
    tmp = input().split()
    node_id = tmp[0]
    node_ls.append(node_id)
    is_visited[node_id] = False
    adj_num = int(tmp[1])
    if adj_num != 0:
        DG[node_id] = tmp[2:]
    else:
        DG[node_id] = []


d = {}
f = {}
t = 1

def dfs(node):
    global t
    
    if is_visited[node]:
        return

    is_visited[node] = True
    d[node] = t
    t += 1
    for no in DG[node]:
        dfs(no)
    f[node] = t
    t += 1

for node in node_ls:
    dfs(node)


for node in node_ls:
    print(node, d[node], f[node])

Solution (Python):
n = int(input())
graph = {}

for i in range(1, n + 1):
    data = input().split()
    graph[i] = [int(i) for i in data[2:]]


class dfs:
    def __init__(self, graph):
        self.g = graph
        self.visited = set()
        self.time = 0
        self.res = {}

    def dfs(self, cur):
        self.visited.add(cur)
        self.time += 1
        start = self.time
        for node in self.g[cur]:
            if node not in self.visited:
                self.dfs(node)
        self.time += 1
        end = self.time
        self.res[cur] = (start, end)


solver = dfs(graph)
for i in range(1, n + 1):
    if i not in solver.visited:
        solver.dfs(i)

for i in range(1, n + 1):
    print(i, solver.res[i][0], solver.res[i][1])

Solution (Python):
def dfs(i,cnt):
    d[i] = cnt
    cnt += 1
    for j in edge[i]:
        if d[j] == -1:
            cnt = dfs(j,cnt)
    f[i] = cnt
    cnt += 1
    return cnt

n = int(input())
edge = [[] for i in range(n)]
for not_used in range(n):
    of_children, not_used, *v = map(lambda x: int(x)-1,input().split())
    edge[of_children] = sorted(v)
c = 1
d = [-1]*n
f = [-1]*n

for i in range(n):
    if d[i] == -1:
        c = dfs(i,c)
for i ,(d,f) in enumerate(zip(d,f)):
    print(i+1,d,f)

Solution (Python):
import sys
input = sys.stdin.readline

from collections import deque

S = deque([])

def getNeighbor(A, i):
    a = len(A)
    for k in range(2, a):
        M[i][A[k]-1] = 1


def dfs(u):
    global t
    t = t + 1
    S.append(u)
    c[u] = 1
    d[u] = t

    for v in range(n):
        if M[u][v] and c[v] == 0:
            dfs(v)
    c[u] = 2
    t += 1
    f[u] = t


n = int(input())

c = [0] * n
d = [0] * n
f = [0] * n

M = [[0] * n for _ in range(n)]
t = 0

for i in range(n):
    A = list(map(int, input().split()))
    getNeighbor(A,i)

for num in range(n):
    if d[num] == 0:
        dfs(num)

for i in range(n):
    print(str(i+1), str(d[i]), str(f[i]))

Solution (Python):
n = int(input())
adjacency_list = []
for i in range(n):
    input_list = list(map(int, input().split()))
    adjacency_list.append(input_list[2:])
checked_set = set()
dfs_stack = []
v =[0 for i in range(n)]
f =[0 for i in range(n)]
time = 1
for i in range(n):
    if i not in checked_set:
        dfs_stack = []
        dfs_stack.append(i)
        while dfs_stack:
            current = dfs_stack.pop()
            if current not in checked_set:
                checked_set.add(current)
                v[current] = time
                dfs_stack.append(current)
                for ad in reversed(adjacency_list[current]):
                    if ad-1 not in checked_set:
                        dfs_stack.append(ad-1)
                time +=1
            elif f[current] == 0:
                f[current] = time
                time +=1
for i in range(n):
    print(f'{i+1} {v[i]} {f[i]}')

Solution (Python):
N=int(input())
L=[[10**9]for i in range(N+1)]
for i in range(N):
    l=list(map(int,input().split()))
    for j in range(l[1]):
        L[i+1].append(l[2+j])

for i in range(N+1):
    L[i].sort(reverse=True)
    

ans=[]
for i in range(N+1):
    ans.append([0,0])


from collections import deque 

Q=deque()
cnt=1
for i in range(N):
    Q.append([0,N-i])
for i in range(10**7):

    if len(Q)==0:
        break
    q0,q1=Q.pop()
    
    if q1!=10**9:
        if ans[q1][0]==0:
            ans[q1][0]=cnt
            cnt+=1
            for j in L[q1]:
                Q.append([q1,j])
    else:
        ans[q0][1]=cnt
        cnt+=1
    
for i in range(1,N+1):
    print(i,ans[i][0],ans[i][1])

Solution (Python):
d_num = int(input())

graph = [[] for _ in range(d_num+1)]
for _ in range(d_num):
    u, k, *neighbors = map(int, input().split())
    graph[u] = neighbors

visited = set()
timestamps = [None for _ in range(d_num+1)]

def dfs(u, stmp):
    visited.add(u)
    entry = stmp

    stmp += 1
    for v in graph[u]:
        if v not in visited:
            stmp = dfs(v, stmp)

    timestamps[u] = entry, stmp
    return stmp+1

stmp = 1
for v in range(1, d_num+1):
    if v not in visited:
        stmp = dfs(v, stmp)

for num, (entry, leave) in enumerate(timestamps[1:], 1):
    print(num, entry, leave)

Solution (Python):
from sys import stdin
input = stdin.readline

N = 100
WHITE = 0 
GRAY = 1 
BLACK = 2 

M = [[0]*N for _ in range(N)] 
color = [WHITE]*N  
d = [0]*N 
f = [0]*N 

def dfs_visit(u): 
    global tt
    color[u] = GRAY
    tt += 1
    d[u] = tt 
    for v in range(n):
        if M[u][v] == 0:
            continue
        if color[v] == WHITE: 
            dfs_visit(v)
    color[u] = BLACK 
    tt += 1
    f[u] = tt 

def dfs():
    global tt
    tt = 0

    for u in range(n):
        if color[u] == WHITE: 
            dfs_visit(u)
    for u in range(n): 
        print(str(u+1) + ' ' + str(d[u]) + ' ' + str(f[u]))

n = int(input())
for _ in range(n): 
    u, k, *vv = input().split()
    u = int(u)-1  
    k = int(k)    
    for v in vv:
        v = int(v)-1
        M[u][v] = 1
dfs()

Solution (Python):
import sys, os, math, bisect, itertools, collections, heapq, queue, copy, array





sys.setrecursionlimit(10000000)

ii = lambda: int(sys.stdin.buffer.readline().rstrip())
il = lambda: list(map(int, sys.stdin.buffer.readline().split()))
fl = lambda: list(map(float, sys.stdin.buffer.readline().split()))
iln = lambda n: [int(sys.stdin.buffer.readline().rstrip()) for _ in range(n)]

iss = lambda: sys.stdin.buffer.readline().decode().rstrip()
sl = lambda: list(map(str, sys.stdin.buffer.readline().decode().split()))
isn = lambda n: [sys.stdin.buffer.readline().decode().rstrip() for _ in range(n)]

lcm = lambda x, y: (x * y) // math.gcd(x, y)

MOD = 10 ** 9 + 7
MAX = float('inf')


def dfs(start, graph, visited, time):
    visited[start][0] = time
    for next in range(len(graph[start])):
        if not graph[start][next]: continue
        if visited[next][0] != -1: continue
        time += 1
        time = dfs(next, graph, visited, time)
    else:
        time += 1
        visited[start][1] = time
    return time


def main():
    if os.getenv("LOCAL"):
        sys.stdin = open("input.txt", "r")

    N = ii()
    G = [[False] * N for _ in range(N)]
    visited = [[-1, -1] for _ in range(N)]

    for n in range(N):
        u, k, *V = il()
        for v in V:
            G[n][v - 1] = True

    time = 0
    for n in range(N):
        if visited[n][0] != -1: continue
        time += 1
        time = dfs(n, G, visited, time)
    for n in range(N):
        print(n + 1, *visited[n])


if __name__ == '__main__':
    main()

Solution (Python):


n = int(input())
G = {}
for _ in range(n):
    g = list(map(int, input().split()))
    G[g[0]] = g[2:]


seen = [False for _ in range(n)]
ans = []


def dfs(v: int) -> None:
    seen[v - 1] = True
    ans.append(v)

    for w in G[v]:
        if not seen[w - 1]:
            dfs(w)

    ans.append(v)


while sum(seen) != n:
    v = seen.index(False)
    dfs(v + 1)

d = [-1 for _ in range(n)]
f = [-1 for _ in range(n)]

for i, a in enumerate(ans):
    if d[a - 1] == -1:
        d[a - 1] = i + 1
    else:
        f[a - 1] = i + 1

for id in range(n):
    print(id + 1, d[id], f[id])

Solution (Python):


import sys
sys.setrecursionlimit(1000000)

N=int(input())
G=[list(map(int, input().split()))[2:] for _ in range(N)]

v=[False]*N
d=[0]*N
f=[0]*N
timecount=1

def dfs(i):
    global timecount
    if v[i] : return
    v[i] = True
    d[i] = timecount
    
    timecount += 1
    for p in G[i]:
        dfs(p-1)
    
    f[i] = timecount
    timecount += 1
    return

for i in range(N):
  if v[i]==0: dfs(i)

for i in range(N):
    print(i+1, d[i], f[i])

Solution (Python):
from collections import deque

N = int(input())
graph = [deque([]) for _ in range((N + 1))]
for _ in range(N):
    u, k, *v = [int(x) for x in input().split()]
    v.sort()
    for i in v:
        graph[u].append(i)
        
time = 0
arrive_time = [-1] * (N + 1)
finish_time = [-1] * (N + 1)

def dfs(v):
    global time
    time += 1
    stack = [v]
    arrive_time[v] = time
    while stack:
        v = stack[-1]
        if graph[v]:
            w = graph[v].popleft()
            if arrive_time[w] < 0:
                time += 1
                arrive_time[w] = time
                stack.append(w)
        else:
            time += 1
            finish_time[v] = time
            stack.pop()
    return [arrive_time, finish_time]
    
for i in range(N):
    if arrive_time[i + 1] < 0:
        ans = dfs(i + 1)
        
for j in range(N):
    temp = [j + 1, ans[0][j + 1], ans[1][j + 1]]
    print(*temp)

Solution (Python):
import sys

sys.setrecursionlimit(10 ** 8)
n = int(input())

graph = [[] for _ in range(n)]
for i in range(n):
    graph[i] = list(map(lambda x: x - 1, list(map(int, input().split()))[2:]))

timestamp = [[] for _ in range(n)]
visited = [False] * n
cnt = 0


def dfs(v):
    global visited
    global cnt
    global timestamp
    cnt += 1
    timestamp[v].append(cnt)
    visited[v] = True
    for to in graph[v]:
        if visited[to]:
            continue
        else:
            dfs(to)
    cnt += 1
    timestamp[v].append(cnt)


dfs(0)

while False in visited:
    nxt = visited.index(False)
    dfs(nxt)


for i, (d, f) in enumerate(timestamp, 1):
    print(i, d, f)

Solution (Python):
n = int(input())

class Node:
    def __init__(self, idd, neighbors):
        self.idd = idd
        self.neighbors = neighbors
        self.foundAt = 0
        self.completeAt = 0
        
    def __repr__(self):
        return "{0} {1} {2}".format(self.idd, self.foundAt, self.completeAt)

Nodes = [None] * n
for i in range(n):
    row = [int(tt) for tt in input().split()]
    Nodes[row[0]-1] = Node(row[0], [ row[j + 2] for j in range(row[1])])
        
def depthSearch(Nodes):
    stack = [Nodes[0]]
    
    time = 2
    current = stack[-1]
    current.foundAt = 1
    while len(stack) > 0 or any([node.foundAt==0 for node in Nodes]):
        if(len(stack)==0):
            newStart = [node for node in Nodes if node.foundAt==0][0]
            newStart.foundAt = time
            stack.append(newStart)
            time += 1
        current = stack[-1]
        if(len(current.neighbors) > 0):
            next_n = Nodes[current.neighbors.pop(0)-1]
            if(next_n.foundAt != 0):
                continue
            next_n.foundAt = time
            stack.append(next_n)
        else:
            current.completeAt = time
            stack.pop(-1)
        time += 1
    return Nodes
Nodes = depthSearch(Nodes)
for node in Nodes:
    print(node)

Solution (Python):
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10**7)

N = int(input())
G = [list(map(lambda x: int(x)-1, input().split()))[2:] for _ in range(N)]
D = [-1]*N
D2 = [-1]*N
def dfs(cur, now):
    if D[cur] != -1: return now
    now += 1
    D[cur] = now
    for nex in G[cur]:
        now = dfs(nex,now)
    now += 1
    D2[cur] = now
    return now
now = 0
for i in range(N):
    now = dfs(i,now)
for i in range(N):
    print(i+1,D[i],D2[i])

Solution (Python):

import itertools
import math
import bisect

class Node:
    def __init__(self, id, next, rest):
        self.id = id
        self.before = None
        self.next = next
        self.rest = rest
        self.d = None
        self.f = None

    def update_next(self):
        self.next = first(self.rest)
        self.rest = rest(self.rest)


N = int(input())
graph = []
for _ in range(N):
    l = list(map(int, input().split(" ")))
    id = l[0]
    if l[1] != 0:
        next = l[2]
    else:
        next = None
    if l[1] >= 2:
        rest = l[3:]
    else:
        rest = []
    graph.append(Node(l[0], next, rest))

def first(l):
    if l==None:
        return None
    if len(l) == 0:
        return None
    else:
        return l[0]

def rest(l):
    if l == None:
        return None
    if len(l) >= 2:
        return l[1:]
    else:
        return None

def dfs(graph):
    stack = [graph[0]]
    stack[-1].d = 1
    tansakuzumi = [1]
    mitansaku = list(range(1, len(graph)+1))
    res_graph = []
    t = 2
    while len(stack) != 0:
        tansakuzumi.append(stack[-1].id)
        if stack[-1].id in mitansaku:
            mitansaku.remove(stack[-1].id)
        if stack[-1].next == None:
            stack[-1].f = t
            res_graph.append(stack.pop())
            t += 1
        elif stack[-1].next in tansakuzumi:
            stack[-1].update_next()
        else:
            stack.append(graph[stack[-1].next-1])
            stack[-2].update_next()
            stack[-1].d = t
            t += 1
        if len(stack) == 0 and len(mitansaku) >= 1:
            stack.append(graph[mitansaku[0]-1])
            stack[-1].d = t
            t += 1
    return res_graph




res_graph = dfs(graph)

res_graph.sort(key=lambda x: x.id)

for n in res_graph:
    print("{} {} {}".format(n.id, n.d, n.f))

Solution (Python):



n = int(input())
M = []
for i in range(n):
    adj = list(map(int,input().split()))
    if adj[1] == 0:
        M += [[]]
    else:
        M += [adj[2:]]
time = 1
ans = [[j+1,0,0] for j in range(n)] 

while True:
    for i in range(n):
        if ans[i][1] == 0:
            stack = [i]
            ans[i][1] = time
            time += 1
            break
        elif i == n-1:
            for k in range(n):
                print(*ans[k])
            exit()
    while stack != []:
        u = stack[-1]
        if M[u] != []:
            for i in range(len(M[u])):
                v = M[u][0]
                M[u].remove(v)
                if ans[v-1][1] == 0:
                    ans[v-1][1] = time
                    stack.append(v-1)
                    time += 1
                    break
        else:
            stack.pop()
            ans[u][2] = time
            time += 1

Solution (Python):
n = int(input())
Adj = [[0]]
for _ in range(n):
    Adj.append(list(map(int, input().split()))[2:])

visited = [False]*(n+1)
s = [0]*(n+1)
f = [0]*(n+1)
time = 0

def dfs(i):
    global time
    time += 1
    s[i] = time
    visited[i] = True
    for j in Adj[i]:
        if not visited[j]:
            dfs(j)
    time += 1
    f[i] = time

while not all(visited[1:]):
    i = visited[1:].index(False) + 1
    dfs(i)

for i in range(1, n+1):
    print(i,s[i], f[i])

Solution (Python):
n = int(input())
G = {i:[] for i in range(1, n+1)}
for _ in range(n):
    ukv = list(map(int, input().split()))
    u = ukv[0]
    k = ukv[1]
    for i in range(2, 2+k):
        G[u].append(ukv[i])
        
d = [-1 for _ in range(n+1)]
f = [-1 for _ in range(n+1)]
counter = 0

def dfs(n):
    global counter
    counter += 1
    d[n] = counter
    
    for n_i in G[n]:
        if d[n_i]==-1:
            dfs(n_i)
            
    counter += 1
    f[n] = counter

for i in range(1, n+1):
    if d[i]==-1:
        dfs(i)

for id_i, (d_i, f_i) in enumerate(zip(d[1:], f[1:]), 1):
    print(id_i, d_i, f_i)

Solution (Python):
N = int(input())

Graph = {}
Node_list = []
visited = {}
d = {}
f = {}
t = 1

for i in range(N):
    
    tmp = input().split()
    id = tmp[0]
    Node_list.append(id)
    visited[id] = False

    if int(tmp[1]) != 0:
        Graph[id] = tmp[2:]
    else:
        Graph[id] = []
 


def dfs(node):
    global t

    if visited[node]:
        return

    visited[node] = True

    d[node] = t
    t += 1

    for no in Graph[node]:
        dfs(no)

    f[node] = t
    t += 1

for node in Node_list:
    dfs(node)

for node in Node_list:
    print(node, d[node], f[node])

Solution (Python):
global graph
global seen
token=0

def dfs(i):
    global token
    token+=1
    seen[i][0]=token
    for x in graph[i]:
        if seen[x][0]==0:
            dfs(x)
    token+=1
    seen[i][1]=token


n=int(input())

graph=[None for _ in range(n+1)]

for i in range(n):
    lst=list(map(int,input().split()))
    graph[lst[0]]=lst[2:]

seen=[[0,0] for _ in range(n+1)]

for i in range(1,n+1):
    if seen[i][0]==0:
        dfs(i)

for i in range(1,n+1):
    print("{} {} {}".format(i,seen[i][0],seen[i][1]))

Solution (Python):
from collections import defaultdict

def dfs(edges, n, d, f, time):
    if n in d:
        return
    time[0] += 1
    d[n] = time[0]
    for to in edges[n]:
        dfs(edges, to, d, f, time)
    time[0] += 1
    f[n] = time[0]

N = int(input())

edges = defaultdict(list)

for _ in range(N):
    l = list(map(int, input().split()))
    fr = l[0]
    degree = l[1]
    edges[fr] = l[2:]

d = {} 
f = {} 

time = [0]
for n in range(1, N+1):
    dfs(edges, n, d, f, time)

for n in range(1, N+1):
    print('%d %d %d' % (n, d[n], f[n]))

Solution (Python):
import sys
from collections import defaultdict


time = 1


def dfs(g, visited, start, ans):
    global time
    visited[start - 1] = True
    ans[start - 1][0] = time
    for e in g[start]:
        if not visited[e - 1]:
            time += 1
            dfs(g, visited, e, ans)
    time += 1
    ans[start - 1][1] = time


def main():
    input = sys.stdin.buffer.readline
    n = int(input())
    g = defaultdict(list)
    for i in range(n):
        line = list(map(int, input().split()))
        if line[1] > 0:
            g[line[0]] = line[2:]
    visited = [False] * n

    ans = [[1, 1] for _ in range(n)]
    global time
    while False in visited:
        start = visited.index(False) + 1
        dfs(g, visited, start, ans)
        time += 1

    for i in range(1, n + 1):
        print(i, *ans[i - 1])


if __name__ == "__main__":
    main()

Solution (Python):
n=int(input())
edge=[[] for _ in range(n+1)]
for i in range(n):
  v,k,*u=list(map(int,input().split()))
  edge[v]=u
d=[0]*(n+1)
f=[0]*(n+1)
def dfs(now,t):
  d[now]=t
  vis.append(now)
  for i in edge[now]:
    if i not in vis:
      t=dfs(i,t+1)
  f[now]=t+1
  return t+1
vis=[]
t=1
for i in range(1,n+1):
  if i not in vis:
    t=dfs(i,t)+1
for i in range(1,n+1):
  print(i,d[i],f[i])

Solution (Python):
stack=[]
n=int(input())
color=[]
graph={}
d_time=[]
f_time=[]
time=0
root=[i for i in range(1,n+1)]

for i in range(n):
    tmp=list(map(int,input().split()))
    graph[tmp[0]]=[0 for j in range(n+1)]
    color=["white" for l in range(n+1)]
    d_time=[0 for j in range(n+1)]
    f_time=[0 for j in range(n+1)]
    for k in range(tmp[1]):
        graph[tmp[0]][tmp[2+k]]=1
        if tmp[2+k] in root:
            root.remove(tmp[2+k])

def function(number):
    global time
    stack.append(number)
    color[number]="gray"
    time+=1
    d_time[number]=time
    while stack!=[]:
        u=stack[-1]
        if 1 in graph[u]:
            v=graph[u].index(1)
            graph[u][v]=0
            if color[v]=="white":
                color[v]="gray"
                time+=1
                d_time[v]=time
                stack.append(v)
        else:
            stack.pop()
            color[u]="black"
            time+=1
            f_time[u]=time

if root==[]:
    function(1)
else:
    for i in range(len(root)):
        function(root[i])

for i in range(1,n+1):
    print(i,d_time[i],f_time[i])

Solution (Python):
from collections import defaultdict as dd

N = int(input())
graph = dd(list)
seen = dd(int)
u = []
d, f = dd(int), dd(int)
ts = 1
for _ in range(N):
  info = list(map(int, input().split()))
  u.append(info[0])
  graph[info[0]] = info[2:]

def dfs(v):
  global ts
  d[v] = ts
  ts += 1
  
  seen[v] = 1
  for next_v in graph[v]:
    if seen[next_v]:
      continue
    dfs(next_v)
  
  f[v] = ts
  ts += 1

for key in u:
  if seen[key]:
    continue
  dfs(key)

for id in u:
  print("{} {} {}".format(id, d[id], f[id]))