#include <bits/stdc++.h>
using namespace std;
int n;
int gender[200000];
int parent[200000];
vector<int> con[200000];
char used[200000];
int forbid1, forbid2;
long long dp[200000][2][2];
int froot;
int fc[2];
void mark_used(int x) {
  used[x] = 2;
  int i, a;
  for (i = 0; i < con[x].size(); i++) {
    a = con[x][i];
    if (used[a] != 2) mark_used(a);
  }
}
long long doit1(int x, int p, int fid, int taken) {
  long long& res = dp[x][fid][taken];
  if (res != -1) return res;
  int i, a;
  vector<int> child;
  for (i = 0; i < con[x].size(); i++) {
    a = con[x][i];
    if (a == p) continue;
    if (x == froot && a == fc[fid]) continue;
    if (x == fc[fid] && a == froot) continue;
    child.push_back(a);
  }
  if (x == froot && fc[0] == fc[1]) child.push_back(fc[0]);
  if (child.empty()) return res = 0;
  long long v1 = 0;
  for (i = 0; i < child.size(); i++) {
    a = child[i];
    v1 += doit1(a, x, fid, 0);
  }
  res = v1;
  if (!taken) {
    for (i = 0; i < child.size(); i++) {
      a = child[i];
      long long v2 = v1 - doit1(a, x, fid, 0) + doit1(a, x, fid, 1);
      v2 += 1000000;
      if (gender[x] != gender[a]) v2++;
      if (v2 > res) res = v2;
    }
  }
  return res;
}
vector<pair<int, int> > the_pairs;
void trace(int x, int p, int fid, int taken) {
  long long res = dp[x][fid][taken];
  int i, a;
  vector<int> child;
  for (i = 0; i < con[x].size(); i++) {
    a = con[x][i];
    if (a == p) continue;
    if (x == froot && a == fc[fid]) continue;
    if (x == fc[fid] && a == froot) continue;
    child.push_back(a);
  }
  if (x == froot && fc[0] == fc[1]) child.push_back(fc[0]);
  if (child.empty()) return;
  long long v1 = 0;
  for (i = 0; i < child.size(); i++) {
    a = child[i];
    v1 += doit1(a, x, fid, 0);
  }
  if (res == v1) {
    for (i = 0; i < child.size(); i++) trace(child[i], x, fid, 0);
    return;
  }
  for (i = 0; i < child.size(); i++) {
    a = child[i];
    long long v2 = v1 - doit1(a, x, fid, 0) + doit1(a, x, fid, 1);
    v2 += 1000000;
    if (gender[x] != gender[a]) v2++;
    if (v2 == res) break;
  }
  int z = i;
  the_pairs.push_back(pair<int, int>(x, child[z]));
  trace(child[z], x, fid, 1);
  for (i = 0; i < child.size(); i++)
    if (i != z) trace(child[i], x, fid, 0);
}
long long doit(int x) {
  int root = x;
  int prev = -1;
  while (!used[root]) {
    used[root] = 1;
    prev = root;
    root = parent[root];
  }
  mark_used(root);
  froot = root;
  fc[0] = parent[root];
  fc[1] = prev;
  long long v1 = doit1(root, -1, 0, 0);
  long long v2 = doit1(root, -1, 1, 0);
  if (v1 > v2) {
    trace(root, -1, 0, 0);
    return v1;
  } else {
    trace(root, -1, 1, 0);
    return v2;
  }
}
int main() {
  scanf("%d", &n);
  int i, a;
  for (i = 0; i < n; i++) con[i].clear();
  for (i = 0; i < n; i++) {
    scanf("%d %d", &a, &gender[i]);
    a--;
    parent[i] = a;
    con[i].push_back(a);
    con[a].push_back(i);
  }
  memset(used, 0, sizeof(used));
  memset(dp, -1, sizeof(dp));
  the_pairs.clear();
  long long res = 0;
  for (i = 0; i < n; i++)
    if (used[i] == 0) {
      res += doit(i);
    }
  printf("%I64d %I64d\n", res / 1000000, res % 1000000);
  for (i = 0; i < the_pairs.size(); i++)
    printf("%d %d\n", the_pairs[i].first + 1, the_pairs[i].second + 1);
  return 0;
}
