#include <bits/stdc++.h>
using namespace std;

struct Node{
  int val;
  Node *next;
};

class List{
    public:
    Node *head, *tail;
    
    List(){
        head = tail = NULL;
    }
    
    Node *getNode(int &data){
        Node *nn = new Node;
        nn->val = data;
        nn->next = NULL;
        return nn;
    }
    
    void insertNode(int &data){
        if(!head){
            head = tail = getNode(data);
            return;
        }
        
        tail->next = getNode(data);
        tail = tail->next;
    }
    
    void mergeSort() {
        head = mergeSortHelper(head);
    }
    
    Node *mergeSortHelper(Node *start){
        if(start && start->next){
            
            Node *mid = divideList(start);
            
            Node *first = mergeSortHelper(start);
            Node *second = mergeSortHelper(mid);
            
            return mergeListsRecur(NULL, first, NULL, second);
        }
        else{
            return start;
        }
    }
/*========================== Iterative Merge =============================*/  
    Node *mergeListsIter(Node* head1, Node* head2) {
        
        if(!head1)
            return head2;
        
        if(!head2)
            return head1;
        
        Node *c1 = head1, *c2 = head2, *p1=NULL, *p2=NULL;

        while(c1 && c2){
            if(c1->val > c2->val){

                if(!p1 && !p2){
                    p2 = c2;
                    c2 = c2->next;

                    p2->next = c1;
                    p1 = p2;
                    p2 = NULL;

                    head1 = p1;
                }
                else if(!p2){
                    p2 = c2;
                    c2 = c2->next;

                    p2->next = c1;
                    p1->next = p2;
                    p1 = p2;
                    p2 = NULL;
                }
            }
            else{
                p1 = c1;
                c1 = c1->next;
            }
        }

        if(!c1 && c2){
            p1->next = c2;
            c2 = NULL;
        }

        return head1;
    }
/*========================== Iterative Merge =============================*/  
    
/*========================== Recursive Merge =============================*/  
    Node *mergeListsRecur(Node *p1, Node *h1, Node* p2, Node *h2){
        
        if(!p1 && !h1)
            return h2;
        
        if(!p2 && !h2)
            return h1;
        
        if(p1 && !h1){
            p1->next = h2;
            return NULL;
        }
        
        if(p2 && !h2){
            return NULL;
        }
        
        Node *start = NULL;
        
        if(h1->val > h2->val){
            Node *nxt = h2->next;
            h2->next = h1;
            
            if(!p1 && !p2){
                start = h2;
            }
            else if(!p2){
                p1->next = h2;
            }
            
            mergeListsRecur(h2, h1, p2, nxt);
        }
        else{
            mergeListsRecur(h1, h1->next, p2, h2);    
        }
        
        return start ? start : h1;
    }
/*========================== Recursive Merge =============================*/  

    Node *divideList(Node *ptr){
        Node *prev = NULL, *slow = ptr, *fast = ptr;
        
        while(fast && fast->next){
            prev = slow;
            slow = slow->next;
            fast = fast->next->next;
        }
        
        if(prev)
            prev->next = NULL;
        
        return slow;
    }
        
    void printList(){
        Node *curr = head;
        
        while(curr){
            cout<<curr->val;
            curr = curr->next;
            
            if(curr)
            	cout<<"->";
        }
    }
};

int main() {
    int n;
    cin>>n;
    
    int data;
    
    List lst;
        
    for(int i = 0; i < n; ++i){
        cin>>data;
        lst.insertNode(data);
    }
    
    lst.mergeSort();
    
    lst.printList();
    
    return 0;
}