#include<stdio.h>
#include<list>
#define maxN 1000005
using namespace std;
FILE*f=fopen("huffman.in","r");
FILE*g=fopen("huffman.out","w");
int n,i,j,fr,pc = 1,uc,pq = 1,uq;
long long value[maxN],lg[maxN],Lg;
struct nod{
nod(nod *lson = NULL,nod *rson = NULL,long long fr = 0, int ind = 0):lson(lson),rson(rson),fr(fr),ind(ind){}
nod *lson,*rson;
long long fr;
int ind;
};
nod *M[2]; list<nod*>C,Q;
inline void citire () {
fscanf(f,"%d",&n); uc = n;
for ( i = 1 ; i <= n ; ++i ){
fscanf(f,"%d",&fr);
C.push_back(new nod(NULL,NULL,fr,i));
}
}
void DFS ( nod *p , int niv , long long val ){
if ( p->ind ){
value[p->ind] = val; lg[p->ind] = niv;
Lg += (1LL*niv*(p->fr));
return ;
}
if ( p->lson != NULL )
DFS(p->lson,niv+1,val+val);
if ( p->rson != NULL )
DFS(p->rson,niv+1,val+val+1);
}
inline void solve () {
for ( i = 1 ; i < n ; ++i ){
for ( j = 0 ; j < 2 ; ++j ){
if ( C.size() && (!Q.size() || C.front()->fr <= Q.front()->fr) ){
M[j] = C.front(); C.pop_front();
}
else{
M[j] = Q.front(); Q.pop_front();
}
}
Q.push_back( new nod(M[0],M[1],M[0]->fr+M[1]->fr,0) );
}
DFS( Q.front() , 0 , 0 );
fprintf(g,"%lld\n",Lg);
for ( i = 1 ; i <= n ; ++i ){
fprintf(g,"%d ",lg[i]);
fprintf(g,"%lld\n",value[i]);
}
}
int main () {
citire();
solve();
fclose(f);
fclose(g);
return 0;
}