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: import sys

n = int(sys.stdin.readline())+1

m = [[0] * n for _ in range(n)]
discover_time = [-1] * n
finish_time = [0] * n
clock = -1

def walk(p):
    global clock
    clock += 1

    for i in range(n):
        if m[p][i]==0: continue
        if discover_time[i]<0:
            discover_time[i] = clock
            clock = walk(i)
            finish_time[i] = clock
            clock +=1

    return clock

m[0] = [1] * n
for i in range(1,n):
    cols = list(map(int, sys.stdin.readline().split()))
    for j in cols[2:]:
        m[i][j]=1

walk(0)

for i in range(1,n):
    print(i,discover_time[i],finish_time[i])

Python: 
# ??±???????????¢?´¢(Depth First Search)

def DFS(n = 1, A = [0], i = 0, d = [0], f = [0], time = 1):
    for j in range(n):
        if A[i][j] == 1 and d[j] == 0:
            time = time + 1
            d[j] = time
            time = DFS(n, A, j, d, f, time)
    time = time + 1
    f[i] = time
    return time

n = int(raw_input())
A = [0] * n
for i in range(n):
    A[i] = [0] * n

for i in range(n):
    value = map(int, raw_input().split())
    u = value[0] - 1
    k = value[1]
    nodes = value[2:]
    for i in range(k):
        v = nodes[i] - 1
        A[u][v] = 1

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

time = 0
for i in range(n):
    if d[i] == 0:
        time = time + 1
        d[i] = time
        time = DFS(n, A, i, d, f, time)

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

Python: T = [0]

def curserch(N,k,T,P,n):
    T[0] = T[0]+1
    P[k]["d"] = T[0]
    for i in range(1,n+1):
        if N[k][i]==1 and P[i]["d"]==0:
            curserch(N,i,T,P,n)
            T[0] = T[0]+1
            P[i]["f"]=T[0]


n = int(input())
A = [[0 for j in range(n+1)] for i in range(n+1)]


for i in range(n):
    vec = input().split()
    u = int(vec[0])
    k = int(vec[1])
    nodes = vec[2:]
    for i in range(int(k)):
        v = int(nodes[i])
        A[u][v] = 1

P=[{"d":0} for i in range(n+1)]
for i in range(1,n+1):
    if P[i]["d"]==0:
        curserch(A,i,T,P,n)
        T[0] = T[0]+1
        P[i]["f"]=T[0]
for i in range(1,n+1):
    print(i,P[i]["d"],P[i]["f"])

Python: #16D8101014F KurumeRyunosuke 2018/6/20

n=int(input())
ls=[[0 for i in range(n)]for j in range(n)]
for i in range(n):
	tmp=input().split()
	for j in range(int(tmp[1])):
		ls[i][int(tmp[j+2])-1]=1

"""
for i in range(n):
    for j in range(n):
        if(j!=n-1):
            print(int(ls[i][j]), end=' ')
        else:
            print(int(ls[i][j]))
"""
stuck=[0]
count=1
d=[0 for i in range(n)]
f=[0 for i in range(n)]
d[0]=count
while True:
	count+=1
	p=0
	for i in range(n):
		if ls[stuck[len(stuck)-1]][i] is not 0:
			ls[stuck[len(stuck)-1]][i]=0
			
			p=1
			#print(stuck)
			stuck.append(i)
			d[stuck[len(stuck)-1]]=count
			break

	if p is 1:
		for i in range(n):
			ls[i][stuck[len(stuck)-1]]=0
	if p is 0:
		#print("//")
		a=stuck.pop()
		f[a]=count
		for i in range(n):
			ls[a][i]=0

	if len(stuck) is 0:
		t=0
		for i in range(n):
			for j in range(n):
				if ls[i][j] is not 0 and t is 0:
					count+=1
					stuck.append(i)
					d[stuck[len(stuck)-1]]=count
					#print(i)
					t=1
					
		if t is 0:
			break
		#print("break")

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

Python: n=0
t=1
def adjacent_matrix():
    global n
    n=int(input())
    v=[]
    array=[]
    for i in range(n):
        zero=[0 for i in range(n)]
        a=list(map(int,input().split()))
        a=a[2:]
        for j in a:
            zero[j-1]=1
        array.append(zero)
    return array
def dfs(array,i,d,f):
    global t
    if i == n:
        return
    else:
        if(d[i] == 0):
            d[i] = t
            t += 1
            for (j,x) in enumerate(array[i]):
                if x == 1:
                    dfs(array,j,d,f)
            f[i] = t
            t += 1
    return 


def main():
    array=adjacent_matrix()
    print()
    d=[0 for i in range(n)]
    f=[0 for i in range(n)]
    for i in range(n):
        dfs(array,i,d,f)
    for i in range(n):
        print("{} {} {}".format(i+1,d[i],f[i]))

if __name__ == "__main__":
    main()

Python: N=int(input())
L=[[10**9]for i in range(N+1)]
for i in range(N):
    l=list(map(int,input().split()))
    for j in range(l[1]):
        L[i+1].append(l[2+j])
#print(L)
for i in range(N+1):
    L[i].sort(reverse=True)
    
#print(L)
ans=[]
for i in range(N+1):
    ans.append([0,0])


from collections import deque 

Q=deque()
cnt=1
for i in range(N):
    Q.append([0,N-i])
for i in range(10**7):

    if len(Q)==0:
        break
    q0,q1=Q.pop()
    #print(q0,q1)
    if q1!=10**9:
        if ans[q1][0]==0:
            ans[q1][0]=cnt
            cnt+=1
            for j in L[q1]:
                Q.append([q1,j])
    else:
        ans[q0][1]=cnt
        cnt+=1
    #print(ans,Q)
for i in range(1,N+1):
    print(i,ans[i][0],ans[i][1])

Python: from sys import stdin
from collections import deque

def read_graph(n):
    A = [ [0]*(n+1) for _ in range(n+1) ]
    for _ in range(n):
        line = deque(stdin.readline().strip().split())
        i = line.popleft()
        line.popleft()
        for k in line:
            A[int(i)][int(k)] = 1
    return A

def dfs_ctrl(n, A):
    color = ["WHITE"] * (n+1)
    d = [0] * (n+1)
    f = [0] * (n+1)
    time = 0

    def dfs(u):
        nonlocal color
        nonlocal time
        if color[u] == "WHITE":
            color[u] = "GRAY"
            time += 1
            d[u] = time

            for v in range(1, n+1):
                if A[u][v] and color[v] == "WHITE":
                    dfs(v)
            color[u] = "BLACK"
            time += 1
            f[u] = time

    for i in range(1, n+1):
        if color[i] == "WHITE":
            dfs(i)

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

n = int(input())
A = read_graph(n)
dfs_ctrl(n, A)