Go: package main

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

func main() {
	scn := bufio.NewScanner(os.Stdin)
	scn.Split(bufio.ScanWords)
	nextInt := func() int { scn.Scan(); r, _ := strconv.Atoi(scn.Text()); return r }
	w := bufio.NewWriter(os.Stdout)

	n := nextInt()
	vecs := make([][]int, n)
	for i := 0; i < n; i++ {
		u := nextInt()
		k := nextInt()
		for j := 0; j < k; j++ {
			vecs[u-1] = append(vecs[u-1], nextInt()-1)
		}
	}

	ds := make([]int, n)
	fs := make([]int, n)
	founds := make([]bool, n)
	t := 0
	for i := range founds {
		if !founds[i] {
			t = dfs(vecs, ds, fs, founds, i, t)
		}
	}

	for i := 0; i < n; i++ {
		fmt.Fprintln(w, i+1, ds[i], fs[i])
	}

	w.Flush()
}

func dfs(vecs [][]int, ds, fs []int, founds []bool, i, t int) (time int) {
	t++
	ds[i] = t
	founds[i] = true
	for _, v := range vecs[i] {
		if !founds[v] {
			t = dfs(vecs, ds, fs, founds, v, t)
		}
	}
	t++
	fs[i] = t

	return t
}

C++: #include<iostream>
int main(){

  int n,a;
  std::cin>>n;

  int Adj[100][100],adj[100][100]={0},find[100][2],back[100][100],depth[100]={0},endflag[100]={0},flag;
	int u[n],k[n],kcou=0,timenow=0,v,pred,prev,firstv,backcount[100]={0};
  for(int i=0;i<n;i++){
    std::cin>>u[i];
    std::cin>>k[i];
    for(int j=0;j<k[i];j++){
      std::cin>>Adj[i][j];
    }
  }
	
	/*
  for(int i=0;i<n;i++){
    for(int j=0;j<n;j++){
    	std::cout<<Adj[i][j]<<" ";
    }
  	std::cout<<"\n";
  }*/
	
	v=0;
	firstv=0;
	while(timenow<n*2){
		flag=0;
		if(find[firstv][0]!=NULL&&find[firstv][1]!=NULL){
			for(int i=0;i<n;i++){
				if(find[i][0]==NULL){
					//std::cout<<i<<"\n";
					firstv=i;
					v=i;
					break;
				}
			}
		}
		
		//std::cout<<v+1<<" ";
		///std::cout<<find[v][0]<<" "<<find[v][1];
		
		if(find[v][0]==NULL){
			timenow++;
			find[v][0]=timenow;
			//std::cout<<" '"<<timenow<<"' ";
			flag=1;
			//std::cout<<flag<<" 1";
		}else if(find[v][1]==NULL){
			if(endflag[v]==1){
				if(backcount[v]<=1){
				timenow++;
				find[v][1]=timenow;
				//std::cout<<" '"<<timenow<<"' ";
				}
				flag=2;
			}
			//std::cout<<flag<<" 2";
		}else{
			backcount[v]--;
			v=back[v][backcount[v]];
			//backcount[v]--;
			flag=3;
			//std::cout<<flag<<" 0";
		}

		if(flag==0){
			pred=depth[v];
			depth[v]++;
			prev=v;
			v=Adj[v][pred]-1;
			back[v][backcount[v]]=prev;
			backcount[v]++;
			//std::cout<<flag<<"\n";
		}else if(flag==1){
			if(endflag[v]==0){
				if(Adj[v][depth[v]]-1!=v&&Adj[v][depth[v]]-1!=firstv){
					pred=depth[v];
					depth[v]++;
					prev=v;
					v=Adj[v][pred]-1;
					back[v][backcount[v]]=prev;
					backcount[v]++;
					//std::cout<<v<<"\n";
				}else{
					pred=depth[v];
					depth[v]++;
				}
			}
		}else if(flag==2){
			backcount[v]--;
			v=back[v][backcount[v]];
			//backcount[v]--;
			//std::cout<<flag<<"\n";
		}
		if(depth[v]>k[v]-1){
			endflag[v]=1;
		}
		
	}
	
	
	
	
  for(int i=0;i<n;i++){
     std::cout<<i+1<<" "<<find[i][0]<<" ";
     std::cout<<find[i][1]<<"\n";
    //std::cout<<"\n";
  }

  return 0;
}

C++: #include<cstdio>
#include<array>
#include<vector>
#include<stack>
using namespace std;
const int MAX_V=101;
array<int,MAX_V> open{0};
array<int,MAX_V> close{0};
array<vector<int>,MAX_V> edge;
int t=0;

void dfs(int f){
  open[f]=++t;
  for(int a:edge[f]){
    if(open[a]==0){
      dfs(a);
    }
  }
  close[f]=++t;
}

int main(){
  int n;scanf("%d",&n);
  for(int i=0;i<n;i++){
    int u;scanf("%d",&u);
    int k;scanf("%d",&k);
    for(int j=0;j<k;j++){
      int v;scanf("%d",&v);
      edge[u].push_back(v);
    }
  }
  for(int i=0;i<n;i++)
    if(open[i+1]==0)
      dfs(i+1);
  for(int i=0;i<n;i++){
    printf("%d %d %d\n",i+1,open[i+1],close[i+1]);
  }
}

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

int A[101][101] = {0};
int n, tt = 0, d[101] = {0}, f[101] = {0}, color[101] = {0};
stack<int> S;

int next(int u) {
    int i;
    for ( i = 1; i <= n; i++ ) {
        if ( A[u][i] == 1 && color[i] != 1 ) return i;
    }

    return -1;
}

void dfs (int u) {
    int i, j ,k;
    S.push(u);
    d[u] = ++tt;
    color[u] = 1;
    while ( !S.empty() ) {
        j = S.top();
        i = next(j);
        if ( i != -1 ) {
            color[i] = 1;
            d[i] = ++tt;
            S.push( i );
        }
    else {
        f[j] = ++tt;
        S.pop();
    }
    }

}

int main() {
    int i, j, k, v;
    cin >> n;
    for ( i = 0; i < n; i++ ) {
        cin >> j >> k;
        while ( k-- ) {
            cin >> v;
            A[j][v] = 1;
        }
    }

    for ( i = 1; i <=n; i++ ) if ( color[i] != 1 ) dfs(i);
    for ( i = 1; i <=n; i++ ) cout << i << ' ' << d[i] << ' ' << f[i] << endl;

    return 0;

}

C++: #include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cassert>
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define REP(i,n) FOR(i,0,n)
#define rep(i,n) FOR(i,0,n)
#define DEBUG(x) cout<<#x<<": "<<x<<endl
#define vint vector<int>
#define vdouble vector<double>
#define vstring vector<string>
using namespace std;

#include<map>
#include<set>
#include<queue>

typedef long long ll;
typedef unsigned long long ull;

const int MAX_N = 1000000;
static const int INFTY = (1 << 21);

class Edge{
public:
    int from, to, cost;
    Edge(int from = 0, int to = 0, int cost = 0) :
            from(from), to(to), cost(cost){}

    bool operator < (const Edge &e) const{
        return cost < e.cost;
    }
    bool operator >(const Edge &e) const{
        return cost > e.cost;
    }

};

class Node{
public:
    vector<Edge> edges;
    int dist;
    int done;
    int times;
    int timee;

    Node(){
        dist = INFTY;
        done = 0;
    }
};

class Graph{
public:
    vector<Node> nodes;
    Graph(int n) {
        rep(i, n) { Node n;  nodes.push_back(n); }
    }
    Node& operator[](int i){
        return nodes[i];
    }
};

class Data{

public:
    int dist;
    Edge *edge;
    Data(int dist, Edge *edge) {
        this->dist = dist;
        this->edge = edge;
    }

    bool operator < (const Data &d) const{
        return dist < d.dist;
    }
    bool operator >(const Data &d) const{
        return dist > d.dist;
    }
};

Graph G(0);

int V;
int t;

void dfs(int v){
    if (G[v].done != 0) return;

    // fprintf(stderr, "%d %d\n", v, t);

    G[v].done = 1;
    t++;
    G[v].times = t;
    for(auto &e: G[v].edges){
        dfs(e.to);
    }
    t++;
    G[v].timee = t;
}

void dfs_run(){
    t = 0;
    dfs(0);
}

int main() {

    int V;
    cin >> V;
    G = Graph(V);

    rep(i, V){
        int from; cin >> from; from--;
        int e_count; cin >> e_count;

        vint vec;
        rep(j, e_count){
            int to; cin >> to; to--;
            vec.push_back(to);
        }
        sort(vec.begin(), vec.end());
        rep(j, e_count){
            G[from].edges.push_back(Edge(from, vec[j], 1));
        }
    }

    dfs_run();

    rep(i, V){
        fprintf(stdout, "%d %d %d\n", i+1, G[i].times, G[i].timee);
    }
}