#include <cstdio>
#include <cmath>
#include <vector>
#include <algorithm>
#include <cassert>
#include <cstring>
#include <climits>
using namespace std;
typedef long long LL;
#ifdef INFOARENA
#define ProblemName "huffman"
#endif
#define MCONCAT(A, B) A B
#ifdef ProblemName
#define InFile MCONCAT(ProblemName, ".in")
#define OuFile MCONCAT(ProblemName, ".out")
#else
#define InFile "fis.in"
#define OuFile "fis.out"
#endif
#define MAXBUF 20000000
char physicalInput[MAXBUF], *head = physicalInput;
LL nextLL() {
LL rez = 0;
while ((*head) < '0' || (*head) > '9')
++head;
do {
rez = rez * 10 + (*head) - '0';
++head;
} while ((*head) >= '0' && (*head) <= '9');
return rez;
}
#define MAXN 1000010
struct nod {
LL cost;
nod *parent;
int bit;
int depth;
LL repr;
} v[MAXN], others[MAXN << 1];
int N;
void setRepr(nod *p) {
if (p->parent == NULL) {
p->depth = 0;
p->repr = 0;
return;
}
if (p->parent->depth < 0)
setRepr(p->parent);
p->depth = p->parent->depth + 1;
p->repr = (p->parent->repr << 1) | p->bit;
}
int main() {
assert(freopen(InFile, "r", stdin));
assert(freopen(OuFile, "w", stdout));
int aux = fread(physicalInput, 1, MAXBUF, stdin);
physicalInput[aux] = 0;
N = (int)nextLL();
for (int i = 0; i < N; ++i) {
v[i].cost = nextLL();
v[i].depth = -1;
}
int i0 = 0, i1 = 0, qe = 0;
while (i0 < N) {
nod *p0;
if (i1 < qe && others[i1].cost < v[i0].cost) {
p0 = &others[i1];
i1++;
}
else {
p0 = &v[i0];
i0++;
}
nod *p1;
if (i0 >= N || i1 < qe && others[i1].cost < v[i0].cost) {
p1 = &others[i1];
i1++;
}
else {
p1 = &v[i0];
i0++;
}
others[qe].cost = p0->cost + p1->cost;
others[qe].depth = -1;
p0->parent = &others[qe]; p0->bit = 0;
p1->parent = &others[qe]; p1->bit = 1;
++qe;
}
while (i1 < qe - 1) {
nod *p0 = &others[i1];
nod *p1 = &others[i1 + 1];
others[qe].cost = p0->cost + p1->cost;
others[qe].depth = -1;
p0->parent = &others[qe]; p0->bit = 0;
p1->parent = &others[qe]; p1->bit = 1;
++qe;
i1 += 2;
}
LL ans = 0;
for (int i = 0; i < N; ++i) {
setRepr(&v[i]);
ans += v[i].cost * v[i].depth;
}
printf("%lld\n", ans);
for (int i = 0; i < N; ++i)
printf("%d %lld\n", v[i].depth, v[i].repr);
return 0;
}