#include <bits/stdc++.h>
using namespace std;
inline void read(int &x) {
  int v = 0, f = 1;
  char c = getchar();
  while (!isdigit(c) && c != '-') c = getchar();
  if (c == '-')
    f = -1;
  else
    v = v * 10 + c - '0';
  while (isdigit(c = getchar())) v = v * 10 + c - '0';
  x = v * f;
}
inline void read(long long &x) {
  long long v = 0ll, f = 1ll;
  char c = getchar();
  while (!isdigit(c) && c != '-') c = getchar();
  if (c == '-')
    f = -1;
  else
    v = v * 10 + c - '0';
  while (isdigit(c = getchar())) v = v * 10 + c - '0';
  x = v * f;
}
inline void readc(char &x) {
  char c;
  while ((c = getchar()) == ' ')
    ;
  x = c;
}
inline void writes(string s) { puts(s.c_str()); }
inline void writeln() { writes(""); }
inline void writei(int x) {
  if (x < 0) {
    putchar('-');
    x = abs(x);
  }
  if (!x) putchar('0');
  char a[25];
  int top = 0;
  while (x) {
    a[++top] = (x % 10) + '0';
    x /= 10;
  }
  while (top) {
    putchar(a[top]);
    top--;
  }
}
inline void writell(long long x) {
  if (x < 0) {
    putchar('-');
    x = abs(x);
  }
  if (!x) putchar('0');
  char a[25];
  int top = 0;
  while (x) {
    a[++top] = (x % 10) + '0';
    x /= 10;
  }
  while (top) {
    putchar(a[top]);
    top--;
  }
}
int n, m, i, j, x, y, typ[200005], hd[200005], nxt[200005], to[200005],
    g[200005], vis[200005], bst[2][200005], incir[200005], mxs, ban;
pair<int, int> dp[2][200005][2], mx, ans;
vector<pair<int, int> > res;
pair<int, int> operator+(const pair<int, int> &x, const pair<int, int> &y) {
  return make_pair(x.first + y.first, x.second + y.second);
}
pair<int, int> operator-(const pair<int, int> &x, const pair<int, int> &y) {
  return make_pair(x.first - y.first, x.second - y.second);
}
void dfs(int x, int fa, int t) {
  vis[x] = 1;
  dp[t][x][0] = dp[t][x][1] = make_pair(0, 0);
  int i;
  for (i = hd[x]; i; i = nxt[i])
    if (to[i] != fa && i / 2 != ban / 2) {
      dfs(to[i], x, t);
      dp[t][x][0] = dp[t][x][0] + max(dp[t][to[i]][0], dp[t][to[i]][1]);
    }
  dp[t][x][1] = dp[t][x][0];
  bst[t][x] = 0;
  for (i = hd[x]; i; i = nxt[i])
    if (to[i] != fa && i / 2 != ban / 2) {
      pair<int, int> s = dp[t][x][0] + dp[t][to[i]][0] -
                         max(dp[t][to[i]][0], dp[t][to[i]][1]) +
                         make_pair(1, typ[x] != typ[to[i]]);
      if (s > dp[t][x][1]) {
        dp[t][x][1] = s;
        bst[t][x] = to[i];
      }
    }
}
void print(int t, int x, int fa, int y) {
  if (!y || !bst[t][x]) {
    int i;
    for (i = hd[x]; i; i = nxt[i])
      if (to[i] != fa && i / 2 != ban / 2) {
        print(t, to[i], x, 1);
      }
  } else {
    int i;
    for (i = hd[x]; i; i = nxt[i])
      if (to[i] != fa && i / 2 != ban / 2) {
        if (bst[t][x] == to[i]) {
          res.push_back(make_pair(x, to[i]));
          print(t, to[i], x, 0);
        } else
          print(t, to[i], x, 1);
      }
  }
}
void solve(int x) {
  while (!vis[x]) {
    vis[x] = 1;
    x = g[x];
  }
  while (vis[x] == 1) {
    vis[x] = 2;
    incir[x] = 1;
    x = g[x];
  }
  vector<int> t;
  int i;
  for (i = hd[x]; i; i = nxt[i])
    if (incir[to[i]]) {
      t.push_back(i);
    }
  mx = make_pair(0, 0);
  for (i = 0; i < t.size(); i++) {
    ban = t[i];
    dfs(x, 0, i);
    if (max(dp[i][x][0], dp[i][x][1]) > mx) {
      mx = max(dp[i][x][0], dp[i][x][1]);
      mxs = i;
    }
  }
  ans = ans + mx;
  ban = t[mxs];
  print(mxs, x, 0, 1);
}
int main() {
  read(n);
  for (((i)) = (1); ((i)) <= ((n)); ((i))++) {
    read(g[i]);
    read(typ[i]);
    nxt[i * 2 + 1] = hd[i];
    hd[i] = i * 2 + 1;
    to[i * 2 + 1] = g[i];
    nxt[i * 2] = hd[g[i]];
    hd[g[i]] = i * 2;
    to[i * 2] = i;
  }
  for (((i)) = (1); ((i)) <= ((n)); ((i))++) {
    if (!vis[i]) {
      solve(i);
    }
  }
  printf("%d %d\n", ans.first, ans.second);
  for (__typeof((res).begin()) it = (res).begin(); it != (res).end(); it++) {
    printf("%d %d\n", it->first, it->second);
  }
  return 0;
}
