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++: 


/**
 *      purpose : 
 *      author  : kyomukyomupurin
 *      created : 
**/

// input/output
#include <iostream>
#include <fstream>
#include <sstream>
// container class
#include <array>
#include <deque>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
// math, algorithm
#include <algorithm>
#include <cmath>
#include <complex>
#include <numeric>
// etc
#include <bitset>
#include <cassert>
#include <cctype>
#include <cstring>
#include <chrono>
#include <iomanip>
#include <random>
#include <utility>
// using-directive
using namespace std;
// alias template
using int64 = long long;
using vi = vector<int>;
using vl = vector<int64>;
using pii = pair<int, int>;
using pll = pair<int64, int64>;
// text macro replacement
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define print(x) cout << (x) << '\n'
#define debug(x) cerr << #x << ": " << (x) << '\n'
#define dbg(v) for (size_t _ = 0; _ < v.size(); ++_){cerr << #v << "[" << _ << "] : " << v[_] << '\n';}
// variadic template
template<typename T> inline void chmin(T &a, T b) {if (a > b) a = b; return;}
template<typename T> inline void chmax(T &a, T b) {if (a < b) a = b; return;}
// constant
const int INF = (1<<30) - 1;
const int64 INF64 = (1LL<<62) - 1;
const int MOD = 1000000007;

vector<vector<int>> graph(101);

vi d(101, -INF), f(101);

int cur = 0;

void dfs(int s){
  d[s] = ++cur;
  for (auto next : graph[s]) {
    if (d[next] != -INF) continue;
    dfs(next);
  }
  f[s] = ++cur;
}

int main(){
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);

  int n; cin >> n;
  graph.resize(n); d.resize(n); f.resize(n);

  rep(i, n) {
    int u, k; cin >> u >> k;
    --u;
    rep(j, k) {
      int v; cin >> v; --v;
      graph[u].push_back(v);
    }
  }
  dfs(0);

  for (int i = 0; i < n; ++i) {
    if (d[i] == -INF) dfs(i);
    cout << i + 1 << " " << d[i] << " " << f[i] << '\n';
  }

  return 0;
}

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

using namespace std;

const int MAX = 101;

vector<int> G[MAX];
int d[MAX], f[MAX];
int *T;

void dfs(int u) {

    if (!d[u]) d[u] = ++(*T);

    for (int v : G[u]) {
        if (!d[v]) {
            d[v] = ++(*T);
            dfs(v);
        }
    }

    if (!f[u]) f[u] = ++(*T);
}

int main() {

    int n;
    cin >> n;

    int t = 0;
    T = &t;
    fill(d, d + MAX, 0);
    fill(f, f + MAX, 0);

    for (int i = 0; i < n; i++) {
        int u, k;
        cin >> u >> k;
        for (int j = 0; j < k; j++) {
            int v;
            cin >> v;
            G[u].push_back(v);
        }
    }

    for (int i = 1; i <= n; i++) {
        if (!d[i]) dfs(i);
    }


    for (int i = 1; i <= n; i++) {
        cout << i << " " << d[i] << " " << f[i] << endl;
    }
}

C++: #include <bits/stdc++.h>
using namespace std;
#define N 100
int t = 0;
stack<int> st;
int d[N + 1], f[N + 1], V[N + 1];
int adj[N + 1][N + 1];

void dfs(int i, int n)
{
    for (int j = 0; j < V[i]; j++)
    {
        if (d[adj[i][j]] == -1)
        {
            d[adj[i][j]] = ++t;
            dfs(adj[i][j], n);
        }
    }
    f[i] = ++t;
}

int main()
{
    int n;
    cin >> n;
    V[0] = n;
    for (int i = 0; i < n; i++)
        adj[0][i] = i + 1;
    for (int i = 0; i < n; i++)
    {
        int u, k;
        cin >> u >> k;
        V[u] = k;
        for (int j = 0; j < k; j++)
        {
            int v;
            cin >> v;
            adj[u][j] = v;
        }
    }

    for (int i = 0; i <= n; i++)
        d[i] = f[i] = -1;

    dfs(0, n);

    for (int i = 1; i <= n; i++)
        cout << i << ' ' << d[i] << ' ' << f[i] << endl;
}

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

using namespace std;

#define MAX 110
int num;
int matrix[MAX][MAX];
int dst[MAX];

void input(){
    cin >> num;
    for(int i=0;i<MAX;i++){
        dst[i] = -1;
        for(int j=0;j<MAX;j++){
            matrix[i][j] = 0;
        }
    }
    for(int i=1;i<=num;i++){
        int v; cin >> v;
        int tmp; cin >>tmp;
        for(int j=0;j<tmp;j++){
            int vi; cin >> vi;
            matrix[v-1][vi-1] = 1;
        }
    }
}

void dfs(){
    stack<int> S;
    S.push(0);
    dst[0] = 0;
    while(!S.empty()){
        int cur = S.top();
        S.pop();
        if(dst[cur]==-1 || dst[cur]== 0){
            for(int i=0;i<num;i++){
                if(matrix[cur][i]==1){
                    S.push(i);
                    dst[i] = dst[cur] + 1;
                }
            }
        }
        else{
            for(int i=0;i<num;i++){
                if(matrix[cur][i]==1){
                    if(dst[cur] +1 <= dst[i]){
                        S.push(i);
                        dst[i] = dst[cur] + 1;
                    }
                }
            }
        }
    }
    for(int i=0;i<num;i++){
        cout << i+1 << " " <<  dst[i] << endl;
    }
}

int main(){
    input();
    dfs();
}

C++: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MOD = 1e9 + 7;
const int inf = 1e9;
const ll INF = 1e18;
const double pi = 3.14159265358979323846;
#define rep(i, n) for (int i = 0; i < n; i++)
using Graph = vector<vector<int>>;
using pint = pair<int, int>;
int dx[4] = { 1, 0, -1, 0 }, dy[4] = { 0, 1, 0, -1 };

int n;
vector<int> first, last;
bool seen[100] = {};

void dfs (const Graph& g, int u, int& ptr) {
    first[u] = ptr++;
    seen[u] = 1;
    for (auto next : g[u]) {
        if (seen[next]) continue;
        dfs (g, next, ptr);
    }
    last[u] = ptr++;
}

int main() {
    cin >> n;
    Graph g (n);
    first.resize (n);
    last.resize (n);
    rep (i, n) {
        int a, k;
        cin >> a >> k;
        rep (j, k) {
            int b;
            cin >> b;
            g[a - 1].push_back (b - 1);
            //g[b].push_back (a);
        }
    }
    int ptr = 0;
    rep (i, n) {
        if (first[i] == 0 && last[i] == 0) {
            dfs (g, i, ptr);
        }
    }

    rep (i, n) cout << i + 1 << " " << first[i] + 1 << " " << last[i] + 1 << "\n";
}

C++: #include <bits/stdc++.h>
using namespace std;

#define REP(i,n) for(int i=0;i<n;++i)

const int MAX_N = 100;
int n, t = 0, flag[MAX_N] = {0}, d[MAX_N], f[MAX_N], G[MAX_N][MAX_N] = {0};

void dfs(int u) {
  int v;
  flag[u] = 1;
  d[u] = ++t;
  REP(v, n) {
    if (!G[u][v]) continue;
    if (!flag[v]) dfs(v);
  }
  flag[u] = 2;
  f[u] = ++t;
}

int main() {
  int u, v, k;
  cin >> n;
  REP(i, n) {
    cin >> u >> k;
    REP(j, k) {
      cin >> v;
      G[u - 1][v - 1] = 1;
    }
  }
  REP(i, n) if (!flag[i]) dfs(i);
  REP(i, n) cout << i + 1 << ' ' << d[i] << ' ' << f[i] << endl;
  return 0;
}