// Original C++ solution (slower):
#include<cstdio>

#include<iostream>

#include<algorithm>

#include<string>

#include<math.h>

#include<vector>

#include<queue>

#include<map>

#include<stack>

#include<fstream>

#include<stdlib.h>

#include<set>

#include<climits>

#include<cmath>  

#include<memory.h> 

#include<sstream>

#include<time.h>

#include<iomanip>

using namespace std;

const unsigned long long BIGEST=1000000000000000000+1000000000000000000;

const long long BIGER=1000000000000000000;

const int BIG=1000000000;

const int MOD=1000000007;

const long long LMOD=1000000007;

#define F first

#define S second

#define p2 pair<int,int>

#define cb make_pair

int n;

int ar[200005];

vector<int>v[200005];

p2 p[200005];

struct seg

{

	int mnid[800005][2];

	int ch(int x,int l=1,int r=n,int k=1)

	{

		if(r<x||x<l)return 0;

		//cout<<"!"<<x<<" "<<l<<" "<<r<<" "<<k<<" ";

		if(ar[x]<ar[mnid[k][x%2]])mnid[k][x%2]=x;

		//cout<<mnid[k][0]<<" "<<mnid[k][1]<<endl;

		if(l!=r)

		{

			ch(x,l,(l+r)/2,k*2);

			ch(x,(l+r)/2+1,r,k*2+1);

		}

		//cout<<"!"<<x<<" "<<l<<" "<<r<<" "<<k<<" ";

		//cout<<mnid[k][0]<<" "<<mnid[k][1]<<endl;

		return 0;

	}

	int q(int a,int b,int v,int l=1,int r=n,int k=1)

	{

		//cout<<" "<<a<<" "<<b<<" "<<v<<" "<<l<<" "<<r<<" "<<k<<endl;

		if(r<a||b<l)return 0;

		//cout<<">"<<a<<" "<<b<<" "<<v<<" "<<l<<" "<<r<<" "<<k<<endl;

		if(a<=l&&r<=b)return mnid[k][v];

		if(l!=r)

		{

			int t1,t2;

			t1=q(a,b,v,l,(l+r)/2,k*2);

			t2=q(a,b,v,(l+r)/2+1,r,k*2+1);

			if(ar[t1]<ar[t2])return t1;

			else return t2;

		}

		return 0;

	}

}T;

int g=0;

int fu(int l,int r)

{

	//cout<<l<<" "<<r<<endl;

	int id=++g;

	p2 t;

	t.F=T.q(l,r,l%2);

	t.S=T.q(t.F,r,(l+1)%2);

	//cout<<"("<<t.F<<","<<t.S<<")";

	if(t.F>l)v[id].push_back(fu(l,t.F-1));

	if(t.S>t.F+1)v[id].push_back(fu(t.F+1,t.S-1));

	if(r>t.S)v[id].push_back(fu(t.S+1,r));

	p[id].F=ar[t.F];

	p[id].S=ar[t.S];

	return id;

}

int main()

{

	ar[0]=BIG;

	scanf("%d",&n);

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

	{

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

		T.ch(i);

	}

	fu(1,n);

	set<pair<p2,int > >q;

	q.insert(cb(p[1],1));

	pair<p2,int> t;

	while(!q.empty())

	{

		t=*q.begin();

		q.erase(t);

		printf("%d %d ",t.F.F,t.F.S);

		//cout<<t.S<<" ";

		for(int i=0;i<v[t.S].size();i++)q.insert(cb(p[v[t.S][i]],v[t.S][i]));

	}

	return 0;

}

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

using namespace std;



const int N = 2e5 + 10;

int n, a[N], t[2][N << 2];



inline int read() {

	int s = 0, f = 1;

	char ch;

	for(; ch < '0' || ch > '9'; ch = getchar())	if(ch == '-')	f = -1;

	for(; ch >= '0' && ch <= '9'; ch = getchar())	s = (s << 1) + (s << 3) + ch - '0';

	return s * f;

}



inline void add(int o, int pos, int l, int r, int cnt) {

	if (a[cnt] < a[t[o][pos]])	t[o][pos] = cnt;

	if (l == r)	return;

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

	if (cnt <= mid)	add(o, pos << 1, l, mid, cnt);

	else	add(o, pos << 1 | 1, mid + 1, r, cnt);

}



inline int ask(int o, int pos, int l, int r, int L, int R) {

	if (l > R || r < L)	return 0;

	if (L <= l && r <= R)	return t[o][pos];

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

	int lans = ask(o, pos << 1, l, mid, L, R);

	int rans = ask(o, pos << 1 | 1, mid + 1, r, L, R);

	return a[lans] < a[rans] ? lans : rans;

}



struct node {

	int l, r, v;

	node() {}

	node(int _l, int _r){ l = _l, r = _r, v = l > r ? 0 : ask(l & 1, 1, 1, n, l, r); }

	friend bool operator < (node A,node B) { return a[A.v] < a[B.v]; }

};



set <node> s;



int main() {

	n = read();

	a[0] = n + 1;

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

		a[i] = read();

		add(i & 1, 1, 1, n, i);

	}

	s.clear();

	s.insert(node(1, n));

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

		node now = *s.begin();

		s.erase(s.begin());

		int l = now.l, r = now.r;

		int lmid = now.v, rmid = ask((lmid & 1) ^ 1, 1, 1, n, lmid, r);

		printf("%d %d ", a[lmid], a[rmid]);

		s.insert(node(l, lmid - 1));

		s.insert(node(lmid + 1, rmid - 1));

		s.insert(node(rmid + 1, r));

	}

	puts("");

	return 0;

}


// Fastest known solution for this problem: