#include <bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f, mod = 1000000007;
const double pi = 3.1415926535897932, eps = 1e-6;
void chmax(int &x, int y) {
  if (x < y) x = y;
}
void chmin(int &x, int y) {
  if (x > y) x = y;
}
int qpow(int x, int y) {
  int ret = 1;
  while (y) {
    if (y & 1) ret = (long long)ret * x % mod;
    x = (long long)x * x % mod;
    y >>= 1;
  }
  return ret;
}
int n;
int to[100005];
int s[100005], in[100005];
pair<int, int> dp[100005][2];
queue<int> q;
vector<int> cyc, rel;
vector<int> g[100005], v[100005];
bool vis[100005], deal[100005], vis2[100005];
int bs;
vector<pair<int, int> > suit, ANS;
pair<int, int> ans;
void dfs(int x) {
  if (deal[x]) return;
  deal[x] = 1;
  cyc.push_back(x);
  dfs(to[x]);
}
void dfs2(int x) {
  if (vis2[x]) return;
  rel.push_back(x);
  vis2[x] = 1;
  for (int(i) = (0); (i) < (g[x].size()); (i)++) {
    int to = g[x][i];
    dfs2(to);
  }
}
pair<int, int> operator+(pair<int, int> a, pair<int, int> b) {
  return make_pair(a.first + b.first, a.second + b.second);
}
pair<int, int> operator-(pair<int, int> a, pair<int, int> b) {
  return make_pair(a.first - b.first, a.second - b.second);
}
void dfs3(int x) {
  pair<int, int> sum = make_pair(0, 0);
  dp[x][1] = make_pair(-inf, -inf);
  for (int(i) = (0); (i) < (v[x].size()); (i)++) {
    int to = v[x][i];
    dfs3(to);
    dp[x][0] = dp[x][0] + max(dp[to][0], dp[to][1]);
    sum = sum + max(dp[to][0], dp[to][1]);
  }
  for (int(i) = (0); (i) < (v[x].size()); (i)++) {
    int to = v[x][i];
    pair<int, int> nw = sum - max(dp[to][0], dp[to][1]) + dp[to][0] +
                        make_pair(1, s[x] != s[to]);
    if (nw > dp[x][1]) dp[x][1] = nw;
  }
}
void rec(int x, bool cover) {
  pair<int, int> cur = dp[x][cover];
  if (cover == 0) {
    for (int(i) = (0); (i) < (v[x].size()); (i)++) {
      int to = v[x][i];
      if (dp[to][0] > dp[to][1])
        rec(to, 0);
      else
        rec(to, 1);
    }
  } else {
    int chosen = 0;
    pair<int, int> sum = make_pair(0, 0);
    for (int(i) = (0); (i) < (v[x].size()); (i)++) {
      int to = v[x][i];
      sum = sum + max(dp[to][0], dp[to][1]);
    }
    for (int(i) = (0); (i) < (v[x].size()); (i)++) {
      int to = v[x][i];
      pair<int, int> nw = sum - max(dp[to][0], dp[to][1]) + dp[to][0] +
                          make_pair(1, s[x] != s[to]);
      if (nw == dp[x][1]) chosen = to;
    }
    assert(chosen);
    suit.push_back(make_pair(x, chosen));
    rec(chosen, 0);
    for (int(i) = (0); (i) < (v[x].size()); (i)++) {
      int to = v[x][i];
      if (to != chosen) {
        if (dp[to][0] > dp[to][1])
          rec(to, 0);
        else
          rec(to, 1);
      }
    }
  }
}
int main() {
  scanf("%d", &n);
  for (int(i) = (1); (i) <= (n); (i)++)
    scanf("%d%d", to + i, s + i), in[to[i]]++, g[to[i]].push_back(i);
  for (int(i) = (1); (i) <= (n); (i)++)
    if (!in[i]) q.push(i);
  while (!q.empty()) {
    int x = q.front();
    int t = to[x];
    vis[x] = 1;
    q.pop();
    in[t]--;
    if (!in[t]) q.push(t);
  }
  for (int(i) = (1); (i) <= (n); (i)++)
    if (!vis[i]) {
      if (deal[i]) continue;
      cyc.clear();
      rel.clear();
      dfs(i);
      dfs2(i);
      bs = cyc[0];
      int m = cyc.size();
      for (int(i) = (0); (i) < (rel.size()); (i)++) {
        int x = rel[i], t = to[rel[i]];
        if (x != bs) v[t].push_back(x);
      }
      int DS = cyc[0];
      dfs3(DS);
      pair<int, int> sds = make_pair(0, 0);
      pair<int, int> u = max(dp[DS][0], dp[DS][1]);
      if (u > sds) {
        sds = u;
        suit.clear();
        if (dp[DS][0] > dp[DS][1])
          rec(DS, 0);
        else
          rec(DS, 1);
      }
      bs = cyc[1];
      DS = cyc[1];
      for (int(i) = (0); (i) < (rel.size()); (i)++) {
        dp[rel[i]][0] = dp[rel[i]][1] = make_pair(0, 0);
        v[rel[i]].clear();
      }
      for (int(i) = (0); (i) < (rel.size()); (i)++) {
        int x = rel[i], t = to[rel[i]];
        if (x != bs) {
          v[t].push_back(x);
        }
      }
      dfs3(DS);
      u = max(dp[DS][0], dp[DS][1]);
      if (u > sds) {
        sds = u;
        suit.clear();
        if (dp[DS][0] > dp[DS][1])
          rec(DS, 0);
        else
          rec(DS, 1);
      }
      for (int(i) = (0); (i) < (rel.size()); (i)++) {
        dp[rel[i]][0] = dp[rel[i]][1] = make_pair(0, 0);
        v[rel[i]].clear();
      }
      while (suit.size()) ANS.push_back(suit.back()), suit.pop_back();
      ans = ans + sds;
    }
  printf("%d %d\n", ans.first, ans.second);
  for (int(i) = (0); (i) < (ANS.size()); (i)++)
    printf("%d %d\n", ANS[i].first, ANS[i].second);
  return 0;
}
