#include <cstdio>
#include <cstring>
#define INF 1000000000
#define MAXN 100
bool viz[2*MAXN+2];
int from[2*MAXN+2], s, d, n, q[2*MAXN+2], c[2*MAXN+2][2*MAXN+2], f[2*MAXN+2][2*MAXN+2];
inline bool bfs(){
int st, dr, x;
st=0;
q[0]=s;
dr=1;
memset(viz, 0, sizeof viz);
memset(from, 0, sizeof from);
viz[s]=1;
while((st<dr)&&(viz[d]==0)){
for(x=1; x<=2*n+1; x++){
if((viz[x]==0)&&(c[q[st]][x]>f[q[st]][x])){
viz[x]=1;
from[x]=q[st];
q[dr++]=x;
}
}
st++;
}
return viz[d];
}
int main(){
int i, j, min, x, ans;
FILE *fin, *fout;
fin=fopen("harta.in", "r");
fout=fopen("harta.out", "w");
fscanf(fin, "%d", &n);
s=0;
d=2*n+1;
for(i=1; i<=n; i++){
for(j=1; j<=n; j++){
if(i!=j){
c[i][j+n]=1;
}
}
fscanf(fin, "%d%d", &c[s][i], &c[i+n][d]);
}
ans=0;
while(bfs()){
for(x=0; x<=2*n; x++){
if((viz[x])&&(c[x][d]>f[x][d])){
from[d]=x;
min=INF;
i=d;
while(i!=s){
if(min>c[from[i]][i]-f[from[i]][i]){
min=c[from[i]][i]-f[from[i]][i];
}
i=from[i];
}
ans+=min;
i=d;
while(i!=s){
f[from[i]][i]+=min;
f[i][from[i]]-=min;
i=from[i];
}
}
}
}
fprintf(fout, "%d\n", ans);
for(i=1; i<=n; i++){
for(j=n+1; j<=2*n; j++){
if(f[i][j]==1){
fprintf(fout, "%d %d\n", i, j-n);
}
}
}
fclose(fin);
fclose(fout);
return 0;
}