Go: package main

import (
	"fmt"
)

func main() {
	var n int
	fmt.Scan(&n)
	g := make([][]int, n+1)
	for i := 0; i < n; i++ {
		var u,k int
		fmt.Scan(&u)
		fmt.Scan(&k)
		g[u] = make([]int, k)
		for j := 0; j < k; j++ {
			fmt.Scan(&g[u][j])
		}
	}

	d := make([]int, n+1)
	f := make([]int, n+1)
	dfs(&g, &d, &f, 1, 1)

	for i := 1; i <= n; i++ {
		fmt.Printf("%d %d %d\n", i, d[i], f[i])
	}
}

func dfs(g *[][]int, d *[]int, f *[]int, id int, t int) int {
	if (*d)[id] > 0 {
		return t
	}
	(*d)[id] = t
	t += 1
	for i := 0; i < len((*g)[id]); i++ {
		t = dfs(g, d, f, (*g)[id][i], t)
	}
	(*f)[id] = t
	return t+1
}

C++: #include<bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
typedef long long ll;
typedef pair<ll, ll> PLL;
typedef vector<int> VI;
typedef vector<char> VC;
typedef vector<double> VD;
typedef vector<string> VS;
typedef vector<ll> VLL;
typedef vector<PLL> VP;
const static int INF = 1000000000;
const static int MOD = 1000000007;
const int dx[4]={1, 0, -1, 0};
const int dy[4]={0, 1, 0, -1};
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; }
#define rep(i,n) for (ll i=0; i<(ll)(n); i++)
#define repd(i,n) for (ll i=n-1; i>=0; i--)
#define rept(i,m,n) for(ll i=m; i<n; i++)
#define stl_rep(itr, x) for (auto itr = x.begin(); itr != x.end(); ++itr)
#define all(x) (x).begin(), (x).end()
#define F first
#define S second
#define PF push_front
#define PB push_back
#define SORT(V) sort((V).begin(), (V).end())
#define RVERSE(V) reverse((V).begin(), (V).end())
#define paired make_pair
#define PRINT(V) for(auto v : (V)) cout << v << " "
//charを整数に
int ctoi(char c) { if (c >= '0' && c <= '9') { return c - '0'; } return 0; }
// 累積和 for (int i = 0; i < N; ++i) s[i+1] = s[i] + a[i]; 
void cum_sum(int N,vector<double> a, vector<double> &s){ for(int i=0; i<N; i++){ s[i+1]=s[i]+a[i];}}
//ユークリッドの控除法
ll gcd(ll a,ll b){
    if(b == 0) return a;
    return gcd(b,a%b);
}
//最小公倍数
ll lcm(ll a,ll b){
    ll g = gcd(a,b);
    return a / g * b; // Be careful not to overflow
}
//素数判定
bool is_prime(long long n) {
    if (n <= 1) return false;
    for (long long p = 2; p * p <= n; ++p) {
        if (n % p == 0) return false;
    }
    return true;
}
int getdigit(ll num){
    unsigned digit=0;
    while(num!=0){
        num /= 10;
        digit++;
    }
    return digit;
}
//空白文字も入力 getline(cin, S);
//桁数指定 setprecision
vector<bool> seen;
vector<int> first_order;
vector<int> last_order;

void dfs(vector<vector<int>> &G, int v, int &ptr){
    first_order[v]=ptr++;
    seen[v]=true;
    for(auto nv:G[v]){
        if(seen[nv]) continue;
        dfs(G, nv, ptr);
    }
    last_order[v]=ptr++;
}

int main()
{
    int n;
    cin >> n;
    vector<vector<int>> G(n);
    rep(i,n){
        int a,b;
        cin >> a;
        cin >> b;
        a--;
        rep(i,b){
            int c;
            cin >> c; 
            c--;
            G[a].push_back(c);
        }
    }
    seen.assign(n, false);
    first_order.resize(n);
    last_order.resize(n);
    int ptr=1;
    rep(i,n){
        if(seen[i]==false){
            dfs(G, i, ptr);
        }
    }
    for(int i=0; i<n; i++){
       cout << i+1 << " " << first_order[i] << " " << last_order[i] << endl;
    }
}

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

static const int N=100;
static const int WHITE=0;
static const int GRAY=1;
static const int BLACK=2;

int n, M[N][N];
int color[N], d[N], f[N], tt;
int nt[N];

// uに隣接するvを番号順に取得
int next(int u){
    for(int v=0; v<n; v++){ // 訪問した場所は探索しなくていいため、v+1にしている？
        nt[u] = v+1;
        if(M[u][v]) return v;
    }
    return -1;
}

// スタックを用いた深さ優先探索
void dfs_visit(int r){
    for(int i=0; i<n; i++) nt[i] = 0;

    stack<int> S;
    S.push(r);
    color[r] = GRAY;
    d[r] = ++tt;

    while(!S.empty()){
        int u=S.top();
        int v=next(u);
        if(v!=-1){
            if(color[v] == WHITE){
                color[v] = GRAY;
                d[v] = ++tt;
                S.push(v);
            }
        }
        else{
            S.pop();
            color[u] = BLACK;
            f[u] = ++tt;
        }
    }
}

void dfs(){
    // 初期化
    for(int i=0; i<n; i++){
        color[i] =WHITE;
        nt[i] = 0;
    }
    tt = 0;

    // 未訪問のuを始点として深さ優先探索
    for(int u=0; u<n; u++){
        if(color[u] == WHITE) dfs_visit(u);
    }
    for(int i=0; i<n; i++){
        cout << i+1 << " " << d[i] << " " << f[i] <<endl; 
    }
}

int main(int argc, char const *argv[])
{
    int u, k, v;

    cin >> n;
    for(int i=0; i<n; i++){
        for(int j=0; j<n; j++) M[i][j] = 0;
    }

    for(int i=0; i<n; i++){
        cin >> u >> k;
        u--; // 0 origin
        for(int j=0; j<k; j++){
            cin >> v;
            v--;
            M[u][v] = 1;
        }
    }

    dfs();

    return 0;
}

C++: #include<cstdio>
#include<iostream>
using namespace std;
int n, adj[101][101], d[101], f[101];
int visited[101]; int  tt=0;

void dfs_visit(int i)
{
  if(visited[i]) return ;
  visited[i] = 1;
  d[i] = ++tt;
  for(int v=1; v<=n; v++)
  {
    if(visited[v]==0 && adj[i][v]==1)
      dfs_visit(v);
  }
  f[i] = ++tt;
}
void dfs(int s)
{
  for(int i=1; i<=n; i++)
  {
    dfs_visit(i);
  }
}

int main()
{
  scanf("%d", &n);
  int u, k, v;
  for(int i=0; i<=n; i++)
  {
    for(int j=0; j<=n; j++)
      adj[i][j] = 0;
  }
  for(int i=0; i<n; i++)
  {
    scanf("%d%d", &u, &k);
    for(int j=0; j<k; j++)
    {
      scanf("%d", &v);
      adj[u][v] = 1;
    }
  }
  for(int i=0; i<=n; i++) visited[i] = 0;
  dfs(1);
  for(int i=1; i<=n; i++)
  {
    printf("%d %d %d\n", i, d[i], f[i]);
  }


  return 0;
}

C++: #include <cstdio>
#include <cstring>

const int MAX = 100;
static int time = 0;
int adj[MAX][MAX];
int discover[MAX];
int finish[MAX];

void visit(int node, int n)
{
  ++time;
  if (discover[node - 1] == 0)
    discover[node - 1] = time;

  for (int i = 0; i < n; ++i)
  {
    if (adj[node - 1][i] == 1 && finish[i] == 0)
      visit(i + 1, n);
  }

  ++time;
  finish[node - 1] = time;
}

int main()
{
  std::memset(adj, 0, sizeof(adj));
  std::memset(discover, 0, sizeof(discover));
  std::memset(finish, 0, sizeof(finish));

  int n;
  scanf("%d", &n);

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

  visit(1, n);

  for (int i = 0; i < n; ++i)
    printf("%d %d %d\n", i + 1, discover[i], finish[i]);

  return 0;
}

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

typedef struct {
	bool endflag;
	int firsttime;
	int endtime;
}State;

const int Max = 100;
int map[Max + 1][Max + 1] = { 0 };
std::stack<int> st;
std::vector<State> state;


int main()
{
	int n, k, v, x;
	int cnt = 1;

	std::cin >> n;
	for (int i = 1; i <= n; i++) {
		std::cin >> x >> k;
		for (int j = 1; j <= k; j++) {
			std::cin >> v;
			map[x][v] = 1;
		}
	}

	State s = { false,0,0 };
	for (int i = 0; i <= n; i++) {
		state.push_back(s);
	}

	while (1) {
		if (st.empty() == true) {
			if (state[1].endflag == true) {
				break;
			}
			else {
				st.push(1);
				state[1].firsttime = cnt;
				cnt++;
				continue;
			}
		}

		bool flag = false;
		for (int i = 1; i <= n; i++) {
			if (map[st.top()][i] == 1) {
				if (state[i].endflag == false) {
					st.push(i);
					state[i].firsttime = cnt;
					cnt++;
					flag = true;
					break;
				}
			}
		}
		if (flag == true) {
			continue;
		}
		else {
			state[st.top()].endflag = true;
			state[st.top()].endtime = cnt;
			cnt++;
			st.pop();
		}
	}

	for (int i = 1; i <= n; i++) {
		std::cout << i << " " << state[i].firsttime << " " << state[i].endtime << std::endl;
	}

	return 0;
}