Go: package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

type TimeRecord struct {
	discoverTime int
	finishTime   int
}

func main() {
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)

	n, err := nextInt(sc)
	if err != nil {
		panic(err)
	}

	timeRecordMap := make([]TimeRecord, n)
	childrenMap := make([][]int, n)
	for i := 1; i <= n; i++ {
		node, err := nextInt(sc)
		if err != nil {
			panic(err)
		}
		timeRecordMap[node-1] = TimeRecord{-1, -1}

		childNum, err := nextInt(sc)
		if err != nil {
			panic(err)
		}
		childrenMap[node-1] = make([]int, childNum)
		for j := 0; j < childNum; j++ {
			child, err := nextInt(sc)
			if err != nil {
				panic(err)
			}
			childrenMap[node-1][j] = child
		}
	}

	timer := 1
	startNode := 1
	for {
		visit(startNode, &timer, childrenMap, timeRecordMap)
		startNode = findStartNode(childrenMap, timeRecordMap)
		if startNode < 0 {
			break
		}
	}
	for k, v := range timeRecordMap {
		fmt.Printf("%d %d %d\n", k+1, v.discoverTime, v.finishTime)
	}
}

func findStartNode(childrenMap [][]int, timeRecordMap []TimeRecord) int {
	x := -1
	for node, timeRecord := range timeRecordMap {
		if timeRecord.discoverTime < 0 {
			x = node + 1
			break
		}
	}
	return x
}

func visit(currentNode int, timer *int, childrenMap [][]int, timeRecordMap []TimeRecord) {
	if timeRecordMap[currentNode-1].discoverTime > 0 {
		return
	}
	children := childrenMap[currentNode-1]
	timeRecordMap[currentNode-1] = TimeRecord{*timer, timeRecordMap[currentNode-1].finishTime}
	(*timer)++
	for i := 0; i < len(children); i++ {
		visit(children[i], timer, childrenMap, timeRecordMap)
	}
	timeRecordMap[currentNode-1] = TimeRecord{timeRecordMap[currentNode-1].discoverTime, *timer}
	(*timer)++
}

func nextInt(sc *bufio.Scanner) (int, error) {
	sc.Scan()
	return strconv.Atoi(sc.Text())
}

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

int r[101][101];
int d[101], f[101], num, visit[100]={0}, p=1;

void dfs(int n){
    if(visit[n]!=1){
        visit[n] = 1;
        d[n] = p++;
        for(int i=1; i<num+1; i++)
            if(r[n][i]==1) dfs(i);
        f[n] = p++;
    }
}

int main(void){
    int u, k, v;
    cin >> num;
    for(int i=0; i<num; i++){
        cin >> u >> k;
        for(int j=0; j<k; j++){
            cin >> v;
            r[u][v]=1;
        }
    }
    for(int i=1; i<num+1; i++){
        if(visit[i]!=1) dfs(i);
    }
    for(int i=1; i<num+1; i++)
        cout << i << " " << d[i] << " " << f[i] << endl;
    return 0;
}

C++: #include <iostream>
#include <algorithm>
 
using namespace std;
 
typedef struct{
  int begin;
  int end;
  bool f;
}fint;
fint T[101];
 
int times = 1;
int n;
int graph[101][101];
 
void bfs(int now){
 
  T[now].f = true;
  T[now].begin = times++;
 
  for( int i = 1 ; i <= n; i++ ){
    if( graph[now][i] == 1 && !T[i].f ) bfs(i);
  }
  T[now].end = times++;
 
}
 
int main(void){
 
  int s,t,u;
  cin >> n;
  for( int i = 0 ; i < n ; i++ ){
    cin >> s >> t;
    for( int j = 1 ; j <= t ; j++ ){
      cin >> u;
      graph[s][u] = 1;
    }
  }
  for( int i = 1 ; i <= n ; i++ ){
    T[i].begin = 0;
    T[i].end = 0;
    T[i].f = false;
  }
  for( int i = 1 ; i <= n ; i++ ){
    if( !T[i].f ) bfs(i);
  }
 
  for( int i = 1 ; i <= n ; i++ ){
    cout << i << " " << T[i].begin << " " << T[i].end << endl;
  }
 
 
  return 0;
}

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

typedef pair<int, int> edge;

int vernum[101];
edge path[101][101];
int n;

edge found[101];

int t=0;
void dfs(int v){
    t++;
    found[v].first = t;
    int i=0;
    while(1){
        if(!path[v][i].first)
            break;
        if(!found[path[v][i].second].first){
            dfs(path[v][i].second);
        }
        i++;
    }
    t++;
    found[v].second = t;
}

int main() {
    int i, j;
    ios_base::sync_with_stdio(0);
    
    int e, v;
    cin >> n;
    
    for(i=1; i<=n; i++){
        cin >> vernum[i];
        cin >> e;
        for(j=0; j<e; j++){
            cin >> v;
            path[i][j] = make_pair(i, v);
        }
    }
    
    for(i=1; i<=n; i++){
        if(!found[i].first)
            dfs(i);
    }
    
    for(i=1; i<=n; i++){
        cout << vernum[i] << " " << found[i].first << " " << found[i].second << endl;
    }
    
    
    return 0;
}

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