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

const int N = 4e6 + 5;

#define st first
#define nd second
#define make(a,b) make_pair(a,b)

typedef pair<int,int> pun;
typedef long long ll;

int MAX = N;

int mem[N];
int drz[N][2];
bool swaped[N];
bool flipped[N];
bool has_dead[N];
int n2 = 1;

void touch(int x) {
	if (not swaped[x]) return;
	swaped[x] = false;
	flipped[x] ^= 1;
//	if (drz[x][0] == 0) printf("%d %d\n", x, drz[x][0]);
//	if (drz[x][1] == 0) printf("%d %d\n", x, drz[x][1]);
	swap(drz[x][0], drz[x][1]);
	
	swaped[2*x] ^= 1;
	swaped[2*x+1] ^= 1;
}

pair<int, bool> szukaj(int v, int p, int k, int x) {
	touch(v);
	touch(2 * v);
	touch(2 * v + 1);
//	printf("szukaj %d -- %d\n", drz[v][x], x);
	if (p + 1 == k) {
// 		printf("znalazlem %d -- %d\n", v, drz[v][x]);
		return make_pair(drz[v][x], flipped[v]);
	}
	if (drz[2 * v][x] == drz[v][x]) return szukaj(2 * v, p, (p+k)/2, x);
	else return szukaj(2 * v + 1, (p+k)/2, k, x);
}

pair<int, bool> szukaj_next(int v, int p, int k, int x, int beg) {
// 	printf("szukaj next %d %d %d %d %d\n", v, p, k, x, beg);
	touch(v);
	if (beg > k) return make_pair(MAX, 0);
	if ((beg <= p && has_dead[v] == 0) || p == k - 1) {
		if (drz[v][x] == 0) printf("maybe %d -- %d\n", drz[v][x], v);
		return make_pair(drz[v][x], has_dead[v]);
	}
	if ((p+k)/2 > beg) {
		auto resl = szukaj_next(2 * v, p, (p+k)/2, x, beg);
		if (resl.second) return resl;
		auto resr = szukaj_next(2 * v + 1, (p+k)/2, k, x, beg);
		return make_pair(min(resl.first, resr.first), resr.second);
	}
	else return szukaj_next(2 * v + 1, (p+k)/2 , k, x, beg);
}

void erase(int v, int p, int k, int where, int x) {
	touch(v);
	touch(2 * v);
	touch(2 * v + 1);
	if (p + 1 == k) {
// 		printf("erase %d\n", drz[v][x]);
		drz[v][x] = MAX;
		has_dead[v] = true;
		return;
	}
	if (where < (p+k)/2) erase(2 * v, p, (p+k)/2, where, x);
	else erase(2 * v + 1, (p+k)/2, k, where, x);
 //	printf("%d %d -- %d -- %d %d\n", v, x, drz[v][x], drz[2 * v][x], drz[2 * v + 1][x]);
	for (int x = 0; x < 2; x ++) {
		drz[v][x] = min(drz[2 * v][x], drz[2 * v + 1][x]);
		if (drz[v][x] == 0) printf("%d %d -- %d -- %d %d\n", v, drz[v][x], x, drz[2 * v][x], drz[2 * v + 1][x]);
	}
//	printf("new %d\n", drz[v][x]);
	has_dead[v] = has_dead[2 * v] || has_dead[2 * v + 1];
}

void flip(int v, int p, int k, int a, int b) {
// 	printf("flip %d %d %d %d %d\n", v, p, k, a, b);
	touch(v);
	if (a <= p && k <= b) {
		swaped[v] = true;
		touch(v);
		return;
	}
	if (b <= p || k <= a) {
		return;
	}
	flip(2 * v, p, (p+k)/2, a, b);
	flip(2 * v + 1, (p+k)/2, k, a, b);
	for (int x = 0; x < 2; x ++) {
		drz[v][x] = min(drz[2 * v][x], drz[2 * v + 1][x]);
	}
}

void solve() {
	pair<int, bool> x = szukaj(1, 0, n2, 0);
	int beg = mem[x.first];
	if (x.second) beg ++;
	pair<int,int> y = szukaj_next(1, 0, n2, 1, beg);
	erase(1, 0, n2, mem[x.first], 0);
	erase(1, 0, n2, mem[y.first], 1);
// 	printf("%d %d\n", mem[x.first], mem[y.first]);
	flip(1, 0, n2, mem[x.first] + x.second, mem[y.first] + 1  - flipped[n2 + mem[y.first]]);
	printf("%d %d ", x.first, y.first);
}

int main() {
	int n;
	scanf("%d", &n);
	while (n2 <= n/2) n2 *= 2;
	for (int i = 0; i < n; i ++) {
		int a;
		scanf("%d", &a);
		drz[n2 + i/2][i % 2] = a;
		mem[a] = i/2;
//		if (a == 0) printf("%d\n", i);
	}
	for (int i = n; i <= 2 * n2; i ++) {
		drz[n2 + i/2][i % 2] = MAX;
		has_dead[n2 + i/2] = true; 
	}
	for (int i = n2 - 1; i > 0; i --) {
		for (int j = 0; j < 2; j ++) {
			drz[i][j] = min(drz[2 * i][j], drz[2 * i + 1][j]);
			has_dead[i] = has_dead[2 * i] || has_dead[2 * i + 1];
		}
	}
	for (int i = 0; i < n/2; i ++) {
		solve();
	}
}


Measured memory_bytes: 20224