Go: package main

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

func main() {
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)
	sc.Scan()
	num, _ := strconv.Atoi(sc.Text())
	nodes := make(map[int]*node)

	for i := 0; i < num; i++ {
		sc.Scan()
		id, _ := strconv.Atoi(sc.Text())
		sc.Scan()
		nodeNum, _ := strconv.Atoi(sc.Text())
		n := node{id, make([]int, 0), 0, 0}
		for j := 0; j < nodeNum; j++ {
			sc.Scan()
			nid, _ := strconv.Atoi(sc.Text())
			n.nexts = append(n.nexts, nid)
		}
		nodes[id] = &n
	}

	s := Stack{}
	for i := 1; i < len(nodes)+1; i++ {
		if nodes[i].s != 0 {
			continue
		}
		walk(i, &nodes, s)
	}
	for i := 1; i < len(nodes)+1; i++ {
		fmt.Printf("%v %v %v\n", (*nodes[i]).id, (*nodes[i]).s, (*nodes[i]).e)
	}
}

var time int

func walk(nid int, nodes *map[int]*node, s Stack) {
	n := (*nodes)[nid]
	if n.s != 0 {
		return
	}
	time++
	n.s = time
	s.Push(n)
	for _, v := range n.nexts {
		walk(v, nodes, s)
	}
	time++
	n.e = time
}

type node struct {
	id    int
	nexts []int
	s     int
	e     int
}

// Stack is Stack
type Stack struct {
	stack []interface{}
}

// Push new value
func (stack *Stack) Push(val interface{}) {
	stack.stack = append(stack.stack, val)
}

// Pop new value
func (stack *Stack) Pop() interface{} {
	val := stack.stack[len(stack.stack)-1]
	stack.stack = stack.stack[0 : len(stack.stack)-1]
	return val
}

Python: # https://onlinejudge.u-aizu.ac.jp/courses/lesson/1/ALDS1/11/ALDS1_11_B
# 本の解説通りかは知らない

# データの読み込み
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  # 関数を終了するときにも+1する


for node in node_ls:  # 孤立しているノードもあるためこうして対処
    dfs(node)

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

Python: N = int(input())
L = [[] for i in range(N+1)]
d = [0] * (N+1)
f = [0] * (N+1)

time = 0

def dfs(key):
    global time
    time += 1
    d[key] = time
    for i in range(len(L[key])):
        if d[L[key][i]] == 0:
            dfs(L[key][i])
    time += 1
    f[key] = time
        

for i in range(N):
    Q = list(map(int, input().split()))
    L[Q[0]].extend(Q[2:])

for i in range(1,N+1):
    if d[i] == 0:
        dfs(i)
        #print("done")

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

Python: n = int(input())
graph = [[0 for i in range(n)] for j in range(n)]
d = [0] * n
f = [0] * n
g = [0] * n

time = 0

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

def search(i):
    global time
    time = time + 1
    d[i] = time
    g[i] = 1
    for j in range(n):
        if (graph[i][j] == 1) & (g[j] == 0):
            search(j)
    time = time + 1
    f[i] = time

for i in range(n):
    if g[i] == 0:
        search(i)
[print(i+1, d[i], f[i]) for i in range(n)]

Python: import sys


def input():
    return sys.stdin.readline().rstrip()


def dfs(c, n, G, ans):
    count = c
    for i, flag in enumerate(G[n]):
        if flag == 1 and ans[i][0] == 0:
            count += 1
            ans[i][0] = i + 1
            ans[i][1] = count
            ans[i][2] = dfs(count, i, G, ans)
            count = ans[i][2]
    else:
        return count + 1


def main():
    n = int(input())
    G = [[0] * n for _ in range(n)]
    ans = [[0] * 3 for _ in range(n)]
    for i in range(n):
        u, k, *v = map(int, input().split())
        for j in range(k):
            G[u-1][v[j]-1] = 1

    count = 1
    for i in range(n):
        if ans[i][0] == 0:
            ans[i][0] = i + 1
            ans[i][1] = count
            ans[i][2] = dfs(count, i, G, ans)
            count = ans[i][2] + 1

    for i in range(n):
        print(*ans[i])


if __name__ == '__main__':
    main()

Python: from collections import deque

n = int(input())

g = [deque([]) *n for _ in range(n)]

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

time = 0
arrive_time = [-1] * n
finish_time = [-1] * n
def dfs(v):
    global time
    time += 1
    stack = [v]
    arrive_time[v] = time
    while stack:
        v = stack[-1]
        if g[v]:
            w = g[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] < 0:
        ans = dfs(i)

for j in range(n):
    temp = [j+1, ans[0][j], ans[1][j]]
    print(*temp)

Python: N = int(input())
adj_list = []
for _ in range(N):
    line = list(input().split(" "))
    adj_list.append([int(k) - 1 for k in line[2:]])

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

visited = set()

def dfs(p):
    global time
    if p in visited:
        return

    d[p] = time
    time += 1
    visited.add(p)
    for ad in adj_list[p]:
        if ad not in visited:
            dfs(ad)
    f[p] = time
    time += 1

for i in range(N):
    dfs(i)

for i in range(N):
    print(f"{i + 1} {d[i]} {f[i]}")

Python: # coding: utf-8
# Your code here!

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)] # id d f

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

Python: n=int(input())
G=[]
for i in range(n):
    L=list(map(int,input().split()))
    G.append(L[2:])
    for j in range(len(G[-1])):
        G[-1][j]-=1

Forder=[-1]*n
Lorder=[-1]*n
ptr=1
def dfs(v):
    #print(v)
    #print(G[v])
    #print()
    global ptr

    Forder[v]=ptr
    ptr+=1

    for next in G[v]:
        if Forder[next]!=-1:
            continue
        dfs(next)
    
    Lorder[v]=ptr
    ptr+=1

#while True:
#    #print(Forder,Lorder)
#    for i in range(n):
#        if Forder[i]!=-1 and Lorder[i]!=-1:
#            pass
#        else:
#            dfs(i)
#            continue
#
#        if i==n-1:
#            break
#    else:
#        continue
#    break
#
#for i in range(n):
#    print(i+1,Forder[i],Lorder[i])

##########
for i in range(n):
    if Forder[i]==-1 or Lorder[i]==-1:
        dfs(i)

for i in range(n):
    print(i+1,Forder[i],Lorder[i])