#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <algorithm>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#define repi(i,a,b) for(ll i=(a);i<(b);++i)
#define rep(i,a) repi(i,0,a)
#define repdi(i,a,b) for(ll i=(a)-1;i>=(b);--i)
#define repd(i,a) repdi(i,a,0)
#define itr(it,a) for( auto it = (a).begin(); it != (a).end(); ++it )
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define endl '\n'
#define debug(x) std::cerr << #x << " = " << (x) << endl;

using ll = long long;
using P = std::pair<ll, ll>;
using Tup = std::tuple<P, ll, ll>;

constexpr ll INF = 1ll<<60;

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

template<class S, class T>
std::ostream& operator<< ( std::ostream& out, const std::pair<S,T>& a )
{ std::cout << '(' << a.first << ", " << a.second << ')'; return out; }

template<class T>
std::ostream &operator<< ( std::ostream& out, const std::vector<T>& a )
{ std::cout << '['; rep( i, a.size() ){ std::cout << a[i]; if( i != a.size()-1 ) std::cout << ", "; } std::cout << ']'; return out; }

template<class T>
struct SegTree {
  using F = std::function<T(T, T)>;

  ll n;
  F op;
  T id;
  std::vector<T> dat;

  SegTree()
  {}

  SegTree( F op, T id )
  : op(op), id(id)
  {}

  void init( ll n_ ) {
    n = 1;
    while( n < n_ )
      n <<= 1;
    
    dat.assign( n<<1, id );
  }

  void build( const std::vector<T> &vs ) {
    ll n_ = vs.size();
    init(n_);
    
    rep( i, n_ )
      dat[n+i] = vs[i];
    
    for( ll i = n-1; i; --i )
      dat[i] = op( dat[(i<<1)|0], dat[(i<<1)|1] );
  }

  void update( ll k, T x ) {
    dat[k += n] = x;

    while( k >>= 1 )
      dat[k] = op( dat[(k<<1)|0], dat[(k<<1)|1] );
  }

  T query( ll a, ll b ) {
    if( a >= b )
      return id;

    T vl = id, vr = id;

    for( ll l = a+n, r = b+n; l < r; l >>= 1, r >>= 1 ) {
      if( l&1 )
        vl = op( vl, dat[l++] );
      if( r&1 )
        vr = op( dat[--r], vr );
    }

    return op( vl, vr );
  }
};

ll N;
std::vector<P> ps[2];
std::vector<ll> ans;

int main() {
  std::cin >> N;

  P id = P( INF, INF );

  rep( i, N ) {
    ll v;
    std::cin >> v;

    rep( j, 2 ) {
      if( (i&1) == j )
        ps[j].emplace_back( v, i );
      else
        ps[j].emplace_back( id );
    }
  }

  SegTree<P> seg0( []( P a, P b ) { return std::min( a, b ); }, id );
  SegTree<P> seg1( []( P a, P b ) { return std::min( a, b ); }, id );

  seg0.build( ps[0] );
  seg1.build( ps[1] );

  std::priority_queue<Tup, std::vector<Tup>, std::greater<Tup>> pque;
  pque.emplace( seg0.query( 0, N ), 0, N );

  rep( i, N/2 ) {
    auto [pr, l, r] = pque.top(); pque.pop();
    auto [mi, idx] = pr;

    auto [mi2, idx2] = (idx&1?seg0:seg1).query( idx, r );

    ans.emplace_back( mi );
    ans.emplace_back( mi2 );

    pque.emplace( (l&1?seg1:seg0).query( l, idx ), l, idx );
    pque.emplace( ((idx+1)&1?seg1:seg0).query( idx+1, idx2 ), idx+1, idx2 );
    pque.emplace( ((idx2+1)&1?seg1:seg0).query( idx2+1, r ), idx2+1, r ); 
  }

  rep( i, ans.size() )
    std::cout << ans[i] << (i==ans.size()-1?'\n':' ');

  return 0;
}

Measured memory_bytes: 38324