Problem:
Score : 900 points

Problem Statement

You are given a sequence D_1, D_2, ..., D_N of length N.
The values of D_i are all distinct.
Does a tree with N vertices that satisfies the following conditions exist?

The vertices are numbered 1,2,..., N.

The edges are numbered 1,2,..., N-1, and Edge i connects Vertex u_i and v_i.

For each vertex i, the sum of the distances from i to the other vertices is D_i, assuming that the length of each edge is 1.

If such a tree exists, construct one such tree.

Constraints

2 \leq N \leq 100000

1 \leq D_i \leq 10^{12}

D_i are all distinct.

Input

Input is given from Standard Input in the following format:

N
D_1
D_2
:
D_N

Output

If a tree with n vertices that satisfies the conditions does not exist, print -1.

If a tree with n vertices that satisfies the conditions exist, print n-1 lines.
The i-th line should contain u_i and v_i with a space in between.
If there are multiple trees that satisfy the conditions, any such tree will be accepted.

Sample Input 1

7
10
15
13
18
11
14
19

Sample Output 1

1 2
1 3
1 5
3 4
5 6
6 7

The tree shown below satisfies the conditions.

Sample Input 2

2
1
2

Sample Output 2

-1

Sample Input 3

15
57
62
47
45
42
74
90
75
54
50
66
63
77
87
51

Sample Output 3

1 10
1 11
2 8
2 15
3 5
3 9
4 5
4 10
5 15
6 12
6 14
7 13
9 12
11 13

Solution in C++14 (Clang 3.8.0) (judge verdict: Wrong Answer)

#include <algorithm>
#include <bitset>
#include <cassert>
#include <chrono>
#include <climits>
#include <cmath>
#include <complex>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <cstdint>
using namespace std;
typedef long long ll;
#define MP make_pair
#define PB push_back
#define inf 1000000007
#define mod 1000000007
#define rep(i,n) for(int i = 0; i < (int)(n); ++i)
#define int long long
class UnionFind {
private:
    int sz;
    vector<int> par, size_;
public:
    UnionFind(){}
    UnionFind(int node_size) : sz(node_size), par(sz), size_(sz, 1){
        iota(par.begin(), par.end(), 0);
    }
    int find(int x){
        if(par[x] == x) return x;
        else return par[x] = find(par[x]);
    }
    void unite(int x,int y){
        x = find(x), y = find(y);
        if(x == y) return;
        if(size_[x] < size_[y]) swap(x,y);
        par[y] = x;
        size_[x] += size_[y];
    }
    int size(int x){
        x = find(x);
        return size_[x];
    }
    bool same(int x,int y){
        return find(x) == find(y);
    }
};

signed main(){
    int n;
    cin >> n;
    UnionFind uf(n+1);
    vector<pair<int,int> > v;
    map<int,int> p;
    rep(i,n){
        int d;
        cin >> d;
        p[d] = i+1;
        v.push_back(MP(d,i+1));
    }
    sort(v.begin(),v.end(),greater<pair<int,int> >());
    map<int,int> mp;
    vector<pair<int,int> > g;
    bool ng = 1;
    rep(i,n){
        int k = v[i].first;
        int u = v[i].second;
        int c = mp[k];
        c++;
        //cerr << k << " " << u << " " << c << endl;
        if(c==n&&i==n-1){
            ng = 0;
            continue;
        }
        int nxt = k - (n-c-c);
        if(p.find(nxt)==p.end()){
            cout << -1 << endl;
            return 0;
        }
        mp[nxt]+=c;
        g.push_back(MP(u,p[nxt]));
        uf.unite(u,p[nxt]);
    }
    for(int i=1;i<=n;i++){
        if(!uf.same(i,1)){
            cout << -1 << endl;
            return 0;
        }
    }
    if(ng){
        cout << -1 << endl;
        return 0;
    }
    for(auto x:g){
        cout << x.first << " " << x.second << endl;
    }
    return 0;
}