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

using namespace std;

const int maxn=1e5+10;

struct edge{int v,nxt;}e[maxn<<1];

int head[maxn],ecnt=0;

void add(int u,int v)

{

	e[++ecnt]=(edge){v,head[u]},head[u]=ecnt;

	e[++ecnt]=(edge){u,head[v]},head[v]=ecnt;

}

struct data

{

	long long D;

	int id;

	bool operator < (const data &b){return D<b.D;}

}c[maxn];

int fa[maxn],siz[maxn],n,rt;

int find(int lim,long long x)

{

	int l=1,r=lim,ans=0;

	while(l<=r)

	{

		int mid=l+r>>1;

		if(c[mid].D>=x)r=mid-1,ans=mid;

		else l=mid+1;

	}

//	cout<<c[ans].D<<endl;

//	if(c[ans].D!=x)printf("fuckyou\n");

	return ans;

}

int dep[maxn];

long long tot=0;

void dfs(int u,int pre)

{

	dep[u]=dep[pre]+1;

	tot+=dep[u]-1;

	for(int i=head[u];~i;i=e[i].nxt)

	{

		int v=e[i].v;

		if(v==pre)continue;

		dfs(v,u);

	}

}

int main()

{

	memset(head,-1,sizeof(head));

	scanf("%d",&n);

	for(int i=1;i<=n;i++)scanf("%lld",&c[i].D),c[i].id=i;

	sort(c+1,c+1+n);

	for(int i=n;i>=2;i--)

	{

		siz[i]++;

		int p=find(i-1,c[i].D-(n-2*1LL*siz[i]));

		if(c[i].D-(n-2*1LL*siz[i])!=c[p].D)

		{

			printf("-1\n");

			return 0;

		}

		siz[p]+=siz[i];

		fa[c[i].id]=c[p].id;

	}

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

	if(fa[i])add(fa[i],i);

	else rt=i;

	dfs(rt,0);

	if(tot!=c[1].D)

	{

		printf("-1\n");

		return 0;

	}

	for(int i=1;i<=n;i++)if(fa[i])printf("%d %d\n",fa[i],i);

}

// Faster C++ solution for the same problem (measured speedup: 1.404407219140392x):
#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]);

}