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: Accepted)

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#include <string>
#include <bitset>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <sstream>
#include <stack>
#include <iomanip>
using namespace std;
#define pb push_back
#define mp make_pair
typedef pair<int,int> pii;
typedef long long ll;
typedef double ld;
typedef vector<int> vi;
#define fi first
#define se second
#define fe first
#define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
#define Edg int M=0,fst[SZ],vb[SZ],nxt[SZ];void ad_de(int a,int b){++M;nxt[M]=fst[a];fst[a]=M;vb[M]=b;}void adde(int a,int b){ad_de(a,b);ad_de(b,a);}
#define Edgc int M=0,fst[SZ],vb[SZ],nxt[SZ],vc[SZ];void ad_de(int a,int b,int c){++M;nxt[M]=fst[a];fst[a]=M;vb[M]=b;vc[M]=c;}void adde(int a,int b,int c){ad_de(a,b,c);ad_de(b,a,c);}
#define es(x,e) (int e=fst[x];e;e=nxt[e])
#define esb(x,e,b) (int e=fst[x],b=vb[e];e;e=nxt[e],b=vb[e])
#define VIZ {printf("digraph G{\n"); for(int i=1;i<=n;i++) for es(i,e) printf("%d->%d;\n",i,vb[e]); puts("}");}
#define VIZ2 {printf("graph G{\n"); for(int i=1;i<=n;i++) for es(i,e) if(vb[e]>=i)printf("%d--%d;\n",i,vb[e]); puts("}");}
#define SZ 666666
int n,a[SZ];
const int M=262144;
int ls[SZ],rs[SZ],ss[SZ];
bool fl[SZ];
pii ps[SZ];
pii mg(pii a,pii b)
{
	return pii(min(a.fi,b.fi),min(a.se,b.se));
}
int qr(int p)
{
	static int s1[SZ],s2[SZ];
	int n1=0,n2=0;
	for(int l=p+M-1,r=n+M+3;l^r^1;l>>=1,r>>=1)
	{
		if(~l&1) s1[++n1]=l^1;
		if(r&1) s2[++n2]=r^1;
	}
	while(n2) s1[++n1]=s2[n2--];
	int g;
	for(int i=1;i<=n1;++i)
		if(ss[s1[i]]) {g=s1[i]; break;}
	while(g<M)
	{
		if(ss[g+g]) g=g+g;
		else g=g+g+1;
	}
	return rs[g]-1;
}
void sett(int x)
{
	for(x+=M;x;x>>=1) ss[x]=1;
}
void build()
{
	for(int i=1;i<=M;++i) ls[i+M]=rs[i+M]=i;
	for(int i=1;i<=n;++i)
		if((n-i)&1) ps[i+M]=pii(a[i],1e9);
		else ps[i+M]=pii(1e9,a[i]);
	for(int i=M-1;i>=1;--i)
		ls[i]=ls[i+i],rs[i]=rs[i+i+1],
		ps[i]=mg(ps[i+i],ps[i+i+1]);
}
void pd(int x)
{
	if(fl[x])
	{
		swap(ps[x].fi,ps[x].se);
		if(x<=M) fl[x+x]^=1, fl[x+x+1]^=1;
		fl[x]=0;
	}
}
void upd(int x)
{
	pd(x+x); pd(x+x+1);
	ps[x]=mg(ps[x+x],ps[x+x+1]);
}
pii qry(int x,int l,int r)
{
	if(rs[x]<l||r<ls[x]) return pii(1e9,1e9);
	pd(x);
	if(l<=ls[x]&&rs[x]<=r)
		return ps[x];
	pii t=mg(qry(x+x,l,r),qry(x+x+1,l,r));
	upd(x); return t;
}
void del(int p)
{
	int x=1;
	while(1)
	{
		pd(x);
		if(x>M) break;
		if(p<=rs[x+x]) x=x+x;
		else x=x+x+1;
	}
	ps[x]=pii(1e9,1e9);
	for(x>>=1;x;x>>=1)
		ps[x]=mg(ps[x+x],ps[x+x+1]); 
}
void flip(int x,int l,int r)
{
	if(rs[x]<l||r<ls[x]) return;
	pd(x);
	if(l<=ls[x]&&rs[x]<=r) {fl[x]^=1; return;}
	flip(x+x,l,r); flip(x+x+1,l,r); upd(x);
}
int os[SZ],on=0,rv[SZ];
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;++i) scanf("%d",a+i),rv[a[i]]=i;
	build(); sett(n+1);
	while(on<n)
	{
		int x=rv[qry(1,1,n).fi],t=qr(x);
		int y=rv[qry(1,x,t).se];
		os[++on]=a[x]; os[++on]=a[y];
		flip(1,x,y);
		del(x); del(y);
		sett(x); sett(y);
	}
	for(int i=1;i<=on;++i) printf("%d ",os[i]);
}
/*
找到一个全局最小的，右边有奇数个的
提出来
找到右边多少个没有padding
找到这部分最小的右边有奇数个的
xor一波删掉 
*/