stablegradients/pie-gem5-pairs huggingface dataset:
// Slower C++ solution:
// Peace Of SHIT

#include<bits/stdc++.h>

#define int long long

using namespace std;

typedef pair<int, int> pii;

const int maxn = 1e5 + 5;

int n, si[maxn];

int sum = 0;

vector<int> e[maxn];

pii d[maxn];



void impossible() {

	cout << -1;

	exit(0);

}



void dfs(int u, int x) {

	sum += x;

	for(int i = 0; i < e[u].size(); i++) {

		dfs(e[u][i], x + 1);

	}

}



int32_t main() {

	cin >> n;

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

		int a;

		cin >> a;

		d[i] = {a, i};

	}

	sort(d, d + n);

	reverse(d, d + n);

	

	vector <pii> k (d, d + n);

	

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

		int leaf = d[q].second;

		int parD = d[q].first - (n - (2 * (si[leaf] + 1)));

		auto it = lower_bound(k.rbegin(), k.rend(), pii(parD, 0));

//		cout << "PAR : " <<it->first << " : " << parD << '\n';

		if(it -> first != parD) {

//			cerr << "AVALI\n";

			impossible();

		}

		int par = it -> second;

		si[par] += si[leaf] + 1;

		if((si[leaf] + 1) * 2 > n) {

//			cout << "DOVOMI\n";

			impossible();

		}

		//SEVOMI HAM MISHE D[I] ROOT OK E ?

		e[par].push_back(leaf);

	}

	int D = d[n - 1].second;

	dfs(D, 0);

	if(sum != d[n - 1].first)

		impossible();

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

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

			cout << i + 1 << " " << e[i][j] + 1 <<'\n';

	}

	return 0;

}

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

using namespace std;

#define ll long long

#define re register

#define gc getchar

#define pc putchar

#define cs const



inline

ll getint(){

	re ll num;

	re char c;

	while(!isdigit(c=gc()));num=c^48;

	while(isdigit(c=gc()))num=(num<<1)+(num<<3)+(c^48);

	return num;

}



inline

void outint(int a){

	static char ch[13];

	if(a==0)pc('0');

	while(a)ch[++ch[0]]=a-a/10*10,a/=10;

	while(ch[0])pc(ch[ch[0]--]^48);

}



cs int N=100005;



int last[N],nxt[N],to[N],ecnt;

inline

void addedge(int u,int v){

	nxt[++ecnt]=last[u],last[u]=ecnt,to[ecnt]=v;

}



map<ll,int> id;

int n;

ll d[N];

int siz[N];



int dist[N];

inline

void dfs(int u){

	for(int re e=last[u],v=to[e];e;v=to[e=nxt[e]]){

		dist[v]=dist[u]+1;

		dfs(v);

	}

}



vector<pair<int,int> > edge;



signed main(){

	n=getint();

	for(int re i=1;i<=n;++i)d[i]=getint(),id[d[i]]=i;

	

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

	for(int re i=1;i<=n;++i)siz[i]=1;

	

	for(int re i=n;i>1;--i){

		int u=id[d[i]];

		int tmp=n-2*siz[u];

		if(tmp<=0)return puts("-1"),0; 

		ll t=d[i]-tmp;

		if(id.count(t)==0)return puts("-1"),0;

		int pos=id[t];

		addedge(pos,u);

		siz[pos]+=siz[u];

		edge.push_back(make_pair(pos,u));

	}

	ll sum=0;

	dfs(id[d[1]]);

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

		sum+=dist[i];

	}

	if(sum!=d[1])return puts("-1"),0;

	for(int re i=0;i<edge.size();++i)outint(edge[i].first),pc(' '),outint(edge[i].second),pc('\n');

	return 0;

}
// Slower C++ solution:
// Peace Of SHIT

#include<bits/stdc++.h>

#define int long long

using namespace std;

typedef pair<int, int> pii;

const int maxn = 1e5 + 5;

int n, si[maxn];

int sum = 0;

vector<int> e[maxn];

pii d[maxn];



void impossible() {

	cout << -1;

	exit(0);

}



void dfs(int u, int x) {

	sum += x;

	for(int i = 0; i < e[u].size(); i++) {

		dfs(e[u][i], x + 1);

	}

}



int32_t main() {

	scanf("%lld", &n);

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

		int a;

		scanf("%lld", &a);

		d[i] = {a, i};

	}

	sort(d, d + n);

	reverse(d, d + n);

	

	vector <pii> k (d, d + n);

	

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

		int leaf = d[q].second;

		int parD = d[q].first - (n - (2 * (si[leaf] + 1)));

		auto it = lower_bound(k.rbegin(), k.rend(), pii(parD, 0));

//		cout << "PAR : " <<it->first << " : " << parD << '\n';

		if(it -> first != parD) {

//			cerr << "AVALI\n";

			impossible();

		}

		int par = it -> second;

		si[par] += si[leaf] + 1;

		if((si[leaf] + 1) * 2 > n) {

//			cout << "DOVOMI\n";

			impossible();

		}

		//SEVOMI HAM MISHE D[I] ROOT OK E ?

		e[par].push_back(leaf);

	}

	int D = d[n - 1].second;

	dfs(D, 0);

	if(sum != d[n - 1].first)

		impossible();

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

		for(int j = 0; j < e[i].size(); j++) {

			printf("%lld %lld\n", i + 1, e[i][j] + 1);

		}

	}

	return 0;

}

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

using namespace std;

#define ll long long

#define re register

#define gc getchar

#define pc putchar

#define cs const



inline

ll getint(){

	re ll num;

	re char c;

	while(!isdigit(c=gc()));num=c^48;

	while(isdigit(c=gc()))num=(num<<1)+(num<<3)+(c^48);

	return num;

}



inline

void outint(int a){

	static char ch[13];

	if(a==0)pc('0');

	while(a)ch[++ch[0]]=a-a/10*10,a/=10;

	while(ch[0])pc(ch[ch[0]--]^48);

}



cs int N=100005;



int last[N],nxt[N],to[N],ecnt;

inline

void addedge(int u,int v){

	nxt[++ecnt]=last[u],last[u]=ecnt,to[ecnt]=v;

}



map<ll,int> id;

int n;

ll d[N];

int siz[N];



int dist[N];

inline

void dfs(int u){

	for(int re e=last[u],v=to[e];e;v=to[e=nxt[e]]){

		dist[v]=dist[u]+1;

		dfs(v);

	}

}



vector<pair<int,int> > edge;



signed main(){

	n=getint();

	for(int re i=1;i<=n;++i)d[i]=getint(),id[d[i]]=i;

	

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

	for(int re i=1;i<=n;++i)siz[i]=1;

	

	for(int re i=n;i>1;--i){

		int u=id[d[i]];

		int tmp=n-2*siz[u];

		if(tmp<=0)return puts("-1"),0; 

		ll t=d[i]-tmp;

		if(id.count(t)==0)return puts("-1"),0;

		int pos=id[t];

		addedge(pos,u);

		siz[pos]+=siz[u];

		edge.push_back(make_pair(pos,u));

	}

	ll sum=0;

	dfs(id[d[1]]);

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

		sum+=dist[i];

	}

	if(sum!=d[1])return puts("-1"),0;

	for(int re i=0;i<edge.size();++i)outint(edge[i].first),pc(' '),outint(edge[i].second),pc('\n');

	return 0;

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

using namespace std;

typedef long long LL;

const int N=100100;



map<LL,int> qaq;



void DSY(){

	puts("-1");

	exit(0);

}



int sz[N];



vector<int> es[N];

LL dd[N]={0};

LL d[N];

void dsy(int x,int fa=-1){

	for(vector<int>::iterator it=es[x].begin();it!=es[x].end();++it){

		if(*it==fa)continue;

		dsy(*it,x);

		dd[x]+=dd[*it]+sz[*it];

	}

}



vector<pair<int,int> > ess;

void ae(int u,int v){

	if(u>v)swap(u,v);

	ess.push_back(pair<int,int>(u,v));

	es[u].push_back(v);

	es[v].push_back(u);

}

void print(){

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

	for(vector<pair<int,int> >::iterator it=ess.begin();it!=ess.end();++it){

		printf("%d %d\n",it->first,it->second);

	}

}



int main(){

	int n;

	scanf("%d",&n);

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

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

		qaq[d[i]]=i;

		sz[i]=1;

	}

	int cnt=n;

	for(map<LL,int>::reverse_iterator it=qaq.rbegin();it!=qaq.rend();++it){

		int x=it->second;

		LL ddd=it->first;

		if(sz[x]*2==n)DSY();

		LL nd=ddd+sz[x]-(n-sz[x]);

		if(cnt==1){

			dsy(x);

			if(dd[x]!=d[x])DSY();

			break;

		}

		if(!qaq.count(nd)){

			DSY();

		}else{

			int v=qaq[nd];

			ae(x,v);

			sz[v]+=sz[x];

		}

		cnt--;

	}

	print();

	return 0;

}

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

using namespace std;

#define ll long long

#define re register

#define gc getchar

#define pc putchar

#define cs const



inline

ll getint(){

	re ll num;

	re char c;

	while(!isdigit(c=gc()));num=c^48;

	while(isdigit(c=gc()))num=(num<<1)+(num<<3)+(c^48);

	return num;

}



inline

void outint(int a){

	static char ch[13];

	if(a==0)pc('0');

	while(a)ch[++ch[0]]=a-a/10*10,a/=10;

	while(ch[0])pc(ch[ch[0]--]^48);

}



cs int N=100005;



int last[N],nxt[N],to[N],ecnt;

inline

void addedge(int u,int v){

	nxt[++ecnt]=last[u],last[u]=ecnt,to[ecnt]=v;

}



map<ll,int> id;

int n;

ll d[N];

int siz[N];



int dist[N];

inline

void dfs(int u){

	for(int re e=last[u],v=to[e];e;v=to[e=nxt[e]]){

		dist[v]=dist[u]+1;

		dfs(v);

	}

}



vector<pair<int,int> > edge;



signed main(){

	n=getint();

	for(int re i=1;i<=n;++i)d[i]=getint(),id[d[i]]=i;

	

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

	for(int re i=1;i<=n;++i)siz[i]=1;

	

	for(int re i=n;i>1;--i){

		int u=id[d[i]];

		int tmp=n-2*siz[u];

		if(tmp<=0)return puts("-1"),0; 

		ll t=d[i]-tmp;

		if(id.count(t)==0)return puts("-1"),0;

		int pos=id[t];

		addedge(pos,u);

		siz[pos]+=siz[u];

		edge.push_back(make_pair(pos,u));

	}

	ll sum=0;

	dfs(id[d[1]]);

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

		sum+=dist[i];

	}

	if(sum!=d[1])return puts("-1"),0;

	for(int re i=0;i<edge.size();++i)outint(edge[i].first),pc(' '),outint(edge[i].second),pc('\n');

	return 0;

}
// Slower C++ solution:
// Peace Of SHIT

#include<bits/stdc++.h>

#define int long long

using namespace std;

typedef pair<int, int> pii;

const int maxn = 1e5 + 5;

int n, si[maxn];

int sum = 0;

vector<int> e[maxn];

pii d[maxn];



void impossible() {

	cout << -1;

	exit(0);

}



void dfs(int u, int x) {

	sum += x;

	for(int i = 0; i < e[u].size(); i++) {

		dfs(e[u][i], x + 1);

	}

}



int32_t main() {

	cin >> n;

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

		int a;

		cin >> a;

		d[i] = {a, i};

	}

	sort(d, d + n);

	reverse(d, d + n);

	

	vector <pii> k (d, d + n);

	

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

		int leaf = d[q].second;

		int parD = d[q].first - (n - (2 * (si[leaf] + 1)));

		auto it = lower_bound(k.rbegin(), k.rend(), pii(parD, 0));

//		cout << "PAR : " <<it->first << " : " << parD << '\n';

		if(it -> first != parD) {

//			cerr << "AVALI\n";

			impossible();

		}

		int par = it -> second;

		si[par] += si[leaf] + 1;

		if((si[leaf] + 1) * 2 > n) {

//			cout << "DOVOMI\n";

			impossible();

		}

		//SEVOMI HAM MISHE D[I] ROOT OK E ?

		e[par].push_back(leaf);

	}

	int D = d[n - 1].second;

	dfs(D, 0);

	if(sum != d[n - 1].first)

		impossible();

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

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

			cout << i + 1 << " " << e[i][j] + 1 <<'\n';

	}

	return 0;

}

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

	}

}
// Slower C++ solution:
// Peace Of SHIT

#include<bits/stdc++.h>

#define int long long

using namespace std;

typedef pair<int, int> pii;

const int maxn = 1e5 + 5;

int n, si[maxn];

int sum = 0;

vector<int> e[maxn];

pii d[maxn];



void impossible() {

	cout << -1;

	exit(0);

}



void dfs(int u, int x) {

	sum += x;

	for(int i = 0; i < e[u].size(); i++) {

		dfs(e[u][i], x + 1);

	}

}



int32_t main() {

	scanf("%lld", &n);

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

		int a;

		scanf("%lld", &a);

		d[i] = {a, i};

	}

	sort(d, d + n);

	reverse(d, d + n);

	

	vector <pii> k (d, d + n);

	

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

		int leaf = d[q].second;

		int parD = d[q].first - (n - (2 * (si[leaf] + 1)));

		auto it = lower_bound(k.rbegin(), k.rend(), pii(parD, 0));

//		cout << "PAR : " <<it->first << " : " << parD << '\n';

		if(it -> first != parD) {

//			cerr << "AVALI\n";

			impossible();

		}

		int par = it -> second;

		si[par] += si[leaf] + 1;

		if((si[leaf] + 1) * 2 > n) {

//			cout << "DOVOMI\n";

			impossible();

		}

		//SEVOMI HAM MISHE D[I] ROOT OK E ?

		e[par].push_back(leaf);

	}

	int D = d[n - 1].second;

	dfs(D, 0);

	if(sum != d[n - 1].first)

		impossible();

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

		for(int j = 0; j < e[i].size(); j++) {

			printf("%lld %lld\n", i + 1, e[i][j] + 1);

		}

	}

	return 0;

}

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

	}

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

using namespace std;

typedef long long LL;

const int N=100100;



map<LL,int> qaq;



void DSY(){

	puts("-1");

	exit(0);

}



int sz[N];



vector<int> es[N];

LL dd[N]={0};

LL d[N];

void dsy(int x,int fa=-1){

	for(vector<int>::iterator it=es[x].begin();it!=es[x].end();++it){

		if(*it==fa)continue;

		dsy(*it,x);

		dd[x]+=dd[*it]+sz[*it];

	}

}



vector<pair<int,int> > ess;

void ae(int u,int v){

	if(u>v)swap(u,v);

	ess.push_back(pair<int,int>(u,v));

	es[u].push_back(v);

	es[v].push_back(u);

}

void print(){

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

	for(vector<pair<int,int> >::iterator it=ess.begin();it!=ess.end();++it){

		printf("%d %d\n",it->first,it->second);

	}

}



int main(){

	int n;

	scanf("%d",&n);

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

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

		qaq[d[i]]=i;

		sz[i]=1;

	}

	int cnt=n;

	for(map<LL,int>::reverse_iterator it=qaq.rbegin();it!=qaq.rend();++it){

		int x=it->second;

		LL ddd=it->first;

		if(sz[x]*2==n)DSY();

		LL nd=ddd+sz[x]-(n-sz[x]);

		if(cnt==1){

			dsy(x);

			if(dd[x]!=d[x])DSY();

			break;

		}

		if(!qaq.count(nd)){

			DSY();

		}else{

			int v=qaq[nd];

			ae(x,v);

			sz[v]+=sz[x];

		}

		cnt--;

	}

	print();

	return 0;

}

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

	}

}
// Slower C++ solution:
// Peace Of SHIT

#include<bits/stdc++.h>

#define int long long

using namespace std;

typedef pair<int, int> pii;

const int maxn = 1e5 + 5;

int n, si[maxn];

int sum = 0;

vector<int> e[maxn];

pii d[maxn];



void impossible() {

	cout << -1;

	exit(0);

}



void dfs(int u, int x) {

	sum += x;

	for(int i = 0; i < e[u].size(); i++) {

		dfs(e[u][i], x + 1);

	}

}



int32_t main() {

	cin >> n;

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

		int a;

		cin >> a;

		d[i] = {a, i};

	}

	sort(d, d + n);

	reverse(d, d + n);

	

	vector <pii> k (d, d + n);

	

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

		int leaf = d[q].second;

		int parD = d[q].first - (n - (2 * (si[leaf] + 1)));

		auto it = lower_bound(k.rbegin(), k.rend(), pii(parD, 0));

//		cout << "PAR : " <<it->first << " : " << parD << '\n';

		if(it -> first != parD) {

//			cerr << "AVALI\n";

			impossible();

		}

		int par = it -> second;

		si[par] += si[leaf] + 1;

		if((si[leaf] + 1) * 2 > n) {

//			cout << "DOVOMI\n";

			impossible();

		}

		//SEVOMI HAM MISHE D[I] ROOT OK E ?

		e[par].push_back(leaf);

	}

	int D = d[n - 1].second;

	dfs(D, 0);

	if(sum != d[n - 1].first)

		impossible();

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

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

			cout << i + 1 << " " << e[i][j] + 1 <<'\n';

	}

	return 0;

}

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

#include<algorithm>

#include<iostream>

#include<map>

#include<vector>

#define ll long long

#define pii pair<int,int>

#define MP make_pair

using namespace std;

ll n;

map<ll,int>rev;

struct node{ll d,siz,val;int id;}a[100005];

bool cmp(node x,node y){return x.d>y.d;}

int back[100005];

vector<pii>ans;

int main(){

    scanf("%d",&n);

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

        scanf("%lld",&a[i].d);

        a[i].siz=1;a[i].id=i;

        rev[a[i].d]=i;

    }

    sort(a+1,a+1+n,cmp);

    for(int i=1;i<=n;i++) back[a[i].id]=i;

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

        if(n-2*a[i].siz<=0){puts("-1");return 0;}

        ll dd=a[i].d+2*a[i].siz-n;

        if(!rev[dd]){puts("-1");return 0;}

        int fa=rev[dd];

        ans.push_back(MP(min(fa,a[i].id),max(fa,a[i].id)));

        a[back[fa]].siz+=a[i].siz;

        a[back[fa]].val+=a[i].val+a[i].siz;

    }

    if(a[n].d!=a[n].val) return puts("-1"),0;

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

    for(int i=0;i<n-1;i++) printf("%d %d\n",ans[i].first,ans[i].second);

    return 0;

}
// Slower C++ solution:
// Peace Of SHIT

#include<bits/stdc++.h>

#define int long long

using namespace std;

typedef pair<int, int> pii;

const int maxn = 1e5 + 5;

int n, si[maxn];

int sum = 0;

vector<int> e[maxn];

pii d[maxn];



void impossible() {

	cout << -1;

	exit(0);

}



void dfs(int u, int x) {

	sum += x;

	for(int i = 0; i < e[u].size(); i++) {

		dfs(e[u][i], x + 1);

	}

}



int32_t main() {

	scanf("%lld", &n);

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

		int a;

		scanf("%lld", &a);

		d[i] = {a, i};

	}

	sort(d, d + n);

	reverse(d, d + n);

	

	vector <pii> k (d, d + n);

	

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

		int leaf = d[q].second;

		int parD = d[q].first - (n - (2 * (si[leaf] + 1)));

		auto it = lower_bound(k.rbegin(), k.rend(), pii(parD, 0));

//		cout << "PAR : " <<it->first << " : " << parD << '\n';

		if(it -> first != parD) {

//			cerr << "AVALI\n";

			impossible();

		}

		int par = it -> second;

		si[par] += si[leaf] + 1;

		if((si[leaf] + 1) * 2 > n) {

//			cout << "DOVOMI\n";

			impossible();

		}

		//SEVOMI HAM MISHE D[I] ROOT OK E ?

		e[par].push_back(leaf);

	}

	int D = d[n - 1].second;

	dfs(D, 0);

	if(sum != d[n - 1].first)

		impossible();

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

		for(int j = 0; j < e[i].size(); j++) {

			printf("%lld %lld\n", i + 1, e[i][j] + 1);

		}

	}

	return 0;

}

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

#include<algorithm>

#include<iostream>

#include<map>

#include<vector>

#define ll long long

#define pii pair<int,int>

#define MP make_pair

using namespace std;

ll n;

map<ll,int>rev;

struct node{ll d,siz,val;int id;}a[100005];

bool cmp(node x,node y){return x.d>y.d;}

int back[100005];

vector<pii>ans;

int main(){

    scanf("%d",&n);

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

        scanf("%lld",&a[i].d);

        a[i].siz=1;a[i].id=i;

        rev[a[i].d]=i;

    }

    sort(a+1,a+1+n,cmp);

    for(int i=1;i<=n;i++) back[a[i].id]=i;

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

        if(n-2*a[i].siz<=0){puts("-1");return 0;}

        ll dd=a[i].d+2*a[i].siz-n;

        if(!rev[dd]){puts("-1");return 0;}

        int fa=rev[dd];

        ans.push_back(MP(min(fa,a[i].id),max(fa,a[i].id)));

        a[back[fa]].siz+=a[i].siz;

        a[back[fa]].val+=a[i].val+a[i].siz;

    }

    if(a[n].d!=a[n].val) return puts("-1"),0;

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

    for(int i=0;i<n-1;i++) printf("%d %d\n",ans[i].first,ans[i].second);

    return 0;

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

using namespace std;

typedef long long LL;

const int N=100100;



map<LL,int> qaq;



void DSY(){

	puts("-1");

	exit(0);

}



int sz[N];



vector<int> es[N];

LL dd[N]={0};

LL d[N];

void dsy(int x,int fa=-1){

	for(vector<int>::iterator it=es[x].begin();it!=es[x].end();++it){

		if(*it==fa)continue;

		dsy(*it,x);

		dd[x]+=dd[*it]+sz[*it];

	}

}



vector<pair<int,int> > ess;

void ae(int u,int v){

	if(u>v)swap(u,v);

	ess.push_back(pair<int,int>(u,v));

	es[u].push_back(v);

	es[v].push_back(u);

}

void print(){

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

	for(vector<pair<int,int> >::iterator it=ess.begin();it!=ess.end();++it){

		printf("%d %d\n",it->first,it->second);

	}

}



int main(){

	int n;

	scanf("%d",&n);

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

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

		qaq[d[i]]=i;

		sz[i]=1;

	}

	int cnt=n;

	for(map<LL,int>::reverse_iterator it=qaq.rbegin();it!=qaq.rend();++it){

		int x=it->second;

		LL ddd=it->first;

		if(sz[x]*2==n)DSY();

		LL nd=ddd+sz[x]-(n-sz[x]);

		if(cnt==1){

			dsy(x);

			if(dd[x]!=d[x])DSY();

			break;

		}

		if(!qaq.count(nd)){

			DSY();

		}else{

			int v=qaq[nd];

			ae(x,v);

			sz[v]+=sz[x];

		}

		cnt--;

	}

	print();

	return 0;

}

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

#include<algorithm>

#include<iostream>

#include<map>

#include<vector>

#define ll long long

#define pii pair<int,int>

#define MP make_pair

using namespace std;

ll n;

map<ll,int>rev;

struct node{ll d,siz,val;int id;}a[100005];

bool cmp(node x,node y){return x.d>y.d;}

int back[100005];

vector<pii>ans;

int main(){

    scanf("%d",&n);

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

        scanf("%lld",&a[i].d);

        a[i].siz=1;a[i].id=i;

        rev[a[i].d]=i;

    }

    sort(a+1,a+1+n,cmp);

    for(int i=1;i<=n;i++) back[a[i].id]=i;

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

        if(n-2*a[i].siz<=0){puts("-1");return 0;}

        ll dd=a[i].d+2*a[i].siz-n;

        if(!rev[dd]){puts("-1");return 0;}

        int fa=rev[dd];

        ans.push_back(MP(min(fa,a[i].id),max(fa,a[i].id)));

        a[back[fa]].siz+=a[i].siz;

        a[back[fa]].val+=a[i].val+a[i].siz;

    }

    if(a[n].d!=a[n].val) return puts("-1"),0;

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

    for(int i=0;i<n-1;i++) printf("%d %d\n",ans[i].first,ans[i].second);

    return 0;

}