/*
Till the roof comes off, till the lights go out
Till my legs give out, canâ��t shut my mouth.
Till the smoke clears out. Am I high? Perhaps
I'ma rip this shit till my bones collapse.
*/
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <deque>
#include <set>
#include <stack>
#include <string.h>
#include <map>
#include <vector>
#include <queue>
#include <math.h>
#include <stack>
#include <complex>


#define ll long long
#define X real()
#define Y imag()
#define f first
#define s second
#define angle(a)                (atan2((a).imag(), (a).real()))
#define vec(a,b)                ((b)-(a))
#define same(p1,p2)             (dp(vec(p1,p2),vec(p1,p2)) < EPS)
#define dp(a,b)                 ( (conj(a)*(b)).real() )	// a*b cos(T), if zero -> prep
#define cp(a,b)                 ( (conj(a)*(b)).imag() )	// a*b sin(T), if zero -> parllel
#define lngth(a)               (hypot((a).imag(), (a).real()))
#define normalize(a)            (a)/length(a)

using namespace std;

const int N=200005;
typedef pair<int,int>ii;
typedef pair<ii,int>event;
typedef complex<double>point;
const double EPS = 1e-9;
const int INF=100000;

const double PI = acos(-1);
int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); }

int n,arr[N],tree[N*4][3],pos[N];
void update(int p,int p2,int s,int e,int idx,int val){
  if(idx<s||e<idx)return;
  if(idx==s&&s==e){
    tree[p][p2]=val;
    return;
  }
  update(p*2,p2,s,(s+e)/2,idx,val);
  update(p*2+1,p2,(s+e)/2+1,e,idx,val);
  tree[p][p2]=min(tree[p*2][p2],tree[p*2+1][p2]);
}
int get(int p,int p2,int s,int e,int from,int to){
  if(e<from||to<s)return n+1;
  if(from<=s&&e<=to)return tree[p][p2];
  return min(get(p*2,p2,s,(s+e)/2,from,to),get(p*2+1,p2,(s+e)/2+1,e,from,to));
}
vector<int>adj[N*10];
ii id[N*10];
int main()
{
    //freopen("test.in","r",stdin);
   //freopen("output.txt","w",stdout);
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d",&arr[i]);
        pos[arr[i]]=i;
        update(1,i%2,0,n-1,i,arr[i]);
        update(1,1-i%2,0,n-1,i,n+1);
    }
    queue<ii>q;
    queue<int>dep;
    q.push(ii(0,n-1));
    dep.push(0);
    memset(id,-1,sizeof(id));
    int d=0;
    while(q.size()){
      ii top=q.front();
      q.pop();
      int cur=dep.front();
      dep.pop();
      int a=top.first,b=top.s;
      if(a>=b)continue;
      if(a+1==b){
        //cout<<arr[a]<<' '<<arr[b]<<endl;
        id[cur]=ii(arr[top.f],arr[top.s]);
      }
      else{
        int val=get(1,a%2,0,n-1,a,b);
        int idx=pos[val];
        q.push(ii(a,idx-1));
        d++;
        dep.push(d);
        adj[cur].push_back(d);
        int second_val=get(1,1-a%2,0,n-1,idx,b);
        int second_idx=pos[second_val];
        q.push(ii(idx+1,second_idx-1));
        d++;
        dep.push(d);
        adj[cur].push_back(d);
        q.push(ii(second_idx+1,b));
        d++;
        dep.push(d);
        adj[cur].push_back(d);
        id[cur]=ii(val,second_val);
      }
    }
    int sum=0;
    vector<int>sol;
    priority_queue<ii>Q;
    Q.push(ii(-id[0].first,0));
    while(Q.size()){
        ii top=Q.top();
        Q.pop();
       if(id[top.s].f==-1)continue;
        sol.push_back(id[top.s].f);
        sol.push_back(id[top.s].s);
        for(int i=0;i<adj[top.s].size();i++){
            int to=adj[top.s][i];
            Q.push(ii(-id[to].f,to));
        }
    }
    for(int i=0;i<sol.size();i++)cout<<sol[i]<<' ';
    return 0;
}


Measured memory_bytes: 76024