#include <cstdio>
#include <ctime>
#include <cstdlib>
struct item {
int key, priority;
int entries;
item* l;
item* r;
item() {
}
item(int _key, int _priority) {
key = _key;
priority = _priority;
entries = 1;
l = r = NULL;
}
};
typedef item* pitem;
// all elems <= key will be pointed to by l
void split(pitem t, int key, pitem& l, pitem& r) {
if (t == NULL) {
l = r = NULL;
return;
}
if (key < t -> key) {
split(t -> l, key, l, t -> l), r = t;
} else {
split(t -> r, key, t -> r, r), l = t;
}
}
// all values in l must be lower than the smallest value in r
void merge(pitem& t, pitem l, pitem r) {
if (l == NULL || r == NULL) {
t = (l == NULL) ? r : l;
return;
}
if (l -> priority > r -> priority) {
merge(l -> r, l -> r, r);
t = l;
} else {
merge(r -> l, l, r -> l);
t = r;
}
}
void insert(pitem& t, pitem it) {
if (t == NULL) {
t = it;
return;
}
if (it -> priority > t -> priority) {
split(t, it -> key, it -> l, it -> r);
t = it;
} else if (it -> key < t -> key) {
insert(t -> l, it);
} else {
insert(t -> r, it);
}
}
pitem search(pitem t, int key) {
if (t == NULL) {
return NULL;
}
if (t -> key == key) {
return t;
} else if (key < t -> key) {
return search(t -> l, key);
}
return search(t -> r, key);
}
void walkTree(pitem t) {
if (t == NULL) {
return;
}
walkTree(t -> l);
for (int entry = 0; entry < t -> entries; entry++) {
printf("%d ", t -> key);
}
walkTree(t -> r);
}
int main() {
freopen("algsort.in", "r", stdin);
freopen("algsort.out", "w", stdout);
srand(time(NULL));
pitem root = NULL;
int N, x;
scanf("%d", &N);
for (int i = 0; i < N; i++) {
scanf("%d", &x);
pitem corespItem = search(root, x);
if (corespItem != NULL) {
corespItem -> entries++;
} else {
insert(root, new item(x, rand()));
}
}
walkTree(root);
printf("\n");
return 0;
}