#include <bits/stdc++.h>   using namespace std;   template <class T1, class T2>   ostream& operator<<(ostream& os, const pair<T1, T2>& p) {     os <<  {  << p.first <<  ,   << p.second <<  } ;     return os;   }   template <class T>   ostream& operator<<(ostream& os, const vector<T>& p) {     os <<  [ ;     int i = 0;     for (typename vector<T>::const_iterator it = p.begin(); it != p.end(); ++it) {       os << (i == 0 ?    :  ,  ) << *it;       i++;     }     os <<  ] ;     return os;   }   template <class T>   ostream& operator<<(ostream& os, const set<T>& p) {     os <<  [ ;     int i = 0;     for (typename set<T>::const_iterator it = p.begin(); it != p.end(); ++it) {       os << (i == 0 ?    :  ,  ) << *it;       i++;     }     os <<  ] ;     return os;   }   template <class K, class V>   ostream& operator<<(ostream& os, const map<K, V>& p) {     os <<  [ ;     int i = 0;     for (typename map<K, V>::const_iterator it = p.begin(); it != p.end(); ++it) {       os << (i == 0 ?    :  ,  ) << *it;       i++;     }     os <<  ] ;     return os;   }   template <class T>   string toString(const T& o) {     stringstream ss;     ss << o;     string ret;     getline(ss, ret);     return ret;   }   template <class T>   vector<T> subv(const vector<T>& v, int from, int to) {     return vector<T>(v.begin() + min(max(0, from), (int)v.size()),                      v.begin() + min(max(0, to), (int)v.size()));   }   pair<int, int> operator+(const pair<int, int>& a, const pair<int, int>& b) {     return make_pair(a.first + b.first, a.second + b.second);   }   pair<int, int> operator*(const int& a, const pair<int, int>& b) {     return make_pair(a * b.first, a * b.second);   }   vector<int> sex, parent, used[2], path, bestw[2];   vector<int> was;   vector<int> points;   vector<vector<int> > adj;   vector<pair<int, int> > w[2], o[2];   int k, mark, n;   void dfs(int v, int color) {     if (was[v] == color) {       points.push_back(v);       return;     }     if (was[v]) return;     was[v] = color;     for (int i = 0; i < adj[v].size(); ++i) dfs(adj[v][i], color);   }   void go(int v) {     if (used[k][v]) return;     used[k][v] = 1;     w[k][v] = o[k][v] = make_pair(0, 0);     for (int i = 0; i < adj[v].size(); ++i) {       int to = adj[v][i];       go(to);       if (mark != to) o[k][v] = o[k][v] + max(w[k][to], o[k][to]);     }     for (int i = 0; i < adj[v].size(); ++i) {       int to = adj[v][i];       if (to == mark) continue;       pair<int, int> val = o[k][v] + (-1) * max(w[k][to], o[k][to]) + o[k][to] +                            make_pair(1, sex[v] != sex[to]);       if (w[k][v] < val) {         bestw[k][v] = to;         w[k][v] = val;       }     }   }   void make_path(int v, bool with) {     int to = -1;     if (with) {       to = bestw[k][v];       path[to] = 1;     }     for (int i = 0; i < adj[v].size(); ++i) {       int to2 = adj[v][i];       if (to2 != mark) make_path(to2, (to2 != to) && (w[k][to2] > o[k][to2]));     }   }   int main() {     cin >> n;     adj.resize(n);     sex.resize(n);     path.resize(n, 0);     parent.resize(n);     was.resize(n, 0);     for (int i = 0; i < 2; ++i) {       bestw[i].resize(n, -1);       w[i].resize(n);       o[i].resize(n);       used[i].resize(n, 0);     }     for (int i = 0; i < n; ++i) {       int f, s;       cin >> f >> s;       f--, s--;       parent[i] = f;       sex[i] = s;       adj[f].push_back(i);     }     for (int i = 0; i < n; ++i)       if (!was[i]) dfs(i, i + 1);     for (int i = 0; i < points.size(); ++i) {       int v1 = points[i];       int v2 = parent[v1];       k = 0;       mark = v1;       go(v1);       k = 1;       mark = v2;       go(v2);       int v;       if (max(o[0][v1], w[0][v1]) > max(o[1][v2], w[1][v2])) {         k = 0;         v = v1;         mark = v1;       } else {         k = 1;         v = v2;         mark = v2;       }       make_path(v, w[k][v] > o[k][v]);     }     int all = 0, diff = 0;     for (int i = 0; i < n; ++i)       if (path[i]) {         all++;         diff += (sex[i] != sex[parent[i]]);       }     cout << all <<     << diff << endl;     for (int i = 0; i < n; ++i)       if (path[i]) cout << i + 1 <<     << parent[i] + 1 << endl;     return 0;   }