#include<fstream>
using namespace std;
#define NMAX 1000005
ifstream fin("huffman.in");
ofstream fout("huffman.out");
struct nod
{
long long v;
int f[2];
} A[NMAX<<1];
int n,k,dh,B[NMAX];
long long lg,C[NMAX],H[NMAX<<1];
inline void inters(long long &a, long long &b)
{
long long aux=a;
a=b, b=aux;
}
inline int extrage_min()
{
int x,y,r=H[1];
inters(H[1],H[dh--]);
x=1;
while (2*x<=dh)
{
y=2*x;
if (y<dh && A[H[y]].v>A[H[y+1]].v)
++y;
if (A[H[x]].v>A[H[y]].v)
inters(H[x],H[y]);
else
break;
x=y;
}
return r;
}
inline void introduce(int &val)
{
int x,y;
H[++dh]=val;
for (x=dh;x>1;x>>=1)
{
y=x>>1;
if (A[H[x]].v<A[H[y]].v)
inters(H[x],H[y]);
else
break;
}
}
void actualizare(int nod, int x, long long y)
{
int i;
if (nod<=n)
B[nod]=x, C[nod]=y;
else
{
actualizare(A[nod].f[0],x+1,y<<1);
actualizare(A[nod].f[1],x+1,(y<<1)+1);
}
}
int main()
{
int i,x,y;
fin>>n;
for (i=1;i<=n;++i)
{
fin>>A[i].v;
H[i]=i;
}
dh=n;
for (k=n+1;k<2*n;++k)
{
x=extrage_min();
y=extrage_min();
A[k].f[0]=x, A[k].f[1]=y;
A[k].v=A[x].v+A[y].v;
lg+=A[k].v;
introduce(k);
}
fout<<lg<<"\n";
actualizare(2*n-1,0,0);
for (i=1;i<=n;++i)
fout<<B[i]<<" "<<C[i]<<"\n";
return 0;
}