#include<bits/stdc++.h>
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define rep(i,a,b) for (int i=(a); i<(b); i++)
#define per(i,a,b) for (int i=(b-1); i>=(a); i--)
#define de(x) //cout << #x << " => " << x << endl
using namespace std;

#define fi first
#define se second
#define mp make_pair
typedef pair<int,int> pii;

#define pb push_back
typedef vector<int> vi;

typedef long long ll;
typedef long double ld;

const int MAX_N = 3e5 + 7;
const int INF = 1e9 + 7;
///----------------------------------------------
int bod[MAX_N];
int p[MAX_N];
struct Tree {
	static const int Tree_N = MAX_N << 2;
	pii val[Tree_N]; int n;
	int ls(int o) { return o << 1; }
	int rs(int o) { return o << 1 | 1; }
	void update(int o) { 
		val[o].fi = min(val[ls(o)].fi, val[rs(o)].fi); 
		val[o].se = min(val[ls(o)].se, val[rs(o)].se);	
	}
	void build(int o, int l, int r) {
		if (l == r) {
			val[o].fi = l&1 ? p[l] : INF;
			val[o].se = l&1 ? INF  : p[l];
		} 
		else {
			int mid = (l + r) >> 1;
			build(ls(o), l, mid);
			build(rs(o), mid + 1, r);
			update(o);
		}
	}
	int init(int _n) { n = _n; build(1, 1, n); }
	//--
	pii _query(int o, int l, int r, int ql, int qr) {
		if (ql <= l && qr >= r) return val[o]; else {
			int mid = (l + r) >> 1;
			pii ret = mp(INF, INF);
			if (ql <= mid) {
				pii tmp =  _query(ls(o), l, mid, ql, qr);
				ret.fi = min(ret.fi, tmp.fi);
				ret.se = min(ret.se, tmp.se);
			}
			if (qr >  mid) {
				pii tmp = _query(rs(o), mid + 1, r, ql, qr);
				ret.fi = min(ret.fi, tmp.fi);
				ret.se = min(ret.se, tmp.se);
			}
			return ret;
		}
	}
	pii query(int ql, int qr) { return _query(1, 1, n, ql, qr); }
	//--
	void _change(int o, int l, int r, int qx, int qv) {
		if (l == r) {
			if (l&1) val[o].fi = qv; 
				else val[o].se = qv;
		}
		else {
			int mid = (l + r) >> 1;
			if (qx <= mid) _change(ls(o), l, mid, qx, qv);
				else _change(rs(o), mid + 1, r, qx, qv);
			update(o);
		}
	}
	void change(int qx, int qv) { _change(1, 1, n, qx, qv); }
}	tree;
///-----
int pos[MAX_N];
int main() {

	///read
	int n; cin >> n;
	rep(i, 1, n + 1) scanf("%d", &p[i]), pos[p[i]] = i;

	///prework
	tree.init(n);
	priority_queue<int, vector<int>, greater<int> > que;
	que.push(tree.query(1, n - 1).fi);

	///work
	set<int> s; s.insert(1); bod[1] = n;
	vi ans;
	rep(i, 0, n/2) {

		//get u
		int u = que.top(); que.pop();
		ans.pb(u); u = pos[u];
		auto it = s.lower_bound(u + 1);
		int beg = *(--it);
		
		//get v
		pii tmp = tree.query(u + 1, bod[beg]); 
		int v = u&1 ? tmp.se : tmp.fi;
		ans.pb(v); 
		v = pos[v];
		
		//change
		tree.change(u, INF);
		tree.change(v, INF);
		if (v < bod[beg]) {
			bod[v + 1] = bod[beg];
			pii nex = tree.query(v + 1, bod[v + 1] - 1);
			if ((v + 1) & 1) que.push(nex.fi);
				else que.push(nex.se);
			s.insert(v + 1);
		}
		if (u > beg) {
			bod[beg] = u - 1;
			pii nex = tree.query(beg, u - 1 - 1);
			if (beg & 1) que.push(nex.fi);
				else que.push(nex.se);
		}
		else s.erase(beg);
		if (u + 1 < v) {
			bod[u + 1] = v - 1;
			pii nex = tree.query(u + 1, v - 1 - 1);
			if ((u + 1) & 1) que.push(nex.fi);
				else que.push(nex.se);
			s.insert(u + 1);
			de(u + 1);
		}
	}

	///print
	rep(i, 0, sz(ans)) printf("%d ", ans[i]);
		



}


Measured memory_bytes: 16496