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 Rust (1.15.1) (judge verdict: Accepted)

use std::collections::BTreeMap;
use std::io::*;
use std::str::FromStr;

#[allow(dead_code)]
fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

fn dfs(from: usize, depth: i64, childs: &Vec<Vec<usize>>) -> i64 {
    let mut ret = depth;
    for &to in childs[from].iter() {
        ret += dfs(to, depth + 1, childs);
    }
    return ret;
}

fn main() {
    let n = read::<usize>();
    let mut items = BTreeMap::<i64, usize>::new();
    for i in 0..n {
        let v = read::<i64>();
        items.insert(v, i);
    }
    let mut childs = vec![vec![]; n];
    let mut parents = vec![n; n];
    let mut cnts = vec![1; n];
    for (&v, &index) in items.iter().rev() {
        let tv = v - (n as i64 - 2 * cnts[index]);
        if cnts[index] == n as i64 || tv <= 0 || tv == v {
            break;
        }
        if let Some(&nindex) = items.get(&tv) {
            parents[index] = nindex;
            childs[nindex].push(index);
            cnts[nindex] += cnts[index];
        } else {
            println!("-1");
            return;
        }
    }
    let root = *items.iter().next().unwrap().1;
    let root_weight = *items.iter().next().unwrap().0;
    let weight = dfs(root, 0, &childs);
    if weight != root_weight {
        println!("-1");
        return;
    }
    for i in 0..n {
        if parents[i] == n {
            continue;
        }
        println!("{} {}", i + 1, parents[i] + 1);
    }
}