#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <cstring>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <utility>
using namespace std;
#define REP(I,N) for (I=0;I<N;I++)
#define rREP(I,N) for (I=N-1;I>=0;I--)
#define rep(I,S,N) for (I=S;I<N;I++)
#define rrep(I,S,N) for (I=N-1;I>=S;I--)
#define FOR(I,S,N) for (I=S;I<=N;I++)
#define rFOR(I,S,N) for (I=N;I>=S;I--)
typedef unsigned long long ull;
typedef long long ll;
//const int INF=0x3f3f3f3f;
const int INF=1e9;
const ll INFF=0x3f3f3f3f3f3f3f3fll;
const ll M=1e9+7;
const ll maxn=1e5+7;
const int MAXN=1005;
const int MAX=2e5+5;
const int MAX_N=MAX;
const ll MOD=1e9+7;
//const double eps=0.00000001;
//ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
template<typename T>inline T abs(T a) {return a>0?a:-a;}
inline ll powMM(ll a,ll b){
    ll ret=1;
    a%=M;
//    b%=M;
    while (b){
        if (b&1) ret=ret*a%M;
        b>>=1;
        a=a*a%M;
    }
    return ret;
}
int mina[MAX<<2][2];
int a[MAX],lo[MAX],n;
void init(int l,int r,int k)
{
    mina[k][0]=mina[k][1]=INF;
    if(l==r)
        return;
    init(l,(l+r)/2,2*k);
    init((l+r)/2+1,r,2*k+1);
}
void build(int l,int r,int k)//左闭右闭
{
    if(l==r)
    {
        scanf("%d",&a[l]);
        lo[a[l]]=l;
        mina[k][l%2]=a[l];return;
    }
    int mid=(l+r)/2;
    build(l,mid,2*k);
    build(mid+1,r,2*k+1);
    mina[k][0]=min(mina[2*k][0],mina[2*k+1][0]);
    mina[k][1]=min(mina[2*k][1],mina[2*k+1][1]);
}
int query(int ql,int qr,int l,int r,int k,int st)
{
//    if(!k)
//    {
//        printf("????\n");
//        system("pause");
//    }
//    if(ql>qr)
//        return INF;
    if(l>=ql&&r<=qr)
        return mina[k][st];
    int mid=(l+r)/2;
    if(mid<ql)
        return query(ql,qr,mid+1,r,2*k+1,st);
    else if(mid>=qr)
        return query(ql,qr,l,mid,2*k,st);
    else
        return min(query(ql,qr,l,mid,2*k,st),query(ql,qr,mid+1,r,2*k+1,st));
}
struct node
{
    int l,r,xiao,status;
    bool operator <(node b)const
    {
        return xiao>b.xiao;
    }
    node(int x=0,int y=0,int z=0,int s=0):l(x),r(y),xiao(z),status(s){}
};
priority_queue<node>que;
int an[MAX],cnt;
int main()
{
    cnt=0;
    scanf("%d",&n);
    init(0,n-1,1);
    build(0,n-1,1);
    node tem;
    tem.l=0;tem.r=n-1;tem.xiao=query(0,n-1,0,n-1,1,0);tem.status=0;
    que.push(tem);
    while(!que.empty())
    {
        tem=que.top();
//        printf("!%d %d %d %d\n",tem.l,tem.r,tem.xiao,tem.status);
//        if(tem.l==tem.r)
//        {
//            printf("!!!impossible!!\n");system("pause");
//        }
        que.pop();
//        if(tem.l>=tem.r)
//            continue;
        int now=lo[tem.xiao];
        int nxt=query(now+1,tem.r,0,n-1,1,1^tem.status);
//        printf("nxt=%d lo=%d\n",nxt,lo[nxt]);
        int to=lo[nxt];
        an[cnt++]=tem.xiao;an[cnt++]=nxt;
        if(now>tem.l)
            {
//                printf("zuo\n");
//                printf("woa~\n");
                que.push(node(tem.l,now-1,query(tem.l,now-1,0,n-1,1,tem.status),tem.status));
            }
//        system("pause");
        if(to-now>1)
            {
//                printf("mid\n");
                que.push(node(now+1,to-1,query(now+1,to-1,0,n-1,1,1^tem.status),1^tem.status));
//                printf("%d %d %d %d\n",now+1,to-1,1^tem.status,query(now+1,to-1,0,n-1,1,1^tem.status));
            }
        if(tem.r>to)
            {
//                printf("you\n");
                que.push(node(to+1,tem.r,query(to+1,tem.r,0,n-1,1,tem.status),tem.status));
            }
    }
    for(int i=0;i<cnt;i++)
        printf("%d ",an[i]);
    return 0;
}


Measured memory_bytes: 10484