#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

void solved() {
    int n; // 节点数量
    cin >> n; // 读取节点数量
    vector<int> d(n + 1); // 存储每个节点的度数,数组大小为 n+1,方便从1开始索引

    int sum = 0; // 用于存储所有节点度数的总和
    for (int i = 1; i <= n; i++) { // 读取每个节点的度数
        cin >> d[i]; // 输入第i个节点的度数
        sum += d[i]; // 累加度数总和
    }

    if (sum & 1) { // 特判:如果度数总和是奇数,无法构造二分图
        cout << -1; // 输出-1表示无解
        return; // 退出函数
    }

    // 动态规划部分,使用01背包思想
    // 定义状态f[i][j]:前i个节点中,选择一些节点,使得它们的度数和恰好为j的最多个数
    // ff数组用来跟踪解,ff[i][j]:当前的f[i][j]是否选了第i个数(0表示没选,1表示选了)
    vector<vector<int>> f(n + 1, vector<int>(sum / 2 + 1, -1e9)); // 初始化f数组,初始值为一个很大的负数
    vector<vector<int>> ff(n + 1, vector<int>(sum / 2 + 1, 0)); // 初始化ff数组,初始值为0
    for (int i = 0; i <= n; i++) f[i][0] = 0; // 当度数和为0时,选择数量为0

    for (int i = 1; i <= n; i++) { // 遍历每个节点
        for (int j = 1; j <= sum / 2; j++) { // 遍历每个可能的度数和
            if (j >= d[i] && f[i - 1][j] <= f[i - 1][j - d[i]] + 1) { // 如果当前节点可以加入集合,并且选择它更优
                f[i][j] = f[i - 1][j - d[i]] + 1; // 更新f数组,选择当前节点
                ff[i][j] = 1; // 标记选择状态为1,表示选择了当前节点
            } else {
                f[i][j] = f[i - 1][j]; // 不选择当前节点,继承上一个状态
            }
        }
    }

    int cnt = 0; // 用于存储边的数量
    vector<int> l, r; // 用于存储两个集合的节点
    if (f[n][sum / 2] <= 0) { // 如果无法找到一种组合使得度数和为sum/2
        cout << -1; // 输出-1表示无解
        return; // 退出函数
    } else { // 如果有解
        int now = sum / 2; // 当前目标度数和
        for (int i = n; i >= 1; i--) { // 跟踪解
            if (ff[i][now]) { // 如果选择了当前节点
                l.push_back(i); // 将当前节点加入集合l
                now -= d[i]; // 更新当前目标度数和
                cnt += d[i]; // 累加边的数量
            } else {
                r.push_back(i); // 否则将当前节点加入集合r
            }
        }
    }

    cout << cnt << '\n'; // 输出边的数量
    for (int lx : l) { // 遍历集合l中的每个节点
        for (int rx : r) { // 遍历集合r中的每个节点
            int z = min(d[lx], d[rx]); // 计算两个节点之间可以连接的边数
            d[lx] -= z; // 更新集合l中节点的剩余度数
            d[rx] -= z; // 更新集合r中节点的剩余度数
            while (z--) cout << lx << ' ' << rx << '\n'; // 输出每条边
        }
    }
}

int main() {
    solved(); // 调用solved函数
    return 0;
}