Go: #include <bits/stdc++.h>
using namespace std;
static const int WHITE = 0;
static const int GRAY  = 1;
static const int BLACK = 2;
static const int N     = 100;

int n, tt;
vector<vector<int>> M(N, vector<int>(N));
vector<int> color(N), d(N), f(N);

void dfs_visit(int u) {
  color[u] = GRAY;
  d[u]     = ++tt;
  for (int v = 0; v < n; v++) {
    if (M[u][v] == 0) continue;
    if (color[v] == WHITE) { dfs_visit(v); }
  }
  color[u] = BLACK;
  f[u]     = ++tt;
}

void dfs() {
  tt = 0;

  for (int u = 0; u < n; u++) {
    if (color[u] == WHITE) dfs_visit(u);
  }
  for (int u = 0; u < n; u++) {
    printf("%d %d %d\n", u + 1, d[u], f[u]);
  }
}

int main() {
  int u, v, k;
  cin >> n;
  for (int i = 0; i < n; i++) {
    cin >> u >> k;
    u--;
    for (int j = 0; j < k; j++) {
      cin >> v;
      v--;
      M[u][v] = 1;
    }
  }

  dfs();
}

Python: # -*- coding: utf_8 -*-

level = False
def debug(v):
    if level:
        print(v)

n = int(input())
a = [0]

for i in range(n):
    v = input().split()
    v.pop(0)
    v.pop(0)
    a.append([int(x) for x in v])

debug(a)
stack = [1]
results = [[0 for i in range(2)] for j in range(n + 1)]
results[0][0] = 0
time = 0


def depth_first_search(a, stack):
    debug(results)
    debug(stack)
    global time
    if len(stack) == 0:
        return

    v = stack.pop()
    if results[v][0] == 0:
        time += 1
        results[v][0] = time

    es = a[v]
    if len(es) == 0 and results[v][1] == 0:
        time += 1
        results[v][1] = time

    if len(es) != 0:
        stack.append(v)
        stack.append(es.pop(0))

    depth_first_search(a, stack)

depth_first_search(a, stack)
debug(results)

results.pop(0)

i = 1
for row in results:
    print(str(i) + " " + str(row[0]) + " " + str(row[1]))
    i += 1

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]))

Python: def dfs(G, u, t, d, visited):
  found = t
  visited.add(u)
  t += 1
  for v in G[u]:
    if v not in visited:
      t = dfs(G, v, t, d, visited)
  complete = t
  d[u] = (found, complete)
  t+=1
  return t


n = int(input())
G = {}
for _ in range(n):
  entries = list(map(int, input().split(' ')))
  u = entries[0]
  k = entries[1]
  G[u] = set()
  for v in entries[2:]:
    G[u].add(v)


d = {}
dfs(G, 1, 1, d, set())
for i in sorted(d):
  print(i,d[i][0],d[i][1])

Python: n = int(input())
a = []
for i in range(n):
    a += [list(map(int, input().split()))[2:]]
cnt = 1
pre = [0]*n
aft = [0]*n
color = [0]*n
def dfs(s):
    global cnt
    pre[s-1] = cnt
    cnt += 1
    color[s-1] = 1
    for i in a[s-1]:
        if color[i-1] == 0:dfs(i)
    aft[s-1] = cnt
    cnt += 1

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

for i in range(n):
    print(i+1, pre[i], aft[i])