Problem: Let N be a positive even number.

We have a permutation of (1, 2, ..., N), p = (p_1, p_2, ..., p_N). Snuke is constructing another permutation of (1, 2, ..., N), q, following the procedure below.

First, let q be an empty sequence. Then, perform the following operation until p becomes empty:

* Select two adjacent elements in p, and call them x and y in order. Remove x and y from p (reducing the length of p by 2), and insert x and y, preserving the original order, at the beginning of q.



When p becomes empty, q will be a permutation of (1, 2, ..., N).

Find the lexicographically smallest permutation that can be obtained as q.

Constraints

* N is an even number.
* 2 ≤ N ≤ 2 × 10^5
* p is a permutation of (1, 2, ..., N).

Input

Input is given from Standard Input in the following format:


N
p_1 p_2 ... p_N


Output

Print the lexicographically smallest permutation, with spaces in between.

Examples

Input

4
3 2 4 1


Output

3 1 2 4


Input

2
1 2


Output

1 2


Input

8
4 6 3 2 8 5 7 1


Output

3 1 2 7 4 6 8 5

Solution (in CPP):

Solution:
#include<set>
#include<vector>
#include<cstdio>
#include<algorithm>
#define MAXN 200000+9
#define INF 0x7fffffff
using namespace std;

int n;
int num[MAXN],aloc[MAXN];
struct T{
	int ls,rs,left_range,right_range;
	int val[2];
}tree[MAXN<<1];
int cnt;
vector<int> vec[MAXN];
set<int> s;
int to[MAXN];

void update(int x){
	tree[x].val[0]=min(tree[tree[x].ls].val[0],tree[tree[x].rs].val[0]);
	tree[x].val[1]=min(tree[tree[x].ls].val[1],tree[tree[x].rs].val[1]);
}

int Build(int l,int r){
	int now=++cnt;
	tree[now].left_range=l;
	tree[now].right_range=r;
	if(l==r){
		tree[now].val[l&1]=num[l];
		tree[now].val[(l&1)^1]=INF;
		return now;
	}
	int mid=(l+r)>>1;
	tree[now].ls=Build(l,mid);
	tree[now].rs=Build(mid+1,r);
	update(now);
	return now;
}

int getnum(int k,int l,int r,int t){
	if(l<=tree[k].left_range && tree[k].right_range<=r){
		return tree[k].val[t];
	}
	int mid=(tree[k].left_range+tree[k].right_range)>>1;
	int re=INF;
	if(l<=mid) re=min(re,getnum(tree[k].ls,l,r,t));
	if(r>=mid+1) re=min(re,getnum(tree[k].rs,l,r,t));
	return re;
}

void DFS(int l,int r,int t,int f){
	int x=aloc[getnum(1,l,r,t)];
	int y=aloc[getnum(1,x,r,t^1)];
	vec[f].push_back(x);
	to[x]=y;
	if(l<x) DFS(l,x-1,t,f);
	if(x+1<y) DFS(x+1,y-1,t^1,x);
	if(r>y) DFS(y+1,r,t,f);
}

void solve(){
	DFS(1,n,1,0);
	int i;
	for(i=0;i<vec[0].size();i++){
		s.insert(num[vec[0][i]]);
	}
	for(i=1;i<=n/2;i++){
		int x=aloc[*s.begin()];
		s.erase(num[x]);
		printf("%d %d ",num[x],num[to[x]]);
		for(int j=0;j<vec[x].size();j++)
			s.insert(num[vec[x][j]]);
	}
	puts("");
}

int main(){
	scanf("%d",&n);
	int i;
	for(i=1;i<=n;i++){
		scanf("%d",&num[i]);
		aloc[num[i]]=i;
	}
	Build(1,n);
	solve();
	return 0;
}