#include <bits/stdc++.h>
using namespace std;
pair<int, int> operator+(pair<int, int> a, pair<int, int> b) {
  pair<int, int> ret = a;
  ret.first += b.first, ret.second += b.second;
  return ret;
}
pair<int, int> operator-(pair<int, int> b, pair<int, int> a) {
  pair<int, int> ret = b;
  ret.first -= a.first, ret.second -= a.second;
  return ret;
}
pair<int, int> qmax(pair<int, int> a, pair<int, int> b) {
  return (a > b) ? a : b;
}
int n;
int par[100100];
bool is_anc[100100], mx_tp[100100];
vector<int> son[100100];
bool col[100100];
bool done[100100], doing[100100];
bool in_cyc[100100];
int now_rt = -1;
int ntp;
pair<int, int> f[2][100100], g[2][100100];
int lst[2][100100];
void get_dp(int now) {
  done[now] = 1;
  pair<int, int> sum = make_pair(0, 0);
  for (int i = 0; i < (int)son[now].size(); i++) {
    if (par[son[now][i]] == now) {
      get_dp(son[now][i]);
      sum = sum + f[ntp][son[now][i]];
    }
  }
  g[ntp][now] = sum;
  f[ntp][now] = sum;
  lst[ntp][now] = -1;
  for (int i = 0; i < (int)son[now].size(); i++) {
    if (par[son[now][i]] == now) {
      pair<int, int> ret = sum - f[ntp][son[now][i]] + g[ntp][son[now][i]] +
                           make_pair(1, (bool)(col[now] != col[son[now][i]]));
      if (ret > f[ntp][now]) {
        f[ntp][now] = ret;
        lst[ntp][now] = son[now][i];
      }
    }
  }
}
void get_ans(int now, bool tp, bool is_f) {
  if (is_f && lst[tp][now] >= 0) {
    cout << now + 1 << " " << lst[tp][now] + 1 << endl;
  }
  for (int i = 0; i < (int)son[now].size(); i++) {
    if (par[son[now][i]] == now) {
      get_ans(son[now][i], tp, !(is_f && (son[now][i] == lst[tp][now])));
    }
  }
}
int main() {
  ios::sync_with_stdio(false);
  cin >> n;
  for (int i = 0; i < n; i++) {
    cin >> par[i];
    par[i]--;
    son[par[i]].push_back(i);
    int ncol;
    cin >> ncol;
    col[i] = (bool)(ncol - 1);
  }
  pair<int, int> ans = make_pair(0, 0);
  for (int curcur = 0; curcur < n; curcur++) {
    if (!done[curcur]) {
      int i = curcur;
      while (!in_cyc[i]) {
        in_cyc[i] = 1;
        i = par[i];
      }
      now_rt = i;
      int pos0 = i, pos1 = par[i];
      int parpos0 = par[pos0], parpos1 = par[pos1];
      ntp = 0;
      par[pos0] = -1;
      get_dp(pos0);
      par[pos0] = parpos0;
      ntp = 1;
      par[pos1] = -1;
      get_dp(pos1);
      par[pos1] = parpos1;
      if (f[0][pos0] > f[1][pos1])
        ans = ans + f[0][pos0], is_anc[pos0] = 1, mx_tp[pos0] = 0;
      else
        ans = ans + f[1][pos1], is_anc[pos1] = 1, mx_tp[pos1] = 1;
    }
  }
  cout << ans.first << " " << ans.second << endl;
  for (int i = 0; i < n; i++) {
    if (is_anc[i]) {
      par[i] = -1;
      get_ans(i, mx_tp[i], 1);
    }
  }
  return 0;
}
