#include"stdio.h"
//归并源{并部分}
void mergearray(int T[],int first,int mid,int last,int temp[]){
int i = first;
int j = mid + 1;
int m = mid;
int n = last;
int k = 0;
while(i<=m && j<=n){
if(T[i]<=T[j])
temp[k++] = T[i++];
else
temp[k++] = T[j++];
}
while(i<=m)
temp[k++] = T[i++];
while(j<=n)
temp[k++] = T[j++];
for (i=0;i<k;i++){
T[first+i] = temp[i];
}
}
//归并源{递归部分}
void X_merge(int T[],int first,int last,int temp[]){
if (first<last){
int mid = (first + last)/2;
//左边递归
X_merge(T,first,mid,temp);
//右边递归
X_merge(T,mid+1,last,temp);
mergearray(T,first,mid,last,temp);
}
}
//归并排序api
void merge_sort(int T[],int N){
int Temp[N];
X_merge(T,0,N-1,Temp);
}
//希尔排序
void shell_sort(int T[],int N){
int a=N/2,i,y,x;
for(;a>0;a=a/2){
//插入排序改
for(i=a;i<N;i++){
y = T[i];
for(x=i;x>0;x=x-a){
if(y<T[x-a]){
T[x]=T[x-a];
if ((x-2*a)<0) {
T[x-a]=y;
break;
}
}
else{
T[x]= y;
break;
}
}
}
}
}
//插入排序
void insert_sort(int T[],int N){
int i,x,y;
for(i=1;i<N;i++){
y = T[i];
for(x=i;x>0;x--){
if(y<T[x-1]){
T[x]=T[x-1];
if (x==1) T[0]=y;
}
else{
T[x]= y;
break;
}
}
}
}
//冒泡排序
void bubble_sort(int T[],int N){
int i,x,y=N,c;
for(i=0;i<N-1;i++){
int flag = 0;
for(x=0;x<y-1;x++){
if(T[x]>T[x+1]){
c=T[x];
T[x]= T[x+1];
T[x+1]=c;
flag = 1;
}
}
y--;
if(flag == 0) break;
}
}
int main (){
int N;
scanf("%d",&N);
int T[N],i;
//保存数据
for(i=0;i<N;i++){
scanf("%d",&T[i]);
}
//冒泡排序
//bubble_sort(T,N) ;
//插入排序
//insert_sort(T,N);
//希尔排序
//shell_sort( T, N);
//归并排序
merge_sort(T,N);
for(i=0;i<N;i++){
if (i<N-1) printf("%d ",T[i]);
else printf("%d",T[i]);
}
return 0;
}