#include <bits/stdc++.h>
const int N = 200010;
int tot = 0, t = 0, l, r, u, first[N], s[N], f[N][3], w[N][3], k[N][3];
bool vis[N];
struct data {
  int y, next;
} g[N * 2];
struct data2 {
  int x, y;
} ans[N];
void add(int x, int y) {
  tot++;
  g[tot].y = y;
  g[tot].next = first[x];
  first[x] = tot;
}
void dfs(int x, int father) {
  vis[x] = true;
  for (int i = first[x]; i; i = g[i].next)
    if (!vis[g[i].y])
      dfs(g[i].y, x);
    else if (g[i].y != father)
      if (i & 1) {
        l = x;
        r = g[i].y;
      } else {
        l = g[i].y;
        r = x;
      }
}
void dp(int x) {
  f[x][0] = f[x][1] = w[x][0] = w[x][1] = k[x][0] = k[x][1] = 0;
  for (int i = first[x]; i; i = g[i].next)
    if (i & 1 && g[i].y != r) {
      dp(g[i].y);
      f[x][0] += f[g[i].y][2];
      w[x][0] += w[g[i].y][2];
    }
  for (int i = first[x]; i; i = g[i].next)
    if (i & 1 && g[i].y != r && g[i].y != u) {
      int tf = f[x][0] - f[g[i].y][2] + f[g[i].y][0] + 1,
          tw = w[x][0] - w[g[i].y][2] + w[g[i].y][0] + (s[x] != s[g[i].y]);
      if (f[x][1] < tf || (f[x][1] == tf && w[x][1] < tw)) {
        f[x][1] = tf;
        w[x][1] = tw;
        k[x][1] = g[i].y;
      }
    }
  if (x == u) f[x][1] = -1;
  if (f[x][0] > f[x][1] || (f[x][0] == f[x][1] && w[x][0] > w[x][1])) {
    f[x][2] = f[x][0];
    w[x][2] = w[x][0];
    k[x][2] = 0;
  } else {
    f[x][2] = f[x][1];
    w[x][2] = w[x][1];
    k[x][2] = 1;
  }
}
void get(int x, int kind) {
  if (kind == 2) kind = k[x][2];
  if (kind == 1 && k[x][1] != 0) {
    t++;
    ans[t].x = x;
    ans[t].y = k[x][1];
  }
  for (int i = first[x]; i; i = g[i].next)
    if (i & 1 && g[i].y != r)
      if (kind == 1 && g[i].y == k[x][1])
        get(g[i].y, 0);
      else
        get(g[i].y, 2);
}
int main() {
  int n, x, i, e = 0, tf, tw;
  scanf("%d", &n);
  memset(first, 0, sizeof(first));
  for (i = 1; i <= n; i++) {
    scanf("%d %d", &x, &s[i]);
    add(x, i);
    add(i, x);
  }
  memset(vis, false, sizeof(vis));
  for (i = 1; i <= n; i++)
    if (!vis[i]) {
      dfs(i, 0);
      u = 0;
      dp(r);
      tf = f[r][2];
      tw = w[r][2];
      u = l;
      dp(r);
      if (tf < f[r][0] + 1 ||
          (tf == f[r][0] + 1 && tw < w[r][0] + (s[l] != s[r]))) {
        e += w[r][0] + (s[l] != s[r]);
        t++;
        ans[t].x = l;
        ans[t].y = r;
        get(r, 0);
      } else {
        e += tw;
        u = 0;
        dp(r);
        get(r, k[r][2]);
      }
    }
  printf("%d %d\n", t, e);
  for (i = 1; i <= t; i++) printf("%d %d\n", ans[i].x, ans[i].y);
  return (0);
}
