// #includes {{{
#include <bits/stdc++.h>
using namespace std;

#define REP(i,n) for(int i=0;i<(int)(n);++i)
#define RREP(i,a,b) for(int i=(int)(a);i<(int)(b);++i)
#define FOR(i,c) for(__typeof((c).begin()) i=(c).begin();i!=(c).end();++i)
#define LET(x,a) __typeof(a) x(a)
//#define IFOR(i,it,c) for(__typeof((c).begin())it=(c).begin();it!=(c).end();++it,++i)
#define ALL(c) (c).begin(), (c).end()
#define MP make_pair

#define EXIST(e,s) ((s).find(e)!=(s).end())

#define RESET(a) memset((a),0,sizeof(a))
#define SET(a) memset((a),-1,sizeof(a))
#define PB push_back
#define DEC(it,command) __typeof(command) it=command

//debug
#define dump(x)  cerr << #x << " = " << (x) << endl;
#define debug(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << endl;
#define debug2(x) cerr << #x << " = [";REP(__ind,(x).size()){cerr << (x)[__ind] << ", ";}cerr << "] (L" << __LINE__ << ")" << endl;

const int INF=0x3f3f3f3f;

typedef long long Int;
typedef unsigned long long uInt;
typedef long double rn;

typedef pair<int,int> pii;

/*
#ifdef MYDEBUG
#include"debug.h"
#include"print.h"
#endif
*/
// }}}

//{{{ io
FILE *file_in=stdin,*file_out=stdout;
#define fin normal_in
#define fout normal_out
//const char fname[]="";
//FILE *fin=fopen(fname,"r"),*fout=fopen(fname,"w");
#ifdef __MINGW32__
#define LLD "%I64d"
#define LLU "%I64u"
#else
#define LLD "%lld"
#define LLU "%llu"
#endif
struct NORMAL_IN{
	bool cnt;
	NORMAL_IN():cnt(true){}
	operator int() const {return cnt;}
#define endl "\n"
	NORMAL_IN& operator>>(int &n){cnt=fscanf(file_in,"%d",&n)!=EOF;return *this;}
	NORMAL_IN& operator>>(unsigned int &n){cnt=fscanf(file_in,"%u",&n)!=EOF;return *this;}
	NORMAL_IN& operator>>(long long &n){cnt=fscanf(file_in,LLD,&n)!=EOF;return *this;}
	NORMAL_IN& operator>>(unsigned long long &n){cnt=fscanf(file_in,LLU,&n)!=EOF;return *this;}
	NORMAL_IN& operator>>(double &n){cnt=fscanf(file_in,"%lf",&n)!=EOF;return *this;}
	NORMAL_IN& operator>>(long double &n){cnt=fscanf(file_in,"%Lf",&n)!=EOF;return *this;}
	NORMAL_IN& operator>>(char *c){cnt=fscanf(file_in,"%s",c)!=EOF;return *this;}
	NORMAL_IN& operator>>(string &s){
		s.clear();
		for(bool r=false;;){
			const char c=getchar();
			if(c==EOF){ cnt=false; break;}
			const int t=isspace(c);
			if(!r and !t)r=true;
			if(r){
				if(!t)s.push_back(c);
				else break;
			}
		}
		return *this;
	}
	template<class T>
		NORMAL_IN& operator>>(vector<T> &v){
			int n;fscanf(file_in,"%d",&n);
			REP(i,n){
				T t;*this>>t;
				v.push_back(t);
			}
		}
} normal_in;

struct NORMAL_OUT{
	NORMAL_OUT& operator<<(const int &n){fprintf(file_out,"%d",n);return *this;}
	NORMAL_OUT& operator<<(const unsigned int &n){fprintf(file_out,"%u",n);return *this;}
	NORMAL_OUT& operator<<(const long long &n){fprintf(file_out,LLD,n);return *this;}
	NORMAL_OUT& operator<<(const unsigned long long &n){fprintf(file_out,LLU,n);return *this;}
	NORMAL_OUT& operator<<(const double &n){fprintf(file_out,"%lf",n);return *this;}
	NORMAL_OUT& operator<<(const long double &n){fprintf(file_out,"%Lf",n);return *this;}
	NORMAL_OUT& operator<<(const char c[]){fprintf(file_out,"%s",c);return *this;}
	NORMAL_OUT& operator<<(const string &s){fprintf(file_out,"%s",s.c_str());return *this;}
} normal_out;
//}}}

//{{{ Segment Tree
template <class T>
struct segment_tree {
	typedef pair<T,T> range;
	bool disjoint(const range &l,const range &r){ return l.second<=r.first or r.second<=l.first;}
	bool contain(const range &l,const range &r){ return r.first<=l.first and l.second<=r.second;}
	int n;
	vector<T> x;
	vector<int> id;
	segment_tree(int n_) {
		n=1;
		while(n < n_)n*=2;
		x.assign(n*2,init_val());
		id.assign(n*2,-1);
	}

	T init_val(){
		return INF;
	}
	T f(const T &a, const T &b){
		return min(a,b);
	}
	pair<T,int> range_query(const range &p, int i, const range &r){
		if(disjoint(p,r))return {init_val(),-1};
		else if(contain(r,p))return {x[i],id[i]};
		else{
			int m = (r.first+r.second)/2;
			auto pl = range_query(p,i*2+1,{r.first,m}), pr = range_query(p,i*2+2,{m,r.second});
			pair<T,int> ret;
			ret.first = f(pl.first,pr.first);
			if(ret.first==pl.first){
				ret.second = pl.second;
			}else{
				ret.second = pr.second;
			}
			return ret;
		}
	}
	pair<T,int> range_query(const range &p){
		return range_query(p,0,{0,n});
	}
	void set(int a,const T &v,int i,const range &r){
		if(r.second-r.first==1){
			x[i] = v;
			id[i] = r.first;
		}else{
			int m = (r.first+r.second)/2;
			int il = i*2+1, ir = i*2+2;
			if(a<m)set(a,v,il,{r.first,m});
			else set(a,v,ir,{m,r.second});
			x[i] = f(x[il],x[ir]);
			if(x[il]<x[ir])id[i] = id[il];
			else id[i] = id[ir];
		}
	}
	void set(int a,const T &v){
		set(a,v,0,0,n);
	}
	void set_all(const vector<T> &v, int i,const range &r){
		if(r.second-r.first==1){
			x[i] = v[r.first];
			id[i] = r.first;
		}else{
			int m = (r.first+r.second)/2;
			int il = i*2 + 1, ir = i*2 + 2;
			set_all(v,il,{r.first,m});
			set_all(v,ir,{m,r.second});
			x[i] = f(x[il],x[ir]);
			if(x[il]<x[ir])id[i] = id[il];
			else id[i] = id[ir];
		}
	}
	void set_all(const vector<T> &v){
		set_all(v,0,{0,n});
	}
};
//}}}

struct S{
	int i,j;
	int t,u;
	int i2,j2;
	int base;
	S(int i,int j,int i2, int j2, int t,int u):i(i),j(j),i2(i2),j2(j2),t(t),u(u){}
	S(){}
	bool operator<(const S &s)const{
		return t>s.t;//INVERSE
	}
};

void solve(long long N, vector<long long> p){
	segment_tree<int> st[2] = {segment_tree<int>(N/2+5), segment_tree<int>(N/2+5)};
	REP(base,2){
		vector<int> p2;
		for(int i=base;i<N;i+=2)p2.push_back(p[i]);
		st[base].set_all(p2);
	}
	function<pair<bool,S>(int,int)> get_param = [&st,&get_param](int i, int j) -> pair<bool,S>{
		if(j-i<=1){
			return make_pair(false,S());
		}
		int base = i%2;
		auto pr = st[base].range_query({i/2,(j+!base)/2});
		int val = pr.first, id = pr.second * 2 + base;
		/*
		   dump(val);dump(id);
		   dump((id+1)/2);
		   dump(j/2);
		   */
		auto pr2 = st[!base].range_query({(id+1)/2,(j+base)/2});
		int val2 = pr2.first, id2 = pr2.second * 2 + (!base);
		//	dump(val2);dump(id2);
		if(false)return get_param(i,j);
		return make_pair(true,S(i,j,id,id2,val,val2));
	};

	priority_queue<S> q;
	vector<int> ret;
	q.push(get_param(0,N).second);
	int ct = 0;

	while(!q.empty()){
		//		cerr<<"==========="<<endl;
		//		dump(q.size());
		S s(q.top());q.pop();
		int i = s.i, j = s.j;
		int base = i%2;
		if(s.t!=-1){
			ret.push_back(s.t);
			ret.push_back(s.u);
		}
		//		cerr<<i<<" "<<j<<" "<<s.i2<<" "<<s.j2<<endl;
		auto pr0 = get_param(i,s.i2);
		if(pr0.first)q.push(pr0.second);
		auto pr1 = get_param(s.i2+1,s.j2);
		if(pr1.first)q.push(pr1.second);
		auto pr2 = get_param(s.j2+1,j);
		if(pr2.first)q.push(pr2.second);
	}
	REP(i,ret.size()){
		fout<<ret[i];
		if(i<ret.size()-1)fout<<" ";
	}
	fout<<endl;
}

int main(){	
	long long N;
	fin >> N;
	vector<long long> p(N-1+1);
	for(int i = 0 ; i <= N-1 ; i++){
		fin >> p[i];
	}
	solve(N, p);
	return 0;
}


Measured memory_bytes: 11616