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<vector>
#include<queue>
#include<set>
#include<cassert>
#include<tuple>

using namespace std;
#define repeat(i,n) for(int i=0;i<(n);i++)
using pii=pair<int, int>;

struct Data{
   int v;
   pii s;
   Data(int vv, pii ss){v=vv; s=ss;}
};

bool operator<(const Data &l, const Data &r){
   return l.v<r.v;
}

struct SegmentTree{

   int sz;
   const int inf=1e9;
   vector<pii> seg;
   SegmentTree(int N){
      sz=1;
      while(sz<N) sz*=2;
      seg.resize(2*sz-1, {inf, -1});
   }

   void init(vector<int> &a, int ev){
      repeat(i, a.size()){
         if((i+ev)%2==1) seg[i+sz-1]={a[i], i};
         else seg[i+sz-1]={inf, i};
      }
      for(int i=sz-2; i>=0; i--){
         seg[i]=mrg(seg[2*i+1], seg[2*i+2]);
      }
   }

   pii mrg(pii l, pii r){
      pii rt;
      rt.first=min(l.first, r.first);
      rt.second=(l.first<r.first?l.second:r.second);
      return rt;
   }

   pii mi(int a, int b, int i, int l, int r){
      if(a<=l and r<=b){
         return seg[i];
      }else if(b<=l or r<=a){
         return {inf, -1};
      }else{
         int m=(r+l)/2;
         auto vl=mi(a, b, 2*i+1, l, m);
         auto vr=mi(a, b, 2*i+2, m, r);
         return mrg(vl, vr);
      }
   }

   pii mi(int a, int b){
      return mi(a, b, 0, 0, sz);
   }

   void out(){
      repeat(i, sz){
         cout<< seg[i+sz-1].first<< " ";
      }cout<< endl;
   }

};

int main(){

   int N; cin>> N;
   vector<int> a(N);
   repeat(i, N) cin>> a[i], a[i]--;

   SegmentTree st[2](N);
   st[0].init(a, 1); st[1].init(a, 0);
   priority_queue<tuple<int, int, int>> Q; // min, l, r
   Q.push(make_tuple(-st[0].mi(0, N).first, 0, N));
   vector<int> q;
   // st[0].out(); st[1].out();
   while(not Q.empty()){
      int v, i, j;
      tie(v, i, j)=Q.top(); Q.pop();
      auto ev=st[i%2].mi(i, j);
      auto od=st[(i+1)%2].mi(ev.second+1, j);
      // cout<< v<< " "<< i<< " "<< j<< endl;
      assert(j-i>=2);
      assert((i+ev.second)%2==0);
      assert((i+od.second)%2==1);
      q.push_back(ev.first); q.push_back(od.first);
      if(i<ev.second){
         auto e=st[i%2].mi(i, ev.second);
         Q.push(make_tuple(-e.first, i, ev.second));
      }
      if(od.second+1<j){
         auto e=st[(od.second+1)%2].mi(od.second+1, j);
         Q.push(make_tuple(-e.first, od.second+1, j));
      }
      if(ev.second+1<od.second){
         auto e=st[(ev.second+1)%2].mi(ev.second+1, od.second);
         Q.push(make_tuple(-e.first, ev.second+1, od.second));
      }
   }

   repeat(i, N){
      if(i){
         cout<< " "<< q[i]+1;
      }else{
         cout<< q[i]+1;
      }
   }cout<< endl;

   return 0;
}