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>
#define lson l, mid, i<<1
#define rson mid+1, r, i<<1|1
#define PII pair<int, int>
#define Size(x) (int)(x.size())
using namespace std;
typedef long long LL;
//const int MOD = 1e9+7;
const auto INF = 0x3f3f3f3f;
const int N = 2e5+5;
struct node {
    int L, R;
    int l, r;
    bool operator < (const struct node &u) const {
        if(l == u.l)
            return r > u.r;
        return l > u.l;
    }
};

priority_queue<node> pri;
int dis[N], a[N];
int sum[2][N<<2], id[N];
vector<PII> answer;

void pustup(int i) {
    sum[0][i] = min(sum[0][i<<1], sum[0][i<<1|1]);
    sum[1][i] = min(sum[1][i<<1], sum[1][i<<1|1]);
}

void build(int l, int r, int i) {
    if(l == r) {
        int x;
        scanf("%d", &x);
        a[l] = x;
        dis[x] = l;
        sum[l&1][i] = x;
        sum[!(l&1)][i] = INF;
        id[x] = (l&1);
        return;
    }
    int mid = (l + r)>>1;
    build(lson);
    build(rson);
    pustup(i);
}

int query(int id, int L, int R, int l, int r, int i) {
    if(L <= l && r <= R) {
        return sum[!id][i];
    }
    int ans = INF, mid = (l + r)>>1;
    if(L <= mid)
        ans = query(id, L, R, lson);
    if(R > mid)
        ans = min(ans, query(id, L, R, rson));
    return ans;
}

int n;

void solve(int L, int R) {
    if(L > R)
        return ;
    int i = query(id[a[R]], L, R, 1, n, 1);
    int x = query(id[i], dis[i]+1, R, 1, n, 1);
    struct node temp;
    temp.L = L, temp.R = R;
    temp.l = i;
    temp.r = x;
    pri.push(temp);
}

int main() {
    scanf("%d", &n);
    build(1, n, 1);
    solve(1, n);
    while(!pri.empty()) {
        struct node temp = pri.top(); pri.pop();
        answer.push_back({temp.l, temp.r});
//        printf("L=%d R=%d l=%d r=%d\n", temp.L, temp.R, temp.l, temp.r);
        solve(temp.L, dis[temp.l]-1);
        solve(dis[temp.l]+1, dis[temp.r]-1);
        solve(dis[temp.r]+1, temp.R);
    }
    
    for(int i=0; i<Size(answer); i++) {
        printf("%d %d%c", answer[i].first, answer[i].second,
               i == Size(answer) - 1 ? '\n' : ' ');
    }
}