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
		}
	}

	// TODO: always start with 1?
	timer := 1
	visit(1, &timer, childrenMap, timeRecordMap)
	for k, v := range timeRecordMap {
		fmt.Printf("%d %d %d\n", k+1, v.discoverTime, v.finishTime)
	}
}

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: WHITE = 0
GRAY = 1
BLACK = 2
color, d, f = [WHITE for i in range(n)]
t = 1

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

for u in range(n):
    if (color[u] == WHITE):
        visit(u)
for u in range(n):
    print(u+1, d[u], f[u], sep = " ", end ="\n")

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

Python: n = int(raw_input())

d = [0 for i in range(n)]
f = [0 for i in range(n)]
a = [[0 for i in range(n)] for j in range(n)]
st = [0 for i in range(n)]
time = [0]
G = [0 for i in range(n)]

def dfs_visit(s):
    st[s] = 1
    time[0] += 1
    d[s] = time[0]
    
    for k in range(n):  
      if a[s][k] == 1 and st[k] == 0:
          dfs_visit(k)
    time[0] += 1
    f[s] = time[0]

def main():
    for s in range(n):
        if st[s] == 0:
            def_visit(s)
    for s in range(n):
        print(s+1,d[s],f[s]) 

for i in range(n):
  G = map(int, raw_input().split())
  for j in range(G[1]):
    v[G[0]-1][G[2+j]-1] = 1
   
main()

Python: # -*- coding: utf-8 -*-

def DFS(adj, start):
    n = len(adj)
    d = [0] * n
    f = [0] * n
    flag = [0] * n
    S = []
    time = 1

    S.append(start)
    flag[start] = 1
    d[start] = time
    time = time + 1
    
    while flag.count(2) != n: # ??¨????????????????????¢?´¢????????????????????§
        if len(S) != 0:
            u = S.pop()
            v = next(adj, u)
            v = [i for i in v if flag[i] == 0] # v <= ??£??\???????????????????????¢?´¢??????????????????
            if len(v) != 0:
                S.append(u)
                S.append(v[0])
                flag[v[0]] = 1
                d[v[0]] = time
                time = time + 1
            else:
            #??£??\??????????????¨????¨??????????
                flag[u] = 2
                f[u] = time
                time = time + 1

        else:
            u = flag.index(0)
            S.append(u)
            flag[u] = 1
            d[u] = time
            time = time + 1            

    return d, f



def next(adj, u):
    """
    u?????£??\??????????????????????????????????????????
    """
    return [i for i, x in enumerate(adj[u]) if x == 1]
    

def main():
    
    n = int(input())
    adj = [[0 for i in range(n)] for j in range(n)]

    for i in range(n):
        tmp = list(map(int, input().split()))
        u = tmp[0]
        u = u -1
        k = tmp[1]
        v = tmp[2:]
        for j in range(k):
            adj[u][v[j]-1] = 1
    
    d, f = DFS(adj, 0)
    for i in range(n):
        print(i+1, d[i], f[i])

if __name__ == "__main__":
    main()

Python: def dfs(adj, s, d, f, now):
    now += 1
    d[s] = now
    for t in adj[s]:
        if t != s and f[t] < 0 and d[t] < 0:
            d, f, now = dfs(adj, t, d, f, now)
    now += 1
    f[s] = now
    return d, f, now


n = int(input())
adj = [[] for _ in range(n)]
for _ in range(n):
    s = [int(x) for x in input().split()]
    u = s[0]
    for v in s[2:]:
        adj[u - 1].append(v - 1)
    adj[u - 1].sort()

d = [-1 for _ in range(n)]
f = [-1 for _ in range(n)]
now = 0
for s in range(n):
    if f[s] < 0:
        d, f, now = dfs(adj, s, d, f, now)

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

Python: n = int(input())
graph = {}
ans = []
for i in range(n):
    t = list(map(int, input().split()))
    v = t[0]
    k = t[1]
    graph[v] = [t[i+2] for i in range(k)]
    ans.append([v,None,None])

class Time:
    def __init__(self):
        self.time = 0
    def getTime(self):
        self.time += 1
        return self.time

t = Time()

def dfs(graph, target):
    # ???????????????????¨????
    if ans[target - 1][1] is None:
        ans[target - 1][1] = t.getTime()
    if graph[target] == []:
        if ans[target - 1][2] is None:
            ans[target - 1][2] = t.getTime()        
        return
    for v in sorted(graph[target]):
        # # ???????????????????¨????        
        if ans[v - 1][1] is None:
            ans[v - 1][1] = t.getTime()        
        dfs(graph,v)
    if ans[target - 1][2] is None:
        ans[target - 1][2] = t.getTime()

dfs(graph, 1)
for row in ans:
    print(*row)

Python: def dfs(v):  # vを訪問する
    global time
    seen[v] = 1
    start[v] = time
    time += 1

    for next_v in graph[v]:
        if seen[next_v]: continue
        dfs(next_v)
    
    end[v] = time
    time += 1


n = int(input())
graph = []
for _ in range(n):
    line = list(map(int, input().split()))
    graph.append([v - 1 for v in line[2:]])

seen = [0] * n  # 0: 未訪問、1: 訪問済
start = [0] * n
end = [0] * n
time = 1

for v in range(n):
    if not seen[v]: dfs(v)

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

Python: n=int(input())
seen=[-1]*n
first_order=[0]*n
last_order=[0]*n
cnt=0
def dfs(G,s):
    global cnt
    first_order[s]=cnt+1
    cnt+=1
    seen[s]=1
    for nv in G[s]:
        if(seen[nv]!=-1):
            continue
        dfs(G,nv)
    last_order[s]=cnt+1
    cnt+=1

G=[[] for i in range(n)]
for i in range(n):
    li=list(map(int,input().split()))
    for x in range(2,len(li)):
        G[i].append(li[x]-1)
for i in range(n):
    if(seen[i]==-1):
        dfs(G,i)
for i in range(n):
    print(i+1,first_order[i],last_order[i])

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