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 <bits/stdc++.h>
using namespace std;

int g[105][105],b[105],f[105],cnt=1,n,is[105];

void dfs(int v)
{
    is[v]=1;
    b[v]=cnt++;
    for(int i=1;i<=n;i++){
        if(i==v) continue;
        if(g[v][i]&&!is[i]) dfs(i);
    }
    f[v]=cnt++;
}

int main()
{
    int v1,d,v2;
    cin>>n;
    memset(g,0,sizeof g);
    memset(is,0,sizeof is);
    for(int i=0;i<n;i++){
        cin>>v1>>d;
        for(int i=0;i<d;i++){
            cin>>v2;
            g[v1][v2]=1;
        }
    }
    dfs(1);
    for(int i=1;i<=n;i++){
        cout<<i<<" "<<b[i]<<" "<<f[i];
        if(i!=n) cout<<endl;
    }
    return 0;
}

C++: #include <bits/stdc++.h>
#define ll long long
#define INF 999999999
#define MOD 1000000007

using namespace std;

typedef pair<int,int>P;

struct edge{
	int from;
	int to;
};

const int MAX_N = 100;

vector<edge> G[MAX_N];
bool flag[MAX_N];
P res[MAX_N];
int t = 1;

void dfs(int x)
{
	res[x].first = t++;
	flag[x] = true;
	for(int i=0;i<G[x].size();i++){
		edge e = G[x][i];
		if(!flag[e.to]){
			dfs(e.to);
		}
	}
	res[x].second = t++;
}

int main()
{
	int n;
	cin >> n;
	for(int i=0;i<n;i++){
		int id,m;
		cin >> id;
		cin >> m;
		for(int j=0;j<m;j++){
			edge e;
			int end;
			cin >> end;
			e.from = id-1;
			e.to = end-1;
			G[id-1].push_back(e);
		}
	}
	fill(flag,flag+n,false);
	int time=0;
	for(int i=0;i<n;i++){
		if(!flag[i]){
			dfs(i);
		}
	}		
	for(int i=0;i<n;i++){
		cout << i+1 << " " << res[i].first << " " << res[i].second << "\n";
	}
}

C++: #include <cstdio>
#include <utility>
#include <vector>
#define rep(i,a) for(int i=0;i<(a);++i)

int n;
std::vector<std::vector<int> > G;
std::vector<bool> used;
std::vector<std::pair<int, int> > res;
int tim = 1;

void dfs( int v )
{
  used[v] = true;
  res[v].first = tim++;

  for( int u : G[v] ) if( !used[u] )
    dfs( u );

  res[v].second = tim++;

  return;
}

int main()
{
  scanf( "%d", &n );
  G.resize( n );
  used.resize( n );
  res.resize( n );

  rep( i, n )
  {
    int u, k;
    scanf( "%d%d", &u, &k );

    rep( j, k )
    {
      int v;
      scanf( "%d", &v );
      G[i].push_back( v-1 );
    }
  }

  rep( i, n ) if( !used[i] )
    dfs( i );

  rep( i, n )
    printf( "%d %d %d\n", i+1, res[i].first, res[i].second );

  return 0;
}

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


using namespace std;

int timecount = 0;

void dfs(int cur, int u, bool* visited, int* timearray, int* timearray_end, unordered_map<int, vector<int> > mymap);

int main(){
  int u, i, id, k, j;
  cin >> u;
  unordered_map<int, vector<int> > mymap;

  for (i = 0; i < u; ++i){
    cin >> id >> k;
    vector<int> points;
    for (j = 0; j < k; ++j){
      int a;
      cin >> a;
      points.push_back(a);
    }
    mymap[id] = points;
  }
  
  bool visited[u+1];
  for (j = 1; j <= u; ++j){
    visited[j] = false;
  }
  visited[1] = true;

  int timearray[u+1];
  for (j = 1; j <= u; ++j){
    timearray[j] = 0;
  }
  int timearray_end[u+1];
  for (j = 1; j <= u; ++j){
    timearray_end[j] = 0;
  }

  dfs(1, u, visited, timearray, timearray_end, mymap);

  for (j = 1; j <= u; ++j){
    cout << j << " " << timearray[j] << " " << timearray_end[j]<< endl;
  }

}

void dfs(int cur, int u, bool* visited, int* timearray, int* timearray_end, unordered_map<int, vector<int> > mymap){
  timecount++;
  timearray[cur] = timecount;

  for(int i = 1; i <= u; ++i){
    
    if((i!=cur)&&(find(mymap[cur].begin(), mymap[cur].end(), i) != mymap[cur].end())&&(!visited[i])){
      visited[i] = true;
      dfs(i, u, visited, timearray, timearray_end, mymap);
    }
  }
  timecount++;

  timearray_end[cur] = timecount;
}

C++: #include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int INF = 1e9;

int d[105] = { -1 }, f[105] = { -1 };
int n = -1;
int mat[105][105] = { { 0 } };
int visited[105] = { 0 };

void dfs(int v, int& now)
{
  d[v] = now;
  visited[v] = 1;
  ++now;
  for (int u = 1; u <= n; ++u) {
    if (mat[v][u] && !visited[u]) {
      dfs(u, now);
    }
  }
  f[v] = now;
  ++now;
}

int main()
{
  fscanf(stdin, "%d", &n);
  for (int i = 0; i < n; ++i) {
    int u = -1, k = -1, v = -1;
    fscanf(stdin, "%d %d", &u, &k);
    for (int j = 0; j < k; ++j) {
      fscanf(stdin, "%d", &v);
      mat[u][v] = 1;
    }
  }
  int now = 1;
  dfs(1, now);
  for (int i = 0; i < n; ++i) {
    fprintf(stdout, "%d %d %d\n", i + 1, d[i + 1], f[i + 1]);
  }
  return 0;
}