Go: package main

import "fmt"

type node struct {
	id, d, v int
	adj      []node
}

var n int
var seen []bool
var graph []node

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func dfs(v, t int) int {
	// fmt.Printf("dfs(v %d, t %d) en:\n", v, t)
	seen[v] = true
	graph[v].v = t
	tt := t
	for _, vv := range graph[v].adj {
		if !seen[vv.id] {
			tt = max(tt, dfs(vv.id, tt+1))
		}
	}
	graph[v].d = tt + 1
	// fmt.Printf("dfs(v %d, t %d) ex: d %d\n", v, t, graph[v].d)
	return graph[v].d
}

func main() {
	fmt.Scan(&n)
	graph = make([]node, n+1)
	for i := 1; i <= n; i++ {
		var u, k, v int
		fmt.Scan(&u, &k)
		graph[u].id = u
		// 頂点uはk個の隣接頂点を持っている
		for j := 0; j < k; j++ {
			fmt.Scan(&v)
			var t node
			t.id = v
			graph[u].adj = append(graph[u].adj, t)
		}
	}
	// fmt.Println("n", n, "graph", graph)
	seen = make([]bool, n+1)
	// t := dfs(1, 1)
	v, t := 1, 1
	done := false
	for !done {
		tt := dfs(v, t)
		done = true
		for i := range seen {
			if !seen[i] {
				done = false
				v = graph[i].id
				t = tt
				break
			}
		}
	}
	for i := 1; i <= n; i++ {
		fmt.Printf("%d %d %d\n", i, graph[i].v, graph[i].d)
	}
}

Python: from sys import stdin
input = stdin.readline

N = 100
WHITE = 0 # 未訪問
GRAY = 1 # 訪問したが、スタックに残っている
BLACK = 2 # 訪問完了済み

M = [[0]*N for _ in range(N)] # n*nの隣接行列の作成
color = [WHITE]*N  # colorの初期化
d = [0]*N # 最初の訪問時刻のタイムスタンプ
f = [0]*N # 完了時刻のタイムスタンプ

def dfs_visit(u): # 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 # uに関する全ての深さを探索しきった処理
    tt += 1
    f[u] = tt # 訪問の完了

def dfs():
    global tt
    tt = 0

    for u in range(n):
        if color[u] == WHITE: # 未訪問のuを始点にする
            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  # 0オリジンにする
    k = int(k)    # kは使わない
    for v in vv:
        v = int(v)-1
        M[u][v] = 1
dfs()

Python: def dfs(v, k):
    if ans[v][1] == 0:
        ans[v][1] = k
    else:
        return k - 1
    for i in d[v]:
        k = dfs(i, k + 1)
    k += 1
    if ans[v][2] == 0:
        ans[v][2] = k
    return k


G = int(input())
vlst = [list(map(int, input().split())) for _ in range(G)]
d = [[] for _ in range(G)]
for i in range(G):
    for j in range(vlst[i][1]):
        d[i].append(vlst[i][2 + j] - 1)
ans = [[_, 0, 0] for _ in range(G)]
k = 1
for i in range(G):
    k = dfs(i, k) + 1
for i in ans:
    print(i[0] + 1, i[1], i[2])

Python: from collections import defaultdict


n = int(input())
rel = defaultdict(set)

times = {}
for _ in range(n):
    rl = list(map(int, input().split()))
    p, ts = rl[0], rl[2:]
    rel[p] = sorted(ts, reverse=True)
    times[p] = {'first': 0, 'last': 0}

t = 0

for f in range(1, len(rel)+1):
    if times[f]['last']:
        continue
    stack = [f]
    while stack:
        u = stack[-1]
        if times[u]['first']:
            if not times[u]['last']:
                t += 1
                times[u]['last'] = t
            stack.pop()
            continue
        t += 1
        times[u]['first'] = t
        for v in rel[u]:
            if not times[v]['first']:
                stack.append(v)

for k in sorted(times):
    print(k, times[k]['first'], times[k]['last'])

Python: import sys
sys.setrecursionlimit(10000000)
MOD = 10 ** 9 + 7
INF = 10 ** 15

G = [[] for _ in range(105)]
begin = [-1] * 105
end = [-1] * 105

t = 1
def dfs(v):
    global t
    begin[v] = t
    t += 1
    for e in G[v]:
        if begin[e] < 0:
            dfs(e)
    end[v] = t
    t += 1

def main():
    N = int(input())
    for i in range(N):
        A = list(map(int,input().split()))
        for a in A[2:]:
            G[i].append(a - 1)
    
    for i in range(N):
        if begin[i] < 0:
            dfs(i)
    for i in range(N):
        print(i + 1,begin[i],end[i])
if __name__ == '__main__':
    main()

Python: 
#kadai11b Depth First Search

n=int(input())
t=1
a=[[0 for i in range(n)]for j in range(n)]
t1=[0 for i in range(n)]
t2=[0 for i in range(n)]
s=[]
c=[]
s.append(0)
t1[0]=t
t+=1
for i in range(n):
    p=[int(x) for x in input().split()]
    for j in range(n):
        if j+1 in p[2:]:
            a[i][j]=1

i=0
while len(c)!=n:
    if 1 not in a[i][0:]:
        if i not in c:
            t2[i]=t
            t+=1
            c.append(i)
            del s[-1]
            if len(s)>0:
                i=s[-1]
    for j in range(n):
        if a[i][j]==1:
            a[i][j]=0
            if j not in c:
                s.append(j)
                i=j
                t1[i]=t
                t+=1
            break

for i in range(n):
    print(i+1,t1[i],t2[i])

"""実行結果
6
1 2 2 3
2 2 3 4
3 1 5
4 1 6
5 1 6
6 0
1 1 12
2 2 11
3 3 8
4 9 10
5 4 7
6 5 6
"""

Python: import sys
n = int(input())
input_line = [[int(i) for i in str.split()] for str in sys.stdin.read().splitlines()]
for i in range(n):
    input_line[i] = [] if len(input_line[i]) == 2 else input_line[i][2:]
detect_time = [0] * n
finish_time = [0] * n
is_visit = [False] * n
stack = []
time = 0

while(time < n*2):
    time += 1
    id = is_visit.index(False) + 1
    stack.append(id)
    is_visit[id-1] = True
    detect_time[id-1] = time
    while(len(stack) != 0):
        id = stack[-1]
        if len(input_line[id-1]) == 0:
            time += 1
            finish_time[stack.pop()-1] = time
        else:
            detect_id = input_line[id-1].pop(0)
            if is_visit[detect_id-1]:
                continue
            stack.append(detect_id)
            time += 1
            detect_time[detect_id-1] = time
            is_visit[detect_id-1] = True


for id in range(n):
    print('{0} {1} {2}'.format(id+1, detect_time[id], finish_time[id]))

Python: 
def DFS(n = 1, i = 0, time = 1):
    for j in range(n):
        if A[i][j] == 1 and d[j] == 0:
            time = time + 1
            d[j] = time
            time = DFS(n, j, time)
    time = time + 1
    f[i] = time
    return time

n = int(raw_input())
A = [0] * n
for i in range(n):
    A[i] = [0] * n

for i in range(n):
    value = map(int, raw_input().split())
    u = value[0] - 1
    k = value[1]
    nodes = value[2:]
    for j in range(k):
        v = nodes[j] - 1
        A[u][v] = 1

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

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

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

Python: WHITE = 0
GRAY = 1
BLACK = 2

n = int(input())

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

d = [0] * (n)
f = [0] * (n)
color = [WHITE] * (n)


time = 0

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

def dfs():
    for u in range(n):
        if color[u] == WHITE:
            dfs_visit(u)

    for u in range(n):
        print("{} {} {}".format(u+1, d[u], f[u]))


if __name__ == "__main__":
    for i in range(n):
        arr = list(map(int, input().split()))
        for v in (arr[2:]):
            M[arr[0]-1][v-1] = 1

    dfs()