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>
#define rep(i,n) for (int i = (0); i < (n); ++i)
#define rrep(i,n) for(int i = 1; i <= (n); ++i)
#define drep(i,n) for(int i = (n)-1; i >= 0; --i)
#define srep(i,s,t) for (int i = s; i < t; ++i)
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
#define limit(x,l,r) max(l,min(x,r))
#define lims(x,l,r) (x = max(l,min(x,r)))
#define isin(x,l,r) ((l) <= (x) && (x) < (r))
#define show(x) cout << #x << " = " << (x) << endl
#define show2(x,y) cout << #x << " = " << (x) << ", " << #y << " = " << (y) << endl
#define show3(x,y,z) cout << #x << " = " << (x) << ", " << #y << " = " << (y) <<  ", " << #z << " = " << (z) << endl
#define showv(v) rep(i,v.size()) printf("%d%c", v[i], i==v.size()-1?'\n':' ')
#define showv2(v) rep(j,v.size()) showv(v[j])
#define showt(t,n) rep(i,n) printf("%d%c", t[i], i==n-1?'\n':' ')
#define showt2(t,r,c) rep(j,r) showt(t[j],c)
#define showvp(p) rep(i,p.size()) printf("%d %d\n", p[i].first, p[i].second)
#define printv(v) rep(i,v.size()) printf("%d\n", v[i])
#define printt(t,n) rep(i,n) printf("%d\n", t[i])
#define incl(v,x) (find(all(v),x)!=v.end())
#define incls(s,c) (s.find(c)!=string::npos)
#define lb(a,x) distance((a).begin(),lower_bound(all(a),(x)))
#define ub(a,x) distance((a).begin(),upper_bound(all(a),(x)))
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define sz(x) (int)(x).size()
#define pcnt __builtin_popcountll
#define bit(n,k) ((n>>k)&1) // nのk bit目
#define bn(x) ((1<<x)-1)
#define dup(x,y) (((x)+(y)-1)/(y))
#define newline puts("")
#define uni(x) x.erase(unique(all(x)),x.end())
#define SP << " " <<
#define v(T) vector<T>
#define vv(T) v(v(T))
using namespace std;
using ll = long long;
using ld = long double;
using vi = vector<int>;
using vvi = vector<vi>;
using vl = vector<ll>;
using vvl = vector<vl>;
using vs = vector<string>;
using P = pair<int, int>;
using T = tuple<int, int, int>;
using vp = vector<P>;
using vt = vector<T>;
const int mod = 1000000007;
const double EPS = 1e-9;
//const long double EPS = 1e-14;
const int INF = (1<<30)-1;
const ll LINF = (1LL<<62)-1;
#define dame { puts("No"); return 0;}
#define yn {puts("Yes");}else{puts("No");}
inline int in() { int x; cin >> x; return x;}
inline ll lin() { ll x; cin >> x; return x;}
inline char chin() { char x; cin >> x; return x;}
inline string stin() { string x; cin >> x; return x;}
inline double din() { double x; cin >> x; return x;}
//template<class T = int> inline T in() { T x; cin >> x; return (x);}
template<typename T>inline ll suma(const v(T)& a) { ll res(0); for (auto&& x : a) res += x; return res;}
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }
char itoa(int n) { return n + '0';}
ll gcd(ll a, ll b) { return b?gcd(b,a%b):a;}
ll lcm(ll a, ll b) { return a/gcd(a,b)*b;}

int n;
vvi to;
vi d, f;
int t = 0;

void dfs(int v, int p=-1) {
  if (d[v] != -1) return; 
  d[v] = ++t;
  for (int u : to[v]) {
    if (u == p) continue;
    dfs(u,v);
  }
  f[v] = ++t;
  return;
}

int main () {
  cin >> n;
  to = vvi(n);
  rep(i,n) {
    int u = in();
    u--;
    int k = in();
    rep(i,k) {
      int v = in();
      v--;
      to[u].pb(v);
    }
  }

  d = vi(n,-1);
  f = vi(n);

  rep(i,n) dfs(i);

  rep(i,n) {
    int id = i+1;
    printf("%d %d %d\n", id, d[i], f[i]);
  }
  return 0;
}

C++: #include<stdio.h>
#define N 100
#define WHITE 0
#define GRAY 1
#define BLACK 2

int n,M[N][N];

int color[N],d[N],f[N],tt;

void dfs_visit(int u){
  int v;
  color[u] = GRAY;
  d[u] = ++tt;
  for(v=0;v<n;v++){
    if(M[u][v] == 0) continue;
    if(color[v] == WHITE){
      dfs_visit(v);
    }
  }
  color[u] = BLACK;
  f[u] = ++tt;
}

void dfs(){
  int u;
  for(u=0;u<n;u++) color[u] =WHITE;
  tt=0;

  for(u=0;u<n;u++){
    if(color[u] == WHITE) dfs_visit(u);
  }
  for(u=0;u<n;u++){
    printf("%d %d %d\n",u+1,d[u],f[u]);
  }
}

int main(){
  int u,v,k,i,j;

  scanf("%d",&n);
  for(i=0;i<n;i++){
    for(j=0;j<n;j++) M[i][j] = 0;
  }

  for(i=0;i<n;i++){
    scanf("%d %d",&u,&k);
    u--;
    for(j=0;j<k;j++){
      scanf("%d",&v);
      v--;
      M[u][v] = 1;
    }
  }
  dfs();

  return 0;
}

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

enum Status {WHITE, GRAY, BLACK};

stack<int> stc;
Status *status;
int *discovered, *finished;
bool *visited;
vector<vector<int> > a;
int n, timer;

void dfs(int i){
        if(status[i]==BLACK) return;
        if(status[i]==WHITE){
                discovered[i] = ++timer;
                status[i] = GRAY;
        }

        if(visited[i]) return;
        visited[i] = true;
        stc.push(i);

        for(int j=0;j<a[i].size();j++) dfs(a[i][j]);

        if(status[i]==GRAY){
                finished[i] = ++timer;
                status[i] = BLACK;
        }
        stc.pop();
}

int main(){

        cin>>n;
        a = vector<vector<int> >(n, vector<int>());
        status = new Status[n];
        discovered = new int[n];
        finished = new int[n];
        visited = new bool[n];

        int m, k, r;
        for(int i=0;i<n;i++){
                cin>>r;
                cin>>m;
                for(int j=0;j<m;j++){
                        cin>>k;
                        a[r-1].emplace_back(k-1);
                }
        }
        for(int i=0;i<n;i++) status[i] = WHITE;
        for(int i=0;i<n;i++) visited[i] = false;

        timer = 0;
        for(int i=0;i<n;i++)
                dfs(i);

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