#include <bits/stdc++.h>
using namespace std;
inline void pr(int n) { printf("%d\n", n); }
const int fx[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
const int fxx[8][2] = {{0, 1}, {0, -1}, {1, 0},  {-1, 0},
                       {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
template <typename T, typename TT>
ostream& operator<<(ostream& s, pair<T, TT> t) {
  return s << "(" << t.first << "," << t.second << ")";
}
template <typename T>
ostream& operator<<(ostream& s, vector<T> t) {
  for (int i = 0; i < ((int)((t).size())); i++) s << t[i] << " ";
  return s;
}
int score(int p, int t) {
  return (3 * p / 10 < p - (p / 250) * t ? p - (p / 250) * t : 3 * p / 10);
}
int main() {
  int(n);
  scanf("%d", &(n));
  vector<pair<int, int> > list(n, pair<int, int>());
  queue<int> leaf;
  vector<pair<int, int> > edges;
  for (int i = 0; i < n; i++) {
    int(deg), (s);
    scanf("%d %d", &(deg), &(s));
    list[i] = make_pair(deg, s);
    if (deg == 0) continue;
    if (deg == 1) leaf.push(i);
  }
  while (!leaf.empty()) {
    int l = leaf.front();
    leaf.pop();
    if (list[l].first == 0) continue;
    list[l].first = 0;
    int p = list[l].second;
    edges.push_back(make_pair(l, p));
    list[p].first--;
    list[p].second ^= l;
    if (list[p].first == 1) leaf.push(p);
  }
  cout << edges.size() << "\n";
  for (int i = 0; i < edges.size(); i++) {
    pair<int, int> k = edges[i];
    cout << k.first << " " << k.second << "\n";
  }
}
