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 Haskell (GHC 7.10.3) (judge verdict: Runtime Error)

import Data.Monoid
import Data.Maybe
import qualified Data.ByteString.Char8 as B
import qualified Data.Set as S

readInt :: B.ByteString -> Int
readInt = maybe undefined fst . B.readInt

readInts :: B.ByteString -> [Int]
readInts = map readInt . B.words

main = do
  n <- readLn :: IO Int
  ps <- readInts <$> B.getLine
  putStrLn $ unwords $ map show (maids n ps)
  --print (maids n ps)

maids n ps = go n treeEven treeOdd q
  where
    q = S.singleton (val treeEven, (1, n), False)
    treeEven = fromList n $ zipWith (\i p -> V p i) [1..] $ zipWith ($) (cycle [id, const maxBound]) ps
    treeOdd  = fromList n $ zipWith (\i p -> V p i) [1..] $ zipWith ($) (cycle [const maxBound, id]) ps

go n treeEven treeOdd q
  | S.null q = []
  | otherwise = pemin : pomin : go n treeEven treeOdd q2
  where
    ((V pemin i, (si,sj), flag), q1) = S.deleteFindMin q
    (V pomin j) = query n (if flag then treeEven else treeOdd) (i+1) sj
    seg1 = if si == i then Nothing else Just (query n treeEven si (i-1), (si, i-1), flag)
    seg2 = if succ i == j then Nothing else
             Just (query n (if flag then treeEven else treeOdd) (i+1) (j-1), (i+1, j-1), not flag)
    seg3 = if j == sj then Nothing else Just (query n treeEven (j+1) sj, (j+1, sj), flag)
    q2 = foldr S.insert q1 (catMaybes [seg1, seg2, seg3])

data V = V Int Index deriving (Eq, Ord, Show)

instance Monoid V where
  mempty = V maxBound 0
  mappend v1@(V p1 _) v2@(V p2 _) = if p1 < p2 then v1 else v2

data SegTree m =
  Leaf !m |
  Node !m !(SegTree m) !(SegTree m)
  deriving (Eq, Show)

type Index = Int
type Size = Int

val :: Monoid m => SegTree m -> m
val (Leaf v) = v
val (Node v _ _) = v

fromList :: Monoid m => Size -> [m] -> SegTree m
fromList 1 [x] = Leaf x
fromList n xs = Node (val left <> val right) left right
  where
    m = div n 2
    (xs1, xs2) = splitAt m xs
    left = fromList m xs1
    right = fromList (n - m) xs2

update :: Monoid m => Size -> SegTree m -> Index -> (m -> m) -> SegTree m
update 1 (Leaf v) 1 f = Leaf (f v)
update _ (Leaf _) _ _ = undefined
update n (Node _ l r) i x
  | i <= m = Node (val left <> val r) left r
  | otherwise = Node (val l <> val right) l right
  where
    m = div n 2
    left = update m l i x
    right = update (n - m) r (i - m) x

query :: Monoid m => Size -> SegTree m -> Index -> Index -> m
query 1 (Leaf v) 1 1 = v
query _ (Leaf _) _ _ = error "query" --undefined
query n (Node v l r) i j
  | (i, j) == (1, n) = v
  | j <= m = query m l i j
  | i > m = query (n - m) r (i - m) (j - m)
  | otherwise = query m l i m <> query (n - m) r 1 (j - m)
  where
    m = div n 2