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 <bits/stdc++.h>
using namespace std;

ifstream in ("test.in" );
ofstream out("test.out");

const int EXP = 2e1 + 0;
const int DIM = 2e5 + 5;

int rmq[2][EXP][DIM], aux[DIM], pos[DIM], arr[DIM];

set<pair<int, pair<int, int>>> mst;

int getrmq(int p, int l, int len)
{
    int r = l + len - 1, k = aux[r - l + 1];
    return min(rmq[p][k][l], rmq[p][k][r - (1 << k) + 1]);
}

int main(void)
{
    ios::sync_with_stdio(false);
    cin.tie(); cout.tie();
    
    int n;
    cin >> n;
    
    for (int i = 0; i < (n >> 1); ++i) {
        cin >> rmq[0][0][i] >> rmq[1][0][i];
        
        pos[rmq[0][0][i]] = (i << 1);
        pos[rmq[1][0][i]] = (i << 1 | 1);
        
        arr[i << 1] = rmq[0][0][i];
        arr[i << 1 | 1] = rmq[1][0][i];
    }
    
    for (int i = 2; i <= n; ++i)
        aux[i] = aux[i >> 1] + 1;
    
    for (int p = 0; p <= 1; ++p)
    for (int k = 1; (1 << k) <= (n >> 1); ++k)
    for (int i = 0, j = (1 << k) - 1; j < (n >> 1); ++i, ++j)
        rmq[p][k][i] = min(rmq[p][k - 1][i], rmq[p][k - 1][i + (1 << (k - 1))]);
    
    mst.insert(make_pair(getrmq(0, 0, n >> 1), make_pair(0, n - 1)));
    
    while (!mst.empty()) {
        int p1 = pos[mst.begin() -> first],
            l = (mst.begin() -> second).first,
            r = (mst.begin() -> second).second,
            par = (l & 1);
        
        int p2 = pos[getrmq(par ^ 1, (p1 + 1) >> 1, (r - p1 + 2) >> 1)];
        
        cout << arr[p1] << " " << arr[p2] << " "; mst.erase(mst.begin());
        
        if (l < p1)
            mst.insert(make_pair(getrmq(par, l >> 1, (p1 - l) >> 1), make_pair(l, p1 - 1)));
        if (p2 < r)
            mst.insert(make_pair(getrmq(par, (p2 + 1) >> 1, (r - p2) >> 1), make_pair(p2 + 1, r)));
        if (p1 + 1 < p2 - 1)
            mst.insert(make_pair(getrmq(par ^ 1, (p1 + 1) >> 1, (p2 - p1 - 1) >> 1), make_pair(p1 + 1, p2 - 1)));
    }
    
    return 0;
}