#include <bits/stdc++.h>   using namespace std;   pair<long long int, long long int> operator+(       pair<long long int, long long int> p0,       pair<long long int, long long int> p1) {     return pair<long long int, long long int>(p0.first + p1.first,                                               p0.second + p1.second);   }   pair<long long int, long long int> operator-(       pair<long long int, long long int> p0,       pair<long long int, long long int> p1) {     return pair<long long int, long long int>(p0.first - p1.first,                                               p0.second - p1.second);   }   vector<long long int> E[100005];   vector<pair<long long int, long long int> > ans;   long long int type[100005];   long long int used[100005];   pair<long long int, long long int> dp[2][100005];   long long int bef[100005];   long long int parent[100005];   pair<long long int, long long int> recur(long long int pos) {     used[pos] = true;     dp[0][pos] = make_pair(0, 0);     for (long long int i = 0;          i < ((long long int)(((long long int)(E[pos]).size()))); ++i)       dp[0][pos] = dp[0][pos] + recur(E[pos][i]);     dp[1][pos] = dp[0][pos];     bef[pos] = -1;     for (long long int i = 0;          i < ((long long int)(((long long int)(E[pos]).size()))); ++i) {       pair<long long int, long long int> tmp =           dp[0][pos] - dp[1][E[pos][i]] + dp[0][E[pos][i]] + make_pair(1, 0);       if (type[pos] != type[E[pos][i]]) tmp.second++;       if (dp[1][pos] < tmp) {         bef[pos] = E[pos][i];         dp[1][pos] = tmp;       }     }     return dp[1][pos];   }   void dump(long long int pos, bool ok,             vector<pair<long long int, long long int> > &root) {     for (long long int i = 0;          i < ((long long int)(((long long int)(E[pos]).size()))); ++i) {       if (ok && bef[pos] == E[pos][i]) root.push_back(make_pair(pos, E[pos][i]));       dump(E[pos][i], !(ok && bef[pos] == E[pos][i]), root);     }   }   pair<long long int, long long int> cal(long long int pos) {     for (; !used[pos]; pos = parent[pos]) used[pos] = true;     vector<pair<long long int, long long int> > root;     pair<long long int, long long int> res = make_pair(0, 0);     for (long long int i = 0; i < ((long long int)(2)); ++i) {       long long int par = parent[pos];       E[par].erase(find(E[par].begin(), E[par].end(), pos));       pair<long long int, long long int> tmp = recur(pos);       if (res < tmp) {         res = tmp;         root.clear();         dump(pos, true, root);       }       E[par].push_back(pos);       pos = par;     }     for (long long int i = 0;          i < ((long long int)(((long long int)(root).size()))); ++i)       ans.push_back(root[i]);     return res;   }   int main() {     pair<long long int, long long int> res =         pair<long long int, long long int>(0, 0);     long long int n, a;     cin >> n;     for (long long int i = 0; i < ((long long int)(n)); ++i) parent[i] = i;     for (long long int i = 0; i < ((long long int)(n)); ++i) {       cin >> parent[i] >> type[i];       parent[i]--;       E[parent[i]].push_back(i);     }     for (long long int i = 0; i < ((long long int)(n)); ++i)       if (!used[i]) res = res + cal(i);     cout << res.first <<     << res.second << endl;     for (long long int i = 0;          i < ((long long int)(((long long int)(ans).size()))); ++i)       cout << ans[i].first + 1 <<     << ans[i].second + 1 << endl;   }