#include <bits/stdc++.h>
using namespace std;
const int NMAX = 1e6;
const int VMAX = 2 * NMAX;
pair <int, int> edges[VMAX + 1];
long long cod[VMAX + 1];
int len[VMAX + 1];
int v[VMAX + 1];
void dfs( int node ) {
if ( edges[node] == make_pair(0, 0) ) return;
int l = edges[node].first, r = edges[node].second;
len[l] = len[r] = len[node] + 1;
cod[l] = cod[node] * 2;
cod[r] = cod[node] * 2 + 1;
dfs( l );
dfs( r );
}
queue <pair<long long, int>> pq1;
queue <pair<long long, int>> pq2;
pair <long long, int> getMin() {
if ( !pq2.empty() && ( pq1.empty() || pq2.front() < pq1.front() ) ) {
auto p = pq2.front();
pq2.pop();
return p;
}
auto p = pq1.front();
pq1.pop();
return p;
}
int main() {
ifstream fin( "huffman.in" );
ofstream fout( "huffman.out" );
int n;
fin >> n;
for ( int i = 1; i <= n; i ++ ) {
fin >> v[i];
pq1.push( {v[i], i} );
}
int m = n;
while ( pq1.size() + pq2.size() > 1 ) {
auto p1 = getMin(), p2 = getMin();
edges[++m] = {p1.second, p2.second};
pq2.push( {p1.first + p2.first, m} );
if ( pq1.empty() ) {
swap( pq1, pq2 );
}
}
dfs( m );
long long totalLen = 0;
for ( int i = 1; i <= n; i ++ ) {
totalLen += (long long)v[i] * len[i];
}
fout << totalLen << '\n';
for ( int i = 1; i <= n; i ++ ) {
fout << len[i] << ' ' << cod[i] << '\n';
}
return 0;
}