#include <bits/stdc++.h>
using namespace std;
long long n, p[200005], a[200005], fix[200005], no[200005], k, ch[200005];
pair<long long, long long> dp[200005][2], pas, ans[200005][2];
vector<long long> v[200005], g;
vector<pair<long long, long long> > sab;
void go(long long x, long long par) {
  if (k == 1) return;
  if (fix[x] == 1) {
    k = 1;
    g.push_back(x);
    return;
  }
  fix[x] = 1;
  g.push_back(x);
  long long raod = 0;
  for (int i = 0; i < v[x].size(); i++) {
    if (v[x][i] == par) {
      raod++;
      if (raod < 2) continue;
    }
    go(v[x][i], x);
    if (k == 1) return;
  }
  g.pop_back();
}
void solve(long long x, long long par) {
  long long ye = 0;
  fix[x] = 1;
  pair<long long, long long> sum0, sum1;
  sum1.first = sum1.second = 0;
  for (int i = 0; i < v[x].size(); i++) {
    if (v[x][i] == par || no[v[x][i]] == 1) continue;
    solve(v[x][i], x);
    sum1.first += dp[v[x][i]][1].first;
    sum1.second += dp[v[x][i]][1].second;
    ye = 1;
  }
  if (!ye) {
    return;
  }
  dp[x][0] = sum1;
  dp[x][1] = dp[x][0];
  for (int i = 0; i < v[x].size(); i++) {
    if (v[x][i] == par || no[v[x][i]] == 1) continue;
    sum1.first -= dp[v[x][i]][1].first;
    sum1.second -= dp[v[x][i]][1].second;
    if (make_pair(sum1.first + dp[v[x][i]][0].first + 1,
                  sum1.second + dp[v[x][i]][0].second + (a[x] ^ a[v[x][i]])) >
        dp[x][1]) {
      dp[x][1] =
          make_pair(sum1.first + dp[v[x][i]][0].first + 1,
                    sum1.second + dp[v[x][i]][0].second + (a[x] ^ a[v[x][i]]));
      ch[x] = v[x][i];
    }
    sum1.first += dp[v[x][i]][1].first;
    sum1.second += dp[v[x][i]][1].second;
  }
  dp[x][1] = max(dp[x][1], dp[x][0]);
}
void ag(long long x, long long par, long long hav) {
  if (hav == 0 || dp[x][0] >= dp[x][1]) {
    for (int i = 0; i < v[x].size(); i++) {
      if (no[v[x][i]] || v[x][i] == par) continue;
      ag(v[x][i], x, 1);
    }
    return;
  }
  sab.push_back(make_pair(x, ch[x]));
  ag(ch[x], x, 0);
  for (int i = 0; i < v[x].size(); i++) {
    if (no[v[x][i]] || v[x][i] == par || v[x][i] == ch[x]) continue;
    ag(v[x][i], x, 1);
  }
}
pair<long long, long long> con(pair<long long, long long> x,
                               pair<long long, long long> y) {
  return make_pair(x.first + y.first, x.second + y.second);
}
int main() {
  ios::sync_with_stdio(false);
  cin >> n;
  for (int i = 1; i <= n; i++) {
    cin >> p[i] >> a[i];
    a[i]--;
    v[p[i]].push_back(i);
    v[i].push_back(p[i]);
  }
  for (int w = 1; w <= n; w++) {
    if (fix[w]) continue;
    g.clear();
    k = 0;
    go(w, 0);
    if (g.size() == 0) continue;
    long long las = g[g.size() - 1];
    vector<long long> cir;
    cir.push_back(las);
    no[las] = 1;
    for (int i = (int)g.size() - 2; i >= 0; i--) {
      if (g[i] == las) break;
      cir.push_back(g[i]);
      no[g[i]] = 1;
    }
    for (int i = 0; i < cir.size(); i++) {
      solve(cir[i], -1);
    }
    pair<long long, long long> mx = make_pair(0, 0);
    ans[cir[0]][0] = dp[cir[0]][0];
    ans[cir[0]][1] = dp[cir[0]][1];
    for (int i = 1; i < cir.size(); i++) {
      long long x = cir[i], le = cir[i - 1];
      pair<long long, long long> p1 = con(ans[le][1], dp[x][0]);
      pair<long long, long long> p2 = con(ans[le][0], dp[x][0]);
      ans[x][0] = max(p1, p2);
      p2 = max(ans[le][0], ans[le][1]);
      p1 = con(p2, dp[x][1]);
      p2 = con(ans[le][0], dp[x][0]);
      p2.first++;
      p2.second += (a[x] ^ a[le]);
      ans[x][1] = max(p1, p2);
    }
    mx = max(ans[cir[cir.size() - 1]][0], ans[cir[cir.size() - 1]][1]);
    for (int i = 0; i < cir.size(); i++)
      ans[cir[i]][0] = ans[cir[i]][1] = make_pair(0, 0);
    cir.push_back(cir[0]);
    ans[cir[1]][0] = dp[cir[1]][0];
    ans[cir[1]][1] = dp[cir[1]][1];
    for (int i = 2; i < cir.size(); i++) {
      long long x = cir[i], le = cir[i - 1];
      pair<long long, long long> p1 = con(ans[le][1], dp[x][0]);
      pair<long long, long long> p2 = con(ans[le][0], dp[x][0]);
      ans[x][0] = max(p1, p2);
      p2 = max(ans[le][0], ans[le][1]);
      p1 = con(p2, dp[x][1]);
      p2 = con(ans[le][0], dp[x][0]);
      p2.first++;
      p2.second += (a[x] ^ a[le]);
      ans[x][1] = max(p1, p2);
    }
    pair<long long, long long> ne =
        max(ans[cir[cir.size() - 1]][0], ans[cir[cir.size() - 1]][1]);
    if (mx > ne) {
      cir.pop_back();
      ans[cir[0]][0] = dp[cir[0]][0];
      ans[cir[0]][1] = dp[cir[0]][1];
      for (int i = 1; i < cir.size(); i++) {
        long long x = cir[i], le = cir[i - 1];
        pair<long long, long long> p1 = con(ans[le][1], dp[x][0]);
        pair<long long, long long> p2 = con(ans[le][0], dp[x][0]);
        ans[x][0] = max(p1, p2);
        p2 = max(ans[le][0], ans[le][1]);
        p1 = con(p2, dp[x][1]);
        p2 = con(ans[le][0], dp[x][0]);
        p2.first++;
        p2.second += (a[x] ^ a[le]);
        ans[x][1] = max(p1, p2);
      }
      long long got = 1;
      for (int i = cir.size() - 1; i >= 0; i--) {
        long long x = cir[i], le = cir[i - 1];
        if (got == 0) {
          got = 1;
          ag(cir[i], -1, 0);
          continue;
        }
        pair<long long, long long> p1 = con(ans[le][1], dp[x][1]);
        pair<long long, long long> p2 = con(ans[le][0], dp[x][1]);
        pair<long long, long long> cur = max(p1, p2);
        p2 = con(ans[le][0], dp[x][0]);
        p2.first++;
        p2.second += (a[x] ^ a[le]);
        if (cur > p2 || !i) {
          ag(cir[i], -1, 1);
          got = 1;
          continue;
        }
        sab.push_back(make_pair(x, le));
        got = 0;
        ag(cir[i], -1, 0);
      }
    } else {
      long long got = 1;
      for (int i = cir.size() - 1; i >= 1; i--) {
        long long x = cir[i], le = cir[i - 1];
        if (i == 1) le = 0;
        if (got == 0) {
          got = 1;
          ag(cir[i], -1, 0);
          continue;
        }
        pair<long long, long long> p1 = con(ans[le][1], dp[x][1]);
        pair<long long, long long> p2 = con(ans[le][0], dp[x][1]);
        pair<long long, long long> cur = max(p1, p2);
        p2 = con(ans[le][0], dp[x][0]);
        p2.first++;
        p2.second += (a[x] ^ a[le]);
        if (cur > p2 || i == 1) {
          ag(cir[i], -1, 1);
          got = 1;
          continue;
        }
        sab.push_back(make_pair(x, le));
        got = 0;
        ag(cir[i], -1, 0);
      }
    }
    mx = max(mx, ne);
    pas = con(pas, mx);
  }
  cout << pas.first << " " << pas.second << '\n';
  for (int i = 0; i < sab.size(); i++)
    cout << sab[i].first << " " << sab[i].second << '\n';
  return 0;
}
