// Original C++ solution (slower):
# include <bits/stdc++.h>



# define pb push_back

# define fr first

# define sc second

# define mk make_pair



using namespace std;



const int inf = 1e9 + 7;

const int N = 2e5 + 5;



typedef long long ll;



int n, a[N], cnt;

pair <int, int> t[N * 4][2];

pair <int, int> v[N];

vector <int> g[N];

set < pair <int, int> > st;



void build(int v = 1, int tl = 1, int tr = n)

{

      if(tl == tr)

      {

            t[v][tl % 2] = mk(a[tl], tl);

            t[v][(tl % 2) ^ 1] = mk(inf, 0);

      }

      else

      {

            int tm = (tl + tr) >> 1;

            build(v << 1, tl, tm);

            build((v << 1) | 1, tm + 1, tr);

            t[v][0] = min(t[v << 1][0], t[(v << 1) | 1][0]);

            t[v][1] = min(t[v << 1][1], t[(v << 1) | 1][1]);

      }

}



pair <int, int> get(int l, int r, int type, int v = 1, int tl = 1, int tr = n)

{

      if(l > tr || tl > r) return mk(inf, 1);

      if(l <= tl && tr <= r) return t[v][type];

      int tm = (tl + tr) >> 1;

      return min(get(l, r, type, v << 1, tl, tm),

                        get(l, r, type, (v << 1) | 1, tm + 1, tr));

}



void dv(int l, int r, int p = 0)

{

      if(l >= r) return ;

      int c = ++ cnt;

      if(l + 1 == r)

      {

            if(p != 0) g[p].pb(c);

            else st.insert(mk(a[l], c));

            v[c] = mk(l, r);

            return ;

      }

      int aa = get(l, r - 1, l % 2).sc;

      int bb = get(aa + 1, r, (l % 2) ^ 1).sc;

      if(p != 0) g[p].pb(c);

      else st.insert(mk(a[aa], c));

      v[c] = mk(aa, bb);

      dv(l, aa - 1, p);

      dv(aa + 1, bb - 1, c);

      dv(bb + 1, r, p);

}



int main()

{

      cin >> n;



      for(int i = 1; i <= n; i ++)

            cin >> a[i];



      build();

      dv(1, n);



      while(!st.empty())

      {

            pair <int, int> vv = *st.begin();

            st.erase(st.begin());

            cout << vv.fr << " " << a[v[vv.sc].sc] << " ";

            for(int to : g[vv.sc])

                  st.insert(mk(a[v[to].fr], to));

      }

}


// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

using namespace std;

int n,a[200010],c[200010];

struct tree

{

	int Min0,Min1,pos0,pos1,l,r,tag;

}t[800010];

int Get(int x) {int an=0;for (;x;x-=x&(-x)) an+=c[x];return an;}

void Add(int x) {for (;x<=n;x+=x&(-x)) c[x]++;}

void Updata(int p)

{

	if (t[p*2].Min0<t[p*2+1].Min0) t[p].pos0=t[p*2].pos0,t[p].Min0=t[p*2].Min0;

	  else t[p].pos0=t[p*2+1].pos0,t[p].Min0=t[p*2+1].Min0;

	if (t[p*2].Min1<t[p*2+1].Min1) t[p].pos1=t[p*2].pos1,t[p].Min1=t[p*2].Min1;

	  else t[p].pos1=t[p*2+1].pos1,t[p].Min1=t[p*2+1].Min1;

}

void Build(int p,int l,int r)

{

	t[p].l=l;t[p].r=r;t[p].Min0=t[p].Min1=1e9;t[p].tag=0;

	if (l==r) {

		if (l&1) t[p].Min1=a[l],t[p].pos1=l;

		  else t[p].Min0=a[l],t[p].pos0=l;

		return;

	}

	int mid=(l+r)>>1;

	Build(p*2,l,mid);

	Build(p*2+1,mid+1,r);

	Updata(p);

}

void Pass(int p)

{

	if (t[p].tag==0) return;

	swap(t[p*2].Min0,t[p*2].Min1);swap(t[p*2].pos0,t[p*2].pos1);

	swap(t[p*2+1].Min0,t[p*2+1].Min1);swap(t[p*2+1].pos0,t[p*2+1].pos1);

	t[p*2].tag^=1;t[p*2+1].tag^=1;

	t[p].tag=0;

}

int Query(int p,int l,int r)

{

	if (t[p].l==l&&t[p].r==r) return t[p].pos0;

	Pass(p);

	int mid=(t[p].l+t[p].r)>>1;

	if (r<=mid) return Query(p*2,l,r);

	  else if (l>mid) return Query(p*2+1,l,r);

	int p1=Query(p*2,l,mid),p2=Query(p*2+1,mid+1,r);

	if (a[p1]<a[p2]) return p1;

	else return p2;

}

void Modify(int p,int l,int r)

{

	if (t[p].l==l&&t[p].r==r) {

		swap(t[p].Min0,t[p].Min1);

		swap(t[p].pos0,t[p].pos1);

		t[p].tag^=1;

		return;

	}

	Pass(p);

	int mid=(t[p].l+t[p].r)>>1;

	if (r<=mid) Modify(p*2,l,r);

	  else if (l>mid) Modify(p*2+1,l,r);

	    else Modify(p*2,l,mid),Modify(p*2+1,mid+1,r);

	Updata(p);

}

void Change(int p,int x)

{

	if (t[p].l==x&&t[p].r==x) {

		t[p].Min0=t[p].Min1=1e9;

		t[p].pos0=t[p].pos1=0;

		return ;

	}

	Pass(p);

	int mid=(t[p].l+t[p].r)>>1;

	if (x<=mid) Change(p*2,x);

	else Change(p*2+1,x);

	Updata(p);

}

int main()

{

	scanf("%d",&n);

	a[0]=1e9;

	for (int i=1;i<=n;i++)

	  scanf("%d",&a[i]);

	Build(1,1,n);

	for (int i=1;i<=n/2;i++) {

		int x=t[1].pos1;

		int l=x+1,r=n;

		int s=Get(x);

		while (l+1<r) {

			int mid=(l+r)>>1;

			if (Get(mid)-s) r=mid;

			else l=mid;

		}

		int y;

		if (Get(l)-s) y=Query(1,x+1,l-1);else if (Get(r)-s) y=Query(1,x+1,r-1);

		else y=Query(1,x+1,r);

		printf("%d %d ",a[x],a[y]);

		if (x<y-1) Modify(1,x+1,y-1);

		Change(1,x);

		Change(1,y);

		Add(x);Add(y);

	}

}

// Fastest known solution for this problem: