Go: package main

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

func main() {
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)
	sc.Scan()
	num, _ := strconv.Atoi(sc.Text())
	nodes := make(map[int]*node)

	for i := 0; i < num; i++ {
		sc.Scan()
		id, _ := strconv.Atoi(sc.Text())
		sc.Scan()
		nodeNum, _ := strconv.Atoi(sc.Text())
		n := node{id, make([]int, 0), 0, 0}
		for j := 0; j < nodeNum; j++ {
			sc.Scan()
			nid, _ := strconv.Atoi(sc.Text())
			n.nexts = append(n.nexts, nid)
		}
		nodes[id] = &n
	}

	s := Stack{}
	for i := 1; i < len(nodes)+1; i++ {
		if nodes[i].s != 0 {
			continue
		}
		walk(i, &nodes, s)
	}
	for i := 1; i < len(nodes)+1; i++ {
		fmt.Printf("%v %v %v\n", (*nodes[i]).id, (*nodes[i]).s, (*nodes[i]).e)
	}
}

var time int

func walk(nid int, nodes *map[int]*node, s Stack) {
	n := (*nodes)[nid]
	if n.s != 0 {
		return
	}
	time++
	n.s = time
	s.Push(n)
	for _, v := range n.nexts {
		walk(v, nodes, s)
	}
	time++
	n.e = time
}

type node struct {
	id    int
	nexts []int
	s     int
	e     int
}

// Stack is Stack
type Stack struct {
	stack []interface{}
}

// Push new value
func (stack *Stack) Push(val interface{}) {
	stack.stack = append(stack.stack, val)
}

// Pop new value
func (stack *Stack) Pop() interface{} {
	val := stack.stack[len(stack.stack)-1]
	stack.stack = stack.stack[0 : len(stack.stack)-1]
	return val
}

C++: #include<math.h>
#include<cmath>
#include<bitset>
#include<stdio.h>
#include<string>
#include<map>
#include<algorithm>
#include<vector>
#include<iostream>
#include<utility>
using namespace std;
vector<int> seen;
int d[110],f[110],z=1;
int dfs(vector<vector<int> > g,int v){
  int i;
  seen[v]=1;
  d[v]=z;
  z++;
  for(i=0;i<g[v].size();i++){
    if(seen[g[v][i]]==0){
      dfs(g,g[v][i]);
    }
  }
  f[v]=z;
  z++;
};
int main(){
  vector<vector<int> > g(110);
  int x,i,j,u,k,n,v;
  scanf("%d\n",&n);
  for(i=0;i<n;i++){
    scanf("%d %d",&u,&k);
    u--;
    for(j=0;j<k;j++){
      scanf("%d",&v);
      v--;
      g[u].push_back(v);
    }
  }
  seen.assign(n,0);
  for(i=0;i<n;i++){
    if(seen[i]==0){
      dfs(g,i);
    }
  }
  for(i=0;i<n;i++){
    printf("%d %d %d\n",i+1,d[i],f[i]);
  }
  return 0;
}

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

using namespace std;

int d[10010]={0};//最初に訪問した時刻を入れるタイムスタンプ
int f[10010]={0};//vの隣接リストを調べ終えた時刻のタイムスタンプ

int back[10010]={0};//番号nのもときた街番号をいれる

int g[1001][1001]={{0}};//要素を0で初期化
int timestamp = 1;
int number;
int dfs(int cur){
  d[cur]= timestamp;
  timestamp += 1;
  for(int dst = 0; dst < number; dst++){
    if(g[cur][dst]==1 && d[dst]==0){
      // d[dst]=timestamp;
      back[dst]=cur;
      dfs(dst);
    }
  }
  // timestamp += 1;
  // cout << "f[cur]" <<f[cur]<<"timestamp"<<timestamp<<"cur"<<cur<<endl;
  // abort();
  if(timestamp > number*2){
    return 0;
  }
  // cout << "f[cur]" <<f[cur]<<"timestamp"<<timestamp<<"cur"<<cur<<endl;
  // abort();
  f[cur]=timestamp;
  timestamp++;
}
void ans(int n){
  for (int i = 0; i < n; ++i)
  {
    cout << i+1 << " " << d[i] <<" "<< f[i] <<endl;
  }
}

int main(){
  // int g[1001][1001]={{0}};//要素を0で初期化
  int n,a,b,c;
  cin >> n;
  number = n;
  for (int i = 0; i < n; ++i)
  {
    cin >> a >> b ;
    for (int i = 0; i < b; ++i)
    {
      cin >> c;
      g[a-1][c-1]=1;/* code */
    }
  }
  d[0]=1;
  dfs(0);
  for (int i = 0; i < number; ++i)
  {
    if(d[i]==0){
      d[i]=timestamp;
      dfs(i);
    }
  }
  // for (int i = 0; i < number; ++i)
  // {
  //   cout << back[i]<<" ";
  // }

  ans(n);
}

C++: #include <iostream>
#include "memory.h"
#include <stack>

using namespace std;

bool matrix[100][100];
int n;

int next(int k){
	for(int i = 0; i < n; i++){
		if(matrix[k][i] == true)
			return i + 1;
	}
	return false;
}

int main(){
	int index, temp, num, current, count = 1;
	int start_end[100][2];
	stack<int> back;

	memset(matrix, 0, sizeof(matrix));
	memset(start_end, 0, sizeof(start_end));

	cin >> n;

	for(int i = 0; i < n; i++){
		cin >> index >> num;
		while(num--){
			cin >> temp;
			matrix[index-1][temp-1] = true;
		}
	}
	back.push(0);
	current = 0;
	while(true){
		while(!back.empty()){
			int r;
			r = next(current);
			if(start_end[current][0] == 0){
				start_end[current][0] = count;
				count++;
			}
			if(r){
				matrix[current][r-1] = false;
				back.push(current);
				current = r - 1;
			}
			else{
				if(start_end[current][1] == 0){
					start_end[current][1] = count;
					count++;
				}
				current = back.top();
				back.pop();
			}
		
		}
		for(int i = 0; i < n; i++){
			if(start_end[i][0] == 0 || start_end[i][1] == 0){
				back.push(i);
				break;
			}
		}
		if(back.empty())
			break;
	}
	for(int i = 0; i < n; i++){
		cout << i + 1 << " " << start_end[i][0] << " " << start_end[i][1] << endl;
	}

}

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

#define ll long long
#define vvi vector<vector<int>>
#define vec vector
#define pq priority_queue
#define all(v) (v).begin(), (v).end()
#define uniqueV(x) sort(x.begin(), x.end()); x.erase(unique(x.begin(), x.end()), x.end());
#define rep(i, n) for (int (i) = (0); (i) < (n); ++(i))
#define repp(i, m, n) for (int (i) = (m); (i) < (n); ++(i))
#define debug(x) cerr << #x << ": " << x << endl;
#define debug2(x, y) cerr<<"("<<#x<<", "<<#y<<") = "<<"("<<x<<", "<<y<<")"<<endl;
#define debug3(x, y, z) cerr<<"("<<#x<<", "<<#y<<", "<<#z<<") = "<<"("<<x<<", "<<y<<", "<<z<<")"<<endl;
#define debugB(x, y) cerr<<#x<<": "<<bitset<y>(x) << endl;
#define line() cerr << "---------------" << endl;

const int dx[] = {1, -1, 0, 0};
const int dy[] = {0, 0, -1, 1};

template<typename T>
void printA(vector<T> &printArray, char between = ' ') {
   int paSize = printArray.size();
   for (int i = 0; i < paSize; i++) { cerr << printArray[i] << between;}
   if (between != '\n') {cerr << endl;}
}

// ------------------------------------------------------------------------------------------

int N;
vector<vector<int>> G;
int d[111], f[111];
int turn;

void dfs(int from) {
   turn++;
   for (int to : G[from]) {
      if (d[to] == 0) {
         d[to] = turn;
         dfs(to);
         turn++;
      }
   }
   if (f[from] == 0) f[from] = turn;
}

int main() {
   cin >> N;
   G = vector<vector<int>>(N);
   rep (i, N) {
      int u, k; cin >> u >> k;
      u--;
      rep (j, k) {
         int a; cin >> a;
         a--;
         G[u].push_back(a);
      }
   }

   rep (i, N) {
      sort(G[i].begin(), G[i].end());
   }

   d[0] = 1;
   turn = 1;
   dfs(0);

   rep (i, N) {
      printf("%d %d %d\n", i+1, d[i], f[i]);
   }

   return 0;
}