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: n = int(input())
A = [[0 for i in range(n)] for j in range(n)]

for i in range(n):
    u, k, *v = list(map(int, input().split()))
    for j in v:
        A[int(u)-1][int(j)-1] = 1
        # A[int(j)-1][int(u)-1] = 1

# for row in A:
#     msg = ' '.join(map(str, row))
#     # print(msg)

d = [-1] * n
f = [-1] * n

t = 0
d[0] = t

# recursive


def dfs(u):
    global t
    # print('visit:', str(u), str(t))
    t += 1
    d[u] = t
    for i in range(len(A[u])):
        if A[u][i] == 1 and d[i] == -1:
            dfs(i)
    t += 1
    f[u] = t
            

dfs(0)


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

Python: n=int(input())

v=[[]]*n
for i in range(n):
    tmp=list(map(int,input().split()))
    tmp=[i-1 for i in tmp[2:]]
    v[i]=tmp

time=1
D=[-1 for _ in range(n)]
F=[-1 for _ in range(n)]

def dfs(src):
    global time
    D[src]=time
    time+=1
    for dst in v[src]:
        if D[dst]==-1:#未訪問
            dfs(dst)
    F[src]=time
    time+=1

for root in range(n):
    if D[root]==-1:
        dfs(root)

for i in range(n):
    print(i+1,D[i],F[i])

Python: n = int(input())
a = [[False]*n for i in range(n)]
  
for i in range(n):
    v = list(map(int, input().split()))
    u = v[0]
    k = v[1]
    for j in range(k):
        a[u - 1][v[2 + j] - 1] = True

d = [0] * n
f = [0] * n
isDiscovered = [False] * n
time_stamp = 0

def dfs(x):
    global time_stamp
    isDiscovered [x] = True
    time_stamp = time_stamp + 1
    d[x] = time_stamp
    for i in range(n):
        if a[x][i]and not isDiscovered[i]:
            dfs(i)
    time_stamp = time_stamp + 1
    f[x] = time_stamp

for i in range(n):
    if not isDiscovered[i]:
        dfs(i)

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

Python: n=int(input())

next=[[] for i in range(n)]
for i in range(n):
	l=list(map(int,input().split()))
	u=l[0]
	k=l[1]
	for j in range(2,k+2):
		next[u-1].append(l[j]-1)

stk=[]
stk.append(0)
print(next)
time=1
d=[0 for i in range(n)]
f=[0 for i in range(n)]
while(len(stk)!=0):
	if len(next[stk[-1]])==0:
		if d[stk[-1]]==0:
			d[stk[-1]]=time
			#print(stk[-1])
			time+=1
		f[stk[-1]]=time
		#print(stk[-1])
		time+=1
		stk.pop()
	else:
		v=min(next[stk[-1]])
		if d[v]!=0:
			next[stk[-1]].remove(v)
		else:
			if d[stk[-1]]==0:
				d[stk[-1]]=time
				time+=1
			#print(stk[-1])
			next[stk[-1]].remove(v)
			stk.append(v)
			

for i in range(n):
	out=[]
	out.append(i+1)
	out.append(d[i])
	out.append(f[i])
	print(*out)

Python: n = int(input())
al = [list(map(lambda s: int(s) - 1, input().split()))[2:] for _ in range(n)]
begin = [-1] * n
end = [-1] * n
not_visited = list(range(n))
t = 1
def dfs(u):
    global begin, end, t, not_visited
    begin[u] = t
    t += 1
    not_visited.remove(u)
    for v in al[u]:
        if begin[v] == -1:
            dfs(v)
    end[u] = t
    t += 1

while len(not_visited) > 0:
    dfs(not_visited[0])

for i in range(n):
    print('{} {} {}'.format(i + 1, begin[i], end[i]))

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

n = int(input())
M = [[False for i in range(n)] for i in range(n)]
for i in range(n):
    tmp = list(map(int, input().split()))
    for i in range(tmp[1]):
        M[tmp[0]-1][tmp[i+2]-1] = 1

WHITE = 0
GRAY = 1
BLACK = 2
color, d, f = [WHITE for i in range(n)]
t = 1
for u in range(n):
    if (color[u] == WHITE):
        visit(u)
for u in range(n):
    print(str(u+1), str(d[u]), str(f[u]), sep = " ")

Python: def dfs(u, colors, matrix, time, detect_time, finished_time):
    # ????????????????????¨??????????????????
    colors = colors
    detect_time = detect_time
    finished_time = finished_time
    time = time + 1
    stack = list()
    stack.append(u)
    colors[u] = 1
    detect_time[u] = time
    while len(stack):
        for i, val in enumerate(matrix[u]):
            if val == 1 and colors[i] == 0:
                time += 1
                stack.append(i)
                colors[i] = 1
                detect_time[i] = time
                u = i
                break
        else:
            time += 1
            e = stack.pop()
            colors[e] = 2
            finished_time[e] = time
            if len(stack):
                u = stack[-1]
    return time


if __name__ == '__main__':
    N = int(input())
    matrix = [[0] * N for _ in range(N)]
    color = [0] * N
    for i in matrix:
        node_info = [int(i) for i in input().split()]
        node_i = node_info[0] - 1
        if not node_info[1] == 0:
            for i in node_info[2:]:
                matrix[node_i][i - 1] = 1
    colors = [0] * len(matrix)
    detect_time = [0] * len(matrix)
    finished_time = [0] * len(matrix)
    time = 0
    for i, val in enumerate(colors):
        if val == 0:
            time = dfs(i, colors, matrix, time, detect_time, finished_time)

    for i in range(len(matrix)):
        print('{} {} {}'.format(i + 1, detect_time[i], finished_time[i]))

Python: #!/usr/bin/env python
# -*- coding:utf-8 -*-
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()