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;
#define sz(a) (int)a.size()

const int MAXN = 2e5 + 1;
int n;

template<typename T1, typename T2>
ostream &operator<<(ostream &out, pair<T1, T2> &p) {
     out << "{" << p.first << ", " << p.second << "} ";//optional
     return out;
}

template<typename T1, typename T2>
istream &operator>>(istream &in, pair<T1, T2> &p) {
     in >> p.first >> p.second;
     return in;
}

template<typename T>
istream &operator>>(istream &in, vector<T> &arr) {
     for (auto &i : arr)
          in >> i;
     return in;
}

template<typename T>
ostream &operator<<(ostream &out, vector<T> &arr) {
     for (int i = 0; i < (int)arr.size(); ++i) {
          if (i != 0) {
               out << ' ';
          }
          out << arr[i];//optional
     }
     out << endl;
     return out;
}



pair<int, int> rmq0[MAXN * 4];
pair<int, int> rmq1[MAXN * 4];
int pl[MAXN];
int p[MAXN];
vector<pair<int, int> > vv;
set<pair<pair<int, int>, pair<int, int> > > ss;

void build(int v, int tl, int tr) {
     if (tl + 1 == tr) {
          rmq1[v] = rmq0[v] = make_pair(MAXN, tl);
          if (tl % 2 == 0)
               rmq0[v] = make_pair(p[tl], tl);
          else
               rmq1[v] = make_pair(p[tl], tl);
          return;
     }
     int m = (tl + tr) >> 1;
     build(v * 2 + 1, tl, m);
     build(v * 2 + 2, m, tr);
     rmq0[v] = min(rmq0[v * 2 + 1], rmq0[v * 2 + 2]);
     rmq1[v] = min(rmq1[v * 2 + 1], rmq1[v * 2 + 2]);
}

pair<int, int> get0(int v, int tl, int tr, int l, int r) {
     if (r <= tl || tr <= l)
          return make_pair(MAXN, 0);
     if (l <= tl && tr <= r)
          return rmq0[v];
     int m = (tl + tr) >> 1;
     return min(get0(v * 2 + 1, tl, m, l, r), get0(v * 2 + 2, m, tr, l, r));
}
pair<int, int> get1(int v, int tl, int tr, int l, int r) {
     if (r <= tl || tr <= l)
          return make_pair(MAXN, 0);
     if (l <= tl && tr <= r)
          return rmq1[v];
     int m = (tl + tr) >> 1;
     return min(get1(v * 2 + 1, tl, m, l, r), get1(v * 2 + 2, m, tr, l, r));
}

pair<int, int> get_(int l, int r) {
     if (l % 2 == 0) {
          int x = get0(0, 0, n, l, r).second;
          return make_pair(x, get1(0, 0, n, x + 1, r).second);
     }
     else {
          int x = get1(0, 0, n, l, r).second;
          return make_pair(x, get0(0, 0, n, x + 1, r).second);
     }
}

pair<int, int> get(int l, int r) {
     pair<int, int> a = get_(l, r);
     return make_pair(p[a.first], p[a.second]);
}

void add(int l, int r) {
     ss.insert(make_pair(get(l, r), make_pair(l, r)));
}

int main() {
     scanf("%d", &n);
     for (int i = 0; i < n; ++i)
          scanf("%d", p + i), --p[i], pl[p[i]] = i;
     build(0, 0, n);
     ss.insert(make_pair(get(0, n), make_pair(0, n)));
     while (!ss.empty()) {
          pair<pair<int, int>, pair<int, int> > a = *ss.begin();
          ss.erase(ss.begin());
          vv.push_back(a.first);
          pair<int, int> x = a.second;
          pair<int, int> y = make_pair(pl[a.first.first], pl[a.first.second]);
          if (x.first < y.first)
               add(x.first, y.first);
          if (y.first + 1 < y.second)
               add(y.first + 1, y.second);
          if (y.second + 1 < x.second)
               add(y.second + 1, x.second);
     }
     for (int i = 0; i < vv.size(); ++i)
          printf("%d %d ", vv[i].first + 1, vv[i].second + 1);
     printf("\n");
     return 0;
}