Go: package main

import "fmt"

type node struct {
	id, d, v int
	adj      []node
}

var n int
var seen []bool
var graph []node

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

func dfs(v, t int) int {
	// fmt.Printf("dfs(v %d, t %d) en:\n", v, t)
	seen[v] = true
	graph[v].v = t
	tt := t
	for _, vv := range graph[v].adj {
		if !seen[vv.id] {
			tt = max(tt, dfs(vv.id, tt+1))
		}
	}
	graph[v].d = tt + 1
	// fmt.Printf("dfs(v %d, t %d) ex: d %d\n", v, t, graph[v].d)
	return graph[v].d
}

func main() {
	fmt.Scan(&n)
	graph = make([]node, n+1)
	for i := 1; i <= n; i++ {
		var u, k, v int
		fmt.Scan(&u, &k)
		graph[u].id = u
		// 頂点uはk個の隣接頂点を持っている
		for j := 0; j < k; j++ {
			fmt.Scan(&v)
			var t node
			t.id = v
			graph[u].adj = append(graph[u].adj, t)
		}
	}
	// fmt.Println("n", n, "graph", graph)
	seen = make([]bool, n+1)
	// t := dfs(1, 1)
	v, t := 1, 1
	done := false
	for !done {
		tt := dfs(v, t)
		done = true
		for i := range seen {
			if !seen[i] {
				done = false
				v = graph[i].id
				t = tt
				break
			}
		}
	}
	for i := 1; i <= n; i++ {
		fmt.Printf("%d %d %d\n", i, graph[i].v, graph[i].d)
	}
}

Python: from collections import defaultdict

def dfs(here, connect, visited, answer):
    global time
    answer[here][1] = time
    time += 1
    visited[here] = 1
    for c in connect[here]:
        if not visited[c]:
            dfs(c, connect, visited, answer)
    answer[here][2] = time
    time += 1

v_num = int(input())
connect = defaultdict(list)
for _ in range(v_num):
    inp = [int(n) - 1 for n in input().split(" ")]
    connect[inp[0]].extend(sorted(inp[2:]))
answer = [[n + 1 for m in range(3)] for n in range(v_num)]
time = 1
visited = [0 for n in range(v_num)]
for i in range(v_num):
    if not visited[i]:
        dfs(i, connect, visited, answer)
for v in range(v_num):
    print(*answer[v])

Python: # coding=utf-8

n = int(input())
first_v = 0
time = 0
L = []
d = [None for _ in range(n)]
f = [None for _ in range(n)]
stuck = []
for _ in range(n):
    u, k, *v = map(int, input().split())
    L.append(list(map(lambda x: x-1, v)))

v = first_v #??¢?´¢????????????
while True:
    """print("------------------------------")
    print("stuck:", *stuck)
    print("L:", L)
    print("d:", *d)
    print("f:", *f)
    print("time:", time)
    print("v:", v)"""
    if len(L[v]) > 0:
        stuck.append(v)
        if not d[v]:
            time += 1
            d[v] = time
        v = L[v].pop(0)
    elif len(stuck) > 0:
        if not d[v]:
            time += 1
            d[v] = time
        if not f[v]:
            time += 1
            f[v] = time
        v = stuck.pop(-1)
    else:
        time += 1
        f[first_v] = time
        break

for i in range(n):
    print("{} {} {}".format(i+1, d[i], f[i]))

Python: # http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=4647653#1



import sys
sys.setrecursionlimit(10 ** 8)
input = sys.stdin.readline

class Graph:
    def __init__(self, n, dictated=False, decrement=True, edge=[]):
        self.n = n
        self.dictated = dictated
        self.decrement = decrement
        self.edge = [set() for _ in range(self.n)]
        self.parent = [-1]*self.n
        self.info = [-1]*self.n
        for x, y in edge:
            self.add_edge(x,y)

    def add_edge(self,x,y):
        if self.decrement:
            x -= 1
            y -= 1
        self.edge[x].add(y)
        if self.dictated == False:
            self.edge[y].add(x)

    def add_adjacent_list(self,i,adjacent_list):
        if self.decrement:
            self.edge[i] = set(map(lambda x:x-1, adjacent_list))
        else:
            self.edge[i] = set(adjacent_list)

    def path_detector(self, start=0, time=0):
        """
        :param p: スタート地点
        :return: 各点までの距離と何番目に発見したかを返す
        """

        edge2= []
        for i in range(self.n):
            edge2.append(sorted(self.edge[i], reverse=True))

        p, t = start, time
        self.parent[p] = -2
        full_path = [(p + self.decrement,t)]
        while True:
            if edge2[p]:
                q = edge2[p].pop()
                if q == self.parent[p] and not self.dictated:
                    """ 逆流した時の処理 """
                    """"""""""""""""""""
                    continue
                if self.parent[q] != -1:
                    """ サイクルで同一点を訪れた時の処理 """
                    """"""""""""""""""""
                    continue
                self.parent[q] = p
                p, t = q, t + 1
                full_path.append((p + self.decrement, t))
            else:
                """ 探索完了時の処理 """
                full_path.append((p + self.decrement, t))
                """"""""""""""""""""
                if p == start and t == time:
                    break
                p, t = self.parent[p], t-1
                """ 二度目に訪問時の処理 """
                """"""""""""""""""""
        return full_path

    def path_list(self):
        """
        :return: 探索経路を返す。
        """
        self.parent = [-1]*self.n
        res = []
        for p in range(self.n):
            if self.parent[p] == -1:
                res.append(self.path_detector(start=p, time=1))
        return res

    def draw(self):
        """
        :return: グラフを可視化
        """
        import matplotlib.pyplot as plt
        import networkx as nx

        if self.dictated:
            G = nx.DiGraph()
        else:
            G = nx.Graph()
        for x in range(self.n):
            for y in self.edge[x]:
                G.add_edge(x + self.decrement, y + self.decrement)
        nx.draw_networkx(G)
        plt.show()

def make_graph(dictated=False, decrement=True):
    """
    自己ループの無いグラフを生成。N>=2
    :param dictated: True = 有効グラフ
    :param decrement: True = 1-indexed
    :return:
    """
    import random
    N = random.randint(2, 5)
    if N > 2:
        M_max = (3*N-6)*(1+dictated)
    else:
        M_max = 1
    graph = Graph(N, dictated, decrement)
    for _ in range(random.randint(0,M_max)):
        graph.add_edge(*random.sample(range(decrement, N+decrement), 2))
    return graph

##################################################################
# 入力が隣接リストの場合
##################################################################

N = int(input())  # 頂点数

graph = Graph(N,dictated=True, decrement=True)

for i in range(N):  # [[頂点1と連結している頂点の集合], [頂点2と連結している頂点の集合],...]
    points = list(map(int, input().split()))[2:]
    graph.add_adjacent_list(i, points)


data = graph.path_list()

from itertools import chain
data = list(chain.from_iterable(data))

res = [[i+1,0,0] for i in range(N)]
for time, a in enumerate(data, start=1):
    i = a[0] - 1
    if res[i][1]:
        res[i][2] = time
    else:
        res[i][1] = time

for a in res:
    print(*a)

Python: from sys import stdin
n = int(stdin.readline())
M = [None]
M += [list(map(int, stdin.readline().split()[2:])) for i in range(n)]
sndf = [None]
sndf += [[False, i] for i in range(1, n + 1)]
tt = 0
def dfs(u):
    global tt
    sndf[u][0] = True
    tt += 1
    sndf[u].append(tt)
    for v in M[u]:
        if not sndf[v][0]:
            dfs(v)
    tt += 1
    sndf[u].append(tt)
for i in range(1, n + 1):
    if not sndf[i][0]:
        dfs(i)
    print(*sndf[i][1:])

Python: def depth(s, time):
    time += 1
    flag[s] = 1
    d[s] = t
    for i in range(1, n+1):
        if G[s][i] == 1:
            if flag[i] == 0:
                depth(i, time)
                t = f[i]
    f[s] = time + 1
 
n = int(raw_input())
G = [[0 for i in range(n+1)] for j in range(n+1)]
d = [0 for i in range(n+1)]
f = [0 for i in range(n+1)]
 
for i in range(n):
    v = map(int, raw_input().split())
    for j in range(v[1]):
        G[v[0]][v[2+j]] = 1
 
flag = [0 for i in range(n+1)]
for i in range(1, n+1):
    if flag[i] == 0:
        depth(i, max(f))
 
for i in range(1, n+1):
    print(str(i) + " " + str(d[i]) + " " + str(f[i]))