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# (Mono 4.6.2.0) (judge verdict: Time Limit Exceeded)

    using System;
    using System.Linq;
    using System.Collections.Generic;
    using System.Text.RegularExpressions;
    using System.Text;
    using System.Net;

     
    public class Program
    {

        public void Proc() {
            int itemCount = int.Parse(Reader.ReadLine());
            int[] items = Reader.ReadLine().Split(' ').Select(a=>int.Parse(a)).ToArray();
            this.NumberList.Add(items[0], new NumberItem(items[0]));
            for(int i=1; i<items.Length; i++) {
                NumberItem newItem = this.NumberList[items[i-1]].CreateNext(items[i]);
                this.NumberList.Add(newItem.Number, newItem);
                int total = newItem.Number + newItem.PrevNumber.Number;
                if(!JoinList.ContainsKey(total)) {
                    JoinList.Add(total, new SortedDictionary<int, int>());
                }
                JoinList[total].Add(newItem.PrevNumber.Number, newItem.Number);
            }

            List<int> ans = new List<int>();
            while(JoinList.Count>0) {
                int num1 = JoinList.Last().Value.Last().Key;
                int num2 = NumberList[num1].NextNumber.Number;
                ans.Add(num2);
                ans.Add(num1);
                NumberItem newNum1 = NumberList[num1].PrevNumber;
                NumberItem newNum2 = NumberList[num2].NextNumber;
                JoinList[num1+num2].Remove(num1);
                if(JoinList[num1+num2].Count<=0) {
                    JoinList.Remove(num1+num2);
                }
                if(newNum1 != null) {
                    JoinList[newNum1.Number+num1].Remove(newNum1.Number);
                    if(JoinList[newNum1.Number+num1].Count <= 0) {
                        JoinList.Remove(newNum1.Number+num1);
                    }
                }
                if(newNum2 != null) {
                    JoinList[num2+newNum2.Number].Remove(num2);
                    if(JoinList[num2+newNum2.Number].Count <=0) {
                        JoinList.Remove(num2+newNum2.Number);
                    }
                }
                if(newNum1 != null && newNum2 != null) {
                    newNum1.NextNumber = newNum2;
                    newNum2.PrevNumber = newNum1;
                    if(!JoinList.ContainsKey(newNum1.Number+newNum2.Number)) {
                        JoinList.Add(newNum1.Number+newNum2.Number, new SortedDictionary<int, int>());
                    }
                    JoinList[newNum1.Number+newNum2.Number].Add(newNum1.Number, newNum2.Number);
                } else if(newNum1 == null && newNum2 == null) {

                } else if(newNum1 == null) {
                    newNum2.PrevNumber = null;
                } else if(newNum2 == null) {
                    newNum1.NextNumber = null;
                }
            }
            ans.Reverse();
            Console.WriteLine(string.Join(" ", ans));
        }

        private Dictionary<int, NumberItem> NumberList = new Dictionary<int, NumberItem>();
        private SortedDictionary<int, SortedDictionary<int, int>> JoinList = new SortedDictionary<int, SortedDictionary<int, int>>();

        private class NumberItem {
            public int Number;

            public NumberItem PrevNumber;
            public NumberItem NextNumber;

            public NumberItem(int num) {
                this.Number = num;
            }

            public NumberItem CreateNext(int num) {
                NumberItem newNum = new NumberItem(num);
                this.NextNumber = newNum;
                newNum.PrevNumber = this;
                return newNum;
            }

        }


        public class Reader {
            public static bool IsDebug = false;
            private static System.IO.StringReader SReader;
            private static string InitText = @"






8
4 6 3 2 8 5 7 1










";
            public static string ReadLine() {
                if(IsDebug) {
                    if(SReader == null) {
                        SReader = new System.IO.StringReader(InitText.Trim());
                    }
                    return SReader.ReadLine();
                } else {
                    return Console.ReadLine();
                }
            }
        }
        public static void Main(string[] args)
        {
            #if DEBUG
            Reader.IsDebug = true;
            #endif
            Program prg = new Program();
            prg.Proc();
        }
    }