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 Rust (1.15.1) (judge verdict: Time Limit Exceeded)

use io::*;
use std::collections::BinaryHeap;
use std::cmp::Ordering;

#[derive(Eq)]

struct Node {
    v1: usize,
    v2: usize,
    child: Vec<Vec<usize>>
}

impl Ord for Node {
    fn cmp(&self, other: &Node) -> Ordering {
        other.v1.cmp(&self.v1)
    }
}

impl PartialOrd for Node {
    fn partial_cmp(&self, other: &Node) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl PartialEq for Node {
    fn eq(&self, other: &Node) -> bool {
        self.v1 == other.v1
    }
}

fn main() {
    let input = read_string();
    let mut sc = Scanner::new(&input);
    let n: usize = sc.next();
    let ps: Vec<usize> = sc.next_vec(n);
    let mut pq: BinaryHeap<Node> = BinaryHeap::new();
    let head = solve(&ps ,n);
    print!("{} {}", head.v1, head.v2);
    for v in head.child {
        pq.push(solve(&v, n));
    }
    loop {
        if pq.is_empty() {
            break;
        }
        let node = pq.pop().unwrap();
        print!(" {} {}", node.v1, node.v2);
        for v in node.child {
            pq.push(solve(&v, n));
        }
    }
    print!("\n");
}

fn solve(v: &Vec<usize>, n: usize) -> Node {
    let mut e = n + 1;
    let mut ei = 0;
    let mut o = n + 1;
    let mut oi = 0;
    for i in 0..v.len() {
        if i % 2 == 0 {
            if e > v[i] {
                e = v[i];
                ei = i;
                o = n + 1;
            }
        } else if o > v[i] {
            o = v[i];
            oi = i;
        }
    }
    let mut child: Vec<Vec<usize>> = Vec::new();
    if 0 < ei {
        child.push(v[0..ei].iter().map(|x| *x).collect());
    }
    if ei + 1 < oi {
        child.push(v[ei+1..oi].iter().map(|x| *x).collect());
    }
    if oi + 1 < v.len() {
        child.push(v[oi+1..].iter().map(|x| *x).collect());
    }
    Node{v1: e, v2: o, child: child}
}

pub mod io {
    use std;
    use std::str::FromStr;

    pub struct Scanner<'a> {
        iter: std::str::SplitWhitespace<'a>,
    }

    impl<'a> Scanner<'a> {
        pub fn new(s: &'a str) -> Scanner<'a> {
            Scanner {
                iter: s.split_whitespace(),
            }
        }

        pub fn next<T: FromStr>(&mut self) -> T {
            let s = self.iter.next().unwrap();
            if let Ok(v) = s.parse::<T>() {
                v
            } else {
                panic!("Parse error")
            }
        }

        pub fn next_vec_len<T: FromStr>(&mut self) -> Vec<T> {
            let n: usize = self.next();
            self.next_vec(n)
        }

        pub fn next_vec<T: FromStr>(&mut self, n: usize) -> Vec<T> {
            (0..n).map(|_| self.next()).collect()
        }

        pub fn next_mat<T: FromStr>(&mut self, w: usize, h: usize) -> Vec<Vec<T>> {
            (0..h).map(|_| self.next_vec(w)).collect()
        }

        pub fn next_vec_char(&mut self) -> Vec<char> {
            self.next::<String>().chars().collect()
        }

        pub fn next_mat_char(&mut self, n: usize) -> Vec<Vec<char>> {
            (0..n).map(|_| self.next_vec_char()).collect()
        }
    }

    pub fn read_string() -> String {
        use std::io::Read;

        let mut s = String::new();
        std::io::stdin().read_to_string(&mut s).unwrap();
        s
    }

    pub fn read_line() -> String {
        let mut s = String::new();
        std::io::stdin().read_line(&mut s).unwrap();
        s.trim_right().to_owned()
    }
}