#include <bits/stdc++.h>
using namespace std;
const long long MOD = 1e9 + 7;
int n, f[100010], s[100010], pr[100010], noin;
pair<int, int> dp[100010][2], tot;
vector<int> g[100010], pass;
vector<vector<int> > cir;
vector<pair<int, int> > ans;
bool vis[100010];
pair<int, int> add(pair<int, int> x, pair<int, int> y) {
  return make_pair(x.first + y.first, x.second + y.second);
}
pair<int, int> minu(pair<int, int> x, pair<int, int> y) {
  return make_pair(x.first - y.first, x.second - y.second);
}
bool dfs(int pos, int hd) {
  vis[pos] = true;
  pass.push_back(pos);
  for (int i = 0; i < g[pos].size(); i++) {
    if (g[pos][i] == hd) {
      cir.push_back(pass);
      return true;
    }
    if (dfs(g[pos][i], hd)) return true;
  }
  pass.pop_back();
  return false;
}
void clr(int pos) {
  for (int i = 0; i < 2; i++) dp[pos][i] = make_pair(-1, -1);
  for (int i = 0; i < g[pos].size(); i++)
    if (g[pos][i] != noin) clr(g[pos][i]);
}
void dfs2(int pos) {
  dp[pos][0] = make_pair(0, 0);
  pair<int, int> sum = make_pair(0, 0);
  for (int i = 0; i < g[pos].size(); i++) {
    if (g[pos][i] == noin) continue;
    dfs2(g[pos][i]);
    sum = add(sum, max(dp[g[pos][i]][0], dp[g[pos][i]][1]));
  }
  dp[pos][0] = add(dp[pos][0], sum);
  for (int i = 0; i < g[pos].size(); i++) {
    if (g[pos][i] == noin) continue;
    sum = minu(sum, max(dp[g[pos][i]][0], dp[g[pos][i]][1]));
    pair<int, int> addd = make_pair(1, (int)(s[pos] != s[g[pos][i]]));
    if (dp[pos][1] < add(addd, add(sum, dp[g[pos][i]][0]))) {
      dp[pos][1] = add(addd, add(sum, dp[g[pos][i]][0]));
      pr[pos] = g[pos][i];
    }
    sum = add(sum, max(dp[g[pos][i]][0], dp[g[pos][i]][1]));
  }
}
pair<int, int> calc(int rt) {
  clr(rt);
  dfs2(rt);
  return max(dp[rt][0], dp[rt][1]);
}
void get(int pos, int w) {
  if (w == 1) ans.push_back(make_pair(pos, pr[pos]));
  for (int i = 0; i < g[pos].size(); i++) {
    if (g[pos][i] == noin) continue;
    if (w == 1 && g[pos][i] == pr[pos])
      get(g[pos][i], 0);
    else {
      if (dp[g[pos][i]][0] > dp[g[pos][i]][1])
        get(g[pos][i], 0);
      else
        get(g[pos][i], 1);
    }
  }
}
int main() {
  cin >> n;
  for (int i = 1; i <= n; i++) {
    scanf("%d%d", &f[i], &s[i]);
    g[f[i]].push_back(i);
  }
  for (int i = 1; i <= n; i++) {
    if (vis[i]) continue;
    pass.clear();
    dfs(i, i);
  }
  for (int i = 0; i < cir.size(); i++) {
    noin = cir[i][1];
    pair<int, int> res1 = calc(cir[i][1]);
    noin = cir[i][0];
    pair<int, int> res2 = calc(cir[i][0]);
    int w = res1 > res2 ? 1 : 0;
    if (w == 1) {
      noin = cir[i][1];
      calc(cir[i][w]);
    }
    tot = add(tot, max(dp[cir[i][w]][0], dp[cir[i][w]][1]));
    if (dp[cir[i][w]][0] > dp[cir[i][w]][1])
      get(cir[i][w], 0);
    else
      get(cir[i][w], 1);
  }
  cout << tot.first << ' ' << tot.second << endl;
  for (int i = 0; i < ans.size(); i++)
    printf("%d %d\n", ans[i].first, ans[i].second);
  return 0;
}
