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>
//#define int long long
//#define _DEBUG
#include <vector>
using namespace std;
int const infty = -1, none = -9;

//input
int N, T[107][107]; //T[i][j]:i->T[i][j]の辺

int /*D[107], */t, d[107], f[107];
bool visited[107];
void dfs(int cur){
    visited[cur] = true;
    d[cur] = t;
    t++;
    //cerr << "Visiting " << cur << " " << t << endl;
    for(int j=0; j<107; j++){
        if(T[cur][j]==none) break;
        if(!visited[T[cur][j]]/* || (D[T[cur][j]]!=infty || D[T[cur][j]]>D[cur])*/){
            //D[T[cur][j]] = D[cur]+1;
            dfs(T[cur][j]);
        }
    }
    f[cur] = t;
    t++;
}
void solve(){
    t = 1;
    //D[0] = 0;
    for(int i=0; i<N; i++){
        if(!visited[i]) dfs(i);
    }
}
void get(){
    cin >> N;
    //fill(D, D+N, infty);
    for(int i=0; i<N; i++){
        for(int j=0; j<N; j++){
            T[i][j] = none;
        }
    }

    for(int i=0; i<N; i++){
        int _i, k;
        cin >> _i >> k;
        for(int j=0; j<k; j++){
            int vj;
            cin >> vj;
            T[i][j] = vj-1;
        }
    }
    fill(visited, visited+N, false);
}

signed main(){
    get();
    solve();
    /*for(int i=0; i<N; i++){
        cout << i+1 << " " << D[i] << endl;
    }*/
    for(int i=0; i<N; i++){
        cout << i+1 << " " << d[i] << " " << f[i] << endl;
    }
}

C++: #include <iostream>
#include <vector>
#include <stack>

using namespace std;

struct Node {
    bool visit = false;
    vector<int> next;
    int position = 0;
    int start;
    int end;
};

int main() {
    int n, id, k, temp, time = 1;
    Node node[101];
    stack<int> st;

    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> id >> k;
        for (int j = 0; j < k; j++) {
            cin >> temp;
            node[id].next.push_back(temp);
        }
    }

    node[1].start = time++;
    st.push(1);
    while (!st.empty()) {
        temp = st.top();
        if (node[temp].position < node[temp].next.size() && node[node[temp].next[node[temp].position]].visit == false) {
            node[node[temp].next[node[temp].position]].start = time++;
            st.push(node[temp].next[node[temp].position++]);
        }
        else {
            node[temp].visit = true;
            node[temp].end = time++;
            st.pop();
        }
    }

    for (int i = 1; i <= n; i++) {
        cout << i << " " << node[i].start << " " << node[i].end << endl;
    }

    return 0;
}

C++: #include <bits/stdc++.h>
using namespace std;

int discover(int &t, int node, int n, vector<vector<int>> &g, vector<int> &d, vector<int> &f);

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

	vector<int> d(n+1);
	vector<int> f(n+1);
	stack<int> st;

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


	int t=0;
	for (int i=1;i<=n;++i)
	{
		if (d[i]<0)
		{
			d[i]=++t;
			discover(t,i,n,g,d,f);
			//f[i]=++t;
		}
	}

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


int discover(int &t, int node, int n, vector<vector<int>> &g, vector<int> &d, vector<int> &f)
{

	for (int i=0;i<g[node].size();++i)
	{
		int nn=g[node][i];
		if (d[nn]<0)
		{
			++t;
			d[nn]=t;
			discover(t,nn,n,g,d,f);
		}
	}

	++t;
	f[node]=t;

	return 0;
}

C++: #define _CRT_SECURE_NO_WARNINGS
#define MAX 2000000000
#include <iostream>
#include <algorithm>
#include <stack>
using namespace std ;

int d[102] = { 0 }, f[102] = { 0 };
int M[102][102];

int main() {
	stack<int> stk;
	int n;
	cin >> n;
	for (int i = 1;i <= n;i++) {
		int k,l,m;
		cin >> m;
		cin >> k;
		for (int j = 0;j < k;j++) {
			cin >> l;
			M[m][l] = 1;
		}
	}
    
	stk.push(1);

    int i = 1,time=1;
    d[1]=1;
	while (!stk.empty()) {
		if (M[stk.top()][i] == 1 && d[i] == 0) {
			stk.push(i);
			time++;
			d[i] = time;
			i = 1;
		}
		else {
			i++;
			if (i > n) {
			    time++;
				f[stk.top()] = time;
				stk.pop();
				i=1;
			}
		}
	}

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

C++: #include<iostream>
#define FOR(i,a,b) for (int i=(a);i<(b);i++)
using namespace std;
int G[100][100] = {};
int time = 0;
typedef struct ANS
{
	int id, t, e;
	bool done;
};

void rec(ANS a[],int t)
{
	::time++;
	a[t].t = ::time;
	a[t].done = true;
	FOR(i, 0, 100)
	{
		if (G[t][i] == 1 && a[i].done == false)
		{
			rec(a, i);
		}
	}
	::time++;
	a[t].e = ::time;
}

int main()
{
	ANS ans[101];
	int n;
	cin >> n;
	FOR(i, 0, n)
	{
		ans[i].id = i + 1;
		ans[i].done = false;
		int u, m;
		cin >> u >> m;
		FOR(j, 0, m)
		{
			int l;
			cin >> l;
			G[u - 1][l - 1] = 1;
		}
	}
	rec(ans, 0);
	FOR(i, 0, n)
	{
		cout << ans[i].id << " " << ans[i].t << " " << ans[i].e << endl;
	}
	return 0;
}

C++: #include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < n; i++)
using namespace std;
typedef long long ll;

int n, t = 0;
vector<vector<int> > G(110);
pair<int, int> toki[110];
bool vis[110];

void dfs(int v)
{
    if(vis[v]) return;
    t++;
    toki[v].first = t;
    vis[v] = true;
    rep(i, G[v].size())
    {
        if(vis[G[v][i]]) continue;
        dfs(G[v][i]);
    }
    t++;
    toki[v].second = t;
    return;
}

int main(void)
{
    cin >> n;
    rep(i, n) vis[i] = false;
    rep(i, n)
    {
        int t, k;
        cin >> t >> k;
        t--;
        rep(j, k)
        {
            int v;
            cin >> v;
            v--;
            G[t].push_back(v);
        }
    }
    rep(i, n)
    {
        dfs(i);
    } 
    rep(i, n)
    {
        cout << i+1 << " " << toki[i].first << " " << toki[i].second << endl;
    }
    return 0;
}

C++: #include <iostream>
#include <stack>
using namespace std;
int d[101],f[101],G[101][101];
stack<int>s;
int n,t;
void dfs(int u)
{
    s.push(u);
    d[u]=t++;
    int i;
    while(!s.empty()){
        u=s.top();
        for(i=1;i<=n;i++)
        {
            if(G[u][i]==1 && d[i]==0)
            {
                s.push(i);
                d[i]=t++;
                //u=i;
                break;
            }
        }
        if(i>n)
        {
            f[s.top()]=t++;
            s.pop();
        }
    }
}
int main()
{
    int k,u,v;
    cin>>n;
    for(int i=1;i<=n;i++){
        d[i]=0;
        for(int j=1;j<=n;j++)
            G[i][j]=0;
    }
    for(int i=0;i<n;i++)
    {
        cin>>u>>k;
        for(int j=0;j<k;j++)
        {
            cin>>v;
            G[u][v]=1;
        }
    }
    t=1;
    for(int i=1;i<=n;i++)
    {
        if(d[i]==0)
            dfs(i);
    }
    for(int i=1;i<=n;i++)
    {
        cout<<i<<' '<<d[i]<<' '<<f[i]<<endl;
    }
    return 0;
}