// Slower C++ solution:
/*

Though leaves are many, the root is one;

Through all the lying days of my youth

I swayed my leaves and flowers in the sun,

Now may I wither into the truth.



- William Butler Yeats

*/

#include <iostream>

#include <algorithm>

#include <math.h>

#include <string.h>

#include <cstdio>

#include <vector>

#include <set>

#include <cassert>

#include <cstdlib>

#include <complex>

#include <cctype>

#include <cmath>

#include <ctime>

#include <deque>

#include <queue>

#include <stack>

#include <map>

#include <set>

#include <sstream>

#include <functional>

#include <iomanip>

#include <bitset>

//#include <windows.h>  //Should be deleted when using AtCoder&POJ

using namespace std;



#define ll long long

#define pii pair<int,int>

#define qi ios::sync_with_stdio(0)

/**==Info==

*Program:6

*Problem:Distance Sums

*Date:2019-7-12

*Algorithm:Orange Boy's Greedy and Sorting

*Stats:WA*/



bool debug=false;





template<typename T1,typename T2> ostream& operator<<(ostream& o,pair<T1,T2> p){

	o<<"{";

	o<<p.first<<","<<p.second;

	o<<"}";

	return o;

}



ll n;

ll d[100005];

map <ll,ll> m;

pair<ll,ll> p[100005];

ll sub[100005];

ll sz[100005];

vector <pair<ll,ll> >res;

 

 int fa[100005];

 

int getFa(int x){

	if(fa[x]==x){

		return x;

	}

	return fa[x]=getFa(fa[x]);

}

 

 

void Union(int a,int b){

	if(fa[a]==fa[b]){

		return;

	}

	fa[getFa(a)]=getFa(b);

}



ll dp[100005];



ll dis[100005];



vector<int> nei[100005];



int main()

{

	ios_base::sync_with_stdio(false);

	cin>>n;

	for(ll i=0;i<n;i++)

	{

		cin>>d[i];

		if(d[i]>n*(n-1)/2){

			cout<<-1;

			return 0;

		}

		m[d[i]]=i;

		p[i].first=d[i];

		p[i].second=i;

		sz[i]=1;

	}

	sort(p,p+n);

	reverse(p,p+n);

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

	for(ll i=0;i<n-1;i++)

	{

		ll de=p[i].first;

		ll x=p[i].second;

		sub[x]=n-sz[x]*2;

		if(sub[x]==0){

			cout<<-1;

			return 0;	

		}

		if(m.find(de-sub[x])==m.end()){

			cout<<-1;

			return 0;

		}

		ll par=m[de-sub[x]];

		sz[par]+=sz[x];

		dp[par]+=dp[x]+sz[x];

		res.push_back(make_pair(x,par));

	}

	

	for(int i=0;i<n-1;i++){

		nei[res[i].first].push_back(res[i].second);

		nei[res[i].second].push_back(res[i].first);

	}

	

	queue<int> q;

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

	q.push(p[n-1].second);

	dis[p[n-1].second]=0;

	

	while(!q.empty()){

		int last=q.front();

		q.pop();

		

		for(int to:nei[last]){

			if(dis[to]==-1){

				dis[to]=dis[last]+1;

				q.push(to);

			}

		}

	}

	

	ll sm=0;

	for(int i=0;i<n;i++){

		sm+=dis[i];

	}

	if(sm!=p[n-1].first){

		cout<<-1;

		return 0;

	}

	

	for(ll i=0;i<n-1;i++)

	{

		cout<<res[i].first+1<<" "<<res[i].second+1<<endl;

	}

	

	

	return 0;

}

// Faster C++ solution for the same problem (measured speedup: 3.5603657648006384x):
#include<bits/stdc++.h>

using namespace std;



#define int long long



#define pii pair<int,int> 



int N;

int a[100010];

map<int,int> mp;



vector<pii> e;

int sz[100010];

int dp[100010];



vector<pii> ans;



bool cmp_d(pii p,pii q)

{

	return p>q;

}



pii norm(int p,int q)

{

	return {min(p,q),max(p,q)};

}



main()

{

	cin>>N;

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

	{

		cin>>a[i];

		mp[a[i]]=i;

		e.push_back({a[i],i});

		sz[i]=1;

	}

	sort(e.begin(),e.end(),cmp_d);

	int x=e.back().first;

	for(int i=0;i<e.size();i++)

	{

		pii& cur=e[i];

		if(cur.first!=x)

		{

			if(sz[cur.second]*2>=N) goto FAIL;

			int p=cur.first-N+2*sz[cur.second];

			if(mp.find(p)==mp.end()) goto FAIL;

			int q=mp[p];

			dp[q]+=dp[cur.second]+sz[cur.second];

			sz[q]+=sz[cur.second];

			ans.push_back(norm(cur.second,q));

		}

	}

	if(dp[e.back().second]!=x) goto FAIL;

	

	sort(ans.begin(),ans.end());

	for(int i=0;i<ans.size();i++)

	{

		cout<<ans[i].first<<" "<<ans[i].second<<endl;

	}

	return 0;

	

	

	

	FAIL:;

	{

		cout<<"-1"<<endl;

		return 0;

	}

}