Problem:
D - インビジブル
Problem Statement
あなたは友達と"
インビジブル
"というカードゲームを遊ぼうとしている．
このカードゲームでは，"
得点カード
"と"
妨害カード
"という2種類のカードを使う．
それぞれの得点カードには，正の値が書かれている．このカードゲームのルールは次の通りである．
ゲームはプレイヤー1とプレイヤー2の2人のプレイヤーで行われる．ゲームはプレイヤー1のターンから始まる．
場には，1つのスタックと2つのデッキがある．スタックは，2人のプレイヤーが置いたカードからなる．また，それぞれのプレイヤーが持つデッキはそのプレイヤーが持つ得点カードと妨害カードからなる．プレイヤーは自分，もしくは相手デッキのカードの順番をいつでも確認できる．ゲームの開始時点ではスタックには1枚もカードはない．
2人のプレイヤーは交互に次の2つの行動のどちらかをちょうど1回行う．
自分のデッキの一番上のカードをスタックの一番上に置く．ただし，この行動は自分のデッキにカードが1枚も存在しない時には行うことができない．
自分のターンをパスする．
プレイヤーがターンをパスした時，次の処理を行う．
各プレイヤーは次の2つの条件を満たすスタック中のすべての得点カードを得る．得た得点カードは場から取り除かれる．
自分がスタックにおいた得点カードである．
相手が置いたどの妨害カードよりも上にある (スタック中に相手の妨害カードが存在しないとき，プレイヤーは自分がスタックに置いたすべてのカードを得る)．
スタックのカードをすべて取り除く．
もしスタックにカードがない状態で両プレイヤーが連続してパスした場合，ゲームを終了する．
各プレイヤーの最終的なスコアは，各プレイヤーが得た得点カードに書かれた数の総和である．
各プレイヤーは，自分のスコアから相手のスコアを引いた値を最大化するために最適な行動をとる．
あなたの仕事は，与えられた各プレイヤーのデッキに対し，各プレイヤーが最適に行動したときのプレイヤー1のスコアとプレイヤー2のスコアの差を計算することである．
Input
入力は次のような形式の単一テストケースからなる．
$n$ $m$
$a_1$ $a_2$ $\dots$ $a_n$
$b_1$ $b_2$ $\dots$ $b_m$
1行目は山札の枚数を表す正の整数 $n$, $m$ ($1 \le n, m \le 50$) からなる．
2行目は $n$ 個の整数からなり，$a_i$ はプレイヤー1のデッキの上から $i$ 番目のカードを表す ($1 \le i \le n$)．$a_i$ は $1$ 以上，$1{,}000{,}000$ 以下，または $-1$ である．
3行目は $m$ 個の整数からなり，$b_j$ はプレイヤー2のデッキの上から $j$ 番目のカードを表す ($1 \le j \le m$)．$b_j$ は $1$ 以上，$1{,}000{,}000$ 以下，または $-1$ である．
$a_i$, $b_j$ が正の整数の時は得点カードを表し，$-1$ の時は妨害カードを表す．
Output
お互いのプレイヤーが最適に行動した時の (プレイヤー1のスコア) - (プレイヤー2のスコア) を出力せよ．
Sample Input 1
2 2
100 -1
200 300
Output for the Sample Input 1
-100
Sample Input 2
3 5
10 30 -1
-1 90 20 10 -1
Output for the Sample Input 2
0
Sample Input 3
4 5
15 20 10 30
50 30 10 20 25
Output for the Sample Input 3
-60

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
      
#define FOR(i,a,b) for( ll i = (a); i < (ll)(b); i++ )
#define REP(i,n) FOR(i,0,n)
#define YYS(x,arr) for(auto& x:arr)
#define ALL(x) (x).begin(),(x).end()
#define SORT(x) sort( (x).begin(),(x).end() )
#define REVERSE(x) reverse( (x).begin(),(x).end() )
#define UNIQUE(x) (x).erase( unique( ALL( (x) ) ) , (x).end() )
#define PW(x) (1LL<<(x))
#define SZ(x) ((ll)(x).size())
#define SHOW(x) cout << #x << " = " << x << endl
#define SHOWA(x,n) for( int yui = 0; yui < n; yui++ ){ cout << x[yui] << " "; } cout << endl

#define pb emplace_back
#define fi first
#define se second

using namespace std;

typedef long double ld;
typedef long long int ll;
typedef pair<int,int> pi;
typedef pair<ll,ll> pl;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<bool> vb;
typedef vector<ld> vd;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<vpl> gr;
typedef vector<vl> ml;
typedef vector<vd> md;
typedef vector<vi> mi;
     
const ll INF = (ll)1e9 + 10;
const ll INFLL = (ll)1e18 + 10;
const ld EPS = 1e-12;
const ll MOD = 1e9+7;
     
template<class T> T &chmin( T &a , const T &b ){ return a = min(a,b); }
template<class T> T &chmax( T &a , const T &b ){ return a = max(a,b); }
template<class T> inline T sq( T a ){ return a * a; }

ll in(){ long long int x; scanf( "%lld" , &x ); return x; }
char yuyushiki[1000010]; string stin(){ scanf( "%s" , yuyushiki ); return yuyushiki; }

// head

const int N = 52;
const int M = 102;

int n, m;
int a[N];
int b[N];

int dp[N][N][M][2][2][2];
bool used[N][N][M][2][2][2];

int f( int l , int r , int sz , int t , int turn, int pass ){
  if( l == n && r == m ){
    return 0;
  }
  if( used[l][r][sz][t][turn][pass] ){
    return dp[l][r][sz][t][turn][pass];
  }
  used[l][r][sz][t][turn][pass] = true;
  vpi card(0);
  int cl = l;
  int cr = r;
  int ct = t;
  REP( i , sz ){
    if( ct == 0 ){
      card.pb( a[cl++] , 0 );
    } else {
      card.pb( b[cr++] , 1 );
    }
    ct = 1 - ct;
  }
  int res;
  if( turn == 0 ){
    res = -INF;
  } else if( turn == 1 ){
    res = INF;
  } else {
    assert( false );
  }
  // put
  if( turn == 0 ){
    if( cl < n ){
      chmax( res , f( l , r , sz+1, t , 1 - turn , 0 ) );
    }
  } else if( turn == 1 ){
    if( cr < m ){
      chmin( res , f( l , r , sz+1, t , 1 - turn , 0 ) );
    }
  } else {
    assert( false );
  }
  // pass
  if( pass == 1 ){
    if( turn == 0 ){
      chmax( res , 0 );
    } else if( turn == 1 ){
      chmin( res , 0 );
    } else {
      assert( false );
    }
  } else {
    int pl = 0;
    int pr = 0;
    bool fl = false;
    bool fr = false;
    REVERSE( card );
    YYS( w , card ){
      if( w.fi == -1 ){
        if( w.se == 0 ){
          fr = true;
        } else if( w.se == 1 ){
          fl = true;
        } else {
          assert( false );
        }
      } else {
        if( w.se == 0 && !fl ){
          pl += w.fi;
        } else if( w.se == 1 && !fr ){
          pr += w.fi;
        }
      }
    }
    int npass = 0;
    if( sz == 0 ){
      npass = 1;
    }
    if( turn == 0 ){
      chmax( res , pl-pr+f( cl , cr , 0 , 1-turn , 1-turn , npass ) );
    } else {
      chmin( res , pl-pr+f( cl , cr , 0 , 1-turn , 1-turn , npass ) );
    }
    /*
    if( l == 0 && r == 0 && sz == 6 && t == 0 && turn == 0 && pass == 0 ){
      cout << res << endl;
    }
    */
    // cout << l << " " << r << " " << sz << " " << t << " " << turn << " " << res << " " << pl << " " << pr << endl;
  }
  return dp[l][r][sz][t][turn][pass] = res;
}

int main(){

  n = in();
  m = in();
  REP( i , n ){
    a[i] = in();
  }
  REP( i , m ){
    b[i] = in();
  }

  printf( "%d\n" , f( 0 , 0 , 0 , 0 , 0 , 0 ) );
  
  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 14208
final_rank: 4

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

// #ifndef ONLINE_JUDGE
// #define _GLIBCXX_DEBUG // 配列外参照のエラー
// #endif

// スタンダードライブラリ
#include <bits/stdc++.h>
using namespace std;

// 型関連
using ll = long long;
using lint = long long;
using pll = pair<ll, ll>;
using plll = tuple<ll, ll, ll>;
using pii = pair<int, int>;
using piii = tuple<ll, ll, ll>;
using vi = vector<int>;
using vvi = vector<vector<int>>;
using vvvi = vector<vector<vector<int>>>;
using vvvvi = vector<vector<vector<vector<int>>>>;
using vl = vector<ll>;
using vvl = vector<vector<ll>>;
using vvvl = vector<vector<vector<ll>>>;
using vvvvl = vector<vector<vector<vector<ll>>>>;

template <class T> using prique = priority_queue<T>;

// 型定数
constexpr ll mod = 998244353;
constexpr ll MOD = 1000000007;
int INF32 = 2e9;
ll INF64 = 9e18;
#define endl '\n';

int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

/////////////////////////// print関連
template <typename T> void print(vector<T> A);
void print();
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail);
void print(string S);
template <typename T> void print(vector<vector<T>> &F);

inline void Yes(bool f);

///////////////////ここから//////////////////////
bool solve() {
    int N, M;
    cin >> N >> M;
    vi A(N), B(M);
    for (int i = 0; i < N; i++) {
        cin >> A[i];
    }
    for (int i = 0; i < M; i++) {
        cin >> B[i];
    }


    map<array<int, 6>, ll> memo;
    auto rec = [&](auto rec, int i, int j, int a, int b, int f, int p) -> ll {
        array<int, 6> key = {i, j, a, b, f, p};
        if (memo.count(key)) {
            return memo[key];
        }
        if (p == 3) {
            return 0;
        }
        ll val = -INF64;

        if (f == 0) {
            if (i < N ) {
                ll score = 0, nval = 0;
                if (A[i] == -1) {
                    nval = rec(rec, i + 1, j, a, j, 1, 0);
                } else {
                    nval = rec(rec, i + 1, j, a, b, 1, 0);
                }

                val = max(val, score - nval);
            }
            ll score = 0, nval = 0;
            for (int k = a; k < i; k++) {
                if (A[k] != -1) {
                    score += A[k];
                }
            }
            for (int k = b; k < j; k++) {
                if (B[k] != -1)
                    nval += B[k];
            }

            nval += rec(rec, i, j, i, j, 1, p + 1);
            val = max(val, score - nval);

        } else {
            if (j < M ) {
                ll score = 0, nval = 0;
                if (B[j] == -1) {
                    nval = rec(rec, i, j + 1, i, b, 0, 0);
                } else {
                    nval = rec(rec, i, j + 1, a, b, 0, 0);
                }
                val = max(val, score - nval);
            }

            ll score = 0, nval = 0;
            for (int k = a; k < i; k++) {
                if (A[k] != -1) {
                    nval += A[k];
                }
            }
            for (int k = b; k < j; k++) {
                if (B[k] != -1)
                    score += B[k];
            }
            nval += rec(rec, i, j, i, j, 0, p + 1);

            val = max(val, score - nval);
        }
        memo[key] = val;

        return val;
    };

    print(rec(rec, 0, 0, 0, 0, 0, 0));

    return true;
}

int main() {
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    solve();
}

////////////////////print/////////////////////////
// 1次元ベクトルを出力する
template <typename T> void print(vector<T> A) {
    if (A.size() == 0) {
        return;
    }
    for (size_t i = 0; i < A.size() - 1; i++) {
        cout << A[i] << ' ';
    }
    cout << A[A.size() - 1] << endl;
    return;
}

// 2次元ベクトルを出力する
template <typename T> void print(vector<vector<T>> &F) {
    for (size_t i = 0; i < F.size(); i++) {
        for (size_t j = 0; j < F[i].size(); j++) {
            cout << F[i][j];
            if (j < F[i].size() - 1) {
                cout << ' ';
            }
        }
        cout << endl;
    }
}

// 空白行を出力するprint
void print() { cout << endl; }

// 数値・文字列を空白区切りで出力する. print(a,b)など
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    cout << head;
    if (sizeof...(tail) != 0)
        cout << " ";
    print(forward<Tail>(tail)...);
}

void print(string S) { cout << S << endl; }

//////////////出力関連

inline void Yes(bool f) {
    if (f) {
        cout << "Yes" << endl;
    } else {
        cout << "No" << endl;
    }
}
accuracy: 1
time_ms: 80
memory_kb: 17920
final_rank: 9

code_snippet: // (⁠◕⁠ᴗ⁠◕⁠✿⁠)

// #pragma GCC target("avx2")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define srep(i, s, n) for (ll i = s; i < (n); i++)
#define len(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
using namespace std;
template<typename T> using vc = vector<T>;
template<typename T> using vv = vc<vc<T>>;
template<typename T> using vvv = vv<vc<T>>;
using vi = vc<int>;using vvi = vv<int>; using vvvi = vv<vi>;
using ll = long long;using vl = vc<ll>;using vvl = vv<ll>; using vvvl = vv<vl>;
using ld = long double; using vld = vc<ld>; using vvld = vc<vld>; using vvvld = vc<vvld>;
using uint = unsigned int;
using ull = unsigned long long;
const ld pi = 3.141592653589793;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
// const ll mod = 1000000007;
const ll mod = 998244353;
inline bool inside(ll y, ll x, ll H, ll W) {return 0 <= (y) and (y) < (H) and 0 <= (x) and (x) < (W); }

#define debug(var)  do{std::cout << #var << " : \n";view(var);}while(0)
template<typename T> void view(T e){cout << e << endl;}
template<typename T> void view(const vc<T>& v){for(const auto& e : v){ cout << e << " "; } cout << endl;}
template<typename T> void view(const vv<T>& vv){ for(const auto& v : vv){ view(v); } }

vvl A;
unordered_map<string, ll> memo;
ll hash_(ll j1, ll j2, ll pass, ll get1, ll i1){
    return get1 * 100000ll + ((j1 * 50 + j2) * 5 + pass) * 2 + i1;
}
ll f(int j1, int j2, int pass, ll get1, ll get2, int i1, int i2){
    ll hs = hash_(j1, j2, pass, get1, i1);
    string key = to_string(hs);
    while (len(key) < 18) key += 'x';
    key += to_string(get2);
    if (memo.count(key)) return memo[key];
    ll ret = -INF;
    // use
    if (j1 < len(A[i1])){
        if (A[i1][j1] == -1){
            ret = max(ret, -f(j2, j1 + 1, 0, 0, get1, i2, i1));
        }else{
            ret = max(ret, -f(j2, j1 + 1, 0, get2, get1 + A[i1][j1], i2, i1));
        }
    }
    // pass
    if (get1 + get2 == 0){
        if (pass == 3) ret = max(ret, 0ll);
        else ret = max(ret, -f(j2, j1, pass + 1, 0, 0, i2, i1));
    }else{
        ret = max(ret, get1 - get2 - f(j2, j1, 0, 0, 0, i2, i1));
    }
    return memo[key] = ret;
}
int main(){
    int N, M; cin >> N >> M;
    vl a(N); rep(i, N) cin >> a[i];
    vl b(M); rep(i, M) cin >> b[i];
    A.push_back(a);
    A.push_back(b);
    cout << f(0, 0, false, 0, 0, 0, 1) << endl;
}
accuracy: 1
time_ms: 60
memory_kb: 23696
final_rank: 5

code_snippet: //#pragma GCC optimize("O3")
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define rep(i,n) for (ll i=0;i<(ll)n;i++)
#define rrep(i,n) for (ll i=n-1;i>=(ll)0;i--)
#define loop(i,m,n) for(ll i=m;i<=(ll)n;i++)
#define rloop(i,m,n) for(ll i=m;i>=(ll)n;i--)
#define vl vector<long long>
#define vvl vector<vector<long long>>
#define vdbg(a) rep(ii,a.size()){cout<<a[ii]<<" ";}cout<<endl;
#define vvdbg(a) rep(ii,a.size()){rep(jj,a[ii].size()){cout<<a[ii][jj]<<" ";}cout<<endl;}
#define setdbg(a) for(const auto & ii:a){cout<<ii<<" ";}cout<<endl;
#define inf 4000000000000000000LL
#define mod 998244353LL
#define eps 0.000000001
//#define mod 1000000007LL
random_device rnd;// 非決定的な乱数生成器
mt19937 mt(rnd());// メルセンヌ・ツイスタの32ビット版、引数は初期シード

//#include<boost/multiprecision/cpp_int.hpp>
//#define bbi boost::multiprecision::cpp_int

//#include<atcoder/lazysegtree>

//√の値が整数かを調べる
bool isSqrt(ll n) {
	if (n < 0) return false;
	ll sqrtN = static_cast<ll>(sqrt(n));
	return sqrtN * sqrtN == n;
}

//整数同士の累乗の計算をする。
ll power(ll A, ll B) {
	ll result = 1;
	for (ll i=0;i<B;i++){
		result *= A;
	}
	return result;
}

//素因数分解
vector<ll> makePrime(ll n){
	vector<ll> factors;
	while (n % 2 == 0) {
		factors.push_back(2);
		n /= 2;
	}
	for (ll i=3; i*i<=n;i+=2) {
		while (n%i == 0) {
			factors.push_back(i);
			n /= i;
		}
	}
	if (n > 2) {
		factors.push_back(n);
	}
	return factors;
}

//map形式で、nを素因数分解した値を返す
map<ll,ll> makeMapPrime(ll n){
	map<ll,ll> factors;
	while (n % 2 == 0) {
		factors[2]++;
		n /= 2;
	}
	for (ll i=3; i*i<=n;i+=2) {
		while (n%i == 0) {
			factors[i]++;
			n /= i;
		}
	}
	if (n > 2) {
		factors[n]++;
	}
	return factors;
}

// nのk乗をmodで割った余りを計算
ll power_mod(ll n, ll k){
	long long result = 1;
	while (k > 0){
		if ((k&1) ==1)result=(result*n)%mod;
		n=n*n%mod;
		k >>= 1;
	}
	return result;
}

//mod mにおけるaの逆元を計算
ll modinv(ll a, ll m) {
	ll b = m, u = 1, v = 0;
	while (b) {
		ll t = a / b;
		a -= t * b; swap(a, b);
		u -= t * v; swap(u, v);
	}
	u %= m; 
	if (u < 0) u += m;
	return u;
}

//場合の数 nCr を求める
ll ncr(ll n,ll r) {
	if(n<r)return 0;
	vvl dp(n+1,vl(r+1));
	rep (i,n+1)dp[i][0] = 1;
	rep (i,r+1)dp[i][i] = 1;
	loop (i,1,n){
		loop (j,1,min((ll)i-1,r)) {
			//nCr= n-1Cr-1 + n-1Cr
			dp[i][j] = dp[i-1][j-1] + dp[i-1][j];
		}
	}
	return dp[n][r];
}

//受け取った文字列を、第2引数が0なら全て小文字に、1なら大文字に変換する関数
string cnvString(const string &str, int mode) {
	string result = str;
	if (mode == 0) {
		// 小文字に変換
		for (char &c : result) {
			c = tolower(c);
		}
	} else if (mode == 1) {
		// 大文字に変換
		for (char &c : result) {
			c = toupper(c);
		}
	}
	return result;
}

//第一引数で受け取った数を、第二引数で受け取った数の進数と見做して、第三引数の進数へ変換する。
string cnvBase(const string &str, ll from_base, ll to_base) {
	ll num = 0;
	//小文字があったら大文字に変換
	string num_str=cnvString(str,1);
	// 数値を10進数に変換
	for (char digit : num_str) {
		num = num * from_base + (isdigit(digit) ? digit - '0' : digit - 'A' + 10);
	}
	string result;
	// 数値を目的の基数に変換
	while (num > 0) {
		ll remainder = num % to_base;
		result.push_back(remainder < 10 ? remainder + '0' : remainder - 10 + 'A');
		num /= to_base;
	}
	// 結果を逆順にして返す
	reverse(result.begin(), result.end());
	return result.empty() ? "0" : result;
}

//底がaの対数xを計算。ただし小数点は繰り上げ。
ll logax(ll a, ll x){
	if(x<=1)return 0;
	ll result = 1;
	ll power = 1;
	while (power < (x+a-1) / a){
		power *= a;
		result++;
	}
	return result;
}

//第一引数を第二引数で割った余りを計算、割る数はint範囲
ll bigmd(const string &num, int md) {
	ll ans = 0;
	ll SIZ = 9; //9桁のチャンク
	ll base = 1000000000;//SIZ個の0
	rep(i,(num.size()-1)/SIZ+1){
		ll chunk = 0;
		ll l = i*SIZ;
		ll r = min((ll)num.size(),l+SIZ);
		if(r!=num.size()){
			ans = (ans*base+stoll(num.substr(l,r-l)))%md;
		}else{
			rep(i,r-l)ans*=10;
			ans=(ans+stoll(num.substr(l,r-l)))%md;
		}
	}
	return ans;
}

//受け取った2次元文字の外側に、文字pをコーティングする。
vector<string> pad(vector<string> &s,char p){
	ll h=s.size();
	ll w=s[0].size();
	vector<string> res(h+2,string(w+2,p));
	rep(i,h)rep(j,w)res[i+1][j+1]=s[i][j];
	return res;
}

//ax+by=cの整数解を得る ただし、cはgcd(a,b)の倍数でない場合、0,0になる
pair<ll,ll> ex_euclid(ll a,ll b,ll c){
	if(a<0||b<0||c<0){
		pair<ll,ll>ans=ex_euclid(abs(a),abs(b),abs(c));
		if(a<0)ans.first*=-1;
		if(b<0)ans.second*=-1;
		if(c<0)ans.first*=-1,ans.second*=-1;
		return ans;
	}
	if(c!=1){
		ll d=gcd(a,b);
		if(c%d!=0)return make_pair(0,0);
		pair<ll,ll>ans = ex_euclid(a/d,b/d,1);
		ans.first*=c/d;
		ans.second*=c/d;
		return ans;
	}
	if(a<b){
		pair<ll,ll>ans=ex_euclid(b,a,c);
		swap(ans.first,ans.second);
		return ans;
	}
	if(a==1&&b==0)return make_pair(1,0);
	else if(b==0) return make_pair(0,0);
	ll x,y;
	tie(x,y)=ex_euclid(b,a%b,c);
	pair<ll,ll> ans=make_pair(y,x-(a/b)*y);
	return ans;
}

//オイラーのトーシェント関数。N以下のNと互いに素な物の数を返す。
ll euler(ll n){
	unordered_map<ll,ll> factors;
	ll tmp=n;
	while (tmp % 2 == 0) {
		factors[2]++;
		tmp /= 2;
	}
	for (ll i=3; i*i<=tmp;i+=2) {
		while (tmp%i == 0) {
			factors[i]++;
			tmp/= i;
		}
	}
	if (tmp > 2)factors[tmp]++;
	ll ans=1;
	for(const auto & val:factors){
		ans*=power(val.first,val.second-1)*(val.first-1);
	}
	return ans;
}

// Union-Find
struct UnionFind {
	vector<int> par, siz;
	UnionFind(int n) : par(n, -1) , siz(n, 1) { }
	// 根を求める
	int root(int x) {
		if (par[x] == -1) return x;
		else return par[x] = root(par[x]);
	}
	// x と y が同じグループに属するかどうか (根が一致するかどうか)
	bool issame(int x, int y) {
		return root(x) == root(y);
	}
	// x を含むグループと y を含むグループとを併合する
	bool unite(int x, int y) {
		x = root(x), y = root(y);
		if (x == y) return false; 
		if (siz[x] < siz[y]) swap(x, y);
		par[y] = x;
		siz[x] += siz[y];
		return true;
	}
	// x を含むグループのサイズ
	int size(int x) {
		return siz[root(x)];
	}
};

//重み付きUF
struct PotentialUnionFind {
	ll n;
	vl par, siz, pot;
	PotentialUnionFind(ll N) : par(N,-1) , siz(N,1) , pot(N,0){n=N;}
	// 根を求める
	ll root(ll x) {
		if (par[x] == -1) return x;
		ll tmp = root(par[x]);
		pot[x] += pot[par[x]];
		par[x] = tmp;
		return par[x];
	}
	// x と y が同じグループに属するかどうか (根が一致するかどうか)
	bool issame(ll x, ll y) {
		return root(x) == root(y);
	}
	//x よりいくつ大きい所に y があるか。根が一致しない場合は"0"
	ll potential(ll x,ll y){
		if(root(x) != root(y)) return 0;
		else return pot[y]-pot[x];
	}
	//x より w だけ大きい状態として y を併合。
	bool unite(ll x, ll y, ll w) {
		ll rx = root(x),ry = root(y);
		if (rx == ry) return false;
		w += pot[x]-pot[y];
		if (siz[rx] < siz[ry]) swap(rx, ry),w*=-1;
		par[ry] = rx;
		siz[rx] += siz[ry];
		siz[ry] = 0;
		pot[ry] = w;
		return true;
	}
	// x を含むグループのサイズ
	ll size(ll x) {
		return siz[root(x)];
	}
	//小さい順にUnionFindグラフを調整、O(n log n)
	void regulation(){
		vvl r(n);
		rep(i,n)r[root(i)].push_back(i);
		rep(i,n){
			if(r[i].size()==0)continue;
			ll mn = i;
			rep(j,r[i].size())if(pot[mn]>pot[r[i][j]])mn=r[i][j];
			siz[mn]=siz[i];
			siz[i]=0;
			ll tmp = pot[mn];
			rep(j,r[i].size()){
				pot[r[i][j]]-=tmp;
				par[r[i][j]] = mn;
			}
			par[mn]=-1;
		}
	}
	void debug(){
		rep(i,n)cout<<setw(4)<<left<<par[i]<<" ";
		cout<<endl;
		rep(i,n)cout<<setw(4)<<left<<pot[i]<<" ";
		cout<<endl;
	}
};

//分離可能UnionFind、経路圧縮をしない。
struct CuttingFind{
	vector<int> par, siz;
	CuttingFind(int n) : par(n, -1) , siz(n, 1) { }
	// 根を求める
	int root(int x) {
		if (par[x] == -1) return x;
		else return root(par[x]);
	}
	// x と y が同じグループに属するかどうか (根が一致するかどうか)
	bool issame(int x, int y) {
		return root(x) == root(y);
	}
	//根x と 根y のグループを併合する(お互い根ではない時、falseで何もしない)
	bool unite(int x, int y) {
		if (issame(x,y) || par[x] != -1 || par[y] != -1) {
			cout<<"error"<<endl;
			return false;
		}
		if (siz[x] < siz[y]) swap(x, y);
		par[y] = x;
		siz[x] += siz[y];
		return true;
	}
	//根の側から、その直系の子供を分離する。片方が根でもう片方が直系の子でなければならない。
	bool separate(int x,int y){
		if(par[y]==-1)swap(x,y);
		if(par[y]!=x||par[x]!=-1){
			cout<<"error2"<<endl;
			return false;
		}
		siz[x] -= siz[y];
		par[y]=-1;
		return true;
	}
	// x を含むグループのサイズを求める
	int size(int x) {
		return siz[root(x)];
	}
};
//セグ木,乗せる値の型が必要
template<typename T>
struct SegTree{
	ll size;
	ll tall;
	vector<T> data;
	function<T(T,T)> p;
	//セグ木に乗せる値の初期値をa配列にし、putの関数をセグ木に乗せる、dをデフォルト値に。
	SegTree(vector<T> a,function<T(T,T)> put,T d) : data(power(2,logax(2,a.size())+1)) {
		size = data.size()/2;
		tall=logax(2,size)+1;
		p=put;
		ll tmp=size;
		data = vector<T>(size*2,d);
		while(tmp!=0){
			if(tmp==size)rep(i,a.size())data[tmp+i]=a[i];
			else rep(i,tmp) data[tmp+i]=p(data[2*(tmp+i)],data[2*(tmp+i)+1]);
			tmp/=2;
		}
	}
	//更新、t番目の値をxにする。
	void update(ll t,T x){
		t+=size;
		while(t!=0){
			if(t>=size)data[t]=x;
			else data[t]=p(data[2*t],data[2*t+1]);
			t/=2;
		}
	}
	//取得、l~r区間内の評価値を取得する。
	T get(ll l,ll r){
		//lとrが範囲外なら範囲内に正す
		l=max(0LL,l);
		r=min(r,size-1);
		r++;
		T ans=data[0];
		ll pos=l+size;
		ll wid=1;
		//出来る限り上に上げきる。
		while(l+(wid*2)<=r){
			while(l%(wid*2)==0&&l+(wid*2)<=r)pos/=2,wid*=2;
			ans=p(ans,data[pos]);
			pos++;
			l+=wid;
		}
		//上げ終わったので今度は下げる
		while(l!=r){
			while(l+wid>r)pos*=2,wid/=2;
			ans=p(ans,data[pos]);
			pos++;
			l+=wid;
		}
		return ans;
	}
	//セグ木デバッグ用、丸ごと出力
	void print(){
		rep(i,size)cout<<setw(7)<<left<<i;
		cout<<endl;
		ll pos=size;
		rep(i,tall){
			rep(j,size){
				if(j%power(2,i)==0)cout<<setw(7)<<left<<data[pos],pos++;
				else cout<<"       ";
			}
			pos/=4;
			cout<<endl;
		}
	}
};

//グリッド問題等用
vl dx={1,0,-1,0};
vl dy={0,1,0,-1};

ll n,m;
vl a,b;

map <vl,ll> memo;

ll dfs(vl dp){
	if(memo.count(dp))return memo[dp];
	//ゲームが終了する場合
	if(dp[1]==2){
		memo[dp]=0;
		return 0;
	}

	//自分の得点-相手の得点
	ll tmp=-inf;
	
	//スキップする場合
	if(dp[2]==dp[4]&&dp[3]==dp[5]){
		//既にスタックがからな場合
		vl ndp={dp[0]^1,dp[1]+1,dp[2],dp[3],dp[2],dp[3]};
		tmp =max(tmp,-dfs(ndp));
	}else{
		vl ndp={dp[0]^1,0,dp[2],dp[3],dp[2],dp[3]};
		//4を2に詰める時のコスト
		ll cost=0;
		loop(i,dp[4],dp[2]-1){
			if(a[i]!=-1)cost+=a[i];
		}
		loop(i,dp[5],dp[3]-1){
			if(b[i]!=-1)cost-=b[i];
		}
		if(dp[0]==1)cost*=-1;
		tmp =max(tmp,-dfs(ndp)+cost);
	}

	//出す場合
	if(dp[0]==0){
		if(dp[2]!=n){
			vl ndp={dp[0]^1,0,dp[2]+1,dp[3],dp[4],dp[5]};
			if(a[dp[2]]==-1)ndp[5]=ndp[3];
			tmp = max(tmp,-dfs(ndp));
		}	
	}else{
		if(dp[3]!=m){
			vl ndp={dp[0]^1,0,dp[2],dp[3]+1,dp[4],dp[5]};
			if(b[dp[3]]==-1)ndp[4]=ndp[2];
			tmp = max(tmp,-dfs(ndp));
		}	
	}
	memo[dp]=tmp;
	return tmp;
}

//メイン
int main(){
	cin>>n>>m;
	rep(i,n){
		ll aa;
		cin>>aa;
		a.push_back(aa);
	}
	rep(i,m){
		ll bb;
		cin>>bb;
		b.push_back(bb);
	}
	cout<<dfs({0,0,0,0,0,0})<<endl;
	return 0;
}
accuracy: 1
time_ms: 150
memory_kb: 30336
final_rank: 16

code_snippet: #include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <climits>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <ranges>
#include <regex>
#include <set>
#include <span>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
// #include <atcoder/dsu>

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rep1(i, n) for (int i = 1; i <= (int)(n); i++)
#define all(a) a.begin(), a.end()
using namespace std;

template <class T>
inline bool chmin(T &a, T b) {
	if (a > b) {
		a = b;
		return true;
	}
	return false;
}
template <class T>
inline bool chmax(T &a, T b) {
	if (a < b) {
		a = b;
		return true;
	}
	return false;
}

template <class T1, class T2>
std::ostream &operator<<(std::ostream &out, const pair<T1, T2> &A) {
	cout << "{" << A.first << "," << A.second << "}";
	return out;
}

template <class T1, class T2>
std::ostream &operator<<(std::ostream &out, const map<T1, T2> &M) {
	for (const auto &A : M) {
		cout << "{" << A.first << "," << A.second << "}";
	}
	return out;
}

template <class T1>
std::ostream &operator<<(std::ostream &out, const set<T1> &M) {
	cout << "{";
	for (const auto &A : M) {
		cout << A << ", ";
	}
	cout << "}" << endl;
	return out;
}

template <class T1>
std::ostream &operator<<(std::ostream &out, const multiset<T1> &M) {
	cout << "{";
	for (const auto &A : M) {
		cout << A << ", ";
	}
	cout << "}" << endl;
	return out;
}

template <class T>
std::ostream &operator<<(std::ostream &out, const vector<T> &A) {
	for (const T &a : A) {
		cout << a << " ";
	}
	return out;
}

void print() { cout << endl; }

template <typename Head, typename... Tail>
void print(Head H, Tail... T) {
	cout << H << " ";
	print(T...);
}

template <class T>
std::istream &operator>>(std::istream &in, vector<T> &A) {
	for (T &a : A) {
		std::cin >> a;
	}
	return in;
}

using ll = long long;
// using mint = modint1000000007;
// using PII = pair<int, int>;
// using PLL = pair<ll, ll>;
// using Graph = vector<vector<int>>;
constexpr int INF = numeric_limits<int>::max() / 2;
constexpr ll LINF = numeric_limits<ll>::max() / 2;

// ランレングス圧縮
// イテレータを受け取る
// verify: https://atcoder.jp/contests/abc380/submissions/60002447
template <typename T, typename Iterator>
vector<pair<T, int>> RLE(Iterator begin, Iterator end) {
	vector<pair<T, int>> res;
	for (auto itr = begin; itr != end; ++itr) {
		if (res.empty() || res.back().first != *itr) {
			res.emplace_back(*itr, 1);
		} else {
			res.back().second++;
		}
	}
	return res;
}

// 座標圧縮
// unordered_mapが使えない場合はmapに変更しよう
// https://atcoder.jp/contests/abc213/submissions/60002695
template <typename T>
unordered_map<T, int> compress(vector<T> &X) {
	auto tmp = X;
	ranges::sort(tmp);
	tmp.erase(unique(tmp.begin(), tmp.end()), tmp.end());
	unordered_map<T, int> res;
	for (int i = 0; i < (int)tmp.size(); i++) {
		res[tmp[i]] = i;
	}
	return res;
}

vector<int> A, B;
int N, M;

map<tuple<int, int, int, int, int, int>, int> memo;
int dfs(int a, int b, int sum_a, int sum_b, int pass, int turn = 0) {
	if (a == N && b == M && sum_a == 0 && sum_b == 0) {
		return 0;
	}
	if (pass == 2) {
		return 0;
	}
	if (memo.contains({a, b, sum_a, sum_b, pass, turn})) {
		return memo[{a, b, sum_a, sum_b, pass, turn}];
	}
	// デッキの一番上がaやb
	// スタックの各合計値がsum_a,sum_b
	// aの手番
	// A[a]を使うか パスするか
	int mx = 0;
	// パスする場合
	if (sum_a == 0 && sum_b == 0) {
		mx = -dfs(b, a, 0, 0, pass + 1, 1 - turn) + sum_a - sum_b;
	} else {
		mx = -dfs(b, a, 0, 0, 0, 1 - turn) + sum_a - sum_b;
	}
	// A[a]を使う
	if (turn == 0) {
		if (a != N) {
			if (A[a] == -1) {
				chmax(mx, -dfs(b, a + 1, 0, sum_a, 0, 1 - turn));
			} else {
				chmax(mx, -dfs(b, a + 1, sum_b, sum_a + A[a], 0, 1 - turn));
			}
		}
	} else if (turn == 1) {
		if (a != M) {
			if (B[a] == -1) {
				chmax(mx, -dfs(b, a + 1, 0, sum_a, 0, 1 - turn));
			} else {
				chmax(mx, -dfs(b, a + 1, sum_b, sum_a + B[a], 0, 1 - turn));
			}
		}
	}
	memo[{a, b, sum_a, sum_b, pass, turn}] = mx;
	return mx;
}

void solve() {
	// ここからスタート
	cin >> N >> M;
	rep(i, N) {
		int a;
		cin >> a;
		A.push_back(a);
	}
	rep(i, M) {
		int a;
		cin >> a;
		B.push_back(a);
	}
	cout << dfs(0, 0, 0, 0, 0) << endl;
}

int main(void) {
	std::cin.tie(0)->sync_with_stdio(0);
	solve();
}
accuracy: 1
time_ms: 80
memory_kb: 17920
final_rank: 9

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

#include <unistd.h>

namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf


uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio


using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */

static int DP[51][51][51][51][2][3];
static bool Flag[51][51][51][51][2][3];

int N, M;
vector<int> A,B,ASUM,BSUM;

void Change(int& A, int B, int C) {
    if (C == 0) chmax(A,B);
    else chmin(A,B);
}

int DFS(int I, int J, int K, int L, int B1, int B2) {
    if (Flag[I][J][K][L][B1][B2]) return DP[I][J][K][L][B1][B2];
    if (B1 == 0) { //sente
        if (I != N) { //tumu
            if (A[I] == -1) {
                Change(DP[I][J][K][L][B1][B2],DFS(I+1,J,K,J,1,0),0);
            }
            else {
                Change(DP[I][J][K][L][B1][B2],DFS(I+1,J,K,L,1,0),0);
            }
        }
        if (B2 == 2) { //Pass
            Change(DP[I][J][K][L][B1][B2],0,0);
        }
        else {
            Change(DP[I][J][K][L][B1][B2], DFS(I,J,I,J,1,B2+1)+ASUM[I]-ASUM[K]-BSUM[J]+BSUM[L],0);
        }
    }
    else {
        if (J != M) { //tumu
            if (B[J] == -1) {
                Change(DP[I][J][K][L][B1][B2],DFS(I,J+1,I,L,0,0),1);
            }
            else {
                Change(DP[I][J][K][L][B1][B2],DFS(I,J+1,K,L,0,0),1);
            }
        }
        if (B2 == 2) { //Pass
            Change(DP[I][J][K][L][B1][B2],0,1);
        }
        else {
            Change(DP[I][J][K][L][B1][B2], DFS(I,J,I,J,0,B2+1)+ASUM[I]-ASUM[K]-BSUM[J]+BSUM[L],1);
        }
    }
    Flag[I][J][K][L][B1][B2] = true;
    return DP[I][J][K][L][B1][B2];
}


int main() {
    cin >> N >> M;
    A.resize(N), B.resize(M), ASUM.resize(N+1), BSUM.resize(M+1);
    rep(i,0,N) cin >> A[i];
    rep(i,0,M) cin >> B[i];
    ASUM[0] = 0, BSUM[0] = 0;
    rep(i,0,N) ASUM[i+1] = ASUM[i] + max(A[i],0);
    rep(i,0,M) BSUM[i+1] = BSUM[i] + max(B[i],0);
    rep(i,0,N+1) rep(j,0,M+1) rep(k,0,N+1) rep(l,0,M+1) rep(m,0,2) rep(n,0,3) DP[i][j][k][l][m][n] = (m==0 ? -inf : inf), Flag[i][j][k][l][m][n] = false;
    cout << DFS(0,0,0,0,0,0) << endl;
}
accuracy: 1
time_ms: 40
memory_kb: 201712
final_rank: 18

code_snippet: #include<iostream>
using namespace std;
void chmax(int &a, int b){if(a<b)a=b;}
void chmin(int &a, int b){if(a>b)a=b;}
const int INF=1<<30;
int N,M,A[55],B[55];
int SA[55],SB[55];
int dp[55][55][55][55][2][2];
int dfs(int la, int ra, int lb, int rb, int t, int p)
{
    int &cur=dp[la][ra][lb][rb][t][p];
    if(cur!=INF)return cur;
    if(t)
    {
        int put=-INF;
        int pass=-INF;
        if(ra<N)chmax(put,dfs(la,ra+1,A[ra]==-1?rb:lb,rb,0,0));
        chmax(pass,p?0:(la==ra&&lb==rb)?dfs(la,ra,lb,rb,0,1):dfs(ra,ra,rb,rb,0,0)+(SA[ra]-SA[la])-(SB[rb]-SB[lb]));
        return cur=max(put,pass);
    }
    else
    {
        int put=INF;
        int pass=INF;
        if(rb<M)chmin(put,dfs(B[rb]==-1?ra:la,ra,lb,rb+1,1,0));
        chmin(pass,p?0:(la==ra&&lb==rb)?dfs(la,ra,lb,rb,1,1):dfs(ra,ra,rb,rb,1,0)+(SA[ra]-SA[la])-(SB[rb]-SB[lb]));
        return cur=min(put,pass);
    }
}
int main()
{
    cin>>N>>M;
    for(int i=0;i<N;i++)
    {
        cin>>A[i];
        SA[i+1]=SA[i]+A[i]+(A[i]==-1?1:0);
    }
    for(int i=0;i<M;i++)
    {
        cin>>B[i];
        SB[i+1]=SB[i]+B[i]+(B[i]==-1?1:0);
    }
    for(int la=0;la<=N;la++)for(int ra=0;ra<=N;ra++)for(int lb=0;lb<=M;lb++)for(int rb=0;rb<=M;rb++)
    {
        for(int t=0;t<2;t++)for(int p=0;p<2;p++)dp[la][ra][lb][rb][t][p]=INF;
    }
    cout<<dfs(0,0,0,0,1,0)<<endl;
}
accuracy: 1
time_ms: 10
memory_kb: 136492
final_rank: 13

code_snippet: #include<bits/stdc++.h>
using namespace std;
void chmax(int &a, int b){if(a<b)a=b;}
void chmin(int &a, int b){if(a>b)a=b;}
const int INF=1<<30;
int N,M,A[55],B[55];
int SA[55],SB[55];
int dp[55][55][55][55][2][2];
int dfs(int la, int ra, int lb, int rb, bool turn, bool passed)
{
    if(dp[la][ra][lb][rb][turn][passed]!=INF)return dp[la][ra][lb][rb][turn][passed];
    if(turn) // player 1
    {
        int put=-INF;
        { // put next card
            if(ra==N){}
            else
            {
                if(A[ra]==-1)chmax(put,dfs(la,ra+1,rb,rb,0,0));
                else chmax(put,dfs(la,ra+1,lb,rb,0,0));
            }
        }
        int pass=-INF;
        { // pass
            if(passed)
            {
                assert(la==ra&&lb==rb);
                chmax(pass,0);
            }
            else
            {
                if(la==ra&&lb==rb)
                {
                    chmax(pass,dfs(la,ra,lb,rb,0,1));
                }
                else
                {
                    chmax(pass,dfs(ra,ra,rb,rb,0,0)+(SA[ra]-SA[la])-(SB[rb]-SB[lb]));
                }
            }
        }
        return dp[la][ra][lb][rb][turn][passed]=max(put,pass);
    }
    else // player 2
    {
        int put=INF;
        { // put next card
            if(rb==M){}
            else
            {
                if(B[rb]==-1)chmin(put,dfs(ra,ra,lb,rb+1,1,0));
                else chmin(put,dfs(la,ra,lb,rb+1,1,0));
            }
        }
        int pass=INF;
        { // pass
            if(passed)
            {
                assert(la==ra&&lb==rb);
                chmin(pass,0);
            }
            else
            {
                if(la==ra&&lb==rb)
                {
                    chmin(pass,dfs(la,ra,lb,rb,1,1));
                }
                else
                {
                    chmin(pass,dfs(ra,ra,rb,rb,1,0)+(SA[ra]-SA[la])-(SB[rb]-SB[lb]));
                }
            }
        }
        return dp[la][ra][lb][rb][turn][passed]=min(put,pass);
    }
}
int main()
{
    cin>>N>>M;
    for(int i=0;i<N;i++)
    {
        cin>>A[i];
        if(A[i]!=-1)SA[i+1]=SA[i]+A[i];
        else SA[i+1]=SA[i];
    }
    for(int i=0;i<M;i++)
    {
        cin>>B[i];
        if(B[i]!=-1)SB[i+1]=SB[i]+B[i];
        else SB[i+1]=SB[i];
    }
    for(int la=0;la<=N;la++)for(int ra=0;ra<=N;ra++)for(int lb=0;lb<=M;lb++)for(int rb=0;rb<=M;rb++)for(int t=0;t<2;t++)for(int p=0;p<2;p++)
    {
        dp[la][ra][lb][rb][t][p]=INF;
    }
    cout<<dfs(0,0,0,0,1,0)<<endl;
}
accuracy: 1
time_ms: 10
memory_kb: 136488
final_rank: 12

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
using vll = vector<ll>;
using vvll = vector<vll>;
#define rep(i,n) for(ll i=0;i<ll(n);i++)
#define all(A) A.begin(),A.end()

void chmax(ll& p, ll q) { p = max(p, q); };
void chmin(ll& p, ll q) { p = min(p, q); };

const ll mod = 998244353;


vll A, B;
vll SA, SB;
ll N, M;

map<tuple<ll, ll, ll, ll, ll, bool>, ll> MP;

//Aをn枚,Bをm枚使用済み.
//使用済みの上a枚はBの妨害より上. 逆もしかり.
//pは前がパス, tはターン
ll dfs(ll n, ll m, ll a, ll b, ll p, bool t) {

    if (MP.count({ n,m,a,b,p,t }))return MP[{n, m, a, b, p, t}];

    if (t == 0) {
        ll res = -1e18;
        //pass
        {
            if (a == 0 && b == 0 && p == 1) {
                chmax(res, 0ll);
            }
            else if (a == 0 && b == 0) {
                chmax(res, dfs(n, m, 0, 0, 1, 1));
            }
            else chmax(res, a-b + dfs(n, m, 0, 0, 0, 1));
        }
        //stack
        if (n != N) {
            if (A[n] == -1) {
                chmax(res, dfs(n + 1, m, a, 0, 0, 1));
            }
            else {
                chmax(res, dfs(n + 1, m, a + A[n], b, 0, 1));
            }
        }
        MP[{n, m, a, b, p, t}] = res;
        return res;
    }
    else {
        ll res = 1e18;
        {
            if (a == 0 && b == 0 && p == 1) {
                chmin(res, 0ll);
            }
            else if (a == 0 && b == 0) {
                chmin(res, dfs(n, m, 0, 0, 1, 0));
            }
            else chmin(res, a-b + dfs(n, m, 0, 0, 0, 0));
        }

        if (m != M) {
            if (B[m] == -1) {
                chmin(res, dfs(n, m + 1, 0, b, 0, 0));
            }
            else {
                chmin(res, dfs(n, m + 1, a, b + B[m], 0, 0));
            }
        }
        MP[{n, m, a, b, p, t}] = res;
        return res;
    }

}

int main() {

    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    cin >> N >> M;
    A.resize(N);
    SA.resize(N + 1, 0);
    B.resize(M);
    SB.resize(M + 1, 0);
    rep(i, N) {
        cin >> A[i];
        SA[i + 1] = SA[i] + A[i];
    }
    rep(i, M) {
        cin >> B[i];
        SB[i + 1] = SB[i] + B[i];
    }
    cout << dfs(0, 0, 0, 0, 0, 0) << endl;
}
accuracy: 1
time_ms: 80
memory_kb: 20704
final_rank: 11

code_snippet: #include <bits/stdc++.h>

int N, M;
long long A[55], B[55];
long long dp[2][2][55][55][105];
bool vis[2][2][55][55][105];

const long long INF{(long long)1e18};

long long score(int turn, int r1, int r2, int rs) {
    int n1{r1}, n2{r2};
    int cur{turn ^ 1};
    bool flag1{}, flag2{};
    long long res{};
    for (int i{} ; i < rs ; i++) {
        if (cur == 0) {
            assert(n1 < N);
            if (A[n1] == -1) flag1 = true;
            if (flag2 == false and A[n1] != -1) {
                res += A[n1];
            }
            n1++;
        }
        else {
            assert(n2 < M);
            if (B[n2] == -1) flag2 = true;
            if (flag1 == false and B[n2] != -1) {
                res -= B[n2];
            }
            n2++;
        }
        cur ^= 1;
    }
    if (rs == 0) assert(res == 0);
    //std::cout << turn << ' ' << r1 << ' ' << r2 << ' ' << rs << " -> " << res << std::endl;
    return res;
}

long long rec(int turn, int pass, int r1, int r2, int rs) {
    if (vis[turn][pass][r1][r2][rs]) {
        return dp[turn][pass][r1][r2][rs];
    }
    vis[turn][pass][r1][r2][rs] = true;
    if (pass == 1) assert(rs == 0);
    if (turn == 0) {
        dp[turn][pass][r1][r2][rs] = -INF;
        if (r1 > 0) {
            dp[turn][pass][r1][r2][rs] = std::max(dp[turn][pass][r1][r2][rs], rec(turn ^ 1, 0, r1 - 1, r2, rs + 1));
        }
        long long val{score(turn, r1, r2, rs)};
        if (pass == 0) val += rec(turn ^ 1, (rs == 0), r1, r2, 0);
        else assert(rs == 0 and val == 0);
        dp[turn][pass][r1][r2][rs] = std::max(dp[turn][pass][r1][r2][rs], val);
    }
    else if (turn == 1) {
        dp[turn][pass][r1][r2][rs] = INF;
        if (r2 > 0) {
            dp[turn][pass][r1][r2][rs] = std::min(dp[turn][pass][r1][r2][rs], rec(turn ^ 1, 0, r1, r2 - 1, rs + 1));
        }
        long long val{score(turn, r1, r2, rs)};
        if (pass == 0) val += rec(turn ^ 1, (rs == 0), r1, r2, 0);
        else assert(rs == 0 and val == 0);
        dp[turn][pass][r1][r2][rs] = std::min(dp[turn][pass][r1][r2][rs], val);
    }
    else {
        assert(false);
    }
    //std::cout << turn << ' ' << pass << ' ' << r1 << ' ' << r2 << ' ' << rs << ' ' << dp[turn][pass][r1][r2][rs] << std::endl;
    return dp[turn][pass][r1][r2][rs];
}

int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);

    std::cin >> N >> M;
    for (int i{} ; i < N ; i++) {
        std::cin >> A[N - i - 1];
    }
    for (int i{} ; i < M ; i++) {
        std::cin >> B[M - i - 1];
    }
    //std::cout << rec(0, 0, 1, 4, 0) << '\n';
    std::cout << rec(0, 0, N, M, 0) << '\n';
}
accuracy: 1
time_ms: 10
memory_kb: 14336
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define ll long long
#define rep(i,n) for(ll i = 0;i < (ll)(n);i++)

ll INF = 1LL << 60;


bool chmax(ll &a, ll b){
  if(a < b){
    a = b;
    return true;
  }else{
    return false;
  }
}

bool chmin(ll &a, ll b){
  if(a > b){
    a = b;
    return true;
  }else{
    return false;
  }
}

using P = pair<ll,ll>;

ll clcscore(vector<P> &stk){
  ll ret = 0;

  bool aok = true,bok = true;
  for(ll i = stk.size()-1;i >= 0;i--){
    auto [cost,isa] = stk[i];
    if(isa){
      if(cost == -1){
        bok = false;
      }else if(aok)ret += cost;
    }else{
      if(cost == -1){
        aok = false;
      }else if(bok){
        ret -= cost;
      }
    }
  }
  return ret;
}


int main(){
  ll n,m;cin >> n >> m;
  vector<ll> a(n),b(m);
  rep(i,n)cin >> a[i];
  rep(i,m)cin >> b[i];

  map<tuple<ll,ll,ll,ll>,ll> mp;

  auto clcsta = [&](ll anxt,ll afin){
    return anxt * n + afin;
  };
  auto clcstb = [&](ll bnxt,ll bfin){
    return bnxt * m + bfin;
  };

  auto dfs = [&](auto dfs,ll isa,ll pas,ll sta,ll stb,vector<P> stk)->ll{
    if(mp.count({isa,pas,sta,stb})){
      return mp[{isa,pas,sta,stb}];
    }

    ll anxt = sta /n;
    ll afin = sta % n;
    ll bnxt = stb/m;
    ll bfin = stb % m;

    if(isa){
      ll ret = -INF;

      if(pas == 2){
        //passして終わり
        chmax(ret,0);
      }else{
        ll tmp = clcscore(stk);
        //pass
        vector<P> emp;
        tmp += dfs(dfs,0,pas+1,clcsta(anxt,anxt),clcstb(bnxt,bnxt),emp);
        chmax(ret,tmp);
      }

      if(anxt >= n)return mp[{isa,pas,sta,stb}] = ret;

      //追加
      stk.push_back({a[anxt],1});
      chmax(ret,dfs(dfs,0,0,clcsta(anxt+1,afin),stb,stk));

      return mp[{isa,pas,sta,stb}] = ret;

    }else{
      ll ret = INF;

      if(pas == 2){
        //passして終わり
        chmin(ret,0);
      }else{
        ll tmp = clcscore(stk);
        //pass
        vector<P> emp;
        tmp += dfs(dfs,1,pas+1,clcsta(anxt,anxt),clcstb(bnxt,bnxt),emp);
        chmin(ret,tmp);
      }

      if(bnxt >= m)return mp[{isa,pas,sta,stb}] = ret;

      //追加
      stk.push_back({b[bnxt],0});
      chmin(ret,dfs(dfs,1,0,sta,clcstb(bnxt+1,bfin),stk));

      return mp[{isa,pas,sta,stb}] = ret;

    }
  };
  vector<P> stk;
  cout << dfs(dfs,1,0,0,0,stk) << endl;
}
accuracy: 1
time_ms: 130
memory_kb: 18920
final_rank: 15

code_snippet: #include <bits/stdc++.h>

int solve() {
    const int INF = 1e9;
    int n, m;
    std::cin >> n >> m;
    if (n == 0) return 1;
    std::vector<int> a(n), b(m);
    for (int i = 0; i < n; i++) std::cin >> a[i];
    for (int i = 0; i < m; i++) std::cin >> b[i];

    std::vector<int> sum_a(n + 1), sum_b(m + 1);
    for (int i = 0; i < n; i++) sum_a[i + 1] = sum_a[i] + std::max(0, a[i]);
    for (int i = 0; i < m; i++) sum_b[i + 1] = sum_b[i] + std::max(0, b[i]);

    std::map<std::tuple<short, short, short, short, bool, bool>, int> memo;
    auto dfs = [&](auto self, short stack_a, short deck_a, short stack_b, short deck_b, bool pass, bool turn) -> int {
        std::tuple key = {stack_a, deck_a, stack_b, deck_b, pass, turn};
        if (memo.find(key) != memo.end()) return memo[key];
        if (turn) { // maximize
            int ans = -INF;
            // put
            if (deck_a < n) {
                if (a[deck_a] == -1) {
                    ans = std::max(ans, self(self, stack_a, deck_a + 1, deck_b, deck_b, 0, false));
                } else {
                    ans = std::max(ans, self(self, stack_a, deck_a + 1, stack_b, deck_b, 0, false));
                }
            }
            // pass
            if (pass) {
                ans = std::max(ans, 0);
            } else if (stack_a == deck_a && stack_b == deck_b) {
                ans = std::max(ans, self(self, deck_a, deck_a, deck_b, deck_b, true, false));
            } else {
                ans = std::max(ans, self(self, deck_a, deck_a, deck_b, deck_b, false, false) 
                        + (sum_a[deck_a] - sum_a[stack_a]) - (sum_b[deck_b] - sum_b[stack_b]));
            }
            return memo[key] = ans;
        } else { // minimize
            int ans = INF;
            // put
            if (deck_b < m) {
                if (b[deck_b] == -1) {
                    ans = std::min(ans, self(self, deck_a, deck_a, stack_b, deck_b + 1, 0, true));
                } else {
                    ans = std::min(ans, self(self, stack_a, deck_a, stack_b, deck_b + 1, 0, true));
                }
            }
            // pass
            if (pass) {
                ans = std::min(ans, 0);
            } else if (stack_a == deck_a && stack_b == deck_b) {
                ans = std::min(ans, self(self, deck_a, deck_a, deck_b, deck_b, true, true));
            } else {
                ans = std::min(ans, self(self, deck_a, deck_a, deck_b, deck_b, 0, true) 
                        + (sum_a[deck_a] - sum_a[stack_a]) - (sum_b[deck_b] - sum_b[stack_b]));
            }
            return memo[key] = ans;
        }
    };
    std::cout << dfs(dfs, 0, 0, 0, 0, 0, true) << '\n';
    return 1;
}

int main() {
    while (!solve());
}
accuracy: 1
time_ms: 70
memory_kb: 14924
final_rank: 6

code_snippet: #include <bits/stdc++.h>

int main() {
    int N, M;
    std::cin >> N >> M;
    std::vector<int> A(N), B(M);
    for (int i{} ; i < N ; i++) {
        std::cin >> A[i];
    }
    for (int i{} ; i < M ; i++) {
        std::cin >> B[i];
    }
    const int INF{(int)2e9};
    std::vector dp(2, std::vector(2, std::vector(N + 1, std::vector(M + 1, std::vector<int>(N + M + 1, INF)))));
    auto calc{[&](int turn, int n, int m, int stk) -> int {
        turn ^= 1;
        int res{};
        bool g1{}, g2{};
        while (stk--) {
            if (turn == 0) {
                assert(n >= 1);
                n--;
                if (A[n] == -1) g2 = true;
                if (g1 == false and A[n] != -1) res += A[n];
            }
            else if (turn == 1) {
                assert(m >= 1);
                m--;
                if (B[m] == -1) g1 = true;
                if (g2 == false and B[m] != -1) res -= B[m];
            }
            else {
                assert(false);
            }
            turn ^= 1;
        }
        return res;
    }};
    auto rec{[&](auto rec, int turn, int cnt, int n, int m, int stk) -> int {
        if (cnt == 2) return 0;
        if (dp[turn][cnt][n][m][stk] != INF) return dp[turn][cnt][n][m][stk];
        if (turn == 0) {
            dp[turn][cnt][n][m][stk] = -INF;
            if (n < N) {
                dp[turn][cnt][n][m][stk] = std::max(dp[turn][cnt][n][m][stk], 
                        rec(rec, turn ^ 1, 0, n + 1, m, stk + 1));
            }
            int val{};
            val += rec(rec, turn ^ 1, (stk == 0 ? cnt + 1 : 0), n, m, 0);
            val += calc(turn, n, m, stk);
            dp[turn][cnt][n][m][stk] = std::max(dp[turn][cnt][n][m][stk], val);
        }
        else if (turn == 1) {
            dp[turn][cnt][n][m][stk] = INF;
            if (m < M) {
                dp[turn][cnt][n][m][stk] = std::min(dp[turn][cnt][n][m][stk], 
                        rec(rec, turn ^ 1, 0, n, m + 1, stk + 1));
            }
            int val{};
            val += rec(rec, turn ^ 1, (stk == 0 ? cnt + 1 : 0), n, m, 0);
            val += calc(turn, n, m, stk);
            dp[turn][cnt][n][m][stk] = std::min(dp[turn][cnt][n][m][stk], val);
        }
        else {
            assert(false);
        }
        return dp[turn][cnt][n][m][stk];
    }};
    std::cout << rec(rec, 0, 0, 0, 0, 0) << '\n';
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 11044
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
using P = pair<int, int>;
#define rep(i, a, b) for(int i = a; i < b; ++i)
#define rrep(i, a, b) for(int i = a; i >= b; --i)
// constexpr int inf = 4e18;
constexpr int inf = 1e9;

int n, m;
vector<int> a, b;
vector<int> cum_a, cum_b;
int memo[51][51][51][51][2][2][2];

int cnt = 0;
int dp(int i, int j, int k, int l, int p, int q, int r) {
    if(q == 1 && r == 1) {
        cerr << "ERROR" << endl;
        exit(0);
    }

    if(memo[i][j][k][l][p][q][r] != inf) {
        return memo[i][j][k][l][p][q][r];
    }
    int res;
    if(p == 0) {
        res = -inf;
        if(i > 0) {
            if(a[i] != -1) {
                res = max(res, dp(i - 1, j, k + 1, l, 1, 0, 1));
            } else {
                res = max(res, dp(i - 1, j, k + 1, 0, 1, 0, 1));
            }
        }

        if(q == 1 && r == 0) {
            res = max(res, 0);
        } else if(q == 0 && r == 0) {
            res = max(res, dp(i, j, k, l, 1, 1, 0));
        } else {
            // a[i+1] ~ a[i+k];
            int ca = cum_a[i + k] - cum_a[i];
            // b[j+1] ~ b[i+l];
            int cb = cum_b[j + l] - cum_b[j];
            res = max(res, dp(i, j, 0, 0, 1, 0, 0) + ca - cb);
        }
    } else {
        res = inf;
        if(j > 0) {
            if(b[j] != -1) {
                res = min(res, dp(i, j - 1, k, l + 1, 0, 0, 1));
            } else {
                res = min(res, dp(i, j - 1, 0, l + 1, 0, 0, 1));
            }
        }

        if(q == 1 && r == 0) {
            res = min(res, 0);
        } else if(q == 0 && r == 0) {
            res = min(res, dp(i, j, k, l, 0, 1, 0));
        } else {
            // a[i+1] ~ a[i+k];
            int ca = cum_a[i + k] - cum_a[i];
            // b[j+1] ~ b[i+l];
            int cb = cum_b[j + l] - cum_b[j];
            res = min(res, dp(i, j, 0, 0, 0, 0, 0) + ca - cb);
        }
    }
    // cerr << i << " " << j << " " << k << " " << l << " " << p << " " << q << " " << r << "\n";
    memo[i][j][k][l][p][q][r] = res;
    // cerr << "A:" << i << " " << j << " " << k << " " << l << " " << p << " " << q << " " << r << "\n";
    return res;
}

int main(void) {
    cin.tie(0);
    ios::sync_with_stdio(0);
    cin >> n >> m;
    a.resize(n + 1, 0);
    b.resize(m + 1, 0);
    rep(i, 1, n + 1) {
        cin >> a[n + 1 - i];
    }
    rep(i, 1, m + 1) {
        cin >> b[m + 1 - i];
    }
    cum_a.resize(n + 1, 0);
    cum_b.resize(m + 1, 0);
    rep(i, 1, n + 1) {
        if(a[i] != -1) {
            cum_a[i] = cum_a[i - 1] + a[i];
        } else {
            cum_a[i] = cum_a[i - 1];
        }
    }
    rep(i, 1, m + 1) {
        if(b[i] != -1) {
            cum_b[i] = cum_b[i - 1] + b[i];
        } else {
            cum_b[i] = cum_b[i - 1];
        }
    }

    rep(i, 0, n + 1) {
        rep(j, 0, m + 1) {
            rep(k, 0, n + 1) {
                rep(l, 0, m + 1) {
                    rep(p, 0, 2) {
                        rep(q, 0, 2) {
                            rep(r, 0, 2) {
                                memo[i][j][k][l][p][q][r] = inf;
                            }
                        }
                    }
                }
            }
        }
    }

    // memo.resize(n + 1);
    // rep(i, 0, n + 1) {
    //     memo[i].resize(m + 1);
    //     rep(j, 0, m + 1) {
    //         memo[i][j].resize(n + 1);
    //         rep(k, 0, n + 1) {
    //             memo[i][j][k].resize(m + 1);
    //             rep(l, 0, m + 1) {
    //                 memo[i][j][k][l].resize(2);
    //                 rep(p, 0, 2) {
    //                     memo[i][j][k][l][p].resize(2);
    //                     rep(q, 0, 2) {
    //                         memo[i][j][k][l][p][q].resize(2, inf);
    //                     }
    //                 }
    //             }
    //         }
    //     }
    // }
    // cerr << "b\n";

    dp(n, m, 0, 0, 0, 0, 0);
    cout << memo[n][m][0][0][0][0][0] << "\n";
}
accuracy: 1
time_ms: 20
memory_kb: 214880
final_rank: 17

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

using f64 = long double;

} // namespace macro

using namespace macro;
#line 3 "A.cpp"

map<pair<int,int>, int> memo[55][55][2][2];

int main() {
    int n = in(), m = in();
    vector<int> a = in(n), b = in(m);

    auto dfs = [&](auto self, int i, int j, int turn, int pass, int Asum, int Bsum) -> int {
        if(memo[i][j][turn][pass].count({Asum, Bsum})) return memo[i][j][turn][pass][{Asum, Bsum}];
        if(turn) {
            int ans = -1e9;
            if(i != n) {
                if(a[i] == -1) {
                    chmax(ans, - self(self, i + 1, j, turn ^ 1, 0, Asum, 0));
                } else {
                    chmax(ans, - self(self, i + 1, j, turn ^ 1, 0, Asum + a[i], Bsum));
                }
            }

            if(pass) {
                chmax(ans, Asum - Bsum);
            } else {
                if(make_pair(Asum, Bsum) == make_pair(0, 0)) {
                    chmax(ans, - self(self, i, j, turn ^ 1, 1, 0, 0));
                } else {
                    chmax(ans, - self(self, i, j, turn ^ 1, 0, 0, 0) + Asum - Bsum);
                }
            }

            return memo[i][j][turn][pass][{Asum, Bsum}] = ans;
        } else {
            int ans = -1e9;
            if(j != m) {
                if(b[j] == -1) {
                    chmax(ans, - self(self, i, j + 1, turn ^ 1, 0, 0, Bsum));
                } else {
                    chmax(ans, - self(self, i, j + 1, turn ^ 1, 0, Asum, Bsum + b[j]));
                }
            }

            if(pass) {
                chmax(ans, Bsum - Asum);
            } else {
                if(make_pair(Asum, Bsum) == make_pair(0, 0)) {
                    chmax(ans, - self(self, i, j, turn ^ 1, 1, 0, 0));
                } else {
                    chmax(ans, - self(self, i, j, turn ^ 1, 0, 0, 0) + Bsum - Asum);
                }
            }

            return memo[i][j][turn][pass][{Asum, Bsum}] = ans;
        }
    };

    print(dfs(dfs, 0, 0, 1, 0, 0, 0));
}
accuracy: 1
time_ms: 20
memory_kb: 15564
final_rank: 3

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,s,t) for (int i = (int)(s); i < (int)(t); ++i)
#define all(x) (x).begin(), (x).end()

int main(){
    int n,m;
    cin>>n>>m;
    vector<int> a(n),b(m);
    for(auto&x:a)cin>>x;
    for(auto&x:b)cin>>x;

    map<tuple<int,int,int,int,int,bool>, int> memo;

    auto calc_score = [&](int itaken, int jtaken, int istack, int jstack, int turn) {
        int t;
        if (istack < jstack) t = 1;
        else if (istack > jstack) t = 0;
        else if (turn == 0) t = 0;
        else t = 1;

        int ascore = 0, bscore = 0;
        rep(_,0,istack+jstack){
            if (t == 0) {
                if (a[itaken] == -1) {
                    bscore = 0;
                } else {
                    ascore += a[itaken];
                }
                ++itaken;
            } else {
                if (b[jtaken] == -1) {
                    ascore = 0;
                } else {
                    bscore += b[jtaken];
                }
                ++jtaken;
            }
            t ^= 1;
        }
        return ascore - bscore;
    };


    auto rec=[&](auto& rec, int itaken, int jtaken, int istack, int jstack, int turn, bool passed) -> int{
        if(memo.count({itaken,jtaken,istack,jstack,turn,passed})) return memo[{itaken,jtaken,istack,jstack,turn,passed}];

        int res;

        if (turn==0){
            res = -1e9;
            if (itaken+istack < n) {
                res=max(res, rec(rec, itaken, jtaken, istack+1, jstack, 1, false));
            }
            if (passed) {
                res=max(res, 0);
            }else{
                res=max(res, calc_score(itaken, jtaken, istack, jstack, turn) + rec(rec, itaken+istack, jtaken+jstack, 0, 0, 1, istack+jstack==0));
            }
        } else {
            res = 1e9;
            if (jtaken+jstack < m) {
                res=min(res, rec(rec, itaken, jtaken, istack, jstack+1, 0, false));
            }
            if (passed) {
                res=min(res, 0);
            }else{
                res=min(res, calc_score(itaken, jtaken, istack, jstack, turn) + rec(rec, itaken+istack, jtaken+jstack, 0, 0, 0, istack+jstack==0));
            }
        }

        return memo[{itaken,jtaken,istack,jstack,turn,passed}] = res;
    };


    cout<<rec(rec, 0, 0, 0, 0, 0, false)<<endl;
}
accuracy: 1
time_ms: 70
memory_kb: 17864
final_rank: 7

code_snippet: #include "bits/stdc++.h"

using namespace std;

using ll=long long;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n,m;cin>>n>>m;
    vector<vector<ll>>card(2);
    for (int i = 0; i <n; ++i) {
        ll a;cin>>a;
        card[0].emplace_back(a);
    }
    for (int i = 0; i < m; ++i) {
        ll b;cin>>b;
        card[1].emplace_back(b);
    }
    map<array<int,6>,ll>dp;
    auto f=[&](auto f,int si,int i,int sj,int j,int p,int q)->ll{
        int p2=1-p;
        if(q==3)return 0LL;
        if(dp.count({si,i,sj,j,p,q}))return dp[{si,i,sj,j,p,q}];
        ll now=0;
        for (int k =si; k <i; ++k) {
            if(card[0][k]==-1)continue;
            now+=card[0][k];
        }
        for (int k =sj; k <j; ++k) {
            if(card[1][k]==-1)continue;
            now-=card[1][k];
        }
        ll pass_score=now+f(f,i,i,j,j,p2,q+1);
        ll play_score=pass_score;
        if(p==0){
            if(i!=n){
                if(card[p][i]==-1)play_score=f(f,si,i+1,j,j,p2,0);
                else play_score=f(f,si,i+1,sj,j,p2,0);
            }
        }
        else{
            if(j!=m){
                if(card[p][j]==-1)play_score=f(f,i,i,sj,j+1,p2,0);
                else play_score=f(f,si,i,sj,j+1,p2,0);
            }
        }
        ll ret;
        if(p==0)ret=max(pass_score,play_score);
        else ret=min(pass_score,play_score);
        return dp[{si,i,sj,j,p,q}]=ret;
    };
    cout<<f(f,0,0,0,0,0,0)<<"\n";
//    cout<<dp[{0,0,0,0,0,0}]<<endl;
}
accuracy: 1
time_ms: 70
memory_kb: 17972
final_rank: 8

code_snippet: #include "bits/stdc++.h"

using namespace std;

using ll=long long;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n,m;cin>>n>>m;
    vector<ll>a(n);
    vector<ll>b(m);
    for(auto &i:a)cin>>i;
    for(auto &i:b)cin>>i;
    map<array<int,6>,ll>dp;
    auto f=[&](auto f,int si,int i,int sj,int j,int p,int q)->ll{
        int p2=1-p;
        if(q==3)return 0LL;
        if(dp.count({si,i,sj,j,p,q}))return dp[{si,i,sj,j,p,q}];
        //先手ー後手の値を返す
        if(p==0){//先手番 maxにしたい
            //pass
            ll now=0;
            for (int k =si; k <i; ++k) {
                if(a[k]==-1)continue;
                now+=a[k];
            }
            for (int k =sj; k <j; ++k) {
                if(b[k]==-1)continue;
                now-=b[k];
            }
            ll ret;
            ret=now+f(f,i,i,j,j,p2,q+1);
            if(i!=n){
                if(a[i]==-1) {
                    ret = max(ret, f(f, si, i +1,j,j,p2,0));
                }
                else{
                    ret=max(ret,f(f,si,i+1,sj,j,p2,0));
                }
            }
            return dp[{si,i,sj,j,p,0}]=ret;
        }
        else{
            ll now=0;
            for (int k =si; k <i; ++k) {
                if(a[k]==-1)continue;
                now+=a[k];
            }
            for (int k =sj; k <j; ++k) {
                if(b[k]==-1)continue;
                now-=b[k];
            }
            ll ret;
            ret=now+f(f,i,i,j,j,p2,q+1);
            if(j!=m){
                if(b[j]==-1){
                    ret=min(ret,f(f,i,i,sj,j+1,p2,0));
                }
                else{
                    ret=min(ret,f(f,si,i,sj,j+1,p2,0));
                }
            }
            return dp[{si,i,sj,j,p,q}]=ret;
        }
    };
    cout<<f(f,0,0,0,0,0,0)<<"\n";
//    cout<<dp[{0,0,0,0,0,0}]<<endl;
}
accuracy: 1
time_ms: 110
memory_kb: 17736
final_rank: 14

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = int;

using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using vvvvll = vector<vvvll>;
using vvvvvll = vector<vvvvll>;
using vvvvvvll = vector<vvvvvll>;
#define rep(i,n) for(ll i=0;i<ll(n);i++) 

ll N, M;
vll A, B;
vvvvvvll DP;
ll dfs(ll n, ll m, ll i, ll j, bool t,ll e) {
    
    if (DP[n][m][i][j][t][e] < 1e9) {
        return DP[n][m][i][j][t][e];
    }
    ll MA;
    if (t) {
        MA = -5e8;
        if (n < N) {
            if (A[n] == -1) {
                MA = max(MA, dfs(n + 1, m, i, m, !t,0));
            }
            else MA = max(MA, dfs(n+1, m, i, j, !t,0));
        }
        ll sa = 0;
        for (ll k = i; k < n; k++) {
            if(A[k]!=-1)sa += A[k];
        }
        for (ll k = j; k < m; k++) {
            if(B[k]!=-1)sa -= B[k];
        }
        if (e==1&&m==j&&n==i) {
            MA = max(MA,sa);
        }
        else if(m==j&&n==i){
            MA = max(MA, dfs(n, m, n, m, !t,1) + sa);
        }
        else MA = max(MA, dfs(n, m, n, m, !t,0) + sa);
    }
    else {
        MA = 5e8;
        if (m < M) {
            if (B[m] == -1) {
                MA = min(MA, dfs(n, m+1, n, j, !t, 0));
            }
            else MA = min(MA, dfs(n, m+1, i, j, !t,0));
        }
        ll sa = 0;
        for (ll k = i; k < n; k++) {
            if(A[k]!=-1)sa += A[k];
        }
        for (ll k = j; k < m; k++) {
            if(B[k]!=-1)sa -= B[k];
        }
        if (e==1&&m==j&&n==i) {
            MA = min(MA,sa);
        }
        else if(m==j&&n==i){
            MA = min(MA, dfs(n, m, n, m, !t,1) + sa);
        }
        else MA = min(MA, dfs(n, m, n, m, !t,0) + sa);
    }
    DP[n][m][i][j][t][e] = MA;
    return MA;
}

int main() {

    cin >> N >> M;
    A.resize(N);
    B.resize(M);
    rep(i, N)cin >> A[i];
    rep(i, M)cin >> B[i];

    DP.resize(N + 1, vvvvvll(M + 1));
    rep(n,N+1){
        rep(m,M+1){
            DP[n][m].assign(n+1,vvvll(m+1,vvll(2,vll(3,1e9))));
        }
    }

    cout << dfs(0, 0, 0, 0, 1,0) << endl;

}
accuracy: 1
time_ms: 220
memory_kb: 266964
final_rank: 19

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;

using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using vvvvll = vector<vvvll>;
#define rep(i,n) for(ll i=0;i<ll(n);i++) 

ll N, M;
vll A, B;
vvvvll DP;
ll dfs(ll n, ll m, ll i, ll j, bool t,bool e) {
    
    if (DP[n][m][i][j] <= 1e17) {
        return DP[n][m][i][j];
    }
    ll MA;
    if (t) {
        MA = -1e17;
        if (n < N) {
            if (A[n] == -1) {
                MA = max(MA, dfs(n + 1, m, i, m, !t, 0));
            }
            else MA = max(MA, dfs(n+1, m, i, j, !t,0));
        }
        ll sa = 0;
        for (ll k = i; k < n; k++) {
            if(A[k]!=-1)sa += A[k];
        }
        for (ll k = j; k < m; k++) {
            if(B[k]!=-1)sa -= B[k];
        }
        if (e&&m==j&&n==i) {
            MA = max(MA,sa);
        }
        else if(m==j&&n==i){
            MA = max(MA, dfs(n, m, n, m, !t,1) + sa);
        }
        else MA = max(MA, dfs(n, m, n, m, !t,0) + sa);
    }
    else {
        MA = 1e17;
        if (m < M) {
            if (B[m] == -1) {
                MA = min(MA, dfs(n, m+1, n, j, !t, 0));
            }
            else MA = min(MA, dfs(n, m+1, i, j, !t,0));
        }
        ll sa = 0, sb = 0;
        for (ll k = i; k < n; k++) {
            if(A[k]!=-1)sa += A[k];
        }
        for (ll k = j; k < m; k++) {
            if(B[k]!=-1)sa -= B[k];
        }
        if (e&&m==j&&n==i) {
            MA = min(MA,sa);
        }
        else if(m==j&&n==i){
            MA = min(MA, dfs(n, m, n, m, !t,1) + sa);
        }
        else MA = min(MA, dfs(n, m, n, m, !t,0) + sa);
    }
    DP[n][m][i][j] = MA;
    return MA;
}

int main() {

    cin >> N >> M;
    A.resize(N);
    B.resize(M);
    rep(i, N)cin >> A[i];
    rep(i, M)cin >> B[i];

    DP.assign(N + 1, vvvll(M + 1, vvll(N + 1, vll(M + 1, 1e18))));

    cout << dfs(0, 0, 0, 0, 1,0) << endl;

}
accuracy: 0.8648648648648649
time_ms: 20
memory_kb: 61392
final_rank: 20