#include <cstdio>
#include <vector>
#include <cstring>
#include <functional>
#include <algorithm>
#include <math.h>
#include <bitset>
#include <set>
#include <queue>
#include <assert.h>
#include <iostream>
#include <string>
#include <sstream>
#include <stack>
#include <complex>
#include <numeric>
#include <map>
#include <time.h>
using namespace std;
typedef long double ld;
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
typedef pair<int,int> pii;
typedef pair<int,ll> pil;
typedef pair<int,ull> piu;
typedef pair<ull,ull> puu;
typedef pair<ll,int> pli;
typedef pair<ll,ll> pll;
typedef pair<pii,ll> ppl;
typedef pair<ll,pii> plp;
typedef pair<ll,pll> plP;
typedef pair<int,pii> pip;
typedef pair<pii,int> ppi;
typedef pair<pii,pii> ppp;
typedef pair<double,int> pdi;
typedef pair<int,double> pid;
typedef pair<double,pii> pdp;
typedef pair<double,double> pdd;
typedef pair<pdd,double> pd3;
typedef vector<ll> vec;
typedef vector<vec> mat;
#define rep(i,n) for (int (i) = 0; (i) < (n); (i)++)
#define repn(i,a,n) for (int (i) = (a); (i) < (n); (i)++)
#define ALL(x) (x).begin(),(x).end()
#define pb push_back
#define SORT(x) sort((x).begin(),(x).end())
#define SORTN(x,n) sort((x),(x)+(n))
#define ERASE(x) (x).erase(unique((x).begin(),(x).end()),(x).end())
#define COUNT(x,c) count((x).begin(),(x).end(),(c))
#define REMOVE(x,c) (x).erase(remove((x).begin(),(x).end(),(c)),(x).end())
#define REVERSE(x) reverse((x).begin(),(x).end())
#define FORIT(it,v) for(__typeof((v).begin()) it=(v).begin();it!=(v).end();it++)
#define LB(x,a) lower_bound((x).begin(),(x).end(),(a))-(x).begin()
#define lb(x,a) lower_bound((x).begin(),(x).end(),(a))
#define LBN(x,a,n) lower_bound((x),(x)+(n),(a))-(x)
#define lbN(x,a,n) lower_bound((x),(x)+(n),(a))
#define UB(x,a) upper_bound((x).begin(),(x).end(),(a))-(x).begin()
#define ub(x,a) upper_bound((x).begin(),(x).end(),(a))
#define BS(x,a) binary_search((x).begin(),(x).end(),(a))
#define BS2(x,n,a) binary_search((x),(x)+(n),(a))
#define NB(x) (((x)&~((x)+((x)&-(x))))/((x)&-(x))>>1)|((x)+((x)&-(x)))
#define NP(x) next_permutation((x).begin(),(x).end())
#define MM(x,p) memset((x),(p),sizeof(x))
#define SQ(x) (x)*(x)
#define SC(c1,c2) strcmp(c1,c2)==0
#define mp make_pair
#define INF (1<<29)
#define INFL (1LL<<61)
#define fi first
#define se second
#define EPS 1e-9
#define MOD 1000000007
#define MIN(x,a) x=min(x,a)
#define MAX(x,a) x=max(x,a)
#define madd(x,a) x=(x+a)%MOD
#define msub(x,a) x=(x+MOD-a)%MOD
#define OUTPUT(x) rep(__,x.size())printf("%d%c",x[__],__+1==x.size()?'\n':' ')

int N;
const int n=1<<18;
int p[n];
struct SegTree
{
	int dat[n*2-1];
	int sol_q(int a,int b)
	{
		if(a==-1)return b;
		else if(b==-1)return a;
		else if(p[a]<p[b])return a;
		else return b;
	}
	void init(bool o,bool e)
	{
		rep(i,n)
		{
			if(i%2==0)
			{
				if(e)dat[i+n-1]=i;
				else dat[i+n-1]=-1;
			}
			else
			{
				if(o)dat[i+n-1]=i;
				else dat[i+n-1]=-1;
			}
		}
		for(int i=n-2;i>=0;i--)dat[i]=sol_q(dat[i*2+1],dat[i*2+2]);
	}
	int query(int a,int b,int k,int l,int r)
	{
		if(r<=a||b<=l)return -1;
		if(a<=l&&r<=b)return dat[k];
		return sol_q(query(a,b,k*2+1,l,(l+r)/2),query(a,b,k*2+2,(l+r)/2,r));
	}
}odd,even,seg;

priority_queue<pip,vector<pip>,greater<pip> > q;

void q_insert(int l,int r)
{
	if(l>=r)return;
	int mi=-1;
	if(l%2==0)mi=p[even.query(l,r,0,0,n)];
	else mi=p[odd.query(l,r,0,0,n)];
	q.push(mp(mi,mp(l,r)));
}

int main()
{
	scanf("%d",&N);
	rep(i,N)scanf("%d",&p[i]);
	odd.init(true,false);
	even.init(false,true);
	seg.init(true,true);
	q_insert(0,N);
	vector<int> res;
	while(!q.empty())
	{
		pip A=q.top();q.pop();
		int l=A.se.fi,r=A.se.se;
		int p1=-1;
		if(l%2==0)p1=even.query(l,r,0,0,n);
		else p1=odd.query(l,r,0,0,n);
		int p2=-1;
		if(l%2==0)p2=odd.query(p1+1,r,0,0,n);
		else p2=even.query(p1+1,r,0,0,n);
		res.pb(p[p1]);
		res.pb(p[p2]);
		q_insert(l,p1);
		q_insert(p1+1,p2);
		q_insert(p2+1,r);
	}
	OUTPUT(res);
}

Measured memory_bytes: 9868