#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5;
const int MAXR = 1;
const int MAXC = 1;
const int INF = (int)1e9;
priority_queue<int, vector<int>, greater<int>> q1;
priority_queue<int, vector<int>, less<int>> q2;
int arr[MAXN];
vector<pair<int, int>> v(MAXN);
vector<vector<int>> adjl(MAXN);
queue<int> q;
set<pair<int, int>> s;
int n;
int x4[] = {-1, 0, 1, 0};
int y4[] = {0, 1, 0, -1};
void createGraph() {
  while (!q.empty()) {
    int vn = q.front();
    q.pop();
    pair<int, int> p = v[vn];
    int deg = p.first;
    int xs = p.second;
    if (deg == 0) continue;
    if (adjl[vn].size() == deg) continue;
    int cxs = 0;
    for (int j = 0; j < adjl[vn].size(); ++j) {
      cxs ^= adjl[vn][j];
    }
    int ns = xs ^ cxs;
    ;
    adjl[vn].push_back(ns);
    ;
    adjl[ns].push_back(vn);
    if (v[ns].first - adjl[ns].size() == 1) {
      q.push(ns);
    }
  };
}
void createEdgeSet() {
  for (int i = 0; i < adjl.size(); ++i) {
    for (int j = 0; j < adjl[i].size(); ++j) {
      int src = i;
      int dest = adjl[i][j];
      pair<int, int> p1 = make_pair(src, dest);
      pair<int, int> p2 = make_pair(dest, src);
      if (s.find(p1) == s.end() && s.find(p2) == s.end()) {
        s.insert(p1);
      }
    }
  };
}
int main(void) {
  ios::sync_with_stdio(false);
  cin >> n;
  v.resize(n);
  adjl.resize(n);
  int d, sv;
  for (int i = 0; i < n; ++i) {
    cin >> d >> sv;
    v[i] = make_pair(d, sv);
    if (d == 1) {
      q.push(i);
    }
  };
  createGraph();
  createEdgeSet();
  cout << s.size() << endl;
  for (set<pair<int, int>>::iterator it = s.begin(); it != s.end(); it++) {
    pair<int, int> p = *it;
    cout << p.first << " " << p.second << endl;
  }
  return 0;
}
