#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:64000000")
using namespace std;
void __never(int a) { printf("\nOPS %d", a); }
set<pair<int, int> > G;
int pre[100100];
bool sex[100100];
bool F[100100];
bool F2[100100];
int n;
bool down;
pair<int, int> ans = make_pair(0, 0);
pair<int, int> ans_p[100100];
int a_sz = 0;
int tmp;
int cur_dp;
pair<pair<int, int>, pair<int, int> > dp[2][100100];
pair<pair<int, int>, pair<int, int> > calc_dp(int v) {
  vector<pair<pair<int, int>, pair<int, int> > > vec;
  vector<bool> child_sex;
  set<pair<int, int> >::iterator it;
  for (it = G.lower_bound(make_pair(v, -1)); it != G.end() && it->first == v;
       it++)
    if (!F2[it->second]) {
      vec.push_back(calc_dp(it->second));
      child_sex.push_back(sex[it->second]);
    }
  if (!(int)((vec).size())) return make_pair(make_pair(0, 0), make_pair(0, 0));
  pair<pair<int, int>, pair<int, int> > re;
  for (int a = (0); a <= ((int)((vec).size()) - 1); a++) {
    pair<int, int> p = max(vec[a].first, vec[a].second);
    re.first.first += p.first;
    re.first.second += p.second;
  }
  for (int a = (0); a <= ((int)((vec).size()) - 1); a++) {
    pair<int, int> p = max(vec[a].first, vec[a].second);
    pair<int, int> p2 =
        make_pair(re.first.first - p.first, re.first.second - p.second);
    p2 = make_pair(p2.first + vec[a].first.first,
                   p2.second + vec[a].first.second);
    p2.first++;
    if (sex[v] != child_sex[a]) p2.second++;
    re.second = max(re.second, p2);
  }
  dp[cur_dp][v] = re;
  return re;
}
void build_ans(int v, pair<int, int> ppp) {
  vector<pair<pair<int, int>, pair<int, int> > > vec;
  vector<int> child;
  set<pair<int, int> >::iterator it;
  for (it = G.lower_bound(make_pair(v, -1)); it != G.end() && it->first == v;
       it++)
    if (!F2[it->second]) {
      vec.push_back(dp[cur_dp][it->second]);
      child.push_back(it->second);
    }
  if (!(int)((vec).size())) return;
  pair<pair<int, int>, pair<int, int> > re;
  for (int a = (0); a <= ((int)((vec).size()) - 1); a++) {
    pair<int, int> p = max(vec[a].first, vec[a].second);
    re.first.first += p.first;
    re.first.second += p.second;
  }
  if (re.first == ppp) {
    for (int a = (0); a <= ((int)((vec).size()) - 1); a++)
      build_ans(child[a], max(vec[a].first, vec[a].second));
    return;
  }
  for (int a = (0); a <= ((int)((vec).size()) - 1); a++) {
    pair<int, int> p = max(vec[a].first, vec[a].second);
    pair<int, int> p2 =
        make_pair(re.first.first - p.first, re.first.second - p.second);
    p2 = make_pair(p2.first + vec[a].first.first,
                   p2.second + vec[a].first.second);
    p2.first++;
    if (sex[v] != sex[child[a]]) p2.second++;
    re.second = max(re.second, p2);
    if (re.second == ppp) {
      ans_p[a_sz++] = make_pair(v, child[a]);
      for (int b = (0); b <= ((int)((vec).size()) - 1); b++)
        if (b == a)
          build_ans(child[b], vec[b].first);
        else
          build_ans(child[b], max(vec[b].first, vec[b].second));
      return;
    }
  }
}
void make_cycle(int v) {
  F2[v] = true;
  cur_dp = 0;
  pair<pair<int, int>, pair<int, int> > dp1 = calc_dp(v);
  F2[v] = false;
  F2[pre[v]] = true;
  cur_dp = 1;
  pair<pair<int, int>, pair<int, int> > dp2 = calc_dp(pre[v]);
  F2[pre[v]] = false;
  pair<int, int> p =
      max(max(dp1.first, dp1.second), max(dp2.first, dp2.second));
  ans.first += p.first;
  ans.second += p.second;
  if (max(dp1.first, dp1.second) > max(dp2.first, dp2.second)) {
    F2[v] = true;
    cur_dp = 0;
    build_ans(v, p);
  } else {
    F2[pre[v]] = true;
    cur_dp = 1;
    build_ans(pre[v], p);
  }
}
void dfs1(int v) {
  F[v] = true;
  if (!F[pre[v]]) {
    dfs1(pre[v]);
    F[v] = false;
    return;
  }
  make_cycle(v);
  tmp = v;
  F[v] = false;
}
void dfs(int v) {
  F[v] = true;
  set<pair<int, int> >::iterator it;
  for (it = G.lower_bound(make_pair(v, -1)); it != G.end() && it->first == v;
       it++)
    if (!F[it->second]) dfs(it->second);
}
void sol() {
  for (int a = (1); a <= (n); a++)
    if (!F[a]) {
      down = true;
      dfs1(a);
      dfs(tmp);
    }
  cout << ans.first << " " << ans.second << "\n";
  for (int a = (0); a <= (a_sz - 1); a++)
    printf("%d %d\n", ans_p[a].first, ans_p[a].second);
}
int main() {
  scanf("%d", &n);
  for (int a = (1); a <= (n); a++) {
    int x, sx;
    scanf("%d%d", &x, &sx);
    sex[a] = (sx == 1);
    pre[a] = x;
    G.insert(make_pair(x, a));
  }
  sol();
  return 0;
}
