#include <iostream>
#include <vector>
#include <queue>
#include <climits>
#include <fstream>
using namespace std;
const int MAX = 205;
int capacity[MAX][MAX];
int bfs(int s, int t, vector<int>& parent, vector<vector<int>>& adj) {
fill(parent.begin(), parent.end(), -1);
parent[s] = -2;
queue<pair<int, int>> q;
q.push({s, INT_MAX});
while (!q.empty()) {
int cur = q.front().first;
int flow = q.front().second;
q.pop();
for (int next : adj[cur]) {
if (parent[next] == -1 && capacity[cur][next]) {
parent[next] = cur;
int new_flow = min(flow, capacity[cur][next]);
if (next == t)
return new_flow;
q.push({next, new_flow});
}
}
}
return 0;
}
int maxflow(int s, int t, vector<vector<int>>& adj) {
int flow = 0;
vector<int> parent(MAX);
int new_flow;
while (new_flow = bfs(s, t, parent, adj)) {
flow += new_flow;
int cur = t;
while (cur != s) {
int prev = parent[cur];
capacity[prev][cur] -= new_flow;
capacity[cur][prev] += new_flow;
cur = prev;
}
}
return flow;
}
int main() {
ifstream fin("harta.in");
ofstream fout("harta.out");
int n;
fin >> n;
vector<vector<int>> adj(MAX);
int s = 0, t = 2 * n + 1;
for (int i = 1; i <= n; ++i) {
int out, in;
fin >> out >> in;
capacity[s][i] = out;
capacity[i + n][t] = in;
adj[s].push_back(i);
adj[i + n].push_back(t);
for (int j = 1; j <= n; ++j) {
if (i != j) {
capacity[i][j + n] = 1;
adj[i].push_back(j + n);
adj[j + n].push_back(i);
}
}
}
int total_flow = maxflow(s, t, adj);
fout << total_flow << endl;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
if (i != j && capacity[j + n][i] > 0) {
fout << i << " " << j << endl;
}
}
}
fin.close();
fout.close();
return 0;
}