#include <iostream>
#include <iomanip>
#include <random>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <numeric>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <sstream>
#include <bitset>
#include <cassert>
#include <fstream>

#define len(X) ((int)(X).size())

#ifdef __LOCAL
	#define DBG(X) cout << #X << "=" << (X) << endl;
#else
	#define DBG(X)
	#define endl '\n'
#endif
 
using namespace std;

using ll = long long int;
using ull = unsigned long long int;
using ld  = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;

const int INT_INF = (int)(2e9);
const ll  LL_INF  = (ll)(2e18);

const ll mod = 1e9 + 7;
const int NIL = -1;
static mt19937 _g(time(nullptr));

inline ll randint(ll a, ll b) { ll w = (_g() << 31LL) ^ _g(); return a + w % (b - a + 1); }
inline void fast_io() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); };
template<typename T> inline T sign(T x) { return T(x > 0) - T(x < 0); }
template<typename T, typename S> inline ostream& operator<<(ostream& os, const pair<T, S> p) { cout << "[" << p.first << ";" << p.second << "]"; return os; }
template<typename T> inline ostream& operator<<(ostream& os, const vector<T>& v) { for(auto el: v) cout << el << " "; return os; }

const int MAX_N = (int)2e5 + 7777;

struct Segtree
{
	int a[MAX_N], t[2 * MAX_N], n;

	inline int choose(int lhs, int rhs)
	{
		return (a[lhs] < a[rhs] ? lhs : rhs);
	}

	inline void init(int _n)
	{
		n = _n;

		for(int i = 0; i < n; ++i)
			t[i + n] = i;

		for(int i = n - 1; i > 0; --i)
			t[i] = choose(t[2 * i], t[2 * i + 1]);
	}

	inline pii extract(int l, int r)
	{
#ifdef __LOCAL
		assert(l <= r);
#endif

		int pos = l;

		l += n;
		r += n + 1;

		while(l < r)
		{
			if(l & 1)
				pos = choose(pos, t[l++]);

			if(r & 1)
				pos = choose(pos, t[--r]);

			l /= 2;
			r /= 2;
		}

		pii answ = {pos, a[pos]};
		a[pos] = INT_INF;
		pos += n;

		for(; pos > 0; pos /= 2)
			t[pos / 2] = choose(t[pos], t[pos ^ 1]);

		return answ;
	}
};

Segtree even, odd;
int n;

struct Node
{
	pii val;
	vector<int> nxt;

	Node()
	{
	}

	void append(int v)
	{
		if(v != NIL)
			nxt.push_back(v);
	}

	bool operator<(const Node& other) const
	{
		return val < other.val;
	}
};

Node nodes[MAX_N];
int sz = 0;

inline int firsteven(int l, int r)
{
	l += (l & 1);

	return l / 2;
}

inline int lasteven(int l, int r)
{
	r -= (r & 1);

	return r / 2;
}

inline int firstodd(int l, int r)
{
	l += 1 - (l & 1);

	return l / 2;
}

inline int lastodd(int l, int r)
{
	r -= 1 - (r & 1);

	return r / 2;
}

int build(int l, int r)
{
	if(r < l)
		return NIL;

	DBG(make_pair(l, r));

	int v = sz++;
	int subl = NIL, subr = NIL;

	if(l & 1)
	{
		auto pr1 = odd.extract(firstodd(l, r), lastodd(l, r));
		subl = 2 * pr1.first + 1;

		auto pr2 = even.extract(firsteven(subl, r), lasteven(subl, r));
		nodes[v].val = {pr1.second, pr2.second};

		subr = 2 * pr2.first;
	}
	else
	{
		auto pr1 = even.extract(firsteven(l, r), lasteven(l, r));
		subl = 2 * pr1.first;

		auto pr2 = odd.extract(firstodd(subl, r), lastodd(subl, r));
		nodes[v].val = {pr1.second, pr2.second};

		subr = 2 * pr2.first + 1;
	}

	DBG(nodes[v].val);

	nodes[v].append(build(l, subl - 1));
	nodes[v].append(build(subl + 1, subr - 1));
	nodes[v].append(build(subr + 1, r));

	return v;
}

void solve()
{
	cin >> n;

	for(int i = 0; i < n; ++i)
	{
		int val;
		cin >> val;

		if(i & 1)
			odd.a[i / 2] = val;
		else
			even.a[i / 2] = val;
	}

	even.init(n);
	odd.init(n);

	int head = build(0, n - 1);
	vector<int> answ;

	set<Node> setik = {nodes[head]};
	DBG(nodes[head].val);

	while(!setik.empty())
	{
		auto iter = setik.begin();

		answ.push_back(iter->val.first);
		answ.push_back(iter->val.second);

		for(auto& v: iter->nxt)
			setik.insert(nodes[v]);

		setik.erase(iter);
	}

	for(auto& x: answ)
		cout << x << " ";

	cout << endl;
}

int main()
{
	fast_io();
	solve();

	return 0;
}


Measured memory_bytes: 23156