#include <bits/stdc++.h>
#include <iomanip>
using namespace std;
using ll = long long ;
using pii = pair <int,int> ;
using pll = pair<ll,ll> ;
using vi = vector <int> ;
using vll = vector < ll > ;
using ld = long double ;
using big = __int128 ;
#define ndl '\n' ;
#define all(x) (x).begin() , (x).end()
#define sz(x) (int)(x).size()
#define nd second
#define st first
#define dbg_vec(x) cout << #x << " : " ; for(auto cc : (x) ) cout << cc << ' ' ; cout << endl
#define DEBU
#ifdef DEBUG
#define dbg(x) cout << #x << " = " << x << endl
#else
#define dbg(x)
#endif
int N , M , NN ;
const int maxn = 200'007 , INFI = 1e9 + 77 ;
vi dodaj[maxn] ; // tutaj byl ostatni "block"
struct segTree{ // drzewo maximum
int n , base ;
vi tree ;
void init(){
n = NN ;
base = ( 1 << (int)ceil(log2(n+7)) ) ;
tree.resize(base*2+7,0) ;
}
void update(int l , int r , int tl , int tr , int v , int val ){
//cout << " l , r, tl , tr , v " << l << ' ' << r << ' ' << tl << ' ' << tr << ' ' << v << endl ;
if( tr < l or tl > r ) return ;
if( l <= tl and tr <= r ) {
tree[v] = max( tree[v] , val ) ;
return ;
}
int mid = (tl+tr) / 2 ;
update(l,r,tl,mid,v*2,val) ;
update(l,r,mid+1,tr,v*2+1,val) ;
}
void call_update( int l , int r , int val ){
update(l,r,0,base-1,1,val) ;
}
int query( int pos ){
int v = pos + base ;
int tres = tree[v] ;
while(v>1){
v/=2 ;
tres = max( tres , tree[v] ) ;
}
return tres ;
}
} ;
int B[maxn] ;
int A[maxn] ;
int main(){
ios_base::sync_with_stdio(false) ; cin.tie(0) ;
cin >> N ; NN = 2*N ;
for(int i=1;i<=N;i++){
cin >> B[i] ;
}
segTree t1 ; t1.init() ;
for(int i=1;i<=N-1;i++){
int mini = min( B[i] , B[i+1] ) , maxi = max( B[i] , B[i+1] ) ;
mini ++ ; maxi -- ;
t1.call_update(mini,maxi,2*i-1) ;
}
// wylicz dodaj
set<int> mozliwe ;
for(int i=1;i<=NN-1;i++){
int res = t1.query(i) ;
dbg(res) ;
if(res == 0 or res == 1){
mozliwe.insert(i) ;
continue ;
}
dodaj[res].push_back(i) ;
}
// //
// for(int i=1;i<=NN-1;i++){
// cout << " i = " << i << endl ;
// dbg_vec(dodaj[i]) ;
// }
// main
vector <bool> vis(NN+7,0) ;
A[1] = B[1] ;
vis[B[1]] = 1 ;
mozliwe.erase(B[1]) ;
for(int i=2;i<=N;i++){ // po B
int pre = B[i-1] ;
auto it_min = mozliwe.begin() ;
auto it2_min = next(it_min) ;
auto it_max = prev(mozliwe.end()) ;
auto it2_max = prev( it_max ) ;
auto it_g = mozliwe.find(B[i]) ;
vector < set<int>::iterator > used ;
if( pre == B[i] ){
used.push_back(it_min) ;
used.push_back(it_max) ;
}
if( vis[B[i]] == 0 ){
used.push_back(it_g) ;
}
if( B[i-1] < B[i] ){
used.push_back(it_max) ;
if ( sz(used) == 1 ) used.push_back(it2_max) ;
}
if(B[i-1] > B[i] ){
used.push_back(it_min) ;
if( sz(used) == 1 ) used.push_back(it2_min) ;
}
assert( sz(used) == 2 ) ;
int idx = i*2 - 2 ;
for(auto it : used ){
assert(it != mozliwe.end() ) ;
vis[*it] = 1 ;
A[idx++] = *it ;
mozliwe.erase(it) ;
}
for(auto u : dodaj[2*i-1] ){
mozliwe.insert(u) ;
}
}
for(int i=1;i<=NN-1;i++){
cout << A[i] << ' ' ;
}
return 0 ;
}