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

C++: #include <algorithm>
#include <complex>
#include <cstdlib>
#include <ctime>
#include <time.h>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
#include <numeric>
#include <limits>
#include <type_traits>

using namespace std;
#define SAY_YES cout << "YES" << endl;
#define SAY_Yes cout << "Yes" << endl;
#define SAY_NO cout << "NO" << endl;
#define SAY_No cout << "No" << endl;
#define IFYES(TRUE_OR_FALSE)   \
    if (TRUE_OR_FALSE)         \
    {                          \
        cout << "YES" << endl; \
    }                          \
    else                       \
    {                          \
        cout << "NO" << endl;  \
    }
#define IFYes(TRUE_OR_FALSE)   \
    if (TRUE_OR_FALSE)         \
    {                          \
        cout << "Yes" << endl; \
    }                          \
    else                       \
    {                          \
        cout << "No" << endl;  \
    }
#define IFyes(TRUE_OR_FALSE)   \
    if (TRUE_OR_FALSE)         \
    {                          \
        cout << "yes" << endl; \
    }                          \
    else                       \
    {                          \
        cout << "no" << endl;  \
    }
#define DEBUG_OUTPUT_ARRAY(XXX, ONE)                            \
    for (int i = 0; i < (ONE); i++)                             \
    {                                                           \
        cout << "DEBUG: i = " << i << " -> " << XXX[i] << endl; \
    }
#define DEBUG_OUTPUT_ARRAY2(XXX, ONE, TWO)                             \
    for (int i = 0; i < (ONE); i++)                                    \
    {                                                                  \
        cout << "<<< i = " << i << " >>>" << endl;                     \
        for (int j = 0; j < (TWO); j++)                                \
        {                                                              \
            cout << "DEBUG: j = " << j << " -> " << XXX[i][j] << endl; \
        }                                                              \
    }
#define DEBUG_OUTPUT_ARRAY2_BOX(XXX, ONE, TWO) \
    for (int i = 0; i < (ONE); i++)            \
    {                                          \
        cout << i << "  ";                     \
        for (int j = 0; j < (TWO); j++)        \
        {                                      \
            cout << XXX[i][j] << " ";          \
        }                                      \
        cout << endl;                          \
    }

typedef pair<long long int, long long int> pll;


const long long int mod = 1000000007;
const long long int INF = 1e18;
const long double PI=3.14159265358979323; 

long long int N,K,M,A[200],k[200203]={},v[2003],res[200][2],sum=0,cou=0,ten=1;
long long int dp[3005][3005]={};
string S,T;
vector<long long int>vec[200];

bool used[200]={};

long long int dfs(long long int now,long long int time){
    if(used[now]){return time;}
    used[now]=true;
    res[now][0]=time;
    long long int nex=time+1;
    for(long long int j = 0; j < vec[now].size(); j++){
        nex=dfs(vec[now][j],nex);
    }
    res[now][1]=nex;
    return nex+1;
}
int main()
{
    cout << fixed << setprecision(18);
    cin>>N;
    
    for(long long int i = 0; i < N; i++){
        cin>>A[i]>>k[i];
        A[i]--;
        for(long long int j = 0; j < k[i]; j++){
            cin>>v[j];
            v[j]--;
            vec[i].push_back(v[j]);
        }
    }
    long long int tim=1;
    for(long long int i = 0; i < N; i++){
        if(!used[i]){
            tim=dfs(i,tim);
        }
    }
    for(long long int i = 0; i < N; i++){
        cout<<i+1<<" "<<res[i][0]<<" "<<res[i][1]<<endl;
    }
    
}

C++: #include <iostream>
#include <stack>
using namespace std;
static const int N=100;
static const int WHITE=0;
static const int GRAY=1;
static const int BLACK=2;

//??¶????????°
int n;
//?????\??????
int M[N][N];
//??°?????¶???????¢????
int color[N];
//??\??¶????????°??¶???
int d[N];
//??\??¶???????????¶???
int f[N];
//??¶???
int tt;

//????????????????????????u?????????v
int next(int u){
    for(int v=0;v<n;v++){
        if(M[u][v]&&color[v]==WHITE)
            return v;
    }
    return -1;
}

//??¨????????°?????±?????????????´¢
void dfs_visit(int r){
    
    stack<int> S;
    S.push(r);
    color[r]=GRAY;
    //?????°??¶???
    d[r]=++tt;

    while(!S.empty()){
        int u=S.top();
        int v=next(u);
        if(v!=-1&&color[v]==WHITE){
            color[v]=GRAY;
            d[v]=++tt;
            S.push(v);
        }
        else{
            //????????????
            S.pop();
            color[u]=BLACK;
            f[u]=++tt;
        }
    }
}

void dfs(){
    //????§????
    for(int i=0;i<n;i++)
        color[i]=WHITE;
    tt=0;

    //??\????????????u?????????????????±?????????????´¢
    for(int u=0;u<n;u++)
        if(color[u]==WHITE)
            dfs_visit(u);

    for(int i=0;i<n;i++)
        cout<<i+1<<" "<<d[i]<<" "<<f[i]<<endl;
}

int main(){
    int u,k,v;

    cin>>n;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            M[i][j]=0;

    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();
}

C++: #include <cstdio>
#include <vector>

using namespace std;

#define MAX_N (105)

vector<int> G[MAX_N];
bool arrived[MAX_N];
int d[MAX_N];
int f[MAX_N];
int n;
int t;
void dfs( int cur ) {
    t++;
    d[cur] = t;

    for ( int i = 0; i < G[cur].size(); i++ ) {
	int next = G[cur][i];
	if ( !arrived[next] ) {
	    arrived[next] = true;
	    dfs( next );
	}
    }

    t++;
    f[cur] = t;

    return;
}

int main()
{
    scanf("%d", &n);
    for ( int i = 0; i < n; i++ ) {
	int u, k;
	scanf("%d %d", &u, &k);
	u--;
	for ( int j = 0; j < k; j++ ) {
	    int v;
	    scanf("%d", &v);
	    v--;
	    G[u].push_back(v);
	}
    }

    t = 0;
    dfs(0);

    for ( int i = 0; i < n; i++ ) {
	printf("%d %d %d\n", i+1, d[i], f[i]);
    }

    return 0;
}