#include <fstream>
#include <algorithm>
#include <math.h>
#include <assert.h>
#define BUFFER_SIZE 1 << 17
char buffer[BUFFER_SIZE];
int pos = BUFFER_SIZE;
int n;
inline char next() {
if (pos == BUFFER_SIZE) {
fread(buffer, 1, BUFFER_SIZE, stdin);
pos = 0;
}
return buffer[pos++];
}
inline void print(int n) {
char snum[65];
int i = 0;
do {
snum[i++] = n % 10 + '0';
n /= 10;
} while (n);
--i;
while (i >= 0) {
putchar(snum[i--]);
}
putchar(' ');
}
inline int next_int() {
int n = 0;
char c = next();
while (!('0' <= c && c <= '9')) {
c = next();
}
while ('0' <= c && c <= '9') {
n = (n << 3) + (n << 1) + (c - '0');
c = next();
}
return n;
}
inline void swap(int *a, int *b) {
int *temp = std::move(a);
a = std::move(b);
b = std::move(temp);
}
inline int binarySearch(int a[], int item, int low, int high) {
if (high <= low)
return (item > a[low])? (low + 1): low;
int mid = (low + high)/2;
if(item == a[mid])
return mid+1;
if(item > a[mid])
return binarySearch(a, item, mid+1, high);
return binarySearch(a, item, low, mid-1);
}
inline void insertion_sort(int v[], int *begin, int *end) {
int left = begin - v;
int right = end - v;
int location, element, j;
for (int i = left + 1; i <= right ; ++i) {
element = v[i];
j = i - 1;
location = binarySearch(v, element, 0, j);
while ( j >= location) {
v[j + 1] = v[j];
--j;
}
v[j + 1] = element;
}
return;
}
inline int* partition(int v[], int low, int high) {
int pivot = v[high];
int i = low - 1;
for (int j = low ; j < high ; ++j) {
if (v[j] <= pivot) {
++i;
std::swap(v[i], v[j]);
}
}
std::swap(v[i + 1], v[high]);
return (v + i + 1);
}
inline int* median(int v[], int *a, int *b, int *c) {
int max = std::max(std::max(v[*a], v[*b]), v[*c]);
int min = std::min(std::min(v[*a], v[*b]), v[*c]);
int median = max ^ min ^ v[*a] ^ v[*b] ^ v[*c];
if (median == v[*a]) {
return a;
}
if (median == v[*b]) {
return b;
}
return c;
}
inline void intro_sort_utils(int v[], int *begin, int *end, int max_depth) {
int size = end - begin;
if (size < 16) {
insertion_sort(v, begin, end);
return;
}
if (max_depth == 0) {
std::make_heap(begin, end + 1);
std::sort_heap(begin, end + 1);
return;
}
int *pivot = median(v, begin, begin + size / 2, end);
swap(pivot, end);
int *partition_point = partition(v, begin - v, end - v);
intro_sort_utils(v, begin, partition_point - 1, max_depth - 1);
intro_sort_utils(v, partition_point + 1, end, max_depth - 1);
return;
}
inline void intro_sort(int v[], int *begin, int *end) {
int max_depth = 2 * log(end - begin);
intro_sort_utils(v, begin, end, max_depth);
return;
}
int main() {
freopen("algsort.in", "r", stdin);
freopen("algsort.out", "w", stdout);
n = next_int();
int v[n];
for (int i = 0 ; i < n ; ++i) {
v[i] = next_int();
}
intro_sort(v, v, v + n - 1);
for (int i = 0 ; i < n ; ++i) {
print(v[i]);
}
return 0;
}