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: #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)

Python: n=int(input())
a=[[0 for i in range(n)]for j in range(n)]
for i in range(n):
    v=list(input().split())
    for j in range(len(v)):
        v[j]=int(v[j])
    x=2
    for k in range(v[1]):
        a[i][v[x+k]-1]=1
#print(a)

stack=[]
v=[]
d=[0]*n
f=[0]*n
t=1

while len(v)<n:
    for i in range(n):
        if i+1 not in v:
            stack.append(i+1)
            d[i]=t
            break
        else: pass
        
    while len(stack)!=0:
        for i in range(n):
            if a[stack[-1]-1][i]==1 and stack[-1]-1!=i and i+1 not in v:
                stack.append(i+1)
                a[stack[-1]-1][i]==0
                t+=1
                d[i]=t
            elif i==n-1:
                t+=1
                f[stack[-1]-1]=t
                v.append(stack.pop())
            else: pass
            # print("stack ",stack)
            #print("v ",v)
#print("d=",d," f=",f)
for i in range(n):
    print(i+1,d[i],f[i])