#include <bits/stdc++.h>

using namespace std;

//#define FILE_IO

const int NMAX = 2e5 + 5;

int N;
int v[NMAX];
int pos[NMAX];

class SegmentTree
{
public:
    int N, ans;
    int val[NMAX];
    int aint[4 * NMAX], add[4 * NMAX];
    int mn[4 * NMAX][2];
    int pos[4 * NMAX];

    void init(int _N)
    {
        N = _N;
        for(int i = 1; i <= N; i++) val[i] = v[i];
        B(1, 1, N);
    }

    void B(int nod, int st, int dr)
    {
        if(st == dr)
        {
            mn[nod][0] = mn[nod][1] = 1 << 30;
            aint[nod] = !(st & 1);
            mn[nod][ aint[nod] ] = val[st];
            add[nod] = 0;
            pos[nod] = N;
            return;
        }

        int mij = st + (dr - st) / 2;
        B(nod * 2, st, mij);
        B(nod * 2 + 1, mij + 1, dr);

        add[nod] = 0;
        pos[nod] = N;
        mn[nod][0] = min(mn[nod * 2][0], mn[nod * 2 + 1][0]);
        mn[nod][1] = min(mn[nod * 2][1], mn[nod * 2 + 1][1]);
    }

    void U(int nod, int st, int dr, int sti, int dri)
    {
        if(sti <= st && dr <= dri)
        {
            aint[nod] ^= 1;
            add[nod] ^= 1;
            swap(mn[nod][0], mn[nod][1]);
            return;
        }

        int mij = st + (dr - st) / 2;
        if(add[nod])
        {
            U(nod * 2, st, mij, st, mij);
            U(nod * 2 + 1, mij + 1, dr, mij + 1, dr);
            add[nod] = 0;
        }

        if(sti <= mij)  U(nod * 2, st, mij, sti, dri);
        if(mij < dri)  U(nod * 2 + 1, mij + 1, dr, sti, dri);

        pos[nod] = min(pos[nod * 2], pos[nod * 2 + 1]);
        mn[nod][0] = min(mn[nod * 2][0], mn[nod * 2 + 1][0]);
        mn[nod][1] = min(mn[nod * 2][1], mn[nod * 2 + 1][1]);
    }

    void U(int nod, int st, int dr, int position)
    {
        if(st == dr)
        {
            aint[nod] = 2;
            mn[nod][0] = mn[nod][1] = 1 << 30;
            add[nod] = 0;
            pos[nod] = st;
            return;
        }

        int mij = st + (dr - st) / 2;
        if(add[nod])
        {
            U(nod * 2, st, mij, st, mij);
            U(nod * 2 + 1, mij + 1, dr, mij + 1, dr);
            add[nod] = 0;
        }

        if(position <= mij)  U(nod * 2, st, mij, position);
        else            U(nod * 2 + 1, mij + 1, dr, position);

        pos[nod] = min(pos[nod * 2], pos[nod * 2 + 1]);
        mn[nod][0] = min(mn[nod * 2][0], mn[nod * 2 + 1][0]);
        mn[nod][1] = min(mn[nod * 2][1], mn[nod * 2 + 1][1]);
    }

    void Q(int nod, int st, int dr, int sti, int dri, int val)
    {
        if(sti <= st && dr <= dri)
        {
            ans = min(ans, mn[nod][val]);
            return;
        }

        int mij = st + (dr - st) / 2;
        if(add[nod])
        {
            U(nod * 2, st, mij, st, mij);
            U(nod * 2 + 1, mij + 1, dr, mij + 1, dr);
            add[nod] = 0;
        }

        if(sti <= mij)  Q(nod * 2, st, mij, sti, dri, val);
        if(mij < dri)  Q(nod * 2 + 1, mij + 1, dr, sti, dri, val);
    }

    void Q(int nod, int st, int dr, int sti, int dri)
    {
        if(sti <= st && dr <= dri)
        {
            ans = min(ans, pos[nod]);
            return;
        }

        int mij = st + (dr - st) / 2;
        if(add[nod])
        {
            U(nod * 2, st, mij, st, mij);
            U(nod * 2 + 1, mij + 1, dr, mij + 1, dr);
            add[nod] = 0;
        }

        if(sti <= mij)  Q(nod * 2, st, mij, sti, dri);
        if(mij < dri)  Q(nod * 2 + 1, mij + 1, dr, sti, dri);
    }

    int query(int st, int dr, int val)
    {
        ans = 1 << 30;
        Q(1, 1, N, st, dr, val);
        return ans;
    }

    int qpos(int st, int dr)
    {
        ans = 1 << 30;
        Q(1, 1, N, st, dr);
        return ans;
    }
};
SegmentTree aint;

int main()
{
    #ifdef FILE_IO
    freopen("1.in", "r", stdin);
    freopen("1.out", "w", stdout);
    #endif

    scanf("%d", &N);
    for(int i = 1; i <= N; i++)
        scanf("%d", &v[i]), pos[ v[i] ] = i;
    aint.init(N);

    for(int i = 1; i <= N / 2; i++)
    {
        int x = aint.query(1, N, 0);
        printf("%d ", x);
        int p = pos[x];
        int mxpos = aint.qpos(p, N);
        int y = aint.query(p, mxpos, 1);
        printf("%d ", y);
        int p2 = pos[y];

        aint.U(1, 1, N, p, p2);
        aint.U(1, 1, N, p);
        aint.U(1, 1, N, p2);
    }

    return 0;
}


Measured memory_bytes: 19584