Go: package main

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

//util
var sc = bufio.NewScanner(os.Stdin)

func nextStr() string {
	sc.Scan()
	return sc.Text()
}

func nextInt() int {
	sc.Scan()
	i, e := strconv.Atoi(sc.Text())
	if e != nil {
		panic(e)
	}
	return i
}

func printList(list []int) {
	n := len(list)
	buf := bufio.NewWriter(os.Stdout)
	for _, v := range list[0 : n-1] {
		buf.Write([]byte(fmt.Sprintf("%d ", v)))
	}
	buf.Write([]byte(fmt.Sprintf("%d\n", list[n-1])))
	buf.Flush()
}

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

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

//solve

const MAX = 100
const WHITE = 0
const GRAY = 1
const BLACK = 2

var time, n int

//隣接行列
var M [MAX][MAX]int

//d[i]: 最初にiを訪問した時刻。発見時刻
//f[i]: iの隣接リストを訪問し終えた時刻。完了時刻
var color, d, f [MAX]int

func dfs_visit(u int) {
	color[u] = GRAY
	time++
	d[u] = time
	//隣接を調べる
	for v := 0; v < n; v++ {
		if M[u][v] == 0 {
			continue
		}
		//隣接するvが、未訪問だった場合
		if color[v] == WHITE {
			dfs_visit(v)
		}
	}
	//訪問完了処理
	color[u] = BLACK
	time++
	f[u] = time
	//訪問完了
}

func dfs() {
	//初期化
	for u := 0; u < n; u++ {
		color[u] = WHITE
	}
	time = 0

	//未訪問のuを始点として、深さ優先探索
	for u := 0; u < n; u++ {

		if color[u] == WHITE {
			dfs_visit(u)
		}
	}

	for u := 0; u < n; u++ {
		fmt.Println(u+1, d[u], f[u])
	}
}

func main() {
	sc.Split(bufio.ScanWords)
	n = nextInt()
	for i := 0; i < n; i++ {
		u, k := nextInt(), nextInt()
		M[u-1][u-1] = 0

		//fmt.Println(u, k)
		if k > 0 {
			for j := 0; j < k; j++ {

				v := nextInt()
				M[u-1][v-1] = 1

			}
		}

	}

	dfs()

}

Python: def dfs_init(color,n,dq):
	for i in range(n):
		color[i] = "White"

def next(u):
	for v in range(list_next[u],n):
		list_next[u] = v+1
		if list_m[u][v]:
			return v


def dfs_visit(u,color,dq,tt):
	tt = tt
	dq.append(u)
	color[u] = "Gray"
	list_d[u] = tt + 1
	tt += 1
	while dq:
		u = dq[-1]
		v = next(u)
		if v != None:
			if color[v] == "White":
				color[v] = "Gray"
				list_d[v] = tt + 1
				tt += 1
				dq.append(v)
		else:
			dq.pop()
			color[u] = "Black"
			list_f[u] = tt + 1
			tt += 1
	return tt

from collections import deque
n = int(input())
list_m = [[0]*n for i in range(n)]
list_next = [0] * n
list_color = [0] * n
list_d = [0]*n
list_f = [0]*n
dq = deque([])

for i in range(n):
	a,b,*args = map(int, input().split())
	for num in args:
		list_m[a-1][num-1] = 1
tt = 0
list_num = [i+1 for i in range(n)]
dfs_init(list_color,n,dq)
for u in range(n):
	if list_color[u] == "White":
		tt = dfs_visit(u,list_color,dq,tt)

for i in range(n):
	print(list_num[i], list_d[i] ,list_f[i])

Python: def dfs(v, cnt):
    D[v] = cnt
    cnt += 1
    for c in edge[v]:
        if D[c] == -1:
            cnt = dfs(c, cnt)
    F[v] = cnt
    cnt += 1
    return cnt
 
 
V = int(input())
edge = [[] for _ in range(V)]
for _ in range(V):
    u, _, *v = map(lambda x: int(x)-1, input().split())
    edge[u] = sorted(v)
D, F = [-1] * V, [-1] * V
c = 1
for i in range(V):
    if D[i] == -1:
        c = dfs(i, c)
for i, (d, f) in enumerate(zip(D, F)):
    print(i+1, d, f)

Python: def depth_search(i, adj, d, f, t):
    if d[i - 1]:
        return t
    d[i - 1] = t
    t += 1
    for v in adj[i - 1]:
        t = depth_search(v, adj, d, f, t)
    f[i - 1] = t
    t += 1
    return t
n = int(input())
adj = [list(map(int, input().split()))[2:] for _ in range(n)]

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

depth_search(1, adj, d, f, 1)

for i, df in enumerate(zip(d, f)):
    print(i, *df)

Python: def DFS(G):
    ans = [0] + [[0,0,0] for _ in range(len(G))]
    def main(G,i):
        ans[0] += 1
        ans[i] = [i, ans[0], ans[0]]
        for j in sorted(G[i-1][2:]):
            if ans[j][0] == 0: main(G,j)
        ans[0] += 1
        ans[i][2] = ans[0]
    for u in G:
        if ans[u[0]][0] == 0: main(G,u[0])
    return ans[1:]


if __name__=='__main__':
    n = int(input())
    G = [list(map(int,input().split())) for _ in range(n)]
    for out in DFS(G): print(*out)

Python: n = int(input())
g = []
for i in range(n):
    a = list(map(int,input().split()))
    g.append(a[2:])
d = [0]*n
f = [0]*n
global t
t = 1
d[0] = 1
x = 1
def find(x):
    global t
    if len(g[x-1]) == 0:
        f[x-1] = t
    for i in g[x-1]:
        if d[i-1] == 0:
            t += 1
            d[i-1] = t
            find(i)
    t += 1
    f[x-1] = t

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

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

WHITE = 0
GRAY = 1
BLACK = 2
color = [WHITE for _ in range(n)]
d = [0 for _ in range(n)]
f = [0 for _ in range(n)]
time = 1

def dfs(u):
    global dfs_color, d, f, time
    color[u] = GRAY
    d[u] += time
    time += 1
    for v in range(n):
        if A[u][v]:
            if color[v] == WHITE:
                dfs(v)
        else:
            continue
    color[u] = BLACK
    f[u] = time
    time += 1 

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

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

Python: n = int(input())
graph = {}
for _ in range(n):
  i = list(map(int,input().split()))
  graph[i[0]] = i[2:]

first = {i:0 for i in range(1,n+1)}
last = {i:0 for i in range(1,n+1)}
seen = set()
time = 1

def dfs(v):
  global time
  seen.add(v)
  first[v] = time
  time += 1
  for nxt in graph[v]:
    if nxt in seen:
      continue
    dfs(nxt)
  last[v] = time
  time += 1

for i in range(1,n+1):
  if i not in seen:
    dfs(i)
  
for i in range(1,n+1):
  print(i, first[i], last[i])

Python: import sys

def debug(x, table):
    for name, val in table.items():
        if x is val:
            print('DEBUG:{} -> {}'.format(name, val), file=sys.stderr)
            return None

time = 0

def dfs(u, adj, d, f, sumi):
    global time
    time += 1
    d[u] = time

    for v in adj[u]:
        if v not in sumi:
            dfs(v, adj, d, f, sumi)
        sumi.add(v)

    time += 1

    f[u] = time


def solve():
    n = int(input())
    adj = [None] * n

    for i in range(n):
        u, k, *vs = [int(j) - 1 for j in input().split()]
        # debug(vs, locals())
        adj[u] = vs

    # debug(adj, locals())
    
    d = [0] * n
    f = [0] * n
    sumi = {0}

    dfs(0, adj, d, f, sumi)

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

    pass

if __name__ == '__main__':
    solve()