#include <bits/stdc++.h>
int setBit(int N, int pos) { return N = N | (1 << pos); }
int resetBit(int N, int pos) { return N = N & ~(1 << pos); }
bool checkBit(int N, int pos) { return (bool)(N & (1 << pos)); }
using namespace std;
const int MAXN = 65536;
int n, deg[MAXN + 5], xr[MAXN + 5];
bool visit[MAXN + 5];
vector<int> graph[MAXN + 5];
set<pair<int, int> > sol;
void solve() {
  queue<int> q;
  int i, siz, u, v;
  for (i = 0; i < n; i++) {
    if (deg[i] == 1) q.push(i);
  }
  while (!q.empty()) {
    u = q.front();
    q.pop();
    if (visit[u]) continue;
    visit[u] = true;
    siz = (int)graph[u].size();
    if (siz > 0) {
      int x = 0;
      for (i = 0; i < siz; i++) {
        x ^= graph[u][i];
      }
      v = x ^ xr[u];
    } else
      v = xr[u];
    if (u == v) continue;
    graph[v].push_back(u);
    sol.insert(pair<int, int>(min(u, v), max(u, v)));
    deg[u]--;
    deg[v]--;
    if (deg[v] == 1)
      q.push(v);
    else if (deg[v] <= 0)
      visit[v] = true;
  }
  for (auto i : sol) {
    printf("%d %d\n", i.first, i.second);
  }
}
int main() {
  int m = 0, i;
  scanf("%d", &n);
  for (i = 0; i < n; i++) {
    scanf("%d %d", &deg[i], &xr[i]);
    m += deg[i];
  }
  printf("%d\n", m / 2);
  solve();
  return 0;
}
