#include<bits/stdc++.h>
using namespace std;
template<typename T>
class FibHeap {
private:
struct node {
T data;
bool mark;
int degree;
node *left, *right;
node *child, *parent;
node() {
mark = false;
degree = 0;
child = parent = nullptr;
left = right = this;
}
};
unsigned size;
node *min;
node *head;
T MIN_VALUE;
void LeftInsert(node *base, node *tmp) {
tmp->left = base->left;
tmp->right = base;
base->left->right = tmp;
base->left = tmp;
}
void link(node *y, node *x) {
y->left->right = y->right;
y->right->left = y->left;
y->parent = x;
if (x->child == nullptr) {
x->child = y;
y->left = y->right = y;
} else LeftInsert(x->child, y);
x->degree++;
y->mark = false;
}
void Consolidate() {
int Dn = (int)log2(size) + 1;
node **nodes = new node*[Dn];
for (int i = 0; i < Dn; i++)
nodes[i] = nullptr;
node *ptr = head->right, *nxt;
do {
int d;
node *x, *y;
x = ptr;
if (x == head) continue;
d = x->degree;
nxt = ptr->right;
while (nodes[d] != nullptr) {
y = nodes[d];
if (x->data > y->data)
std::swap(x, y);
link(y, x);
nodes[d] = nullptr;
d++;
}
nodes[d] = x;
ptr = nxt;
} while (ptr != head);
min = nullptr;
head->left = head->right = head;
for (int i = 0; i < Dn; i++) {
if (nodes[i] != nullptr) {
if (min == nullptr) {
min = nodes[i];
LeftInsert(head, min);
} else {
LeftInsert(head, nodes[i]);
if (nodes[i]->data < min->data)
min = nodes[i];
}
}
}
}
public:
FibHeap() {
size = 0;
min = nullptr;
head = new node;
}
FibHeap(T MIN_VALUE) {
size = 0;
min = nullptr;
head = new node;
this->MIN_VALUE = MIN_VALUE;
}
T GetMin() {
return min->data;
}
int Size() {
return size;
}
void Insert(node *data) {
if (min == nullptr) {
min = data;
LeftInsert(head, min);
} else {
LeftInsert(min, data);
if (data->data < min->data) {
min = data;
}
}
size++;
}
void Insert_(T data) {
node *tmp = new node;
tmp->degree = 0;
tmp->data = data;
tmp->parent = tmp->child = nullptr;
tmp->left = tmp->right = tmp;
tmp->mark = false;
if (min == nullptr) {
min = tmp;
LeftInsert(head, min);
} else {
LeftInsert(min, tmp);
if (data < min->data)
min = tmp;
}
size++;
}
FibHeap<T> Merge(FibHeap<T> H2) {
node *ptr = head->right;
do {
node *rb = ptr->right;
H2.Insert(ptr);
ptr = rb;
} while (ptr != head);
if (H2.min == nullptr || (min != nullptr && min->data < H2.GetMin()))
H2.min = min;
return H2;
}
T DeleteMin() {
T ret = min->data;
node *ptr = min;
if (ptr != nullptr) {
node *tmp = min->child, *nxt;
for (int i = 0; i < min->degree; i++) {
nxt = tmp->right;
LeftInsert(head, tmp);
tmp = nxt;
}
ptr->left->right = ptr->right;
ptr->right->left = ptr->left;
if (ptr == ptr->right)
min = nullptr;
else {
min = min->right;
if (min == head) min = min->right;
Consolidate();
}
size--;
}
return ret;
}
void Cut(node *x, node *y) {
if (y->degree == 1)
y->child = nullptr;
else {
x->left->right = x->right;
x->right->left = x->left;
}
y->degree--;
LeftInsert(head, x);
x->parent = nullptr;
x->mark = false;
}
void CascadingCut(node *y) {
node *z = y->parent;
if (z != nullptr) {
if (y->mark == false)
y->mark = true;
else {
Cut(y, z);
CascadingCut(z);
}
}
}
void DecreaseKey(node *x, T key) {
if (key >= x->data) return;
x->data = key;
node *y = x->parent;
if (y != nullptr && x->data < y->data) {
Cut(x, y);
CascadingCut(y);
}
if (x->data < min->data)
min = x;
}
void Delete(node *x) {
DecreaseKey(x, MIN_VALUE);
DeleteMin();
}
};
const int inf = 0x3f3f3f3f;
FibHeap<pair<int, int> > heap;
int a[100010];
int n;
int main() {
cin>>n;
for(int i = 1;i<=n;++i)cin>>a[i] , heap.Insert_(make_pair(a[i],i)) ;
for(int i = 1;i<=n;++i) {
int min_idx = heap.GetMin().second;
cout<<a[min_idx]<<' ';
heap.DeleteMin();
}
}