#include <bits/stdc++.h>
using namespace std;
vector<vector<int> > edge;
vector<bool> gender;
int n;
vector<int> circle;
vector<bool> used, visit;
vector<pair<int, int> > f, g;
vector<int> fm;
vector<int> match;
bool dfs(int prev, int now) {
  vector<int> &list = edge[now];
  used[now] = true;
  circle.push_back(now);
  for (vector<int>::iterator it = list.begin(); it != list.end(); it++) {
    if (*it == prev) continue;
    if (used[*it]) {
      circle.push_back(*it);
      return true;
    }
    if (dfs(now, *it)) return true;
  }
  circle.pop_back();
  return false;
}
void dp(int root) {
  vector<int> &list = edge[root];
  pair<int, int> tf(0, 0), tg(0, 0);
  visit[root] = true;
  vector<int> go;
  for (vector<int>::iterator it = list.begin(); it != list.end(); it++) {
    if (visit[*it]) continue;
    go.push_back(*it);
    dp(*it);
    tg.first += f[*it].first;
    tg.second += f[*it].second;
  }
  tf = tg;
  for (vector<int>::iterator it = go.begin(); it != go.end(); it++) {
    pair<int, int> tmp(tg.first - f[*it].first + g[*it].first + 1,
                       tg.second - f[*it].second + g[*it].second +
                           ((gender[root] xor gender[*it]) ? 1 : 0));
    if (tf < tmp) {
      tf = tmp;
      fm[root] = *it;
    }
  }
  f[root] = tf;
  g[root] = tg;
}
void make_match(int prev, int now) {
  vector<int> &list = edge[now];
  for (vector<int>::iterator it = list.begin(); it != list.end(); it++) {
    if (*it == prev) continue;
    match[*it] = -1;
  }
  if (match[now] < 0) {
    int other = fm[now];
    if (other >= 0) {
      match[now] = other;
      match[other] = now;
    }
  }
  for (vector<int>::iterator it = list.begin(); it != list.end(); it++) {
    if (*it == prev) continue;
    make_match(now, *it);
  }
}
pair<int, int> solve(int root) {
  circle.clear();
  dfs(-1, root);
  if (circle.empty()) {
    dp(root);
    match[root] = -1;
    make_match(-1, root);
    return f[root];
  }
  circle.erase(circle.begin(),
               find(circle.begin(), circle.end(), circle.back()) + 1);
  int m = circle.size();
  for (int i = 0; i < m; i++) {
    vector<int> &list = edge[circle[i]];
    list.erase(find(list.begin(), list.end(), circle[(i + m - 1) % m]));
    list.erase(find(list.begin(), list.end(), circle[(i + 1) % m]));
  }
  for (int i = 0; i < m; i++) {
    dp(circle[i]);
  }
  pair<int, int> ans(0, 0);
  for (int loop = 0; loop < 2; loop++) {
    vector<pair<int, int> > x(m + 1);
    vector<bool> d(m + 1);
    x[0] = make_pair(0, 0);
    for (int i = 1; i <= m; i++) {
      x[i] = make_pair(x[i - 1].first + f[circle[i - 1]].first,
                       x[i - 1].second + f[circle[i - 1]].second);
      if (i > 1) {
        int a = circle[i - 2], b = circle[i - 1];
        pair<int, int> tmp =
            make_pair(x[i - 2].first + g[a].first + g[b].first + 1,
                      x[i - 2].second + g[a].second + g[b].second +
                          ((gender[a] xor gender[b]) ? 1 : 0));
        if (x[i] < tmp) {
          x[i] = tmp;
          d[i] = true;
        }
      }
    }
    if (ans < x[m]) {
      ans = x[m];
      for (int i = m; i > 0;) {
        if (d[i]) {
          match[circle[i - 1]] = circle[i - 2];
          match[circle[i - 2]] = circle[i - 1];
          make_match(-1, circle[i - 1]);
          make_match(-1, circle[i - 2]);
          i -= 2;
        } else {
          match[circle[i - 1]] = -1;
          make_match(-1, circle[i - 1]);
          i--;
        }
      }
    }
    rotate(circle.begin(), circle.begin() + 1, circle.end());
  }
  return ans;
}
int main() {
  scanf("%d", &n);
  edge.clear();
  edge.resize(n);
  gender.clear();
  gender.resize(n);
  set<pair<int, int> > clean;
  for (int i = 0; i < n; i++) {
    int v, g;
    scanf("%d%d", &v, &g);
    gender[i] = g > 1;
    v--;
    if (i == v) continue;
    pair<int, int> tmp(min(i, v), max(i, v));
    if (clean.find(tmp) != clean.end()) continue;
    clean.insert(tmp);
    edge[i].push_back(v);
    edge[v].push_back(i);
  }
  used.clear();
  used.resize(n);
  f.clear();
  f.resize(n);
  fm.clear();
  fm.resize(n);
  fill(fm.begin(), fm.end(), -1);
  g.clear();
  g.resize(n);
  visit.clear();
  visit.resize(n);
  match.clear();
  match.resize(n);
  fill(match.begin(), match.end(), -1);
  pair<int, int> ans(0, 0);
  for (int i = 0; i < n; i++) {
    if (visit[i]) continue;
    pair<int, int> tmp = solve(i);
    ans.first += tmp.first;
    ans.second += tmp.second;
  }
  printf("%d %d\n", ans.first, ans.second);
  for (int i = 0; i < n; i++) {
    if (match[i] < i) continue;
    printf("%d %d\n", i + 1, match[i] + 1);
  }
  return 0;
}
