Go: package main

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

const (
	initialBufSize = 100000
	maxBufSize     = 1000000
)

var sc *bufio.Scanner

func initScanner(r io.Reader) *bufio.Scanner {
	buf := make([]byte, initialBufSize)

	sc := bufio.NewScanner(r)
	sc.Buffer(buf, maxBufSize)
	sc.Split(bufio.ScanWords) // bufio.ScanLines
	return sc
}

func main() {
	sc = initScanner(os.Stdin)
	resolve(parseProblem())
}

type graph struct {
	size  int
	edges [][]int
}

func parseProblem() *graph {
	n := scanInt(sc)
	g := &graph{
		size:  n,
		edges: make([][]int, n),
	}
	for i := 0; i < g.size; i++ {
		_ = scanInt(sc)
		k := scanInt(sc)
		g.edges[i] = make([]int, k)
		for j := 0; j < k; j++ {
			g.edges[i][j] = scanInt(sc) - 1
		}
	}
	return g
}

func resolve(g *graph) {
	ds := make([]int, g.size)
	fs := make([]int, g.size)
	time := 0
	for i := 0; i < len(ds); i++ {
		if ds[i] == 0 {
			time++
			time = _dfs(ds, fs, time, g, i)
		}
	}
	for i := 0; i < len(ds); i++ {
		fmt.Println(i+1, ds[i], fs[i])
	}
	return
}

func _dfs(ds, fs []int, time int, g *graph, idx int) int {
	ds[idx] = time
	for _, next := range g.edges[idx] {
		if ds[next] > 0 {
			continue
		}
		time++
		time = _dfs(ds, fs, time, g, next)
	}
	time++
	fs[idx] = time
	return time
}

// snip-scan-funcs
func scanInt(sc *bufio.Scanner) int {
	sc.Scan()
	i, _ := strconv.Atoi(sc.Text())
	return int(i)
}
func scanString(sc *bufio.Scanner) string {
	sc.Scan()
	return sc.Text()
}

C++: #include<stdio.h>
#include<algorithm>
#include<stack>
#include<string.h>
using namespace std;
#define INFTY 2000000001
#define MAX 101
#define WHITE 0
#define GRAY 1
#define BLACK 2

int n = 0;
int adl[MAX][MAX], deg[MAX];
int adm[MAX][MAX];
int color[MAX];
int d[MAX][2];
stack<int> depth;


void dfs() {
  int time = 1;
  for ( int i = 0; i < n; i++ ) {
    color[i] = WHITE;
  }
  depth.push(0);
  color[0] = GRAY;
  d[0][0] = time++;

  while (!depth.empty()) {
    int top = depth.top();

    int next;
    for (int i = 0; i < n; i++) {
      next = i;
      if (adm[top][i] == 1 && color[i] == WHITE) {
        depth.push(i);
        d[i][0] = time++;

        color[i] = GRAY;
        break;
      }
      next = n;
    }

    if (next == n) {
      color[top] = BLACK;
      d[top][1] = time++;
      depth.pop();
    }

    if (depth.empty()) {
      for (int i = 0; i < n; i++) {
        if (color[i] == WHITE) {
          depth.push(i);
          color[i] = GRAY;
          d[i][0] = time++;
        }
      }
    }
  }
}

int main() {
  scanf("%d", &n);
  for ( int i = 0; i < n; i++ ) {
    for ( int j = 0; j < n; j++ ) {
      adm[i][j] = 0;
    }
  }
  for ( int i = 0; i < n; i++ ) {
    int num;
    scanf("%d", &num);
    num--;
    scanf("%d", &deg[num]);
    for ( int j = 0; j < deg[num]; j++) {
      scanf("%d", &adl[num][j]);
      adl[num][j]--;
      adm[num][adl[num][j]] = 1;
    }
  }

  dfs();

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



  return 0;
}

C++: #include <cstdio>
#include <vector>
#include <algorithm>

#define rep(i, n) for(int i = 0; i < (n); ++i)

using namespace std;

int n;
vector<int> g[100];
int t;
int p[100];
int q[100];

void dfs(int i){
	p[i] = t++;
	rep(j, g[i].size()){
		int v = g[i][j];
		if(!p[v]){
			dfs(v);
		}
	}
	q[i] = t++;
}

int main(){
	scanf("%d", &n);
	rep(i, n){
		int u, k;
		scanf("%d%d", &u, &k);
		rep(j, k){
			int v;
			scanf("%d", &v);
			g[u - 1].push_back(v - 1);
		}
	}
	rep(i, n){
		if(!p[i]){
			t = 1;
			dfs(i);
		}
	}
	rep(i, n){
		printf("%d %d %d\n", i + 1, p[i], q[i]);
	}
	return 0;
}

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++;
      }
   }
   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());
   }

   // f[0] = dfs(0, 1);
   d[0] = 1;
   turn = 1;
   dfs(0);

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

   return 0;
}

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

using namespace std;

int n, m;
const int N = 110;
vector<int> G[N];
int d[N], f[N];
int timestamp = 1;

void dfs(int u) {
    d[u] = timestamp++;
    for (int i = 0; i < G[u].size(); i++) {
        int v = G[u][i];
        if (d[v] > 0) continue;
        dfs(v);
    }
    f[u] = timestamp++;
}

int main() {
    cin >> n;
    for (int i = 0; i < n; i++) {
        int u, k;
        cin >> u >> k;
        int v;
        for (int j = 0; j < k; j++) {
            cin >> v;
            if (u != v)
            G[u].push_back(v);
        }
    }

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

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

    return 0;
}

C++: #include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <string>
#include <cstring>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>

using namespace std;

// ---------------------
// repetition
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)

// debug
#define dump(x)  cerr << #x << " = " << (x) << endl;
#define debug(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << endl;

// ---------------------
#define INF 922337203685477580
typedef long long ll;

int matrix[110][110];
int d[110];
int f[110];
int n;
int elapsed = 1;

void visit(int v) {
  d[v] = elapsed++;

  FOR(i, 1, n + 1) {
    if (matrix[v][i] && d[i] < 0 ) {
      visit(i);
    }
  }
  f[v] = elapsed++;
}

int main() {
  REP(x, 110) {
    REP(y, 110) {
      matrix[x][y] = 0;
    }
    d[x] = -1;
    f[x] = -1;
  }

  // int n;
  cin >> n;

  REP(_, n) {
    int v, num;
    cin >> v >> num;

    REP(i, num) {
      int cv;
      cin >> cv;
      matrix[v][cv] = 1;
      // matrix[cv][v] = 1;
    }
  }


  FOR(v, 1, n + 1) {
    if (d[v] < 0) {
      visit(v);
    }
  }

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


  return 0;
}