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: Wrong Answer)


//  main.cpp
//  solve
//
//  Created by Ahmed on 11/16/16.
//  Copyright © 2016 Abdellah. All rights reserved.
//


#include<set>
#include<map>
#include <unordered_map>
#include <unordered_set>
#include<list>
#include<iomanip>
#include<cmath>
#include<string>
#include<vector>
#include<queue>
#include<stack>
#include<complex>
#include<sstream>
#include<iostream>
#include<fstream>
#include<algorithm>
#include<numeric>
#include<utility>
#include<functional>
#include<stdio.h>
#include<assert.h>
#include<memory.h>
#include<bitset>
#include<math.h>
#include <strings.h>



#define f first
#define s second
#define pb push_back
#define sz(a) (int)a.size()
#define lp(i,a,n) for(int (i)=(a);(i)<=(int)(n);(i)++)
#define lpd(i,n,a) for(ll (i)=(n);(i)>=(a);--(i))
#define mp make_pair
#define clr(a,b) memset(a,b,sizeof a)
#define all(v) v.begin(),v.end()
#define mod 1000000007
#define eps 1e-6
#define infi 1000000002
#define infll 1000000000000000000ll
#define MX 1000000
#define X real()
#define Y imag()
#define polar(r,t) ((r)* exp(point(0,(t))))
#define length(a) hypot( (a).X , (a).Y )
#define angle(a) atan2( (a).Y , (a).X )
#define vec(a,b) ( (b) - (a) )
#define dot(a,b) (conj(a)*(b)).X
#define cross(a,b) (conj(a)*(b)).Y
#define lengthsqr(a) dot(a,a)
#define reflect(V,M) (conj((V)/(M)) * (M))
#define normalize(a)   ((a)/length(a))
#define ccw(a,b,c)   cross(vec(a,b) , vec(a,c)) > -eps
#define cosRule(a,b,c) (acos(((a)*(a)+(b)*(b)-(c)*(c))/(2*(a)*(b))))
#define cosDot(a,b) (acos(dot(a,b)/length(a)/length(b)))
#define EQ(a,b) (fabs((a) - (b)) <= eps) /* equal to */
#define NE(a,b) (fabs((a) - (b)) > eps)  /* not equal to */
#define LT(a,b) ((a) < (b) - eps)        /* less than */
#define GT(a,b) ((a) > (b) + eps)        /* greater than */
#define LE(a,b) ((a) <= (b) + eps)       /* less than or equal to */
#define GE(a,b) ((a) >= (b) - eps)       /* greater than or equal to */
#define mod1 100050001
#define mod2 100030001
#define base1 37
#define base2 31
#define que priority_queue<pair<int,int>, vector<pair<int,int>> , greater<pair<int,int> > >
#define rotate(v,t) ((v)*exp(point(0,t)))
#define rotateabout(v,t,a) (rotate(vec(a,v),t)+(a))
#define PI atan(1)*4

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<double,double> pdd;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vi> vvi;
typedef set<int> si;
typedef map<int, int> mii;
typedef complex<long double> point;
typedef pair<point, point> line;
typedef pair<double , point> Circle;

const int N = 2000005;
int n,a[N];
pii tree[4*N];
bool rev[4*N];


void propagate(int l,int r,int i) {
    if(!rev[i]) return;
    
    rev[i] = 0;
    swap(tree[i].f, tree[i].s);
    rev[i<<1] ^= 1 , rev[(i<<1)|1] ^= 1;
    
}

void build(int l,int r,int i) {
    if(l == r) {
        if(l&1) tree[i] = {l,n+1};
        else tree[i] = {n+1,l};
        return;
    }
    
    int mid = (l+r)>>1;
    build(l, mid, i<<1) , build(mid+1, r, (i<<1)|1);
    
    if(a[tree[i<<1].f]  < a[tree[(i<<1)|1].f])
        tree[i].f = tree[i<<1].f;
    else
        tree[i].f = tree[(i<<1)|1].f;
    

    
    if(a[tree[i<<1].s]  < a[tree[(i<<1)|1].s])
        tree[i].s = tree[i<<1].s;
    else
        tree[i].s = tree[(i<<1)|1].s;
    
}

void removee(int l,int r,int i,int x) {
    
    propagate(l, r, i);
    
    if(l == r){
        tree[i] = {n+1,n+1};
        return;
    }
    
    int mid = (l+r)>>1;
    if(mid >= x) removee(l,mid,i<<1,x);
    else removee(mid+1, r, (i<<1)|1, x);
    
    if(a[tree[i<<1].f]  < a[tree[(i<<1)|1].f])
        tree[i].f = tree[i<<1].f;
    else
        tree[i].f = tree[(i<<1)|1].f;
    
    
    
    if(a[tree[i<<1].s]  < a[tree[(i<<1)|1].s])
        tree[i].s = tree[i<<1].s;
    else
        tree[i].s = tree[(i<<1)|1].s;
    
}

void flip (int l,int r,int i,int x,int y) {
    propagate(l, r, i);
    
    if(l > y || r < x) return ;
    
    if(l >= x && r <= y) {
        rev[i] ^= 1;
        propagate(l, r, i);
        return ;
    }
    int mid = (l+r)>>1;
    
    flip(l, mid, i<<1, x, y) , flip(mid+1, r, (i<<1)|1, x, y);
    
    if(a[tree[i<<1].f]  < a[tree[(i<<1)|1].f])
        tree[i].f = tree[i<<1].f;
    else
        tree[i].f = tree[(i<<1)|1].f;
    
    
    
    if(a[tree[i<<1].s]  < a[tree[(i<<1)|1].s])
        tree[i].s = tree[i<<1].s;
    else
        tree[i].s = tree[(i<<1)|1].s;
    
}

int query(int l,int r,int i, int x,int y , bool t) {
    propagate(l, r, i);
    
    if(l > y || r < x) return n+1;
    
    if(l >= x && r <= y) return t ? tree[i].f:tree[i].s;
    
    int mid = (l+r)>>1;
    
    int r1 = query(l, mid, i<<1, x, y, t);
    int r2 = query(mid+1, r, (i<<1)|1, x, y, t);
    
    if(a[r1]  < a[r2]) return r1;
    return r2;
}

void mergeee(vector<pii> &a,vector<pii> &b, vector<pii> &ret) {
    
    int i = 0, j = 0;
    
    while(i < sz(a) && j < sz(b)) {
        if(a[i] < b[j]) ret.pb(a[i++]);
        else ret.pb(b[j++]);
    }
    
    while(i < sz(a)) ret.pb(a[i++]);
    
    while(j < sz(b)) ret.pb(b[j++]);
    
}

void solve(int l,int r , vector<pii> &ans) {
    if(l >= r) return;
    int x = query(1, n,  1, l, r, false);
    int y = query(1, n, 1, l, r, true);
    int tx = query(1, n, 1, x, r, true);
    int ty =  query(1, n, 1, y, r, false);
    
    if(x == n+1 || y == n+1) return;
    
    vector<pii> ans1 , ans2 ;
    
    
    if(ty == n+1 || (a[x] < a[y] && tx != n+1)) {
        ans.pb({a[x],a[tx]});
        
        removee(1, n, 1, x) , removee(1, n, 1, tx);
        flip(1, n, 1, l, x) , flip(1, n, 1, l, tx);
        
        solve(x+1,tx-1,ans1) , solve(l,r,ans2);
    }
    else  {
        ans.pb({a[y],a[ty]});
        removee(1, n, 1, y) , removee(1, n, 1, ty);
        flip(1, n, 1, l, y) , flip(1, n, 1, l, ty);
        solve(y+1,ty-1,ans1) , solve(l,r,ans2);
    }
    
    mergeee(ans1, ans2, ans);
    
}

int main()
{
    scanf("%d",&n);
    lp(i, 1, n)scanf("%d",&a[i]);
    a[n+1] = infi;
    
    build(1, n, 1);
    vector<pii> ans;
    solve(1, n,  ans);
    
    for(pii x:ans) printf("%d %d ",x.f,x.s);
    printf("\n");
    
    return 0;
}
/*
 
 */
//freopen("output.txt","w",stdout);
//freopen("input.txt","r",stdin);
//ios::sync_with_stdio(0);cin.tie(0);