// Slower C++ solution:
#include <bits/stdc++.h>



using namespace std;



#define loop(i, n) for(int i = 0;i < int(n);i++)

#define rloop(i, n) for(int i = int(n);i >= 0;i--)

#define range(i, a, b) for(int i = int(a);i <= int(b);i++)

#define SZ(c) int(c.size())

#define ALL(c) c.begin(), c.end()

#define RALL(c) c.rbegin(), c.rend()

#define PI acos(-1)

#define pb push_back

#define mp make_pair

#define fr first

#define sc second

#define sfi1(v) scanf("%d",&v)

#define sfi2(v1, v2) scanf("%d %d",&v1,&v2)

#define sfi3(v1, v2, v3) scanf("%d %d %d",&v1,&v2,&v3)

#define sfll1(v) scanf("%I64d",&v);

#define sfll2(v1, v2) scanf("%I64d %I64d",&v1,&v2)

#define sfll3(v1, v2, v3) scanf("%I64d %I64d %I64d",&v1,&v2,&v3)

#define endl '\n'



typedef vector<int> vi;

typedef vector<pair<int, int> > vii;

typedef long long ll;

typedef pair<int, int> pii;



const int N = 1e5 + 5;

vi adj[N];

int w[N];

set<pair<ll, int> > s;

vii ans;

ll D[N];

int n;



ll sum;



void dfs(int u, int par, int lvl) {

    sum += lvl;

    for (int nxt : adj[u]) {

        if (nxt == par)continue;

        dfs(nxt, u, lvl + 1);

    }

}





int main() {



#ifndef ONLINE_JUDGE

    //freopen("in.in", "r", stdin);

    //freopen("out.in", "w", stdout);

#endif

    ios_base::sync_with_stdio(0);

    cin.tie(0);

    cout.tie(0);



    cin >> n;

    range(i, 1, n) {

        w[i] = 1;

        cin >> D[i];

        //D[i] += 5;

        s.insert({D[i], i});

    }



    while (SZ(s) > 1) {

        auto it = prev(s.end());

        ll have = it->fr;

        int idx = it->sc;

        ll need = have - (n - 2 * w[idx]);

        auto c = s.lower_bound({need, -1});

        if (c == s.end() || it == c || c->fr != need) {

            cout << -1 << endl;

            return 0;

        }

        w[c->sc] += w[idx];

        ans.push_back({idx, c->sc});

        s.erase(it);

    }



    for (auto edge : ans) {

        adj[edge.fr].push_back(edge.sc);

        adj[edge.sc].push_back(edge.fr);

    }



    dfs(s.begin()->sc, -1, 0);

    if (sum != s.begin()->fr) {

        cout << -1 << endl;

        return 0;

    }



    for (auto edge: ans)cout << edge.fr << " " << edge.sc << endl;



    return 0;



}

// Faster C++ solution for the same problem (measured speedup: 3.6005273211149484x):
#include <map>

#include <cstdio>

#include <cstring>

#include <iostream>

#include <algorithm>

using namespace std;

#define ll long long

#define N 100005

#define M 200005

map<ll, int>p;

map<ll, int>::iterator it;

int fat[N], siz[N], a[N], b[N], fir[N], nex[M], tar[M];

int n, cnt;

void Add(int a, int b)

{

	++cnt;

	tar[cnt] = b;

	nex[cnt] = fir[a];

	fir[a] = cnt;

}

ll wd[N], d[N];

void Dfs(int x, int dis)

{

    siz[x] = 1;

    d[1] += dis;

	for (int i = fir[x]; i; i = nex[i])

    {

		if (tar[i] != fat[x])

		{

			fat[tar[i]] = x;

			Dfs(tar[i], dis + 1);

			siz[x] += siz[tar[i]];

        }

    }

}

void Dfs(int x)

{

	for (int i = fir[x]; i; i = nex[i])

	{

		if (tar[i] != fat[x])

        {

            d[tar[i]] = d[x] + n - siz[tar[i]] * 2;

            Dfs(tar[i]);

        }

    }

}

int Getbel(int x)

{

	if (fat[x] == x)

		return x;

	return fat[x] = Getbel(fat[x]);

}

int main()

{

	scanf("%d",&n);

	for (int i = 1; i <= n; i++)

	{

		scanf("%lld", &wd[i]);

		p[wd[i]] = i;

	}

	for (int i = 1; i <= n; i++)

	{

		fat[i] = i;

		siz[i] = 1;

	}

	it = p.end();

	for (it--; it != p.begin(); it--)

	{

		if (n - siz[it -> second] * 2 == 0 || !p.count(it -> first - (n - siz[it -> second] * 2)))

		{

			puts("-1");

			return 0;

		}

		cnt++;

		a[cnt] = it -> second;

		b[cnt] = p[it -> first - (n - siz[it -> second] * 2)];

		siz[fat[a[cnt]] = Getbel(b[cnt])] += siz[a[cnt]];

	}

	cnt = 0;

	for (int i = 1; i < n; i++)

	{

		Add(a[i], b[i]);

		Add(b[i], a[i]);

	}

	fat[1] = 0;

	Dfs(1, 0);

	Dfs(1);

	for (int i = 1; i <= n; i++)

	{

		if (wd[i] != d[i])

		{

			puts("-1");

		    return 0;

		}

	}

	for (int i = 1; i < n; i++)

		printf("%d %d\n", a[i], b[i]);

}