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)
using namespace std;

int G[100][100];
int d[100] = {0};
int f[100];
int now_time = 1;
stack<int> search_stack;

int main() {
    // 制約見て！！！デカかったらlong longにすること！
    int n, u, k, v;
    cin >> n;
    rep(i, n) {
        cin >> u >> k;
        u--;
        rep(j, k) {
            cin >> v;
            v--;
            G[u][v] = 1;
        }
    }
    rep(i,n){
        if(d[i]==0){
            search_stack.push(i);
            d[i]=now_time++;
        }
        while(search_stack.size() > 0) {
            int s = search_stack.top();
            rep(i, n + 1) {
                if(i == n) {
                    f[s] = now_time++;
                    search_stack.pop();
                }
                else if(s != i && d[i] == 0 && G[s][i] == 1) {
                    search_stack.push(i);
                    d[i] = now_time++; 
                    break;
                }
            }
        }
    }
    rep(i, n) { printf("%d %d %d\n", i + 1, d[i], f[i]); }
}

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

const int MAX_N = 100;

struct Node {
  int v;
  int firstVisitedTime;
  int lastVisitedTime;
  bool visited;
};

void visit(int *count, int n, std::vector<std::list<int> *> *graph, std::vector<struct Node *> *nodes) {
  (*count)++;
  
  struct Node *node = nodes->at(n);

  if (!node->visited) {
    node->firstVisitedTime = *count;
    node->visited = true;
  }  

  //  std::cout << (*count) << " = " << n << std::endl;

  std::list<int> *neighbors = graph->at(n);

  while (!neighbors->empty()) {
    int v = neighbors->front();
    neighbors->pop_front();
    
    if (!nodes->at(v)->visited) {
      visit(count, v, graph, nodes);
    }
  }

  (*count)++;
  node->lastVisitedTime = (*count);

  //  std::cout << (*count) << " = " << n << std::endl;
}

int main(void) {
  std::cin.tie(0);
  std::ios::sync_with_stdio(false);  

  int n = 0;
  std::cin >> n;

  std::vector<std::list<int> *> *graph = new std::vector<std::list<int> *>(n + 1);
  std::vector<struct Node *> *nodes = new std::vector<struct Node *>(n + 1);
  
  for (int i = 1; i <= n; i++) {
    int v = 0;
    std::cin >> v;

    int k = 0;
    std::cin >> k;

    std::list<int> *neighbors = new std::list<int>();

    for (int i = 0; i < k; i++) {
      int a = 0;
      std::cin >> a;

      neighbors->push_back(a);
    }

    graph->at(i) = neighbors;

    struct Node *node = (struct Node *) std::malloc(sizeof(struct Node));

    node->v = i;
    node->firstVisitedTime = 0;
    node->lastVisitedTime = 0;
    node->visited = false;
    
    nodes->at(i) = node;
  }

  int count = 0;
  int start = 1;

  visit(&count, start, graph, nodes);  

  for (std::vector<struct Node *>::iterator iterator = nodes->begin() + 1; iterator != nodes->end(); ++iterator) {
    struct Node *node = *iterator;
        
    std::cout << node->v << " " << node->firstVisitedTime << " " << node->lastVisitedTime << std::endl;
  }
  
  return 0;
}

C++: #include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < n; ++i)
#define FOR(i, a, b) for (int i = a; i < b; ++i)
#define ALL(vec) vec.begin(), vec.end()
#define rALL(vec) vec.rbegin(), vec.rend()
using namespace std;
using ll = long long;

vector<int> d, f, color;
vector<vector<int>> A;
int cnt = 0;

int next(int i) {
    for (auto j : A[i]) {
        if (color[j] == 0) {
            d[j] = cnt;
            color[j] = 1;
            return j;
        }
    }
    f[i] = cnt;
    color[i] = 2;
    return -1;
}

void dfs(int u) {
    cnt += 1;
    stack<int> S;
    S.push(u);
    d[u] = cnt;
    color[u] = 1;
    while (!S.empty()) {
        cnt += 1;
        int i = S.top();
        int j = next(i);
        if (j != -1) S.push(j);
        else S.pop();
    }
}

int main() {
    int n;
    cin >> n;
    A = vector<vector<int>>(n, vector<int>(0));
    d = vector<int>(n, 0);
    f = vector<int>(n, 0);
    color = vector<int>(n, 0);
    rep(i, n) {
        int u, k;
        cin >> u >> k;
        rep(j, k) {
            int tmp;
            cin >> tmp;
            A[i].push_back(--tmp);
        }
    }
    rep(i, n) {
        if (color[i] == 0) dfs(i);
    }
    rep(i, n) {
        printf("%d %d %d\n", i + 1, d[i], f[i]);
    }
    return 0;
}