#include <bits/stdc++.h>
using namespace std;
int NODES, EDGES;
int fx[] = {1, -1, 0, 0, 1, 1, -1, -1};
int fy[] = {0, 0, 1, -1, 1, -1, 1, -1};
int row, col;
vector<int> visit;
struct two {
  int a, b;
  bool operator<(const two& t) const {
    if (b == t.b) return a < t.a;
    return (a < t.a) && (b < t.b);
  }
};
int check(int tx, int ty) {
  if (tx >= 0 && tx < row && ty >= 0 && ty < col) return 1;
  return 0;
}
struct graph {
  int x;
  int y;
};
struct prior_to {
  prior_to() {
    main_element = "";
    no_of_prior_element_left = 0;
  }
  vector<string> parent;
  string main_element;
  int no_of_prior_element_left;
};
string rotate(vector<int> X, int index) {
  string str = "";
  char ch;
  int k, y, x, m, n = X.size();
  for (k = index, y = 0; y < n; k++, y++) {
    m = k % n;
    x = X[m];
    ch = x + '0';
    str = str + ch;
  }
  return str;
}
graph g[65540];
int sum_XOR[65540], no_dependency, index_of_dependent, degree[65540];
int main() {
  int n, m, x, y, i, j, k, sum, flag;
  char ch;
  string str;
  set<int> X;
  vector<int> Y;
  int test_case = 0, min = 999999999, first, last;
  int a, b, c, d;
  long long x1, y1, x2, y2;
  while (scanf("%d", &n) == 1) {
    vector<int> result;
    memset(sum_XOR, 0, sizeof(sum_XOR));
    vector<int> zero_degree;
    i = 0;
    while (i < n) {
      scanf("%d %d", &x, &y);
      sum_XOR[i] = y;
      degree[i] = x;
      if (degree[i] == 1) zero_degree.push_back(i);
      i++;
    }
    sum = 0;
    k = 0;
    for (i = 0; i < zero_degree.size(); i++) {
      x = zero_degree[i];
      if (degree[x] > 0) {
        y = sum_XOR[x];
        sum_XOR[y] = sum_XOR[y] ^ x;
        degree[x]--;
        degree[y]--;
        if (degree[y] == 1) zero_degree.push_back(y);
        g[k].x = x;
        g[k].y = y;
        k++;
      }
    }
    cout << k << "\n";
    for (i = 0; i < k; i++) cout << g[i].x << " " << g[i].y << "\n";
  }
  return 0;
}
