#include <iostream>
using namespace std;
int main() {#include<bits/stdc++.h>
using namespace std;
const int maxN=(1e6)+5;
deque<pair<int,int> > q,q2;
//vector<pair<int,pair<int,long long> > > sol;
pair<int,long long> sol[maxN];
bool cmp(pair<int,pair<int,int> > a,pair<int,pair<int,int> > b)
{
return a.second.second<b.second.second;
}
int g[maxN][2],n;
int frecv[maxN];
long long ans=0;
void dfs(int node,int len,long long code)
{
if(node<=n)
{
sol[node]=make_pair(len,code);
ans=ans+1LL*frecv[node]*len;
return;
}
dfs(g[node-n][0],len+1,code*2LL);
dfs(g[node-n][1],len+1,code*2LL+1LL);
}
char buff[100005];
const int dim=(1e5);
int pos=0;
void read(int &nr)
{
nr=0;
while(!isdigit(buff[pos]))
{
pos++;
if(pos==dim)
{
pos=0;
fread(buff,1,dim,stdin);
}
}
while(isdigit(buff[pos]))
{
nr=nr*10+buff[pos]-'0';
pos++;
if(pos==dim)
{
pos=0;
fread(buff,1,dim,stdin);
}
}
}
pair<int,pair<int,int> > vect[5];
int main()
{
freopen("huffman.in","r",stdin);
freopen("huffman.out","w",stdout);
fread(buff,1,dim,stdin);
read(n);
for(int i=1;i<=n;i++)
{
int x;
//scanf("%d",&x);
read(x);
frecv[i]=x;
q.push_back(make_pair(i,x));
}
int currentNode=n;
while(1)
{
//for the current Minimum
int dvect=0;
int cnt=0;
while(!q.empty() && cnt<2)
{
vect[++dvect]=make_pair(1,q.front());
q.pop_front();
cnt++;
}
cnt=0;
while(!q2.empty() && cnt<2)
{
vect[++dvect]=make_pair(2,q2.front());
q2.pop_front();
cnt++;
}
reverse(vect+1,vect+dvect+1);
for(int i=1;i<=dvect;i++)
if(vect[i].first==1) q.push_front(vect[i].second);
else q2.push_front(vect[i].second);
reverse(vect+1,vect+dvect+1);
if(dvect<2)
break;
//stable_sort(vect.begin(),vect.end(),cmp);
pair<int,pair<int,int> > pr1={0,{0,INT_MAX}};
pair<int,pair<int,int> > pr2={0,{0,INT_MAX}};
for(int i=1;i<=dvect;i++)
if(vect[i].second.second<pr1.second.second)
{
pr2=pr1;
pr1=vect[i];
}
else if(vect[i].second.second<pr2.second.second)
{
pr2=vect[i];
}
if(pr1.first==1) q.pop_front();
else q2.pop_front();
if(pr2.first==1) q.pop_front();
else q2.pop_front();
currentNode++;
g[currentNode-n][0]=pr1.second.first;
g[currentNode-n][1]=pr2.second.first;
q2.push_back(make_pair(currentNode,pr1.second.second+pr2.second.second));
}
dfs(currentNode,0,0);
//edfddfdfsdf
printf("%lld\n",ans);
for(int i=1;i<=n;i++)
{
printf("%d %lld\n",sol[i].first,sol[i].second);
}
return 0;
}
// your code goes here
return 0;
}