Go: package main

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

// repr state of visited node
// WHITE yet visit
// GEAY  visiting
// BLACK visited
const (
	WHITE int = iota
	GRAY
	BLACK
)

type dfsGraph struct {
	g      [][]int
	colors []int
	stime  []int // Start time of visiting node
	ftime  []int // Finish time of visiting node
}

var time int

func makeAdjList() [][]int {
	var n int
	fmt.Scanf("%d", &n)

	adj := make([][]int, n)
	for i := 0; i < n; i++ {
		adj[i] = make([]int, n)
	}

	sc := bufio.NewScanner(os.Stdin)
	for i := 0; i < n; i++ {
		sc.Scan()
		nodeInfo := strings.Split(sc.Text(), " ")
		outDegree, _ := strconv.Atoi(nodeInfo[1])

		if outDegree > 0 {
			for k := 0; k < outDegree; k++ {
				j, _ := strconv.Atoi(nodeInfo[k+2])
				j-- // convert 1 based to 0 based
				adj[i][j] = 1
			}
		}
	}

	return adj
}

func (dg dfsGraph) dfsVisit(u int) {
	// 頂点uを訪問中に設定
	dg.colors[u] = GRAY
	time++
	dg.stime[u] = time

	// uの隣接nodeを訪問
	for v := 0; v < len(dg.g); v++ {
		if dg.g[u][v] == 0 {
			continue // 辺がなければスキップ
		}

		// vが未訪問なら訪問
		if dg.colors[v] == WHITE {
			dg.dfsVisit(v)
		}
	}

	// 頂点uを訪問済みに設定
	dg.colors[u] = BLACK
	time++
	dg.ftime[u] = time
}

func (dg dfsGraph) dfs() {
	for i := 0; i < len(dg.g); i++ {
		if dg.colors[i] == WHITE {
			dg.dfsVisit(i)
		}
	}
}

func (dg dfsGraph) printDfsTime() {
	for i := 0; i < len(dg.g); i++ {
		fmt.Printf("%d %d %d\n", i+1, dg.stime[i], dg.ftime[i])
	}
}

func main() {
	adj := makeAdjList()
	colors := make([]int, len(adj))
	stime := make([]int, len(adj))
	ftime := make([]int, len(adj))
	graph := dfsGraph{adj, colors, stime, ftime}
	graph.dfs()
	graph.printDfsTime()
}

C++: #define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <cstdlib>
#include <string>
#include <iostream>
#include <climits>
#include <stack>

using namespace std;

int main() {
	stack<int> S;

	int n;
	int u, v;
	int AdjList[101][99];
	int next[101];
	int Deg[101];
	bool Visited[101];
	int d[101], f[101], time;
	int i, j;
	cin >> n;
	for (i = 1; i <= n; i++) {
		Visited[i] = false;
		next[i] = 0;
		d[i] = 0;
		cin >> u;
		cin >> Deg[u];
		for (j = 0; j < Deg[u]; j++) {
			cin >> v;
			AdjList[u][j] = v;
		}
	}

	time = 1;
	v = 1;
	S.push(v);
	while (S.empty() != true) {
		v = S.top();
		if (d[v] == 0) {
			d[v] = time++;
		}
		Visited[v] = true;
		for (i = next[v]; i < Deg[v]; i++) {
			u = AdjList[v][i];
			if (Visited[u] != true) {
				S.push(u);
				break;
			}
		}
		if (i == Deg[v]) {
			S.pop();
			f[v] = time++;
		}
		else {
			next[v] = i + 1;
		}
	}

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

	return 0;

}

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

using namespace std;

template <class T>
struct Edge {
    int to;
    T cost;
    Edge(int to, T cost) : to(to), cost(cost){};
};

template <class T = int>
class Graph {
public:
    explicit Graph(int N = 0) : size(N) { path.resize(size); }
    void span(int u, int v, T cost = 1) { path[u].push_back(Edge<T>(v, cost)); }
    vector<Edge<T>> operator[](int v) const { return path[v]; }

    int size;
    vector<vector<Edge<T>>> path;
};

int main() {
    int N;
    cin >> N;
    Graph<> graph(N);
    for (int i = 0; i < N; ++i) {
        int v, k;
        cin >> v >> k;
        --v;
        for (int j = 0; j < k; ++j) {
            int sv;
            cin >> sv;
            graph.span(v, --sv);
        }
    }

    vector<int> d(N, -1), f(N, -1);
    function<int(int, int)> dfs = [&](int v, int t) -> int {
        d[v] = t;
        for (auto e : graph[v]) {
            if (d[e.to] < 0) t = dfs(e.to, t + 1);
        }
        return f[v] = ++t;
    };

    int t = 0;
    for (int v = 0; v < N; ++v) {
        if (d[v] < 0) t = dfs(v, t + 1);
    }

    for (int v = 0; v < N; ++v) {
        cout << v + 1 << " " << d[v] << " " << f[v] << endl;
    }
    return 0;
}

C++: #include<bits/stdc++.h>
using namespace std;
#define rep(i,a) for(int i=0;i<a;i++)
#define pd(a,n) for(int i=0;i<n;i++)cout<<a[i]<<((i==n-1)?"\n":" ")
#define pdd(a,n,m)for(int i=0;i<m;i++)pd(a,m)
#define mp make_pair
#define pb push_back
#define ll __int64
#define __int64 long long
#define P pair<int,int>
#define PP pair<P,int>

int n;
vector<int>G[1111];
int d[111];
int f[111];
int cnt;

void dfs(int x){

  d[x]=++cnt;

  rep(i,G[x].size()){
    int to=G[x][i];
    if(d[to]==0)
      dfs(to);
  }
  f[x]=++cnt;
}

int main(){
  cin>>n;
  rep(i,n){
    int k,s;
    cin>>k>>s;
    rep(j,s){
      int to;
      cin>>to;
      G[k].pb(to);
    }
    sort(G[k].begin(),G[k].end());
  }

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

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

  return 0;
}

C++: #include <iostream>
using namespace std;
int t = 1;
int d[100], f[100];
int a[100][100];
int N;
void dfs(int cur) {
 d[cur] = t;
 t++;
 for (int i=0; i<N; i++) {
  if (a[cur][i] == 1 && d[i] == 0) {
   dfs(i);
  }
 }
 f[cur] = t;
 t++;
}

int main() {
 cin >> N;
 for (int i=0; i<N; i++) {
  for (int j=0; j<N; j++) {
   a[i][j] = 0;
  }
  d[i] = 0;
  f[i] = 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;
   a[u-1][v-1] = 1;
  }
 }
 for (int i=0; i<N; i++) {
  if (d[i] == 0) { dfs(i); }
 }
 for (int i=0; i<N; i++) {
  cout << i+1 << " " << d[i] << " " << f[i] << endl;
 }
}

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

struct TNode
{
	int Index;
	bool Visited;
	std::list<TNode*> Target;
	
	int ClockStart;
	int ClockEnd;
	
	TNode(int AIndex)
	: Index(AIndex), Visited(false), ClockStart(0), ClockEnd(0)
	{
	}
	
	void Visit(int& Clock)
	{
		if(Visited) return;
		Visited = true;
		ClockStart = Clock;
		++Clock;
		for(std::list<TNode*>::iterator It = Target.begin(); It != Target.end(); ++It){
			(*It)->Visit(Clock);
		}
		ClockEnd = Clock;
		++Clock;
	}
};

class TGraph
{
	std::vector<TNode*> FNodes;
public:
	TGraph(int Count)
	: FNodes(Count)
	{
		for(int i = 0; i < Count; ++i){
			FNodes[i] = new TNode(i + 1);
		}
	}
	
	~TGraph()
	{
		for(unsigned int i = 0; i < FNodes.size(); ++i){
			delete FNodes[i];
		}
	}
	
	void InputNode(int Index, int BranchCount)
	{
		for(int i = 0; i < BranchCount; ++i){
			int Target;
			std::cin >> Target;
			FNodes[Index - 1]->Target.push_back(FNodes[Target - 1]);
		}
	}
	
	void DepthFirstSearch()
	{
		int Clock = 1;
		FNodes[0]->Visit(Clock);
	}
	
	void OutputClocks()const
	{
		for(unsigned int i = 0; i < FNodes.size(); ++i){
			std::cout << FNodes[i]->Index      << " "
			          << FNodes[i]->ClockStart << " "
			          << FNodes[i]->ClockEnd   << std::endl;
		}
	}
};

int main()
{
	int Count;
	std::cin >> Count;
	TGraph Graph(Count);
	for(int i = 0; i < Count; ++i){
		int Index;
		std::cin >> Index;
		int BranchCount;
		std::cin >> BranchCount;
		Graph.InputNode(Index, BranchCount);
	}
	Graph.DepthFirstSearch();
	Graph.OutputClocks();
	return 0;
}

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

using namespace std;

int n;
vector<vector<int>> g; 
int time = 0;
vector<int> d, f;
 
void dfs(int node){
    time++;

    if(d[node] == 0){
        d[node] = time;
    }

    for(auto next : g[node]){
        if(d[next] == 0){
            dfs(next);
        }
    }
    
    time++;
    if(f[node] == 0){
        f[node] = time;
    }
}
    
int main(){
    
    cin >> n;

    d.assign(n + 1, 0);
    f.assign(n + 1, 0);

    g.assign(n + 1, vector<int>());

    for(int i = 0; i < n; i++)
    {
        int nod, numOut;
        cin  >> nod >> numOut;
        for(int j = 0; j < numOut; j++)
        {
            int temp;
            cin >> temp;
            g[nod].push_back(temp);
        }
    }
    
    dfs(1);

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

    return 0;
}