#pragma GCC optimize("Ofast,unroll-loops")
#pragma GCC target("sse,sse2,sse3,sse4,sse4.1,sse4.2,abm,bmi,bmi2,popcnt,lzcnt,avx,avx2,fma")
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stack>
#include <vector>
#include <string>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
#include <cmath>
#include <time.h>
#include <deque>
#define ll long long
#define t_c_b ios_base::sync_with_stdio (0);cin.tie (0);cout.tie (0);long long n;cin >> n;vector <int> g (n);for (long long i = 0; i < n; i++) {cin >> g[i];}
using namespace std;
using loh = long long; // loh
using flag = bool;
using lohd = long double; // short (4bite) // dolik loh

bool comporator (pair <int, int> a, pair <int, int> b) {
	if (a.first > b.first) return true;
	if (a.first == b.first && a.second < b.second) return true;
	return false;
}
int main () <%
	t_c_b;
	vector <pair <int, int> > G;
	multiset <int> Set;
	for (int i = 0; i < n; ++i) {
		Set.insert (g[i]);
	%>
	while (!Set.empty ()) {
		G.push_back ({ Set.count (*Set.begin ()), *Set.begin () });
		Set.erase (*Set.begin ());
	}
	sort (G.begin (), G.end (), comporator);
	if (G[0].first > n/2) {
		cout << -1; return 0;
	}
	vector <int> tree (n);
	ll itter = 1;
	for (int i = 0; i < n; ++i) {
		if (i == 0) {
			tree[0] = G[0].second;
		}
		else {
			if (i&1) {
				tree[i] = tree[i / 2];
			}
			else {
				tree[i] = G[itter].second;
				itter++;
			}
		}
	}
	vector <int> tree_copy = tree;
	sort (tree_copy.begin (), tree_copy.end ());
	sort (g.begin (), g.end ());
	if (g != tree_copy){
		cout << -1;
		return 0;
	}
	for (int i = 1; i < n; ++i) {
		if (i & 1) {
			if (tree[i / 2] != min (tree[i], tree[i + 1]) || tree[i]==tree[i+1]) {
				cout << -1;
				return 0;
			}
		}
		else {
			i--;
			if (tree[i / 2] != min (tree[i], tree[i + 1]) || tree[i] == tree[i + 1]) {
				cout << -1;
				return 0;
			}
			i++;
		}
	}
	for (int i = n/2; i < n; ++i) {
		cout << tree[i] << " ";
	}
}