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

int read() {
	int ans = 0, flag = 1; char ch = getchar();
	while(ch > '9' || ch < '0') {if(ch == '-') flag = - flag; ch = getchar();}
	while(ch >= '0' && ch <= '9') {ans = ans * 10 + ch - '0'; ch = getchar();}
	return ans * flag;
}

const int N = 200010;
int INF = INT_MAX;

struct Key {
	int key, pos;
	bool operator < (Key x) const {return key == x.key ? pos < x.pos : key < x.key;}
	bool operator > (Key x) const {return key == x.key ? pos > x.pos : key > x.key;}
	Key min(Key a, Key b) {return a < b ? a : b;}
};

struct Sge {
	int ch[N << 1][2];
	Key keyMin[N << 1][2];
	int cnt = 1;

	#define L (ch[x][0])
	#define R (ch[x][1])
	#define mid ((l + r) >> 1)

	void upd(int x, bool p) {
		keyMin[x][1] = keyMin[L][1];
		if(keyMin[x][1] > keyMin[R][1 ^ p]) keyMin[x][1] = keyMin[R][1 ^ p];
		keyMin[x][0] = keyMin[L][0];
		if(keyMin[x][0] > keyMin[R][0 ^ p]) keyMin[x][0] = keyMin[R][0 ^ p];
	}

	void build(int a[], int x, int l, int r) {
		if(l == r) {
			keyMin[x][1] = {a[l], l};
			keyMin[x][0] = {INF, l};
		}
		else {
			L = ++ cnt; build(a, L, l, mid);
			R = ++ cnt; build(a, R, mid + 1, r);
			bool p = (mid - l + 1) % 2;
			upd(x, p);
		}
	}
	Key query(int x, int l, int r, int ll, int rr, bool& p) {
		if(l >= ll && r <= rr) {
			int np = p; p ^= (r - l + 1) % 2;
			return keyMin[x][np];
		}
		else {
			Key ans = {INF, 0};
			if(mid >= ll) ans = min(ans, query(L, l, mid, ll, rr, p));
			if(mid < rr) ans = min(ans, query(R, mid + 1, r, ll, rr, p));
			return ans;
		}
	}

	#undef L
	#undef R
	#undef mid
	/*
	返回一个<最小值，最小值位置>的Key类型
	*/
}sg;

struct Tree {
	int former, latter;
	bool operator < (Tree x) const {return former < x.former;}
	bool operator > (Tree x) const {return former > x.former;}
	vector <int> son;
}tr[N >> 1];
int trCnt;

struct Heap {
	struct Id {
		int id;
		bool operator < (Id x) const {return tr[id] < tr[x.id];}
		bool operator > (Id x) const {return tr[id] > tr[x.id];}
		bool operator = (int x) {id = x;}
	}a[N >> 1];
	int cnt;

	void push(int id) {
		a[++ cnt] = {id};
		int now = cnt;
		while((now >> 1) && a[now] < a[now >> 1]) {
			swap(a[now], a[now >> 1]);
			now >>= 1;
		}
	}
	void pop() {
		a[1] = 0; a[1] = a[cnt]; a[cnt --] = 0;
		int now = 1, son = now << 1;
		while(son <= cnt) {
			if(son + 1 <= cnt && a[son + 1] < a[son]) ++ son;
			if(a[son] < a[now]) {
				swap(a[son], a[now]);
				now = son; son = now << 1;
			}
			else break;
		}
	}
	bool empty() {return cnt == 0;}
}hp;

int n, a[N];

int solve(int l, int r) {
	bool np;
	np = 1; Key L = sg.query(1, 1, n, l, r, np);
	np = 1; Key R = sg.query(1, 1, n, L.pos + 1, r, np);
	int num = ++ trCnt;
	tr[num] = {L.key, R.key};
	if(L.pos != l) {tr[num].son.push_back(solve(l, L.pos - 1));}
	if(R.pos != r) {tr[num].son.push_back(solve(R.pos + 1, r));}
	if(L.pos + 1 != R.pos) tr[num].son.push_back(solve(L.pos + 1, R.pos - 1));
	return num;
}

int main() {
	n = read();
	for(int i = 1; i <= n; ++ i) a[i] = read();
	sg.build(a, 1, 1, n);
	int fst = solve(1, n);
	hp.push(fst);
	while(!hp.empty()) {
		int id = hp.a[1].id; hp.pop();
		printf("%d %d ", tr[id].former, tr[id].latter);
		for(auto it : tr[id].son)
			hp.push(it);
	}
	puts("");
	return 0;
}

Measured memory_bytes: 44416