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 <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <string>
#include <cstring>
#include <sstream>
#include <cmath>
#include <functional>
#include <fstream>
#include <cstdlib>
typedef long long ll;
const int MOD = 1e9+7;


#define REP(i, N) for (int i = 0; i < (N); i++)
#define REPP(i, a, b) for (int i = (a); i < (b); i++)
#define ALL(v) (v).begin(), (v).end()
#define RALL(v) (v).rbegin(), (v).rend()
#define VSORT(c) sort((c).begin(),(c).end())
#define SZ(x) ((int)(x).size())
//vvintを作る　マクロで　 #define vvint(N,M) vector<vector<int>>

using namespace std;


int main(){
    
    cin.tie(0);
    ios::sync_with_stdio(false);

    int n;
    cin >> n;
    int d[n+1],f[n+1];
    int color[n+1];
    REPP(i,1,n+1) color[i] = 0;
    REPP(i,1,n+1) d[i] = -1;
    REPP(i,1,n+1) f[i] = -1;

    vector<queue<int> > graph(n+1);
    int tmp,idx,row;
    for(int i = 1; i < n+1;i++){
        cin >> idx >> row;
        for(int l = 0; l < row;l++){
            cin >> tmp;
            //  追加順はソート済みと仮定
            graph[i].push(tmp);
        }
    }

    stack<int> doing;
    int t = 0;

    for(int i = 1; i < n+1;i++){
        int now = i;
        if(color[i] == 0){
             doing.push(now);
             color[i] = 1;
             d[i] = ++t;
        }
        while(!doing.empty()){
            if(!graph[now].empty()){
                if(color[graph[now].front()] == 0){
                    color[graph[now].front()] = 1;
                    doing.push(graph[now].front());
                    int tmp = graph[now].front();
                    graph[now].pop();
                    now = tmp;
                    
                    t++;
                    d[now] = t;
                }else{
                    graph[now].pop();
                }
            }else{
                t++;
                f[now] = t;
                doing.pop();
                if(!doing.empty()){
                    now = doing.top();
                }
            }
        }
    } 

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

    return 0;
}

C++: #include <iostream>
#include <stack>
using namespace std;

#define MAX 100

stack<int> G;
int Graph[MAX+1][MAX+1];
int result[MAX+1][2];
int n;
int cnt = 0;

void dfs(int idx) {
    bool bl = false;
    bool bl2 = false;
    int idx2;
    for(int i=1; i<=n; i++) {
        //もし一つでも残っているノードがあればpushする
        if(Graph[idx][i]==1) {
            for(int j=1; j<=n; j++) {
                Graph[j][i] = 0;
            }
            //cout << "push: " << i << endl;
            cnt++;
            result[i][0] = cnt;
            G.push(i);
            dfs(i);
            bl = true;
        }
    }
    //一つも残っていなかったらpopする
    if(bl==false) {
        //cout << "pop: " << G.top() << endl;
        cnt++;
        result[G.top()][1] = cnt;
        for(int i=1; i<=n; i++) {
            if(Graph[G.top()][i]==1) {
                bl2 = true;
                idx2 = i;
            }
        }
        G.pop();
        if(G.empty() && bl2==false) {
            return;
        }
        else if(bl2==true) {
            dfs(idx2);
        }
        else {
            dfs(G.top());
        }
    }
}

int main() {
    int idx, g_num, a;

    cin >>n;
    for(int i=0; i<n; i++) {
        cin >> idx >> g_num;
        for(int j=0; j<n; j++) {
            Graph[idx][j] = 0;
        }
        for(int j=0; j<g_num; j++) {
            cin >> a;
            Graph[idx][a] = 1;
        }
    }
    G.push(1);
    cnt++;
    result[1][0] = cnt;
    //cout << "push: " << 1 << endl;
    dfs(1);

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

    return 0;
}

C++: #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
 
struct status{
    int idx_node;
    vector<int> children;
    int finded = 0;
    int visited = 0;
};
 
int step = 0;
vector<status> graph;
 
void dfs(int now_node){
    ++step;
    graph[now_node-1].finded = step;
    for(auto&& next_node:graph[now_node-1].children){
        if(not graph[next_node-1].finded){
            dfs(next_node);
        }
    }
    ++step;
    graph[now_node-1].visited = step;
}
 
int main(void){cin.tie(0);ios::sync_with_stdio(false);
 
    //stdi
    int nb_nodes; cin >> nb_nodes;
    graph.resize(nb_nodes);
    for(auto& times:graph){
        int idx_node; cin >> idx_node; graph[idx_node-1].idx_node = idx_node;
        int nb_edges; cin >> nb_edges; graph[idx_node-1].children.resize(nb_edges);
        for(auto& a:graph[idx_node-1].children){
            cin >> a;
        }
        sort(graph[idx_node-1].children.begin(),graph[idx_node-1].children.end());
    }
     
    //dfs
    for(int i=1; i<=nb_nodes; ++i){
        if(not graph[i-1].finded) dfs(i);
    }
     
    //stdo
    for(auto& a:graph){
        cout<<a.idx_node<<" "
            <<a.finded<<" "
            <<a.visited<<"\n";
    }
}