Go: package main

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

const N = 100

const (
	WHITE = iota
	GRAY
	BLACK
)

type Graph struct {
	M               [N][N]int
	color, d, f, nt [N]int
	tt              int
}

func (g *Graph) next(u, n int) int {
	for v := g.nt[u]; v < n; v++ {
		g.nt[u] = v + 1
		if g.M[u][v] != 0 {
			return v
		}
	}
	return -1
}

func (g *Graph) dfsVisit(r, n int) {
	var S []int
	S = append([]int{r}, S...)
	g.color[r] = GRAY
	g.tt++
	g.d[r] = g.tt

	for len(S) != 0 {
		u := S[0]
		v := g.next(u, n)
		if v == -1 {
			S = S[1:]
			g.color[u] = BLACK
			g.tt++
			g.f[u] = g.tt
			continue
		}

		if g.color[v] != WHITE {
			continue
		}

		g.color[v] = GRAY
		g.tt++
		g.d[v] = g.tt
		S = append([]int{v}, S...)
	}
}

func (g *Graph) dfs(n int) string {
	for i := 0; i < n; i++ {
		g.color[i] = WHITE
	}
	g.tt = 0

	for u := 0; u < n; u++ {
		if g.color[u] == WHITE {
			g.dfsVisit(u, n)
		}
	}

	var out bytes.Buffer
	for i := 0; i < n; i++ {
		out.WriteString(fmt.Sprintf("%d %d %d\n", i+1, g.d[i], g.f[i]))
	}

	return strings.TrimRight(out.String(), "\n")
}

func answer(reader io.Reader) string {
	sc := bufio.NewScanner(reader)
	sc.Split(bufio.ScanWords)

	sc.Scan()
	n, _ := strconv.Atoi(sc.Text())

	var g Graph
	for i := 0; i < n; i++ {
		sc.Scan()
		u, _ := strconv.Atoi(sc.Text())
		sc.Scan()
		k, _ := strconv.Atoi(sc.Text())
		u--
		for j := 0; j < k; j++ {
			sc.Scan()
			v, _ := strconv.Atoi(sc.Text())
			v--
			g.M[u][v] = 1
		}
	}

	return g.dfs(n)
}

func main() {
	fmt.Println(answer(os.Stdin))
}

C++: #include <iostream>
#include <vector>
#include <stack>
using namespace std;
static const int MAX=101;
bool Visited[MAX]; //??\?????????????¢??????????
vector<int> Adjacency[MAX];
int dTime[MAX]; int fTime[MAX]; //?¢??????°??¶??´????¢?????????¶??´
void dfs(int j,int& clock)
{

    stack<int> S;
    S.push(j);dTime[j]=++clock;
    Visited[j]=true;
    while(!S.empty())
    {
        int p=S.top(); //???????????¶??????
        if(Adjacency[p].size()==0)
        {
            S.pop();
            fTime[p]=++clock;
            continue;
        }
        int i=0;
        if(Adjacency[p].size())
          while(Visited[Adjacency[p][i]]==true)
          {
            i++;
            if(i==Adjacency[p].size()) //???????°??????????????±?????????????
            {
                S.pop();
                fTime[p]=++clock;
                break;
            }
          }
        if(i==Adjacency[p].size()) continue;
        //if founded
        S.push(Adjacency[p][i]); dTime[Adjacency[p][i]]=++clock;
        Visited[Adjacency[p][i]]=true;
    }
}
int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++) Visited[i]=false;

    for(int i=1;i<=n;i++)
    {
        int p;cin>>p;
        int num;
        cin>>num;

        for(int j=0;j<num;j++)
        {
            int t;
            cin>>t;
            Adjacency[p].push_back(t);
        }
    }
    int clock=0;
    for(int i=1;i<=n;i++)  //???????????????????????°DFS?£?????????????
    {
        if(Visited[i]==false) dfs(i,clock);
    }
    for(int i=1;i<=n;i++)
        cout<<i<<' '<<dTime[i]<<' '<<fTime[i]<<endl;
}

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

bool M[100][100];
int n,m,num;
int color[100], d[100], f[100], tt,mark[100];

int next(int u) {
	for (int i = mark[u]; i < n; i++) {
		if (M[u][i] != 0) {
			mark[u] = i + 1;
			return i;
		}
	}
	return -1;
}

void dfs_visit(int r) {
	stack<int> s;
	s.push(r);
	d[r] = ++tt;
	color[r] = 1;

	while (!s.empty()){
		int v = s.top();
		int k = next(v);
		if (k != -1) {
			if (color[k] == 0) {
				color[k] = 1;
				d[k] = ++tt;
				s.push(k);
			}
		}
		else {
			color[v] = 2;
			f[v] = ++tt;
			s.pop();
		}
	}




}




int main()
{
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> m;
		cin >> m;
		for (int v = 0; v < m; v++) {
			cin >> num;
			M[i - 1][num-1] = 1;
		}
	}
	for (int i = 0; i < n; i++) {
		if (color[i] == 0) {
			dfs_visit(i);
		}
	}
	for (int i = 0; i < n; i++) {
		cout << i + 1 << " " << d[i] << " " << f[i]<< endl;
	}
	
}

C++: #include<stdio.h>
#define MAX 100

int adj[MAX][MAX];/*隣接行列*/
int d[MAX];/*発見時刻*/
int f[MAX];/*終了時刻*/
int flg[MAX];/*ノード訪問したかどうか*/
int time=0;

void dfs(int u,int n){
	
	flg[u]=1;
	d[u]=++time;
	
	for(int i=0;i<n;i++){
		if(adj[u][i] && !flg[i]){/*ノードuから到達可能かつ未訪問*/
			dfs(i,n);
		}
	}
	f[u]=++time;
	
	return;
	
}

int main(){
	int n,i,j;
	int x,y,z;
	
	scanf("%d",&n);
	
	for(i=0;i<n;i++){
		flg[i]=0;
		for(j=0;j<n;j++)
			adj[i][j]=0;
	}
	
	for(i=0;i<n;i++){
		scanf("%d %d",&x,&y);
		for(j=0;j<y;j++){
			scanf("%d",&z);
			adj[x-1][z-1]=1;
		}
	}
	
	for(i=0;i<n;i++)
		if(!flg[i])
			dfs(i,n);
	
	
	for(i=0;i<n;i++)
		printf("%d %d %d\n",i+1,d[i],f[i]);
	
	return 0;
	
}

C++: #include <iostream>
#include <string>
#include <vector>
#include <functional>
#include <algorithm>
#include <array>
#include <stack>
#include <map>

using namespace std;

template<typename ISTREAM>
void readGraphListAsMatrix(const size_t n, ISTREAM& cin, vector< vector<int> >& graphMatrix) {
	graphMatrix = vector< vector<int> >(n, vector<int>(n, 0));
	for (size_t i = 0; i != n; ++i) {
		size_t u;
		size_t k;
		cin >> u;
		cin>> k;
		for (size_t j = 0; j != k; ++j) {
			size_t v;
			cin >> v;
			graphMatrix.at(u - 1).at(v - 1) = 1;
		}
	}
}

void printMatrix(const vector< vector<int> >& grapthMatrix) {
	const size_t n = grapthMatrix.size();
	for (size_t i = 0; i != n; ++i) {
		const vector<int>& adj = grapthMatrix.at(i);
		cout << adj.front();
		for (size_t j = 1; j != n; ++j) {
			cout << " " << adj.at(j);
		}
		cout << endl;
	}
}


template<typename T>
void execute(T& cin) {
	size_t n;
	cin >> n;
	vector< vector<int> > graphMatrix;
	readGraphListAsMatrix(n, cin, graphMatrix);
	stack<int> visitedNodeIDs;
	visitedNodeIDs.push(0);
	int time = 0;
	vector<pair<int, int>> timeStamp(n,make_pair(0,0));//pair<初回訪問時刻, 完了時刻>
	vector<vector<int>::iterator> searchBeginPos; {
		searchBeginPos.reserve(n);
		for (auto& v : graphMatrix)searchBeginPos.push_back(v.begin());
	}
	timeStamp.at(0).first = 1;
	while (!visitedNodeIDs.empty()) {
		++time;
		const int nodeID_1 = visitedNodeIDs.top();
		vector<int>& neighbourNodeList = graphMatrix.at(nodeID_1);
		vector<int>::iterator result = find(searchBeginPos.at(nodeID_1), neighbourNodeList.end(), 1);
		if (result != neighbourNodeList.end()) {
			const int nextVisitID_1 = distance(neighbourNodeList.begin(), result);
			timeStamp.at(nextVisitID_1).first = time + 1;
			for (auto&v : graphMatrix) v.at(nextVisitID_1) = 0;
			visitedNodeIDs.push(nextVisitID_1);
			searchBeginPos.at(nodeID_1) = result + 1;
		}
		else {
			//隣接リストに検索対象なし
			timeStamp.at(nodeID_1).second = time+1;
			visitedNodeIDs.pop();
		}
	}
	for (int i = 0; i != n; ++i) {
		cout << i + 1 << " " << timeStamp.at(i).first << " " << timeStamp.at(i).second << endl;
	}
}

int main()
{
	execute(cin);

	return 0;
}

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

int d[101]={0};
int f[101]={0};
int AdjM[101][101]={0};
int lapse=0;

void dfs(int cur){
    ++lapse;
    d[cur]=lapse;
    //cerr<<"visiting "<<cur<<" "<<lapse<<"\n";
    for(int dst=1;dst<101;++dst){
        if(AdjM[cur][dst]!=0 && d[dst]==0){
            dfs(dst);
        }
    }
    ++lapse;
    f[cur]=lapse;
}

int main(){
    int N;
    cin>>N;
    int id,edgnum,adj;
    for(int i=0;i<N;++i){
        cin>>id>>edgnum;
        for(int j=0;j<edgnum;++j){
            cin>>adj;
            AdjM[id][adj]+=1;
        }
    }

    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]<<"\n";
    }
}