#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef long double LD;
typedef pair < int, int > PII;
typedef pair < LL, LL > PLL;
typedef pair < LD, LD > PDD;

#define _upgrade ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define all(x) (x).begin(), (x).end()
#define sz(x) (int)(x).size()
template < typename _T > inline void _DBG(const char *s, _T x) { cerr << s << " = " << x << "\n"; }
template < typename _T, typename... args > void _DBG(const char *s, _T x, args... a) { while(*s != ',') cerr << *s++; cerr << " = " << x << ','; _DBG(s + 1, a...); }

#ifdef LOCAL
#define DBG(...) _DBG(#__VA_ARGS__, __VA_ARGS__)
#else
#define DBG(...) (__VA_ARGS__)
#define cerr if(0) cout
#endif

// ********************** CODE ********************** //

const int N = 2e5 + 7;
const int INF = 1e9 + 7;
const int MAX = 1 << 18;

PII tree[2 * MAX + 7];
int lazy[2 * MAX + 7];

inline void propagate(int node, int l, int r)
{
    if(lazy[node])
    {
        swap(tree[node].first, tree[node].second);
        if(l != r)
        {
            lazy[2 * node] ^= 1;
            lazy[2 * node + 1] ^= 1;
        }
        lazy[node] = 0;
    }
}

void update(int a, int b, int node = 1, int l = 0, int r = MAX - 1)
{
    propagate(node, l, r);
    if(b < l || r < a) return;
    if(a <= l && r <= b)
    {
        lazy[node] ^= 1;
        propagate(node, l, r);
        return;
    }
    update(a, b, 2 * node, l, (l + r) / 2);
    update(a, b, 2 * node + 1, (l + r) / 2 + 1, r);
    tree[node].first = min(tree[2 * node].first, tree[2 * node + 1].first);
    tree[node].second = min(tree[2 * node].second, tree[2 * node + 1].second);
}

void erase(int e, int node = 1, int l = 0, int r = MAX - 1)
{
    propagate(node, l, r);
    if(e < l || r < e) return;
    if(l == r)
    {
        tree[node].first = tree[node].second = INF;
        return;
    }
    int m = (l + r) / 2;
    erase(e, 2 * node, l, m);
    erase(e, 2 * node + 1, m + 1, r);
    tree[node].first = min(tree[2 * node].first, tree[2 * node + 1].first);
    tree[node].second = min(tree[2 * node].second, tree[2 * node + 1].second);
}

PII query(int a, int b, int node = 1, int l = 0, int r = MAX - 1)
{
    propagate(node, l, r);
    if(b < l || r < a) return {INF, INF};
    if(a <= l && r <= b) return tree[node];
    PII x = query(a, b, 2 * node, l, (l + r) / 2);
    PII y = query(a, b, 2 * node + 1, (l + r) / 2 + 1, r);
    return {min(x.first, y.first), min(x.second, y.second)};
}

int n, p[N], g[N];
set < int > zero;

int main()
{
    _upgrade
    cin >> n;
    for(int i = 0; i < 2 * MAX + 7; i++)
        tree[i].first = tree[i].second = INF;
    for(int i = 0; i < n; i++)
    {
        cin >> p[i];
        g[p[i]] = i;
        tree[i + MAX] = {p[i], INF};
        if(i & 1) swap(tree[i + MAX].first, tree[i + MAX].second);
    }
    for(int node = MAX - 1; node; node--)
    {
        tree[node].first = min(tree[2 * node].first, tree[2 * node + 1].first);
        tree[node].second = min(tree[2 * node].second, tree[2 * node + 1].second);
    }
    zero.insert(n);
    for(int i = 1; 2 * i <= n; i++)
    {
        int x = tree[1].first;
        int val = *zero.lower_bound(g[x]);
        int y = query(g[x], val).second;
        update(g[x], g[y]);
        cout << x << " " << y << " ";
        erase(g[x]); erase(g[y]);
        zero.insert(g[x]);
        zero.insert(g[y]);
    }
	return 0;
}


Measured memory_bytes: 18560