#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using pl = pair<ll,ll>;
using pii = pair<int,int>;
using tpl = tuple<int,int,int>;
#define all(a) a.begin(), a.end()
#define filter(a) a.erase(unique(all(a)), a.end())
struct Fraction {
ll a, b;
Fraction() : a(0), b(1) {}
Fraction (ll a, ll b) : a(a), b(b) {
ll g = __gcd(abs(a), abs(b));
a /= g, b /= g;
}
bool operator< (const Fraction &o) const {
return a * o.b < o.a * b; // assume that both b and o.b > 0
}
bool operator== (const Fraction &o) const {
return a * o.b == o.a * b;
}
bool operator!= (const Fraction &o) const {
return a * o.b != o.a * b;
}
friend ostream& operator<< (ostream &oup, const Fraction &f) {
return oup << 1.0 * f.a / f.b, oup;
}
};
const int mn = 2e5 + 5;
int a[mn], b[mn];
multiset<int> sA, sB;
Fraction getFraction (int i, bool isA) {
int prv = *prev((isA ? sA : sB).lower_bound(i));
return isA ? Fraction(a[i] - a[prv], i - prv) : Fraction(b[i] - b[prv], i - prv);
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
int n, m; cin >> n >> m;
priority_queue<tuple<Fraction,int,int>> pq;
for (int i = 1; i <= n; i++) {
cin >> a[i], sA.insert(i);
if (i > 1) pq.emplace(Fraction(a[i] - a[i - 1], 1), i, 1);
}
for (int i = 1; i <= m; i++) {
cin >> b[i], sB.insert(i);
if (i > 1) pq.emplace(Fraction(b[i] - b[i - 1], 1), i, 0);
}
ll ans = 0, curX = n, curY = m;
while (pq.size()) {
Fraction u; int idx, isA; tie(u, idx, isA) = pq.top(); pq.pop();
multiset<int> &curSet = (isA ? sA : sB);
if (!curSet.count(idx) || getFraction(idx, isA) != u) continue;
curSet.erase(idx);
auto it = curSet.upper_bound(idx);
if (it != curSet.end()) pq.emplace(getFraction(*it, isA), *it, isA);
while (curX > *sB.rbegin()) curX--, ans += a[curY];
while (curY > *sA.rbegin()) curY--, ans += b[curX];
}
cout << ans << "\n";
return 0;
}