#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
#include<utility>
#include<set>
#include<stack>
#include<list>
#include<deque>
#include<bitset>
#include<iomanip>
#include<cstring>
#include<sstream>
#include<cstdio>
#include<cstdlib>
#include<climits>
#include<cmath>
#include<cctype>


#define pb push_back
#define mp make_pair
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define ren(i,a,b) for(int i=a;i>=b;i--)
#define ff first
#define ss second
#define pll pair<long long int,long long int>
#define pii pair<int,int>
#define vll vector<long long int>
#define vii vector<int>
#define gi(n) scanf("%d",&n)
#define gll(n) scanf("%lld",&n)
#define gstr(n) scanf("%s",n)
#define gl(n) cin >> n
#define oi(n) printf("%d",n)
#define oll(n) printf("%lld",n)
#define ostr(n) printf("%s",n)
#define ol(n) cout << n
#define os cout<<" "
#define on cout<<"\n"
#define o2(a,b) cout<<a<<" "<<b
#define all(n) n.begin(),n.end()
#define present(s,x) (s.find(x) != s.end())
#define cpresent(s,x) (find(all(s),x) != s.end())
#define tr(container, it) for(__typeof(container.begin()) it = container.begin(); it != container.end(); it++)
using namespace std;

typedef unsigned long long int ull;
typedef long long int ll;
typedef long double ld;
typedef vector<vector<ll> > mat;

int n,a[1000005],pos[1000005];

struct node
{
	int omn,emn,romn,remn,mn,sz;
}tree[1000005],x1;
 
node merge(node a,node b)
{
	node r;
	r.sz=a.sz+b.sz;
	r.mn=min(a.mn,b.mn);
	if(a.sz%2==1)
	{
		if(a.omn<b.emn)
		{
			r.omn=a.omn;
			r.romn=min(a.romn,b.omn);
		}
		else
		{
			r.omn=b.emn;
			r.romn=b.remn;
		}
		if(a.emn<b.omn)
		{
			r.emn=a.emn;
			r.remn=min(a.remn,b.emn);
		}
		else
		{
			r.emn=b.omn;
			r.remn=b.romn;
		}
	}
	else
	{
		if(a.omn<b.omn)
		{
			r.omn=a.omn;
			r.romn=min(a.romn,b.emn);
		}
		else
		{
			r.omn=b.omn;
			r.romn=b.romn;
		}
		if(a.emn<b.emn)
		{
			r.emn=a.emn;
			r.remn=min(a.remn,b.omn);
		}
		else
		{
			r.emn=b.emn;
			r.remn=b.remn;
		}
	}
	return r;
} 
 
void build(int lo,int hi,int i)
{
  if(lo==hi)
  {
  	tree[i].omn=tree[i].mn=a[lo];
  	tree[i].emn=tree[i].romn=tree[i].remn=1e9+7;
  	tree[i].sz=1;
  	return;
  }	
  int mid=(lo+hi)/2;
  build(lo,mid,2*i);
  build(mid+1,hi,2*i+1);
  tree[i]=merge(tree[2*i],tree[2*i+1]);
}
 
 
node query(int left,int right,int l,int r,int i)
{
 if(left>=l&&right<=r)
 return tree[i];
 int mid=(left+right)/2;
 node t1,t2;
 if(r<=mid)
 return query(left,mid,l,r,2*i);
 if(l>mid)
 return query(mid+1,right,l,r,2*i+1);
 t2=query(mid+1,right,mid+1,r,2*i+1);
 t1=query(left,mid,l,mid,2*i);

 return merge(t1,t2);
}
 

int main()
{ios_base::sync_with_stdio(false);
int n;
cin>>n;
rep(i,1,n)cin>>a[i],pos[a[i]]=i;

build(1,n,1);

set<pair<pii,pii> > s;

node q=tree[1];

s.insert(mp(mp(q.omn,q.romn),mp(1,n)));
vii ans;
while(!s.empty())
{
	set<pair<pii,pii> > :: iterator it=s.begin();
	int x=(it->ff).ff,y=(it->ff).ss,l=(it->ss).ff,r=(it->ss).ss;
	ans.pb(x);
	ans.pb(y);
	s.erase(s.begin());
	int px=pos[x],py=pos[y];
	if(px!=l)
	{
		q=query(1,n,l,px-1,1);
		s.insert(mp(mp(q.omn,q.romn),mp(l,px-1)));
	}
	if(py>px+1)
	{
		q=query(1,n,px+1,py-1,1);
		s.insert(mp(mp(q.omn,q.romn),mp(px+1,py-1)));
	}
	if(py!=r)
	{
		q=query(1,n,py+1,r,1);
		s.insert(mp(mp(q.omn,q.romn),mp(py+1,r)));
	}
}
tr(ans,it)
{
	ol(*it);os;
}
return 0;
}



Measured memory_bytes: 23284