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: def dfs(num, lst, d, f, cnt):
    if d[num] != 0:
        return cnt - 1
    d[num] = cnt
    for n in lst[num]:
        cnt += 1
        cnt = dfs(n - 1, lst, d, f ,cnt)
    cnt += 1
    f[num] = cnt
    return cnt


n = int(input())
d = [0 for i in range(n)]
f = [0 for i in range(n)]
lst = []
for _ in range(n):
    n = list(map(int, input().split()))
    lst.append(n[2:])

cnt = 1
while 0 in d:
    num = d.index(0)
    cnt = dfs(num, lst, d, f, cnt) + 1

for i, j in enumerate(zip(d, f)):
    print(i + 1, j[0], j[1])

Python: #!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys

UNVISITED, VISITED_IN_STACK, POPPED_OUT = 0, 1, 2


def generate_adj_matrix(v_info):
    for v_detail in v_info:
        v_adj_list = v_detail[2:]
        # assert len(v_adj_list) == int(v_detail[1])
        for each in v_adj_list:
            init_adj_matrix[int(v_detail[0]) - 1][int(each) - 1] = 1
    return init_adj_matrix


def graph_dfs(v_init):
    global time

    # init the first node of overall graph iterations(times >= 1)
    vertices_visit_stack.append(v_init)
    vertices_status_list[v_init] = VISITED_IN_STACK
    vertices_d_time[v_init] += time
    # init end

    while len(vertices_visit_stack) > 1:
        current_vertex = vertices_visit_stack[-1]
        next_vertex = get_adj_vertices(vertex=current_vertex)

        if next_vertex:
            if vertices_status_list[next_vertex] is UNVISITED:
                vertices_status_list[next_vertex] = VISITED_IN_STACK
                time += 1
                vertices_d_time[next_vertex] += time
                vertices_visit_stack.append(next_vertex)
        else:
            vertices_visit_stack.pop()
            vertices_status_list[current_vertex] = POPPED_OUT
            time += 1
            vertices_f_time[current_vertex] += time

    return None


def get_adj_vertices(vertex):
    index = int(vertex) - 1
    for j in range(vertices_num):
        if adj_matrix[index][j]:
            adj_matrix[index][j] = 0
            return j + 1
    return None


def dfs_start():
    global time
    for i in range(vertices_num):
        if vertices_status_list[i + 1] == UNVISITED:
            # print('round: ', i + 1)
            graph_dfs(v_init=i + 1)
            time += 1


if __name__ == '__main__':
    _input = sys.stdin.readlines()
    vertices_num = int(_input[0])
    vertices_info = list(map(lambda x: x.split(), _input[1:]))
    init_adj_matrix = tuple([[0] * vertices_num for _ in range(vertices_num)])
    # assert len(vertex_info) == vertex_num

    # config length = (vertex_num + 1)
    vertices_visit_stack = [-1]
    vertices_status_list = [UNVISITED] * vertices_num
    vertices_status_list.insert(0, -1)
    vertices_d_time, vertices_f_time = ([0] * (vertices_num + 1) for _ in range(2))

    adj_matrix = generate_adj_matrix(vertices_info)
    # timing start from 1
    time = 1
    dfs_start()
    for k in range(vertices_num):
        print(k + 1, vertices_d_time[k + 1], vertices_f_time[k + 1])

Python: from sys import stdin

d_num = int(stdin.readline().strip())

graph = [[] for _ in range(d_num+1)]
for _ in range(d_num):
    u, k, *neighbors = map(int, stdin.readline().split())
    for v in neighbors:
        graph[u].append(v)
        graph[v].append(u)

visited = set()
timestamps = [None for _ in range(d_num+1)]

def dfs(u, stmp):
    visited.add(u)
    entry = stmp

    stmp += 1
    for v in graph[u]:
        if v not in visited:
            stmp = dfs(v, stmp)

    timestamps[u] = entry, stmp
    return stmp+1

dfs(1, 1)

for num, (entry, leave) in enumerate(timestamps[1:], 1):
    print(num, entry, leave)

Python: #Boost Force  / Backtracking
import sys
input = sys.stdin.readline
d = []
f = []
time = 0
#ทำการ search
def search(r):
    global d,f,time,s
    if d[r] == 0:
        time += 1
        d[r] = time
    else:
        return
    for x in s[r]:
        search(x)
    time += 1
    f[r] = time


n = int(input()) #รับค่าจำนวน node ทั้งหมด
s = [[] for i in range(n+1)]
for _ in range(n):
    d = list(map(int,input().split())) #รับข้อมูลทีละบรรทัด split เก็บเป็น int
    #ตน d[0] คือ node ตน 1 คือ ดีกรี ตนตั้งแต่ 2ไป คือ vertex
    s[d[0]] = d[2:]

d = [0 for _ in range(n+1)]
f = [0 for _ in range(n+1)]

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

#แสดง node เวลาที่เจอ และ เวลา finish
for i in range(1,n+1):
    print (i,d[i],f[i])

Python: import sys
# sys.stdin = open('input.txt')

def fillMatrix():
    for i in range(n):
        u, k, *v = map(int, input().split())
        for j in v:
            matrix[i][j-1] = 1

def dfs(u):
    global time
    status[u] = VISITING
    time += 1
    discoverTime[u] = time
    for v in range(n):
        if matrix[u][v] and status[v] == NOT_VISITED:
            dfs(v)
    status[u] = VISITED
    time += 1
    finishTime[u] = time


n = int(input())
matrix = [[0]*n for i in range(n)]
time = 0
discoverTime = [0] * n
finishTime = [0] * n

NOT_VISITED = 0 # WHITE
VISITING = 1 # GRAY
VISITED = 2 # BLACK
status = [NOT_VISITED] * n

fillMatrix()
# Calling dfs(0) alone cannot reach nodes not connected from 0
for i in range(n):
    if status[i] != VISITED:
        dfs(i)

for i in range(n):
    ans = []
    ans.append(i+1)
    ans.append(discoverTime[i])
    ans.append(finishTime[i])
    ans = map(str, ans)
    print(' '.join(ans))

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


class Graph:
    def __init__(self, n, adj_matrix):
        self.n = n
        self.g = adj_matrix

    def show(self):
        for _ in self.g:
            print(*_)

    def dfs(self, u, init=False):
        if init:
            self.states = [1] * self.n
            self.stack = []
            self.d = [None] * self.n
            self.f = [None] * self.n
            self.time = 0

        self.states[u] = 0
        self.time += 1
        self.d[u] = self.time

        for v, edge in enumerate(self.g[u]):
            if edge and self.states[v]:
                self.dfs(v)

        self.states[u] = 0
        self.time += 1
        self.f[u] = self.time

    def show_dfs(self, start=0):
        self.dfs(u=start, init=True)
        for i, (d, f) in enumerate(zip(self.d, self.f)):
            print(i + 1, d, f)


if __name__ == '__main__':
    n = int(input())
    adj_matrix = [[0] * n for i in range(n)]
    for i in range(n):
        for v in input().split()[2:]:
            adj_matrix[i][int(v) - 1] = 1

    g = Graph(n, adj_matrix)
    g.show_dfs()