# _*_ coding:utf-8 _*_

#  Atcoder_Beginners_Contest042-B

#  TODO https://atcoder.jp/contests/abc042/tasks/abc042_b

import time

from contextlib import contextmanager

# from time import sleep

@contextmanager

def timer(title):

	t0 = time.time()

	yield

	print(("{} - done in {:.0f}s".format(title,time.time()-t0) ))



def  makeString(givenStringCount):

	givenStringsList = []

	lineRange = list(range(0,givenStringCount,+1))

	for i in lineRange:

		givenStringsList.append(input().strip())

	givenStringsSortedList = sorted(givenStringsList,reverse=False)

	smallString = "".join(givenStringsSortedList)

	answer = smallString

	return answer





if __name__ == '__main__':

	N,_ = list(map(int,input().strip().split(' ')))

#	with timer("makeString"):

	solution=makeString(N)

	print(("{}".format(solution)))
# Problem: https://atcoder.jp/contests/abc042/tasks/abc042_b

# Python 1st Try



import sys

# from collections import defaultdict

# import heapq,copy

# from collections import deque





def II(): return int(sys.stdin.readline())





def MI(): return list(map(int, sys.stdin.readline().split()))





def LI(): return list(map(int, sys.stdin.readline().split()))





def LLI(rows_number): return [LI() for _ in range(rows_number)]





def solver(allNum, longLeng, eachString):

    result = ''

    eachString.sort()

    result = "".join(eachString)

    return result





if __name__ == "__main__":

    N, L = MI()

    SI = []

    for _ in range(0, N, +1):

        getStrList = sys.stdin.readline().split()

        SI.append(getStrList[0])

    print(("{}".format(solver(N, L, SI))))

# _*_ coding:utf-8 _*_
#  Atcoder_Beginners_Contest042-B
#  TODO https://atcoder.jp/contests/abc042/tasks/abc042_b
import time
from contextlib import contextmanager

# from time import sleep
@contextmanager
def timer(title):
    t0 = time.time()
    yield
    print(("{} - done in {:.0f}s".format(title, time.time() - t0)))


def makeString(givenStringCount):
    givenStringsList = []
    lineRange = list(range(0, givenStringCount, +1))
    for i in lineRange:
        givenStringsList.append(input().strip())
    givenStringsSortedList = sorted(givenStringsList, reverse=False)
    smallString = "".join(givenStringsSortedList)
    answer = smallString
    return answer


if __name__ == "__main__":
    N, _ = list(map(int, input().strip().split(" ")))
    # 	with timer("makeString"):
    solution = makeString(N)
    print(("{}".format(solution)))

# Problem: https://atcoder.jp/contests/abc042/tasks/abc042_b
# Python 1st Try
import sys

# from collections import defaultdict
# import heapq,copy
# from collections import deque
def II():
    return int(sys.stdin.readline())


def MI():
    return list(map(int, sys.stdin.readline().split()))


def LI():
    return list(map(int, sys.stdin.readline().split()))


def LLI(rows_number):
    return [LI() for _ in range(rows_number)]


def solver(allNum, longLeng, eachString):
    result = ""
    eachString.sort()
    result = "".join(eachString)
    return result


if __name__ == "__main__":
    N, L = MI()
    SI = []
    for _ in range(0, N, +1):
        getStrList = sys.stdin.readline().split()
        SI.append(getStrList[0])
    print(("{}".format(solver(N, L, SI))))

-# _*_ coding:utf-8 _*_ -#  Atcoder_Beginners_Contest042-B -#  TODO https://atcoder.jp/contests/abc042/tasks/abc042_b -import time -from contextlib import contextmanager +# Problem: https://atcoder.jp/contests/abc042/tasks/abc042_b +# Python 1st Try +import sys -# from time import sleep -@contextmanager -def timer(title): -    t0 = time.time() -    yield -    print(("{} - done in {:.0f}s".format(title, time.time() - t0))) +# from collections import defaultdict +# import heapq,copy +# from collections import deque +def II(): +    return int(sys.stdin.readline()) -def makeString(givenStringCount): -    givenStringsList = [] -    lineRange = list(range(0, givenStringCount, +1)) -    for i in lineRange: -        givenStringsList.append(input().strip()) -    givenStringsSortedList = sorted(givenStringsList, reverse=False) -    smallString = "".join(givenStringsSortedList) -    answer = smallString -    return answer +def MI(): +    return list(map(int, sys.stdin.readline().split())) + + +def LI(): +    return list(map(int, sys.stdin.readline().split())) + + +def LLI(rows_number): +    return [LI() for _ in range(rows_number)] + + +def solver(allNum, longLeng, eachString): +    result = "" +    eachString.sort() +    result = "".join(eachString) +    return result -    N, _ = list(map(int, input().strip().split(" "))) -    # 	with timer("makeString"): -    solution = makeString(N) -    print(("{}".format(solution))) +    N, L = MI() +    SI = [] +    for _ in range(0, N, +1): +        getStrList = sys.stdin.readline().split() +        SI.append(getStrList[0]) +    print(("{}".format(solver(N, L, SI))))