#include <bits/stdc++.h>

using namespace std;

#define all(v) (v).begin(), (v).end()

using li = long long;

array<pair<int, int>, 2> shiftIndices(array<pair<int, int>, 2> mi, int by) {
    return array<pair<int, int>, 2> { { { mi[0].first, mi[0].second + by }, { mi[1].first, mi[1].second + by } } };
}

class Treap {
public:
	typedef struct _node {
		int val;
		_node* l;
		_node* r;
		int cnt;
		int prior;
        
        array<pair<int, int>, 2> minIndex;
        
		_node(int val) :val(val), l(nullptr), r(nullptr), cnt(1) {
            prior = (rand() << 16) | rand();
            minIndex[0] = make_pair(val, 0);
            minIndex[1] = make_pair(1e9, -1);
        }

		void push() {
			
		}
		
		void recalc() {
            int cntl = Cnt(l);
            int cntr = Cnt(r);
			cnt = 1 + cntl + cntr;
            
            if (cntl > 0) {
                minIndex = l->minIndex;
            } else {
                minIndex[0] = make_pair((int)1e9, -1);
                minIndex[1] = make_pair((int)1e9, -1);
            }
            
            minIndex[cntl % 2] = min(minIndex[cntl % 2], make_pair(val, cntl));
            
            if (cntr > 0) {
                auto shifted = shiftIndices(r->minIndex, cntl + 1);
                minIndex[(cntl + 1) % 2] = min(minIndex[(cntl + 1) % 2], shifted[0]);
                minIndex[(cntl + 1 + 1) % 2] = min(minIndex[(cntl + 1 + 1) % 2], shifted[1]);
            }
		}

		static int Cnt(_node* v) {
			if (!v)
				return 0;
			return v->cnt;
		}
	}*node;

	static int Cnt(node v) {
		if (!v)
			return 0;
		return v->cnt;
	}

	node root;

	size_t Size;

	static node merge(node l, node r) {
		if (!l)
			return r;
		if (!r)
			return l;
		if (l->prior < r->prior) {
			l->push();
			l->r = merge(l->r, r);
			l->recalc();
			return l;
		}
		else {
			r->push();
			r->l = merge(l, r->l);
			r->recalc();
			return r;
		}
	}

	static void split(node v, int idx, node& l, node& r) {
		l = r = nullptr;
		if (!v)
			return;
		v->push();
		if (Cnt(v->l) < idx) {
			l = v;
			split(l->r, idx - Cnt(v->l) - 1, l->r, r);
			l->recalc();
		}
		else {
			r = v;
			split(r->l, idx, l, r->l);
			r->recalc();
		}
	}

public:
	Treap() {
		root = nullptr;
		Size = 0;
	}
	
	Treap(node n) {
        root = n;
        Size = n ? n->cnt : 0;
    }

	size_t size() const {
		return Size;
	}

	void insert(int idx, int val) { //insert at the idx - position
		node l = nullptr, r = nullptr;
		split(root, idx, l, r);
		node cur_node = new _node(val);
		root = merge(merge(l, cur_node), r);
		++Size;
	}

	void erase(int idx) {
		node l = nullptr, m = nullptr, r = nullptr;
		split(root, idx, l, r);
		split(r, 1, m, r);
		root = merge(l, r);
		--Size;
	}

	void push_back(int val) {
		return insert(Size, val);
	}
	void push_front(int val) {
		return insert(0, val);
	}

	node operator [] (int idx) {
		node l = nullptr, m = nullptr, r = nullptr;
		split(root, idx, l, r);
		split(r, 1, m, r);
		if (m == nullptr) {
			throw runtime_error("IndexTreapOutOfBound");
		}
		root = merge(merge(l, m), r);
		return m;
	}
	
	pair<int, node> getKey() const {
        return make_pair(root ? root->minIndex[0].first : (int)1e9, root);
    }
};

typedef Treap::node Node;

void solve(bool read) {
    int n;
    if (read)
        cin >> n;
    else
        n = 100;
    
    Treap t;
    
    vector<int> p(n);
    
    if (!read) {
        for (int i = 0; i < n; i++)
            p[i] = i + 1;
        random_shuffle(all(p));
        
        printf("%d\n", n);
        for (int x: p) printf("%d ", x);
        printf("\n");
    }
    
    for (int i = 0; i < n; i++) {
        if (read)
            cin >> p[i];
        t.push_back(p[i]);
    }
    
    set<pair<int, Node>> treaps;
    treaps.emplace(t.getKey());
    
    vector<int> answer;
    for (int i = 0; i < n / 2; i++) {
        auto it = treaps.begin();
        Node root = it->second;
        treaps.erase(it);
        
        Treap tRoot(root);
        
        int aValue = tRoot.root->minIndex[0].first;
        int a = tRoot.root->minIndex[0].second;
        
        int bValue = -1, b = -1;
        
        {
            Node l = nullptr, r = nullptr;
            Treap::split(tRoot.root, a + 1, l, r);
            
            assert(r && r->cnt > 0);
            
#if 0
            Treap tr(r);
            printf("tr: ");
            for (int i = 0; i < tr.size(); i++)
                printf("%d ", tr[i]->val);
            printf("\n");
#endif
            
            bValue = r->minIndex[0].first;
            b = r->minIndex[0].second + (l ? l->cnt : 0);
            
            tRoot.root = Treap::merge(l, r);
        }
        
        //printf("pair of mins %d (%d), %d (%d)\n", aValue, a, bValue, b);
        answer.push_back(aValue);
        answer.push_back(bValue);
        
        {
            Node l = nullptr, m = nullptr, r = nullptr;
            Treap::split(tRoot.root, b, l, r);
            Treap::split(r, 1, m, r);
            
            //root = merge(l, r);
            
            Node ll = nullptr, rr = nullptr, m2 = nullptr;
            Treap::split(l, a, ll, rr);
            Treap::split(rr, 1, m2, rr);
            
            // ll, m2, rr, m, r
            
            assert(m && m->cnt == 1);
            assert(m2 && m2->cnt == 1);
            
            if (ll)
                treaps.emplace(Treap(ll).getKey());
            
            if (rr) {
                treaps.emplace(Treap(rr).getKey());
                
#if 0
                auto x = Treap(rr);
                for (int i = 0; i < x.size(); i++)
                    cout << x[i]->val << " ";
                cout << "\n";
#endif
            }
            
            if (r)
                treaps.emplace(Treap(r).getKey());
        }
    }
    
    for (int x: answer)
        cout << x << " ";
    cout << "\n";
}

int main() {
#ifndef LOCAL
    ios_base::sync_with_stdio(false);
    cin.tie(0);
#endif
    
    //while (true) solve(false);
    
    solve(true);
    
    return 0;
}



Measured memory_bytes: 18164