import os

import sys



if os.getenv("LOCAL"):

    sys.stdin = open("_in.txt", "r")



sys.setrecursionlimit(2147483647)

INF = float("inf")

IINF = 10 ** 18

MOD = 10 ** 9 + 7



# あああああああああああくそHとWぎゃくだ

W,H = list(map(int, sys.stdin.readline().split()))

P = [int(sys.stdin.readline()) for _ in range(W)]

Q = [int(sys.stdin.readline()) for _ in range(H)]



edges = []

for p in P:

    edges.append((p, 'P'))

for q in Q:

    edges.append((q, 'Q'))

edges.sort()



ans = 0

a = W + 1

b = H + 1

for e, pq in edges:

    if pq == 'P':

        ans += e * b

        a -= 1

    else:

        ans += e * a

        b -= 1

print(ans)

import itertools

import os

import sys



if os.getenv("LOCAL"):

    sys.stdin = open("_in.txt", "r")



sys.setrecursionlimit(2147483647)

INF = float("inf")

IINF = 10 ** 18

MOD = 10 ** 9 + 7





class UnionFind:

    def __init__(self, size=None, nodes=None):

        """

        size か nodes どっちか指定。

        nodes は set、size は list を使う。

        set の最悪計算量は O(N) なので size 指定のほうが若干速い

        :param int size:

        :param collections.Iterable nodes:

        """

        assert size is not None or nodes is not None

        if size is not None:

            self._parents = [i for i in range(size)]

            self._ranks = [0 for _ in range(size)]

            self._sizes = [1 for _ in range(size)]

        else:

            self._parents = {k: k for k in nodes}

            self._ranks = {k: 0 for k in nodes}

            self._sizes = {k: 1 for k in nodes}



    def unite(self, x, y):

        """

        x が属する木と y が属する木を併合

        :param x:

        :param y:

        :return:

        """

        x = self.root(x)

        y = self.root(y)

        if x == y:

            return



        # rank が小さい方が下

        if self._ranks[x] > self._ranks[y]:

            # x が root

            self._parents[y] = x

            self._sizes[x] += self._sizes[y]

        else:

            # y が root

            self._parents[x] = y

            self._sizes[y] += self._sizes[x]

            if self._ranks[x] == self._ranks[y]:

                self._ranks[y] += 1



    def root(self, x):

        """

        x が属する木の root

        :param x:

        :return:

        """

        if self._parents[x] == x:

            return x

        self._parents[x] = self.root(self._parents[x])

        return self._parents[x]



    def size(self, x):

        """

        x が属する木のノード数

        :param x:

        :return:

        """

        return self._sizes[self.root(x)]





W, H = list(map(int, sys.stdin.readline().split()))

P = [int(sys.stdin.readline()) for _ in range(W)]

Q = [int(sys.stdin.readline()) for _ in range(H)]





def test():

    edges = []

    vs = []

    for h, w in itertools.product(list(range(H + 1)), list(range(W + 1))):

        if w < W:

            edges.append((P[w], (w, h), (w + 1, h)))

        if h < H:

            edges.append((Q[h], (w, h), (w, h + 1)))

    for h, w in itertools.product(list(range(H + 1)), list(range(W + 1))):

        vs.append((w, h))

    edges.sort()



    # kruskal

    uf = UnionFind(nodes=vs)

    ret = 0

    for s, v, u in edges:

        if uf.root(v) != uf.root(u):

            uf.unite(v, u)

            ret += s

    return ret





# 横棒

hs = P.copy()

# 縦棒

vs = Q.copy()



hs.sort(reverse=True)

vs.sort(reverse=True)



ans = 0

v_nodes = W + 1

h_nodes = H + 1

while hs or vs:

    if not vs or (hs and hs[-1] < vs[-1]):

        # 横棒を使う

        # まだくっつけてない横軸の数だけ辺を張る

        ans += hs.pop() * h_nodes

        v_nodes -= 1

    else:

        # 縦棒のが短い

        ans += vs.pop() * v_nodes

        h_nodes -= 1

print(ans)



# print(test())

import os
import sys

if os.getenv("LOCAL"):
    sys.stdin = open("_in.txt", "r")
sys.setrecursionlimit(2147483647)
INF = float("inf")
IINF = 10**18
MOD = 10**9 + 7
# あああああああああああくそHとWぎゃくだ
W, H = list(map(int, sys.stdin.readline().split()))
P = [int(sys.stdin.readline()) for _ in range(W)]
Q = [int(sys.stdin.readline()) for _ in range(H)]
edges = []
for p in P:
    edges.append((p, "P"))
for q in Q:
    edges.append((q, "Q"))
edges.sort()
ans = 0
a = W + 1
b = H + 1
for e, pq in edges:
    if pq == "P":
        ans += e * b
        a -= 1
    else:
        ans += e * a
        b -= 1
print(ans)

import itertools
import os
import sys

if os.getenv("LOCAL"):
    sys.stdin = open("_in.txt", "r")
sys.setrecursionlimit(2147483647)
INF = float("inf")
IINF = 10**18
MOD = 10**9 + 7


class UnionFind:
    def __init__(self, size=None, nodes=None):
        """
        size か nodes どっちか指定。
        nodes は set、size は list を使う。
        set の最悪計算量は O(N) なので size 指定のほうが若干速い
        :param int size:
        :param collections.Iterable nodes:
        """
        assert size is not None or nodes is not None
        if size is not None:
            self._parents = [i for i in range(size)]
            self._ranks = [0 for _ in range(size)]
            self._sizes = [1 for _ in range(size)]
        else:
            self._parents = {k: k for k in nodes}
            self._ranks = {k: 0 for k in nodes}
            self._sizes = {k: 1 for k in nodes}

    def unite(self, x, y):
        """
        x が属する木と y が属する木を併合
        :param x:
        :param y:
        :return:
        """
        x = self.root(x)
        y = self.root(y)
        if x == y:
            return
        # rank が小さい方が下
        if self._ranks[x] > self._ranks[y]:
            # x が root
            self._parents[y] = x
            self._sizes[x] += self._sizes[y]
        else:
            # y が root
            self._parents[x] = y
            self._sizes[y] += self._sizes[x]
            if self._ranks[x] == self._ranks[y]:
                self._ranks[y] += 1

    def root(self, x):
        """
        x が属する木の root
        :param x:
        :return:
        """
        if self._parents[x] == x:
            return x
        self._parents[x] = self.root(self._parents[x])
        return self._parents[x]

    def size(self, x):
        """
        x が属する木のノード数
        :param x:
        :return:
        """
        return self._sizes[self.root(x)]


W, H = list(map(int, sys.stdin.readline().split()))
P = [int(sys.stdin.readline()) for _ in range(W)]
Q = [int(sys.stdin.readline()) for _ in range(H)]


def test():
    edges = []
    vs = []
    for h, w in itertools.product(list(range(H + 1)), list(range(W + 1))):
        if w < W:
            edges.append((P[w], (w, h), (w + 1, h)))
        if h < H:
            edges.append((Q[h], (w, h), (w, h + 1)))
    for h, w in itertools.product(list(range(H + 1)), list(range(W + 1))):
        vs.append((w, h))
    edges.sort()
    # kruskal
    uf = UnionFind(nodes=vs)
    ret = 0
    for s, v, u in edges:
        if uf.root(v) != uf.root(u):
            uf.unite(v, u)
            ret += s
    return ret


# 横棒
hs = P.copy()
# 縦棒
vs = Q.copy()
hs.sort(reverse=True)
vs.sort(reverse=True)
ans = 0
v_nodes = W + 1
h_nodes = H + 1
while hs or vs:
    if not vs or (hs and hs[-1] < vs[-1]):
        # 横棒を使う
        # まだくっつけてない横軸の数だけ辺を張る
        ans += hs.pop() * h_nodes
        v_nodes -= 1
    else:
        # 縦棒のが短い
        ans += vs.pop() * v_nodes
        h_nodes -= 1
print(ans)
# print(test())

+import itertools -# あああああああああああくそHとWぎゃくだ + + +class UnionFind: +    def __init__(self, size=None, nodes=None): +        """ +        size か nodes どっちか指定。 +        nodes は set、size は list を使う。 +        set の最悪計算量は O(N) なので size 指定のほうが若干速い +        :param int size: +        :param collections.Iterable nodes: +        """ +        assert size is not None or nodes is not None +        if size is not None: +            self._parents = [i for i in range(size)] +            self._ranks = [0 for _ in range(size)] +            self._sizes = [1 for _ in range(size)] +        else: +            self._parents = {k: k for k in nodes} +            self._ranks = {k: 0 for k in nodes} +            self._sizes = {k: 1 for k in nodes} + +    def unite(self, x, y): +        """ +        x が属する木と y が属する木を併合 +        :param x: +        :param y: +        :return: +        """ +        x = self.root(x) +        y = self.root(y) +        if x == y: +            return +        # rank が小さい方が下 +        if self._ranks[x] > self._ranks[y]: +            # x が root +            self._parents[y] = x +            self._sizes[x] += self._sizes[y] +        else: +            # y が root +            self._parents[x] = y +            self._sizes[y] += self._sizes[x] +            if self._ranks[x] == self._ranks[y]: +                self._ranks[y] += 1 + +    def root(self, x): +        """ +        x が属する木の root +        :param x: +        :return: +        """ +        if self._parents[x] == x: +            return x +        self._parents[x] = self.root(self._parents[x]) +        return self._parents[x] + +    def size(self, x): +        """ +        x が属する木のノード数 +        :param x: +        :return: +        """ +        return self._sizes[self.root(x)] + + -edges = [] -for p in P: -    edges.append((p, "P")) -for q in Q: -    edges.append((q, "Q")) -edges.sort() + + +def test(): +    edges = [] +    vs = [] +    for h, w in itertools.product(list(range(H + 1)), list(range(W + 1))): +        if w < W: +            edges.append((P[w], (w, h), (w + 1, h))) +        if h < H: +            edges.append((Q[h], (w, h), (w, h + 1))) +    for h, w in itertools.product(list(range(H + 1)), list(range(W + 1))): +        vs.append((w, h)) +    edges.sort() +    # kruskal +    uf = UnionFind(nodes=vs) +    ret = 0 +    for s, v, u in edges: +        if uf.root(v) != uf.root(u): +            uf.unite(v, u) +            ret += s +    return ret + + +# 横棒 +hs = P.copy() +# 縦棒 +vs = Q.copy() +hs.sort(reverse=True) +vs.sort(reverse=True) -a = W + 1 -b = H + 1 -for e, pq in edges: -    if pq == "P": -        ans += e * b -        a -= 1 +v_nodes = W + 1 +h_nodes = H + 1 +while hs or vs: +    if not vs or (hs and hs[-1] < vs[-1]): +        # 横棒を使う +        # まだくっつけてない横軸の数だけ辺を張る +        ans += hs.pop() * h_nodes +        v_nodes -= 1 -        ans += e * a -        b -= 1 +        # 縦棒のが短い +        ans += vs.pop() * v_nodes +        h_nodes -= 1 +# print(test())