#include <iostream>
#include <fstream>
#include <queue>
#include <vector>
using namespace std;
ifstream fin("huffman.in");
ofstream fout("huffman.out");
const long long INF = 1LL*1000*1000*1000*1000*1000*1000;
struct Node
{
long long freq = INF;
int left = -1, right = -1;
};
queue<int> q1, q2;
int getmin(vector<Node> &nodes)
{
int x1 = 0, x2 = 0;
if(!q1.empty()){
x1 = q1.front();
}
if(!q2.empty()){
x2 = q2.front();
}
if(x1 == 0 || nodes[x1].freq > nodes[x2].freq){
q2.pop();
return x2;
}
q1.pop();
return x1;
}
long long sum = 0;
void DFS(vector<Node> &nodes, vector<pair<int, long long>> &code, int level, long long currCode, int curr)
{
if(nodes[curr].left == -1){
code[curr].first = level;
code[curr].second = currCode;
sum += nodes[curr].freq * level;
return;
}
DFS(nodes, code, level+1, 2*currCode, nodes[curr].left);
DFS(nodes, code, level+1, 2*currCode+1, nodes[curr].right);
}
int main()
{
int N;
fin >> N;
vector<Node> nodes(2*N+1);
for(int i = 1; i <= N; i++){
fin >> nodes[i].freq;
q1.push(i);
}
int newNode = N+1;
while(q1.size() + q2.size() > 1){
int index1, index2;
index1 = getmin(nodes);
index2 = getmin(nodes);
nodes[newNode].freq = nodes[index1].freq + nodes[index2].freq;
nodes[newNode].left = index1;
nodes[newNode].right = index2;
q2.push(newNode);
newNode++;
}
vector<pair<int, long long>> code(N+1, {1, 0});
DFS(nodes, code, 0, 0, newNode-1);
fout << sum << endl;
for(int i = 1; i <= N; i++){
fout << code[i].first << " " << code[i].second << endl;
}
return 0;
}