Go: package main

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

// repr state of visited node
// WHITE yet visit
// GEAY  visiting
// BLACK visited
const (
	WHITE int = iota
	GRAY
	BLACK
)

type dfsGraph struct {
	g      [][]int
	colors []int
	stime  []int // Start time of visiting node
	ftime  []int // Finish time of visiting node
}

var time int

func makeAdjList() [][]int {
	var n int
	fmt.Scanf("%d", &n)

	adj := make([][]int, n)
	for i := 0; i < n; i++ {
		adj[i] = make([]int, n)
	}

	sc := bufio.NewScanner(os.Stdin)
	for i := 0; i < n; i++ {
		sc.Scan()
		nodeInfo := strings.Split(sc.Text(), " ")
		outDegree, _ := strconv.Atoi(nodeInfo[1])

		if outDegree > 0 {
			for k := 0; k < outDegree; k++ {
				j, _ := strconv.Atoi(nodeInfo[k+2])
				j-- // convert 1 based to 0 based
				adj[i][j] = 1
			}
		}
	}

	return adj
}

func (dg dfsGraph) dfsVisit(u int) {
	// 頂点uを訪問中に設定
	dg.colors[u] = GRAY
	time++
	dg.stime[u] = time

	// uの隣接nodeを訪問
	for v := 0; v < len(dg.g); v++ {
		if dg.g[u][v] == 0 {
			continue // 辺がなければスキップ
		}

		// vが未訪問なら訪問
		if dg.colors[v] == WHITE {
			dg.dfsVisit(v)
		}
	}

	// 頂点uを訪問済みに設定
	dg.colors[u] = BLACK
	time++
	dg.ftime[u] = time
}

func (dg dfsGraph) dfs() {
	for i := 0; i < len(dg.g); i++ {
		if dg.colors[i] == WHITE {
			dg.dfsVisit(i)
		}
	}
}

func (dg dfsGraph) printDfsTime() {
	for i := 0; i < len(dg.g); i++ {
		fmt.Printf("%d %d %d\n", i+1, dg.stime[i], dg.ftime[i])
	}
}

func main() {
	adj := makeAdjList()
	colors := make([]int, len(adj))
	stime := make([]int, len(adj))
	ftime := make([]int, len(adj))
	graph := dfsGraph{adj, colors, stime, ftime}
	graph.dfs()
	graph.printDfsTime()
}

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