Problem:
Score : 800 points

Problem Statement

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.

Sample Input 1

4
3 2 4 1

Sample Output 1

3 1 2 4

The solution above is obtained as follows:

p

q

(3, 2, 4, 1)

()

↓

↓

(3, 1)

(2, 4)

↓

↓

()

(3, 1, 2, 4)

Sample Input 2

2
1 2

Sample Output 2

1 2

Sample Input 3

8
4 6 3 2 8 5 7 1

Sample Output 3

3 1 2 7 4 6 8 5

The solution above is obtained as follows:

p

q

(4, 6, 3, 2, 8, 5, 7, 1)

()

↓

↓

(4, 6, 3, 2, 7, 1)

(8, 5)

↓

↓

(3, 2, 7, 1)

(4, 6, 8, 5)

↓

↓

(3, 1)

(2, 7, 4, 6, 8, 5)

↓

↓

()

(3, 1, 2, 7, 4, 6, 8, 5)

Solution in C++14 (GCC 5.4.1) (judge verdict: Runtime Error)

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
typedef pair<int, int> pii;
struct node{
	int l, r, m, p, a;
	node *lch, *rch;
	node(){}
	node(int L, int R):l(L), r(R){
		m=(l+r)>>1; p=a=0;
		lch=rch=NULL;
	}
}pn[400010], *r[2];
int n, arr[200010], nT;
void build(node *p, int a){
	p->a=a;
	if(p->r-p->l==1){
		p->p=p->l; return;
	}
	p->lch=&(pn[nT++]=node(p->l, p->m)); build(p->lch, a);
	p->rch=&(pn[nT++]=node(p->m, p->r)); build(p->rch, a);
	if(arr[p->lch->p<<1|a]<arr[p->rch->p<<1|a]) p->p=p->lch->p;
	else p->p=p->rch->p;
}
int query(node *p, int l, int r){
	if(r<=p->l||p->r<=l) return n>>1;
	if(l<=p->l&&p->r<=r) return p->p;
	int q1=query(p->lch, l, r), q2=query(p->rch, l, r);
	if(arr[q1<<1|p->a]<arr[q2<<1|p->a]) return q1;
	else return q2;
}
vector<pii> dfs(int l, int r, int a){
	vector<pii> ret((r-l+1)/2);
	if(r>l){
		int p1=query(::r[a], l>>1, (r>>1)+(a^1)), p2=query(::r[a^1], p1+a, (r>>1)+1);
		p1=p1<<1|a, p2=p2<<1|a; p2^=1;
		vector<pii> r1=dfs(l, p1-1, a), r2=dfs(p1+1, p2-1, a^1), r3=dfs(p2+1, r, a);
		vector<pii> t1(r1.size()+r2.size());
		merge(r1.begin(), r1.end(), r2.begin(), r2.end(), t1.begin());
		ret[0]=pii(arr[p1], arr[p2]);
		merge(t1.begin(), t1.end(), r3.begin(), r3.end(), ret.begin()+1);
	}
	return ret;
}
int main(){
	scanf("%d", &n);
	for(int i=0;i<n;i++)
		scanf("%d", arr+i);
	arr[n]=arr[n|1]=0x3f3f3f3f;
	r[0]=&(pn[nT++]=node(0, n>>1)); build(r[0], 0);
	r[1]=&(pn[nT++]=node(0, n>>1)); build(r[1], 1);
	vector<pii> ans=dfs(0, n-1, 0);
	for(auto t: ans)
		printf("%d %d ", t.first, t.second);
	return 0;
}