Go: package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

type TimeRecord struct {
	discoverTime int
	finishTime   int
}

func main() {
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)

	n, err := nextInt(sc)
	if err != nil {
		panic(err)
	}

	timeRecordMap := make([]TimeRecord, n)
	childrenMap := make([][]int, n)
	for i := 1; i <= n; i++ {
		node, err := nextInt(sc)
		if err != nil {
			panic(err)
		}
		timeRecordMap[node-1] = TimeRecord{-1, -1}

		childNum, err := nextInt(sc)
		if err != nil {
			panic(err)
		}
		childrenMap[node-1] = make([]int, childNum)
		for j := 0; j < childNum; j++ {
			child, err := nextInt(sc)
			if err != nil {
				panic(err)
			}
			childrenMap[node-1][j] = child
		}
	}

	timer := 1
	startNode := 1
	for {
		visit(startNode, &timer, childrenMap, timeRecordMap)
		startNode = findStartNode(childrenMap, timeRecordMap)
		if startNode < 0 {
			break
		}
	}
	for k, v := range timeRecordMap {
		fmt.Printf("%d %d %d\n", k+1, v.discoverTime, v.finishTime)
	}
}

func findStartNode(childrenMap [][]int, timeRecordMap []TimeRecord) int {
	x := -1
	for node, timeRecord := range timeRecordMap {
		if timeRecord.discoverTime < 0 {
			x = node + 1
			break
		}
	}
	return x
}

func visit(currentNode int, timer *int, childrenMap [][]int, timeRecordMap []TimeRecord) {
	if timeRecordMap[currentNode-1].discoverTime > 0 {
		return
	}
	children := childrenMap[currentNode-1]
	timeRecordMap[currentNode-1] = TimeRecord{*timer, timeRecordMap[currentNode-1].finishTime}
	(*timer)++
	for i := 0; i < len(children); i++ {
		visit(children[i], timer, childrenMap, timeRecordMap)
	}
	timeRecordMap[currentNode-1] = TimeRecord{timeRecordMap[currentNode-1].discoverTime, *timer}
	(*timer)++
}

func nextInt(sc *bufio.Scanner) (int, error) {
	sc.Scan()
	return strconv.Atoi(sc.Text())
}

Python: from collections import defaultdict


def dfs(v, t):
    if start[v] == 0:
        start[v] = t
        t += 1
    else:
        return t

    for nv in graph[v]:
        t = dfs(nv, t)

    end[v] = t
    t += 1

    return t


n = int(input())

graph = defaultdict(list)

for _ in range(n):
    u, k, *v = map(int, input().split())
    for v in v:
        graph[u].append(v)

start = [0] * (n + 1)
end = [0] * (n + 1)


t = 1

for i in range(1, n + 1):
    t = dfs(i, t)

for i in range(1, n + 1):
    print(i, start[i], end[i])

Python: 
d = None
f = None


def dfs(g, cur, time):
    global d, f
    d[cur] = time
    for next in g[cur]:
        if d[next] == 0:
            time = dfs(g, next, time+1)
    f[cur] = time + 1
    return time + 1


def main():
    global d, f
    n = int(input())
    g = [[] for _ in range(n)]
    d = [0 for _ in range(n)]
    f = [0 for _ in range(n)]
    for _ in range(n):
        inp = list(map(int, input().split()))
        m = inp[0] - 1
        k = inp[1]
        for i in range(k):
            g[m].append(inp[i+2] - 1)
    dfs(g, 0, 1)
    for i in range(n):
        print(i, d[i], f[i])


if __name__ == '__main__':
    main()

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

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 = " ")