#include <bits/stdc++.h>
using namespace std;
const int maxN = 100005;
const int inf = 214748364;
struct edge {
  int a, l;
} e[maxN];
int sex[maxN], start[maxN], p[maxN], q[maxN], ans[maxN][2];
int n, t, tot, k, root, fa[maxN];
bool bo[maxN], flag;
struct Node {
  int x, y;
  Node() {}
  Node(int x1, int y1) {
    x = x1;
    y = y1;
  }
  bool operator>(const Node &o) const {
    return x > o.x || (x == o.x && y > o.y);
  }
  Node operator+(const Node &o) { return Node(x + o.x, y + o.y); }
} f[maxN][2], g[maxN], tmp, cnt;
void add(int x, int y) {
  e[++tot].l = start[x];
  e[tot].a = y;
  start[x] = tot;
}
void init() {
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) {
    scanf("%d%d", fa + i, sex + i);
    add(fa[i], i);
  }
}
void dfs(int x) {
  bo[x] = 1;
  for (int i = start[x]; i; i = e[i].l)
    if (e[i].a != root) dfs(e[i].a);
  t = 0;
  for (int i = start[x]; i; i = e[i].l)
    if (e[i].a != root) q[++t] = e[i].a;
  tmp = g[t + 1] = Node(0, 0);
  for (int i = t; i; --i)
    g[i] =
        g[i + 1] + ((f[q[i]][0]) > (f[q[i]][1]) ? (f[q[i]][0]) : (f[q[i]][1]));
  f[x][0] = g[1];
  f[x][1] = Node(-inf, 0);
  p[x] = 0;
  for (int i = 1; i <= t; ++i) {
    cnt = tmp + g[i + 1] + f[q[i]][0] + Node(1, sex[x] != sex[q[i]]);
    if (q[i] == fa[root] && flag) cnt = Node(-inf, 0);
    if (cnt > f[x][1]) {
      f[x][1] = cnt;
      p[x] = q[i];
    }
    tmp = tmp + ((f[q[i]][0]) > (f[q[i]][1]) ? (f[q[i]][0]) : (f[q[i]][1]));
  }
  if (flag && x == fa[root]) f[x][1] = Node(-inf, 0);
}
void get(int x, bool flag) {
  if (flag == 1) f[x][1] = Node(-inf, 0);
  if (f[x][0] > f[x][1])
    p[x] = 0;
  else {
    ++k;
    ans[k][0] = x;
    ans[k][1] = p[x];
  }
  for (int i = start[x]; i; i = e[i].l)
    if (e[i].a != root) get(e[i].a, e[i].a == p[x]);
}
void work() {
  int x, old;
  Node best, tmp, cnt;
  best = Node(0, 0);
  for (int i = 1; i <= n; ++i)
    if (!bo[i]) {
      x = i;
      old = k;
      while (!bo[x]) bo[x] = 1, x = fa[x];
      root = x;
      flag = 0;
      dfs(x);
      cnt = ((f[x][0]) > (f[x][1]) ? (f[x][0]) : (f[x][1]));
      get(x, 0);
      flag = 1;
      dfs(x);
      tmp = f[x][0] + Node(1, sex[x] != sex[fa[x]]);
      if (tmp > cnt) {
        cnt = tmp;
        k = old;
        get(x, 1);
        ++k;
        ans[k][0] = x;
        ans[k][1] = fa[x];
      }
      best = best + cnt;
    }
  printf("%d %d\n", best.x, best.y);
  for (int i = 1; i <= k; ++i) printf("%d %d\n", ans[i][0], ans[i][1]);
}
int main() {
  init();
  work();
  return 0;
}
