#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>
using namespace std;
// Używamy stałej do oznaczania nieskończoności dla porównań min/max
const int INF = 1e9;
int main() {
// Optymalizacja wejścia/wyjścia (dla dużych danych)
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n, m;
if (!(cin >> n >> m)) return 0;
vector<int> A(n);
vector<int> B(m);
// Wczytanie stosu 1 (od spodu do góry)
for (int i = 0; i < n; i++) cin >> A[i];
// Wczytanie stosu 2 (od spodu do góry)
for (int i = 0; i < m; i++) cin >> B[i];
// ODWRACAMY tablice, aby indeks 0 oznaczał górę stosu (pierwszy do zdjęcia)
reverse(A.begin(), A.end());
reverse(B.begin(), B.end());
// Tablica DP: dp[i][j] przechowuje wynik dla stanu, gdzie
// zdjęto 'i' naleśników z lewego stosu i 'j' z prawego.
// Rozmiar to (n+1) x (m+1)
vector<vector<int>> dp(n + 1, vector<int>(m + 1));
// Wypełniamy tablicę od końca (od momentu, gdy talerze są puste)
for (int i = n; i >= 0; i--) {
for (int j = m; j >= 0; j--) {
// Stan końcowy: oba talerze puste -> suma 0
if (i == n && j == m) {
dp[i][j] = 0;
continue;
}
// Sprawdzamy czyja tura.
// Liczba wykonanych ruchów to (i + j).
// Jeśli parzysta -> Bajtek (zaczyna od 0).
bool bajtekTurn = ((i + j) % 2 == 0);
if (bajtekTurn) {
// Tura Bajtka: Chce ZMAKSYMALIZOWAĆ swoją sumę
int opcjaA = -INF, opcjaB = -INF;
// Jeśli może wziąć ze stosu A
if (i < n) opcjaA = A[i] + dp[i + 1][j];
// Jeśli może wziąć ze stosu B
if (j < m) opcjaB = B[j] + dp[i][j + 1];
dp[i][j] = max(opcjaA, opcjaB);
} else {
// Tura Bitka: Chce ZMINIMALIZOWAĆ sumę Bajtka
// Bitek bierze naleśnik dla siebie, więc do sumy Bajtka dodajemy 0 (tylko przechodzimy do nast. stanu)
int opcjaA = INF, opcjaB = INF;
if (i < n) opcjaA = dp[i + 1][j];
if (j < m) opcjaB = dp[i][j + 1];
dp[i][j] = min(opcjaA, opcjaB);
}
}
}
// Wynik dla stanu początkowego (0 zdjętych naleśników)
cout << dp[0][0] << endl;
return 0;
}