#include <bits/stdc++.h>


using namespace std;

using ll = long long;
using ld = long double;

#define mp make_pair

const int p = 998244353;


int mul(int a, int b) {
    return (1LL * a * b) % p;
}

int add(int a, int b) {
    int s = (a+b);
    if (s>=p) s-=p;
    return s;
}

int sub(int a, int b) {
    int s = (a+p-b);
    if (s>=p) s-=p;
    return s;
}

int po(int a, int deg)
{
    if (deg==0) return 1;
    if (deg%2==1) return mul(a, po(a, deg-1));
    int t = po(a, deg/2);
    return mul(t, t);
}

int inv(int n)
{
    return po(n, p-2);
}

/*struct DSU {
    vector<int> sz;
    vector<int> parent;

    void make_set(int v) {
        parent[v] = v;
        sz[v] = 1;
    }

    int find_set(int v) {
        if (v == parent[v])
            return v;
        return parent[v] = find_set(parent[v]);
    }

    void union_sets(int a, int b) {
        a = find_set(a);
        b = find_set(b);
        if (a != b) {
            if (sz[a] < sz[b])
                swap(a, b);
            parent[b] = a;
            sz[a] += sz[b];
        }
    }

    DSU(int n) {
        sz.resize(n);
        parent.resize(n);
        for (int i = 0; i < n; i++) make_set(i);
    }
};*/

/*const int N = 1200000;

vector<int> facs(N), invfacs(N);

void init()
{
    facs[0] = 1;
    for (int i = 1; i<N; i++) facs[i] = mul(facs[i-1], i);
    invfacs[N-1] = inv(facs[N-1]);
    for (int i = N-2; i>=0; i--) invfacs[i] = mul(invfacs[i+1], i+1);
}

int C(int n, int k)
{
    return mul(facs[n], mul(invfacs[k], invfacs[n-k]));
}*/

const int N = 1e9;

struct MinSegTree
{
    int n;
    vector<int> t;

    void build(vector<int> &a, int v, int tl, int tr) {
        if (tl == tr) {
            t[v] = a[tl];
        } else {
            int tm = (tl + tr) / 2;
            build(a, v*2, tl, tm);
            build(a, v*2+1, tm+1, tr);
            t[v] = min(t[v*2], t[v*2+1]);
        }
    }

    int minn(int v, int tl, int tr, int l, int r) {
        if (l > r)
            return N;
        if (l == tl && r == tr) {
            return t[v];
        }
        int tm = (tl + tr) / 2;
        return min(minn(v*2, tl, tm, l, min(r, tm)), minn(v*2+1, tm+1, tr, max(l, tm+1), r));
    }

    int get_min(int l, int r)
    {
        return minn(1, 0, n-1, l, r);
    }

    MinSegTree(vector<int> &a)
    {
        n = a.size();
        t.resize(4*n);
        build(a, 1, 0, n-1);
    }

};



int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(nullptr);

    int n;
    cin>>n;
    vector<int> a(n);
    for (int i = 0; i<n; i++) {cin>>a[i]; a[i]--;}

    vector<int> invprm(n);
    for (int i = 0; i<n; i++) invprm[a[i]] = i;

    vector<int> odd(a), even(a);
    for (int i = 0; i<n; i++)
    {
        if (i%2==0) odd[i] = N;
        else even[i] = N;
    }

    MinSegTree E(even), O(odd);

    set<pair<int, pair<int, int>>> kek;
    kek.insert(mp(E.get_min(0, n-1), mp(0, n-1)));

    vector<int> suck;

    while (kek.size())
    {
        auto it = *kek.begin();
        kek.erase(it);
        int l = it.second.first; int r = it.second.second;
        if (l>r) continue;
        int pos1 = invprm[it.first];
        int val;
        if (pos1%2) val = E.get_min(pos1+1, r);
        else val = O.get_min(pos1+1, r);
        int pos2 = invprm[val];
        suck.push_back(a[pos1]);
        suck.push_back(a[pos2]);

        if (l%2)
        {
            kek.insert(mp(O.get_min(l, pos1-1), mp(l, pos1-1)));
            kek.insert(mp(E.get_min(pos1+1, pos2-1), mp(pos1+1, pos2-1)));
            kek.insert(mp(O.get_min(pos2+1, r), mp(pos2+1, r)));
        }
        else
        {
            kek.insert(mp(E.get_min(l, pos1-1), mp(l, pos1-1)));
            kek.insert(mp(O.get_min(pos1+1, pos2-1), mp(pos1+1, pos2-1)));
            kek.insert(mp(E.get_min(pos2+1, r), mp(pos2+1, r)));
        }
    }

    for (auto it: suck) cout<<it+1<<' ';





}



Measured memory_bytes: 24180