Go: package main

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

// I/O
type Scanner struct {
	sc *bufio.Scanner
}

func NewScanner() *Scanner {
	sc := bufio.NewScanner(os.Stdin)
	sc.Split(bufio.ScanWords)
	sc.Buffer(make([]byte, 1024), int(1e+9))
	return &Scanner{sc}
}

func (s *Scanner) nextStr() string {
	s.sc.Scan()
	return s.sc.Text()
}

func (s *Scanner) nextInt() int {
	i, e := strconv.Atoi(s.nextStr())
	if e != nil {
		panic(e)
	}
	return i
}

func (s *Scanner) nextFloat() float64 {
	f, e := strconv.ParseFloat(s.nextStr(), 64)
	if e != nil {
		panic(e)
	}
	return f
}

func (s *Scanner) nextRuneSlice() []rune {
	return []rune(s.nextStr())
}

func (s *Scanner) nextIntSlice(n int) []int {
	res := make([]int, n)
	for i := 0; i < n; i++ {
		res[i] = s.nextInt()
	}
	return res
}

func (s *Scanner) nextFloatSlice(n int) []float64 {
	res := make([]float64, n)
	for i := 0; i < n; i++ {
		res[i] = s.nextFloat()
	}
	return res
}

// Arithmetic
func max(nums ...int) int {
	m := nums[0]
	for _, i := range nums {
		if m < i {
			m = i
		}
	}
	return m
}

func min(nums ...int) int {
	m := nums[0]
	for _, i := range nums {
		if m > i {
			m = i
		}
	}
	return m
}

func abs(x int) int {
	if x > 0 {
		return x
	}
	return -x
}

func pow(x, y int) int {
	res := 1
	for i := 0; i < y; i++ {
		res *= x
	}
	return res
}

func ceil(a, b int) int {
	if a%b == 0 {
		return a / b
	} else {
		return a/b + 1
	}
}

// Sort
type RuneSlice []rune

func (a RuneSlice) Len() int           { return len(a) }
func (a RuneSlice) Less(i, j int) bool { return a[i] < a[j] }
func (a RuneSlice) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }

// Main
func main() {
	sc := NewScanner()
	wtr := bufio.NewWriter(os.Stdout)
	N := sc.nextInt()
	G := make([][]int, N)
	for i := 0; i < N; i++ {
		u, k := sc.nextInt()-1, sc.nextInt()
		for j := 0; j < k; j++ {
			G[u] = append(G[u], sc.nextInt()-1)
		}
	}
	ans := make([][2]int, N)
	time := 0
	found := make(map[int]bool)
	var dfs func(cur int)
	dfs = func(cur int) {
		time++
		ans[cur][0] = time
		found[cur] = true
		for i := 0; i < len(G[cur]); i++ {
			next := G[cur][i]
			if !found[next] {
				dfs(G[cur][i])
			}
		}
		time++
		ans[cur][1] = time
	}
	for i := 0; i < N; i++ {
		if !found[i] {
			dfs(i)
		}
	}

	for i := 0; i < N; i++ {
		fmt.Fprint(wtr, i+1)
		for j := 0; j < 2; j++ {
			fmt.Fprint(wtr, " ")
			fmt.Fprint(wtr, ans[i][j])
		}
		fmt.Fprintln(wtr)
	}
	wtr.Flush()
}

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

const int nmax = 105;
const int NIL = -1;

int n, t;
// state of vertex
// 0: not visited
// 1: visited
// 2: complete search from the vertex
std::array<int, nmax> color, d, f;

std::array<std::array<int, nmax>, nmax> adj;


void dfs_1v(int v)
{
  d[v] = ++t;
  color[v] = 1;

  for (int j=0; j<n; ++j)
    {
      if (adj[v][j] == 1 && color[j] ==0)
        {
          dfs_1v(j);
        }
    }
  f[v] = ++t;
  color[v] = 2;
}

void dfs()
{
  t = 0;
  for (int i=0; i<n; ++i)
    {
      if (color[i] != 2)
        dfs_1v(i);
    }
}

int main ()
{
  std::cin >> n;

  color.fill(0);
  std::for_each(adj.begin(), adj.end(), [](auto x){x.fill(0);});
  for (int i=0; i<n; ++i)
    {
      int u, k;
      std::cin >> u >> k;
      for (int j=0; j<k; ++j)
        {
          int v;
          std::cin >> v;
          adj[u-1][v-1] = 1;
        }
    }

  dfs();

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

}

C++: #include <bits/stdc++.h>

using namespace std;
int t;

void dfs(vector<vector<bool> >& A, vector<vector<int> >& B, int s, int n){
    for(int i = 0; i < n; i++){
        if(i == 0){
            if(B[s][1] == 0){
                B[s][1] = t;
                t++;
            }
        }
        if(A[s][i] == true){
            A[s][i] = false;
            dfs(A, B, i, n);
        }
        if(i == n-1){
            if(B[s][2] == 0){
                B[s][2] = t;
                t++;
            }
        }
    }
}

int main(void){

    //??£??\??????????????£??\???????????????
    int n, k;

    cin >> n;
    vector<vector<bool> > A(n, vector<bool>(n, false));
    for(int i = 0; i < n; i++){
        cin >> k >> k;
        for(int j = 0; j < k; j++){
            int input;
            cin >> input;
            A[i][input-1] = true;
        }
    }

   

    vector<vector<int> > B(n, vector<int>(3, false));
    for(int i = 0; i < n; i++){
        B[i][0] = i + 1;
    }

    t = 1;
    for(int k = 0; k < n; k++){
        if(B[k][1] == 0) dfs(A, B, k, n);
    }
    

    //??????
    for(int i = 0; i < n; i++){
        for(int j = 0; j < 3; j++){
            if(j != 2) cout << B[i][j] << " ";
            else cout << A[i][j];
        }
        cout << endl;
    }
    return 0;
}

C++: #include <stdio.h>
#include <iostream>
#include <stack>
#include <string>
using namespace std;

#define NUM 100
int node_num;
int V[NUM + 1][NUM + 1];
int d[NUM + 1];
int f[NUM + 1];
string color[NUM + 1];
int t;
int pos;
stack<int> s;

void createAdj(int n){
    for(int j = 0; j <= n; j++){
        if(j == 0){
            V[0][j] = 0;
        }
        V[0][j] = 1;
    }

    for(int i = 1; i < NUM; i++){
        for(int j = 1; j < NUM; j++){
            V[i][j] = 0;
        }
    }

    for(int i = 0; i < n; i++){
        int num1;
        scanf("%d", &num1);

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

        int num2;
        for(int j = 0; j < n; j++){
            scanf("%d", &num2);
            V[num1][num2] = 1;
        }
    }
}

int search(int n){
    for(int i = 1; i <= node_num; i++) {
        if(V[n][i] == 1 && color[i] == "white")
            return i;
    }
    return -1;
}

void dfs_init(){
    t = 0;
    for(int i = 0; i < NUM; i++){
        color[i] = "white";
    }
}

void dfs(){
    s.push(0);
    pos = 0;
    color[0] = "grey";
    d[0] = t;

    while(s.size()){
        int u = s.top();
        int next_node = search(u);
        if(next_node != -1){
            pos = next_node;
            s.push(next_node);
            pos = next_node;
            t++;
            color[next_node] = "grey";
            d[next_node] = t;
        }else{
            s.pop();
            color[u] = "black";
            t++;
            f[u] = t;
        }
    }
}

void print(){
    for(int i = 1; i <= node_num; i++){
        printf("%d %d %d\n", i, d[i], f[i]);
    }
}

int main(void){
    scanf("%d", &node_num);
    createAdj(node_num);

    dfs_init();
    dfs();

    print();
}

C++: #include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;

bool A[110][110];
int flag[110],in[110],out[110];
int now=1,n;

void dfs(int u){
	flag[u]=1;
	in[u]=now++;
	for(int i=1;i<=n;i++){
		if(flag[i]==0 && A[i][u]==true){
			dfs(i);
		}
	}
	out[u]=now++;
	return ;
}

int main(){
	int a,b,c;
	cin>>n;
	for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				A[i][j]=false;
		}
	}
	for(int i=1;i<=n;i++){
		cin>>a>>b;
		for(int j=1;j<=b;j++){
			cin>>c;
			A[a][c]=true;
			A[c][a]=true;
		}
	}
	for(int i=1;i<=n;i++){
		if(flag[i]==0) dfs(i);
	}
	for(int i=1;i<=n;i++){
		cout<<i<<" "<<in[i]<<" "<<out[i]<<endl;
	}
	return 0;
}

C++: #include<iostream>
#include<stdio.h>

using namespace std;
int d[101];
int f[101];
int n;
int M[101][101];
int t;
void DFS(int v) {
	t = t + 1;
	d[v] = t;
	for (int j = 1; j < n + 1; j++) {
		if (M[v][j] == 1) {
			if (d[j] == 0) {
				DFS(j);

			}
		}
	}
	t = t + 1;
	f[v] = t;

}

int main() {
	int  u, k, v;//頂点数、頂点の番号、出次数、隣接する頂点の番号
	t = 0;

	cin >> n;



	//初期化
	for (int i = 0; i < 101; i++) {
		d[i] = 0;
		f[i] = 0;
		for (int j = 0; j < 101; j++) {
			M[i][j] = 0;

		}
	}

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


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

	return 0;
}