Go: package main

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

/***************************************************************
stackによる深さ優先探索を実装する。
***************************************************************/

const (
	N     = 100
	WHITE = 0
	GRAY  = 1
	BLACK = 2
)

var (
	n            int
	Adj          [N][N]int
	statusColor  [N]int
	discoverTime [N]int
	finishTime   [N]int
	clock        int
	nt           [N]int
)

/***************************************************************
Stackの定義:
- field
	container: ノードの格納されたスライス
	sp: スタックポインタ
- method
	size(): スタックに積まれているノードの個数を返す
	top(): スタックの一番上に積まれているノードを返す
	isEmpty(): スタックが空かどうかを返す
	pop(): スタックの要素をポップし削除する
	push(): スタックに要素を積む
***************************************************************/

type Stack struct {
	container []int
	sp        int
}

func (s *Stack) size() int {
	return len(s.container)
}

func (s *Stack) top() int {
	return s.container[s.sp]
}

func (s *Stack) isEmpty() bool {
	return s.sp == 0
}

func (s *Stack) pop() int {
	_pop := func() {
		s.container = s.container[:len(s.container)-1]
	}
	defer _pop()
	if s.isEmpty() {
		panic("There is no elements in stack!")
	}
	s.sp--
	return s.container[s.sp]
}

func (s *Stack) push(n int) {
	s.sp++
	s.container[s.sp] = n
}

func next(u int) int {
	for v := nt[u]; v < n; v++ {
		nt[u] = v + 1
		if Adj[u][v] == 1 {
			return v
		}
	}
	return -1
}

func _DFS(target int) {
	for i := 0; i < n; i++ {
		nt[i] = 0
	}
	stack := new(Stack)
	stack.container = make([]int, N)
	stack.push(target)
	statusColor[target] = GRAY
	clock++
	discoverTime[target] = clock
	for !stack.isEmpty() {
		u := stack.top()
		v := next(u)
		if v != -1 {
			if statusColor[v] == WHITE {
				statusColor[v] = GRAY
				clock++
				discoverTime[v] = clock
				stack.push(v)
			}
		} else {
			stack.pop()
			statusColor[u] = BLACK
			clock++
			finishTime[u] = clock
		}
	}
}

func DFS() {
	for i := 0; i < n; i++ {
		statusColor[i] = WHITE
		nt[i] = 0
	}
	clock = 0
	for i := 0; i < n; i++ {
		if statusColor[i] == WHITE {
			_DFS(i)
		}
	}
	for i := 0; i < n; i++ {
		fmt.Printf("%d %d %d\n", i+1, discoverTime[i], finishTime[i])
	}
}

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)
	scanner.Scan()
	n, _ = strconv.Atoi(scanner.Text())
	for i := 0; i < n; i++ {
		for j := 0; j < n; j++ {
			Adj[i][j] = 0
		}
	}
	for i := 0; i < n; i++ {
		scanner.Scan()
		u, _ := strconv.Atoi(scanner.Text())
		scanner.Scan()
		k, _ := strconv.Atoi(scanner.Text())
		u--
		for j := 0; j < k; j++ {
			scanner.Scan()
			v, _ := strconv.Atoi(scanner.Text())
			v--
			Adj[u][v] = 1
		}
	}

	DFS()
}

Python: def h(G,G1,d,f,c,tmp,tmp1,n):
    if c[0]==2:
        f[0]=f[tmp]+1
        return 0
    cnt=0
    for i in range(n):
        if G1[tmp1][i]==1:
            if c[i]==0:
                d[i]=d[tmp1]+1
                c[i]+=1
                tmp=tmp1
                tmp1=i
                G1[tmp][i]=0
                h(G,G1,d,f,c,tmp,tmp1,n)

        else:
            cnt+=1
            if cnt==n:
                if c[tmp1]==1:
                    d[tmp1]=d[tmp]+1
                    c[tmp1]+=1
                    f[tmp1]=d[tmp1]+1
                    tmp=tmp1
                    for j in range(n):
                        if G[j][tmp]==1:
                            tmp1=j
                    G1[j][tmp1]=0
                    c[tmp1]+=1
                    h(G,G1,d,f,c,tmp,tmp1,n)
                elif c[tmp1]==2:
                    f[tmp1]=f[tmp]+1
                    tmp=tmp1
                    for j in range(n):
                        if G[j][tmp]==1:
                           tmp1=j
                           G1[j][tmp]=0
                    c[tmp1]+=1
                    h(G,G1,d,f,c,tmp,tmp1,n)
n=int(input())
d=[1 for i in range(n)]
f=[0 for i in range(n)]
c=[0 for i in range(n)]
G=[[0 for i in range(n)]for j in range(n)]
G1=[[0 for i in range(n)]for j in range(n)]
u=[0 for i in range(n)]
for i in range(n):
    A=input().split()
    u[i]=int(A[0])
    k=int(A[1])
    for j in range(k):
        x=int(A[j+2])-1
        G[i][x]=1
        G1[i][x]=1

d[0]=1
c[0]+=1
for i in range(n):
    if G[0][i]==1:
        d[i]=d[0]+1
        c[i]+=1
        tmp=0
        tmp1=i
        G1[0][i]=0
        break
h(G,G1,d,f,c,tmp,tmp1,n)
for i in range(n):
    print(i+1,d[i],f[i])

Python: n=int(input())

l=[[0 for i in range(n)] for j in range(n)]##静的確保 隣接行列
d=[0 for i in range(n)]##発見
f=[0 for i in range(n)]##完了
stack=[]##スタック
check=[]

for i in range(n):
    p=[int(x) for x in input().split()]
    
    for j in range(n):
        if j+1 in p[2:]:
            l[i][j]=1
##print("---隣接行列---")
##print(l)

time=1


while len(check)<n:
    for i in range(n):
        if i+1 not in check:
            stack+=[i+1]
            d[i]=time
            break
        else: pass

    while len(stack)!=0:
        print("----------while---------")
        for i in range(n):
            if l[stack[-1]-1][i]==1 and not i+1 in check and stack[-1]-1!=i:
                time+=1
                d[i]=time
                stack+=[i+1]

               ## print("stack:",stack)
               ## print("check:",check)
               ## print("d[",i,"]:",d[i])
                break
            elif i==n-1:
##最深    
                check+=[stack[-1]]
                time+=1
                f[stack.pop()-1]=time

               ## print("f[",i,"]:",f[i])
               ## print("check:",check)
    time+=1


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

Python: n = int(input())

from collections import deque

graph = [deque([]) for _ in range(n+1)]

for _ in range(n):
    u, k, *v = [int(x) for x in input().split()]

    v.sort()
    for i in v:
        graph[u].append(i)
    
arrive = [-1 for i in range(n+1)]
finish = [-1 for i in range(n+1)]

times = 0

def dfs(v):
    global times
    times += 1
    arrive[v] = times
    stack = [v]
    
    while stack:
        v = stack[-1]
        if graph[v]:
            w = graph[v].popleft()
            if arrive[w] == -1:
                times += 1
                arrive[w] = times
                stack.append(w)
        else:
            times += 1
            finish[v] = times
            stack.pop()
    return

for i in range(n):
    if arrive[i+1] == -1:
        dfs(i+1)

for j in range(n):
    tmp = [j+1, arrive[j+1], finish[j+1]]
    print(*tmp)

Python: n=int(input())
G=[[j for j in range(n)] for i in range(n)]
for i in range(n):
    g_in=list(map(int,input().split()))
    u=g_in[0]
    k=g_in[1]
    v=g_in[2:]
    for j in v:
        G[u-1][j-1]=1

visited=[0 for i in range(n)]
finished=[0 for i in range(n)]
L=[]
out=[[i+1,0,0] for i in range(n)]
step=0

def dfs(cn):
    flg=0
    if visited[cn]==0:
        flg=1
        L.append(cn)
    visited[cn]=1
    for i in range(n):
        if cn!=i and G[cn][i]==1 and visited[i]==0:
            dfs(i)
    if flg==1:
        L.append(cn)

i=0
while visited.count(1)<n:
    dfs(i)
    i+=1
copied=[0 for i in range(len(L))]

for i in range(len(L)):
    if copied[L[i]]==0:
        copied[L[i]]=1
        out[L[i]][1]=i+1
    elif copied[L[i]]==1:
        copied[L[i]]=2
        out[L[i]][2]=i+1

out=[' '.join(map(str,i)) for i in out]
#print(' '.join(map(str,[i+1 for i in L])))
print('\n'.join(map(str,out)))

Python: import sys
u=[]
k=[]
v=[]

time = 0

n=int(sys.stdin.readline().strip())
yattayatu=[False for i in range(n)]

s=[0 for i in range(n)]
f=[0 for i in range(n)]

for i in range(n):
	inp = sys.stdin.readline().strip().split(" ")
	inp = list(map(lambda x: int(x), inp))
	u.append(inp[0])
	k.append(inp[1])
	v.append(inp[2:])


def func(nodeid):
	global time
	if(yattayatu[nodeid-1]==True):
		return
	time += 1
	s[nodeid-1] = time
	for i in range(k[nodeid-1]):
		func(v[nodeid-1][i])
	time +=1
	f[nodeid-1]=time
	yattayatu[nodeid-1]=True

func(1)

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