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<iostream>
using namespace std;
#include<stdio.h>

int G[101][102];
int found[101];
int comp[101];   // complete.
int t;  // time.

typedef struct box{ int val; box* next; } box_t;  // stack.

box_t* init()
{
    box_t* head = new box_t;
    head->val = -1;
    head->next = NULL;
    return head;
}

bool isEmpty(box_t* head){ return (head->next == NULL ? true : false); }

box_t* push(box_t* head, int data)
{
    box_t* box = new box_t;
    box->val = data;
    box->next = head->next;
    head->next = box;
    return box;
}

int pop(box_t* head)
{
    if(isEmpty(head)){ return -1; }
    box_t* box = head->next;
    int val;
    head->next = box->next;
    val = box->val;
    delete box;
    return val;
}

int front(box_t* head)
{
    int val;
    if(isEmpty(head)){ return -1; }
    val = head->next->val;
    return val;
}

box_t* stack = init();

void search_loop(int i)
{
    int j, k;
    while(1){
        if(found[i] == 0){
            t++; found[i] = t;
            push(stack, i);
        }
        for(k = G[i][0]; G[i][k] != 0 && found[G[i][k]] != 0; k++);
        if(G[i][k] == 0){
            if(isEmpty(stack)){ return; }
            else{
                j = pop(stack);
                t++; comp[j] = t;
                i = front(stack);
            }
        }else{
            G[i][0] = k + 1;
            i = G[i][k];
        }
    };
    return;
}

int main()
{
    int n, i, j, a, b, e;
    scanf("%d", &n);
    for(i = 1; i <= n; i++){
        G[i][0] = 1;
        for(j = 1; j <= n + 1; j++){ G[i][j] = 0; } }

    for(i = 1; i <= n; i++){
        scanf("%d %d", &a, &e);
        for(j = 1; j <= e; j++){
            scanf("%d", &b); G[a][j] = b; } }  // adjacent representation.

    for(i = 1; i <= n; i++){ found[i] = 0; comp[i] = 0; }
    t = 0;
    while(1){
        for(i = 1; i <= n; i++){
            if(found[i] == 0) break;
        }
        if(i > n) break;
        search_loop(i);
    };

    for(i = 1; i <= n; i++){
        printf(" %d %d %d\n", i, found[i], comp[i]);
    }
    return 0;
}

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

vector<bool> seen;
vector<int> fo;
vector<int> lo;
void dfs(vector<vector<int>> &g,int v,int& fp,int& lp){
    if(fo[v]==0)fo[v]=fp++;
    seen[v]=true;
    for(auto next:g[v]){
        if(seen[next])continue;
        dfs(g,next,fp,lp);
    }
    if(lo[v]==0)lo[v]=fp++;
}

int main(){
    int n;
    cin>>n;
    vector<vector<int>> g(n);
    int u,k,v;
    for(int i=0;i<n;i++){
        cin>>u>>k;
        if(k==0)continue;
        for(int j=0;j<k;j++){
            cin>>v;
            if(u==v)continue;
            g[u-1].push_back(v-1);
        }
    }

    seen.assign(n,false);
    fo.resize(n);
    lo.resize(n);
    int fp=1,lp=n+1;
    //dfs(g,0,fp,lp);
    for(int i=0;i<n;i++)dfs(g,i,fp,lp);

    for(int i=0;i<n;i++){
        cout<<i+1<<" ";
        cout<<fo[i]<<" ";
        cout<<lo[i]<<endl;
    }
    return 0;
}

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

const long N = 100;
const long WHITE = 0;
const long GRAY = 1;
const long BLACK = 2;

long n, M[N + 1][N + 1];
long color[N + 1], d[N + 1], f[N + 1], tt;
long nt[N + 1];

long next(long u){
	for (long v = nt[u]; v < n; v++){
		nt[u] = v;
		if (M[u][v]) return v;
	}
	return -1;
}

void dfs_visit(long r){
	for (long i = 1; i <= n; i++) nt[i] = 0;

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

	while (!S.empty()){
		long u = S.top();
		long 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 (long i = 1; i <= n; i++){
		color[i] = WHITE;
		nt[i] = 0;
	}
	tt = 0;

	for (long u = 1; u <= n; u++){
		if (color[u] == WHITE) dfs_visit(u);
	}
	for (long i = 1; i <= n; i++){
		cout << i << " " << d[i] << " " << f[i] << endl;
	}
}

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

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

	dfs();

	return 0;
}

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

int n;
int t;
vector<int> G[MAX];
bool used[MAX];
int start[MAX];
int finish[MAX];

void DFS(int s) {
	if (used[s]) return;
	used[s] = true;
	start[s] = t++;
	for (int &v : G[s]) {
		DFS(v);
	}
	finish[s] = t++;
}

int main()
{
	cin >> n;
	for (int i = 0, u, k; i < n; i++) {
		cin >> u >> k;
		for (int j = 0, v; j < k; j++) {
			cin >> v;
			G[u - 1].push_back(v - 1);
		}
	}
	t = 1;
	DFS(0);
	for (int i = 0; i < n; i++) {
		cout << i + 1 << ' ' << start[i] << ' ' << finish[i] << endl;
	}
	return 0;
}

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

#define FOR(i, a, b) for(long long int i=(a);i<=(b);i++)
#define RFOR(i, a, b) for(long long int i=(a);i>=(b);i--)
#define MOD 1000000007
#define INF 1000000000 //2000000000
#define LLINF 1000000000000000000 //9000000000000000000
#define PI 3.14159265358979

using namespace std;
typedef long long int ll;
typedef pair< long long int, long long  int> P;

int n;
int u, k, v;
int hour = 1;
int d[101] = {}, f[101] = {};
int gra[101][101] = {};
int color[101] = {};




void dfs(int u) {
	color[u] = 1;
	d[u] = hour;
	hour++;
	FOR(i, 1, n) {
		if (gra[u][i] == 1 && color[i] == 0) {
			dfs(i);
		}
	}
	color[u] = 2;
	f[u] = hour;
	hour++;
}

void dfs_call(void) {

	FOR(i, 1, n) {
		if (color[i] == 0) {
			dfs(i);
		}
	}
}


int main(void) {
	cin >> n;
	
	FOR(i, 1, n) {
		cin >> u >> k;
		FOR(t, 1, k) {
			cin >> v;
			gra[u][v] = 1;
		}
	}
	d[1] = hour;

	dfs_call();

	FOR(i, 1, n) {
		cout << i << " " << d[i] << " " << f[i] << endl;
	}

	return 0;
}

C++: #include <iostream>
using namespace std;
static const int N=100;
static const int WHITE=0;
static const int GRAY=1;
static const int BLACK=2;

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

void dfs_visit(int u){
	int v;
	color[u]=GRAY;
	d[u]=++tt;
	for(v=0;v<n;v++){
		if(M[u][v]==0)
			continue;
		if(color[v]==WHITE){
			dfs_visit(v);
		}
	}
	color[u]=BLACK;
	f[u]=++tt;
	
}

void dfs(){
	int u;
	for(int i=0;i<n;i++){
		color[i]=WHITE;
	}
	tt=0;
	
	for(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 k,u,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--;
		for(int j=0;j<k;j++){
			cin>>v;
			v--;
			M[u][v]=1;
		}
	}
		
	dfs();	

	return 0;
}