#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <algorithm>
#include <functional>
#include <utility>
#include <bitset>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstdio>
#include <cstring>
#include <climits>
#include <string.h>
#include <stdio.h>
#define LL long long
#define all(x) (x).begin(),(x).end()
#define pii pair<int,int>
#define piii pair<int, pii >
#define REP(i,n) for (int (i)=0;(i)<(n);(i)++)
#define vi vector<int>
#define vpi vector< pii >
#define INF 2147483647
#define big 19260817
#define pb push_back
#define mp make_pair
using namespace std;
const int Maxk=1005;
string mul(string a,string b){
	int res[Maxk];
	memset(res,0,sizeof(res));
	reverse(a.begin(),a.end());
	reverse(b.begin(),b.end());
	for (int i=0;i<a.length();i++){
		for (int j=0;j<b.length();j++){
			res[i+j]+=(a[i]-'0')*(b[j]-'0');
		}
	}
	for (int i=0;i<Maxk;i++){
		if (res[i]>=10) {
			res[i+1]+=(res[i]/10);
			res[i]%=10;
		}
	}
	string ret;
	bool flag=false;
	for (int i=Maxk-1;i>=0;i--){
		if (flag || res[i]){
			flag=true;
			ret=ret+(char)(res[i]+'0');
		}
	}
	if (ret=="") ret="0";
	return ret;
}
string add(string a,string b){
	if (a.length()<b.length()) swap(a,b);
	while (a.length()!=b.length()){
		b='0'+b;
	}
	for (int i=a.length()-1;i>=0;i--){
		a[i]+=(b[i]-'0');
		if (a[i]>'9' && i){
			a[i]-=10;
			a[i-1]++;
		}
	}
	if (a[0]>'9'){
		a[0]-=10;
		a='1'+a;
	}
	return a;
}

// cf IO: I64d
// atcoder IO: ｌｌｄ
inline int read()
{
	int x = 0, f = 1; char ch = getchar();
	while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
	while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
	return x * f;
}
const int Maxn=200005;
int tree1[Maxn*4],tree0[Maxn*4];
int a[Maxn],pos[Maxn],n;
bool vis[Maxn];
int ans[Maxn];
set<int> lim;
void build1(int p,int l,int r){
	if (l==r){
		if (l%2==1)tree1[p]=a[l];
		else tree1[p]=1e9;
		return;
	}
	int mid=(l+r)>>1;
	build1(p*2,l,mid);
	build1(p*2+1,mid+1,r);
	tree1[p]=min(tree1[p*2],tree1[p*2+1]); 
}
void build0(int p,int l,int r){
	if (l==r){
		if (l%2==0)tree0[p]=a[l];
		else tree0[p]=1e9;
		return;
	}
	int mid=(l+r)>>1;
	build0(p*2,l,mid);
	build0(p*2+1,mid+1,r);
	tree0[p]=min(tree0[p*2],tree0[p*2+1]); 
}
int query1(int p,int l,int r,int lo,int hi){
	if (lo>hi) return 1e9;
	if (lo<=l && r<=hi){
		return tree1[p];
	}
	int mid=(l+r)>>1;
	int ans=1e9;
	if (lo<=mid){
		ans=min(ans,query1(p*2,l,mid,lo,min(hi,mid)));
	}
	if (hi>mid){
		ans=min(ans,query1(p*2+1,mid+1,r,max(lo,mid+1),hi));
	}
	return ans;
}
int query0(int p,int l,int r,int lo,int hi){
	if (lo>hi) return 1e9;
	if (lo<=l && r<=hi){
		return tree0[p];
	}
	int mid=(l+r)>>1;
	int ans=1e9;
	if (lo<=mid){
		ans=min(ans,query0(p*2,l,mid,lo,min(hi,mid)));
	}
	if (hi>mid){
		ans=min(ans,query0(p*2+1,mid+1,r,max(lo,mid+1),hi));
	}
	return ans;
}
int f(int l,int r){
	if (l%2==1) return query1(1,1,n,l,r);
	return query0(1,1,n,l,r);
}
int main(){
	scanf("%d",&n);
	for (int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		pos[a[i]]=i;
	}
	build1(1,1,n);
	build0(1,1,n);
	priority_queue<pair<int,pair<int,int> > > Q;
	Q.push(mp(-query1(1,1,n,1,n),mp(1,n)));
	int cnt=0;
	while (!Q.empty()){
		pair<int,pair<int,int> > x=Q.top();
		Q.pop();
		int pos1=pos[-x.first],pos2;
		if (pos1%2==0) pos2=query1(1,1,n,pos1+1,x.second.second);
		else pos2=query0(1,1,n,pos1+1,x.second.second);
		pos2=pos[pos2];
		if (x.second.first!=pos1){
			Q.push(mp(-f(x.second.first,pos1-1),mp(x.second.first,pos1-1)));
		}
		if (pos1+1!=pos2){
			Q.push(mp(-f(pos1+1,pos2-1),mp(pos1+1,pos2-1)));
		}
		if (pos2!=x.second.second){
			Q.push(mp(-f(pos2+1,x.second.second),mp(pos2+1,x.second.second)));
		}
		ans[cnt++]=a[pos1];
		ans[cnt++]=a[pos2];
	}
	for (int i=0;i<cnt;i++){
		printf("%d ",ans[i]);
	}
	printf("\n");
	return 0;
}

Measured memory_bytes: 10104