#include <stdio.h>
#define MAX 100001

long long pref[MAX];
int n;

int main()
{
	int i, k;
	long long sum = 0;
	scanf("%d", &n);
	for (i = 0; i < n; i++) {
		scanf("%d", &k);
		sum += k;
		pref[i] = sum;
	}

	int count = 0;
	for (i = 0; i < n-1; i++)
		if (pref[i] == sum-pref[i])
			count++;
	printf("%d\n", count);

	return 0;
}


#include <stdio.h>
#define MAX 10001

long long pref[MAX];
int n;

int main()
{
	int i, k, sum = 0;
	scanf("%d", &n);
	for (i = 0; i < n; i++) {
		scanf("%d", &k);
		sum += k;
		pref[i] = sum;
	}

	int count = 0;
	for (i = 0; i < n-1; i++)
		if (pref[i] == sum-pref[i])
			count++;
	printf("%d\n", count);

	return 0;
}


#include <cstdio>

#define ll long long

using namespace std;

int main()
{
	int n, d, m, l;
	ll p = 0;
	scanf( "%d%d%d%d", &n, &d, &m, &l );
	while(1)
	{
		if( p%m>l || p/n>=m )
		{
			printf( "%lld", p );
			break;
		}
		if( p && p%m==0 )
		{
			printf( "%lld", (((ll)n*m+d-1)/d)*d );
			break;
		}
		p += d;
	}
	return 0;
}


#include <stdio.h>

int n, s[10000], ans, i;
long long l, r;

int main()
{
	scanf( "%d", &n );
	for( i = 0; i < n; i++ )
	{
		scanf( "%d", &s[i] );
		r += s[i];
	}
	for( i = 0; i < n-1; i++ )
	{
		l += s[i]; r -= s[i];
		if( l==r ) ans++;
	}
	printf( "%d\n", ans );
	return 0;
}


#include <stdio.h>

int n, s[10000], ans, i;
long long l, r;

int main()
{
	scanf( "%d", &n );
	for( i = 0; i < n; i++ )
	{
		scanf( "%d", &s[i] );
		r += s[i];
	}
	for( i = 0; i < n-1; i++ )
	{
		l += s[i], r -= s[i];
		if( l==r ) ans++;
	}
	printf( "%d\n", ans );
	return 0;
}


#include <stdio.h>

int n, s[10000], ans, i;
//long long l, r;
int l, r;

int main()
{
	scanf( "%d", &n );
	for( i = 0; i < n; i++ )
	{
		scanf( "%d", &s[i] );
		r += s[i];
	}
	for( i = 0; i < n-1; i++ )
	{
		l += s[i], r -= s[i];
		if( l==r ) ans++;
	}
	printf( "%d", ans );
	return 0;
}


#include<stdio.h>
int main()
    {
    int n;
    scanf("%d",&n);
    int a[100000],i;
    long long int S=0,S1=0,ans=0;
    for(i=0;i<n;i++)
        {
        scanf("%d",&a[i]);
        S+=a[i];
        }
    for(i=0;i<n-1;i++)
        {
        S1+=a[i];
        if(S-S1==S1)
            {
            ans++;
            }
        }
    printf("%I64d",ans);
    return 0;
    }


#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<ctype.h>

#define N 112345

int a[N];
int tot;
int n;

main()
{
 // freopen( "input.dat", "r", stdin );
  int i, o, p, j, k;
  int l, r;
  l = 0;
  r = 0;
  scanf( "%d", &n );
  for (i=0;i<n;++i)
  {
    scanf( "%d", &a[i] );
    r += a[i];
  }
  for (i=0;i<n-1;++i)
  {
    l += a[i];
    r -= a[i];
    if (l==r) ++tot;
  }
  printf( "%d\n", tot );
  return 0;
}


#include <algorithm>
#include <bitset>
#include <cassert>
#include <chrono>
#include <climits>
#include <cmath>
#include <complex>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <iomanip>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <cstdint>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pii;
#define MP make_pair
#define PB push_back
#define inf 1000000007
#define rep(i,n) for(int i = 0; i < (int)(n); ++i)
#define all(x) (x).begin(),(x).end()

template<typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val){
    std::fill( (T*)array, (T*)(array+N), val );
}

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

template<class T> inline bool chmin(T &a, T b){
    if(a>b){
        a = b;
        return true;
    }
    return false;
}
int a[300010][2];
int b[300010];
pair<int,int> na[300010][2];
int nb[300010];

map<pair<int,int>,int> mp;

ll dfs(int i,int j){
    if(mp.find(MP(i,j))!=mp.end()){
        return mp[MP(i,j)];
    }
    int k = max(i,j);
    int nk = nb[k];
    int ni = na[i][0].first;
    int ri = na[i][0].second;
    int nj = na[j][1].first;
    int rj = na[j][1].second;
    // cerr << i << " " << j << " " << ni << " " << nj << " " << nk << endl;
    if(nk > ni|| nk > nj){
        if(nk>ni){
            return mp[MP(i,j)] = dfs(ni,j) + 1;
        }else{
            return mp[MP(i,j)] = dfs(i,nj) + 1;
        }
    }
    if(nk!=inf){
        if(ri<=nk&&rj<=nk){
            return mp[MP(i,j)] = max(dfs(nk,nk) + 1,dfs(ni,nj) + 2);
        }else{
            return mp[MP(i,j)] = dfs(nk,nk) + 1;
        }
    }else{
        if(ni==inf&&nj==inf){
            return 0;
        }
        if(ni!=inf){
            return mp[MP(i,j)] = dfs(ni,j) + 1;
        }else if(nj!=inf){
            return mp[MP(i,j)] = dfs(i,nj) + 1;
        }
    }

}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n;
    cin >> n;
    map<ll,int> s[2],u;
    rep(j,2){
        rep(i,n){
            cin >> a[i][j];
        }
    }
    ll c = 0;
    Fill(na,MP(inf,inf));
    Fill(nb,inf);
    rep(j,2){
        s[j][0] = n;
        s[j][1] = n;
        for(int i=n-1;i>=0;i--){
            c += a[i][j];
            if(s[j].find(c)!=s[j].end()){
                na[i][j] = MP(s[j][c],i);
            }else{
                na[i][j] = MP(inf,inf);
            }
            s[j][c] = i;
        }
        for(int i=n-2;i>=0;i--){
            chmin(na[i][j],na[i+1][j]);
        }
    }
    c = 0;
    u[0] = n;
    for(int i=n-1;i>=0;i--){
        c += a[i][0]+a[i][1];
        if(u.find(c)!=u.end()){
            nb[i] = u[c];
        }else{
            nb[i] = inf;
        }
        u[c] = i;
    }
    for(int i=n-2;i>=0;i--){
        chmin(nb[i],nb[i+1]);
    }
    cout << dfs(0,0) << endl;
    return 0;
}


#include <algorithm>
#include <bitset>
#include <cassert>
#include <chrono>
#include <climits>
#include <cmath>
#include <complex>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <iomanip>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <cstdint>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pii;
#define MP make_pair
#define PB push_back
#define inf 1000000007
#define rep(i,n) for(int i = 0; i < (int)(n); ++i)
#define all(x) (x).begin(),(x).end()

template<typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val){
    std::fill( (T*)array, (T*)(array+N), val );
}

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

template<class T> inline bool chmin(T &a, T b){
    if(a>b){
        a = b;
        return true;
    }
    return false;
}
int a[300010][2];
int b[300010];
pair<int,int> na[300010][2];
int nb[300010];

map<pair<int,int>,int> mp;

ll dfs(int i,int j){
    if(mp.find(MP(i,j))!=mp.end()){
        return mp[MP(i,j)];
    }
    int k = max(i,j);
    int nk = nb[k];
    int ni = na[i][0].first;
    int ri = na[i][0].second;
    int nj = na[j][1].first;
    int rj = na[j][1].second;
    // cerr << i << " " << j << " " << ni << " " << nj << " "<< ri  << " " << rj  << " " << nk << endl;
    if(nk > ni|| nk > nj){
        if(nk>ni){
            return mp[MP(i,j)] = dfs(ni,j) + 1;
        }else{
            return mp[MP(i,j)] = dfs(i,nj) + 1;
        }
    }
    if(nk!=inf){
        if(ri<=nk&&rj<=nk){
            return mp[MP(i,j)] = max(dfs(nk,nk) + 1,dfs(ni,nj) + 2);
        }else{
            return mp[MP(i,j)] = dfs(nk,nk) + 1;
        }
    }else{
        if(ni==inf&&nj==inf){
            return 0;
        }
        if(ni<nj){
            return mp[MP(i,j)] = dfs(ni,j) + 1;
        }else{
            return mp[MP(i,j)] = dfs(i,nj) + 1;
        }
    }

}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n;
    cin >> n;
    map<ll,int> s[2],u;
    rep(j,2){
        rep(i,n){
            cin >> a[i][j];
        }
    }
    ll c = 0;
    Fill(na,MP(inf,inf));
    Fill(nb,inf);
    rep(j,2){
        c = 0;
        s[j][0] = n;
        for(int i=n-1;i>=0;i--){
            c += a[i][j];
            if(s[j].find(c)!=s[j].end()){
                na[i][j] = MP(s[j][c],i);
            }else{
                na[i][j] = MP(inf,inf);
            }
            s[j][c] = i;
        }
        for(int i=n-2;i>=0;i--){
            chmin(na[i][j],na[i+1][j]);
        }
    }
    c = 0;
    u[0] = n;
    for(int i=n-1;i>=0;i--){
        c += a[i][0]+a[i][1];
        if(u.find(c)!=u.end()){
            nb[i] = u[c];
        }else{
            nb[i] = inf;
        }
        u[c] = i;
    }
    for(int i=n-2;i>=0;i--){
        chmin(nb[i],nb[i+1]);
    }
    cout << dfs(0,0) << endl;
    return 0;
}


#include <algorithm>
#include <bitset>
#include <cassert>
#include <chrono>
#include <climits>
#include <cmath>
#include <complex>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <iomanip>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <cstdint>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pii;
#define MP make_pair
#define PB push_back
#define inf 1000000007
#define rep(i,n) for(int i = 0; i < (int)(n); ++i)
#define all(x) (x).begin(),(x).end()

template<typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val){
    std::fill( (T*)array, (T*)(array+N), val );
}

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

template<class T> inline bool chmin(T &a, T b){
    if(a>b){
        a = b;
        return true;
    }
    return false;
}
int a[300010][2];
int b[300010];
pair<int,int> na[300010][2];
int nb[300010];

map<pair<int,int>,int> mp;

ll dfs(int i,int j){
    if(mp.find(MP(i,j))!=mp.end()){
        return mp[MP(i,j)];
    }
    int k = max(i,j);
    int nk = nb[k];
    int ni = na[i][0].first;
    int ri = na[i][0].second;
    int nj = na[j][1].first;
    int rj = na[j][1].second;
    // cerr << i << " " << j << " " << ni << " " << nj << " " << nk << endl;
    if(nk > ni|| nk > nj){
        if(nk>ni){
            return mp[MP(i,j)] = dfs(ni,j) + 1;
        }else{
            return mp[MP(i,j)] = dfs(i,nj) + 1;
        }
    }
    if(nk!=inf){
        if(ri<=k&&rj<=k){
            return mp[MP(i,j)] = max(dfs(nk,nk) + 1,dfs(ni,nj) + 2);
        }else{
            return mp[MP(i,j)] = dfs(nk,nk) + 1;
        }
    }else{
        if(ni==inf&&nj==inf){
            return 0;
        }
        if(ni!=inf){
            return mp[MP(i,j)] = dfs(ni,j) + 1;
        }else if(nj!=inf){
            return mp[MP(i,j)] = dfs(i,nj) + 1;
        }
    }

}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n;
    cin >> n;
    map<ll,int> s[2],u;
    rep(j,2){
        rep(i,n){
            cin >> a[i][j];
        }
    }
    ll c = 0;
    Fill(na,MP(inf,inf));
    Fill(nb,inf);
    rep(j,2){
        s[j][0] = n;
        s[j][1] = n;
        for(int i=n-1;i>=0;i--){
            c += a[i][j];
            if(s[j].find(c)!=s[j].end()){
                na[i][j] = MP(s[j][c],i);
            }else{
                na[i][j] = MP(inf,inf);
            }
            s[j][c] = i;
        }
        for(int i=n-2;i>=0;i--){
            chmin(na[i][j],na[i+1][j]);
        }
    }
    c = 0;
    u[0] = n;
    for(int i=n-1;i>=0;i--){
        c += a[i][0]+a[i][1];
        if(u.find(c)!=u.end()){
            nb[i] = u[c];
        }else{
            nb[i] = inf;
        }
        u[c] = i;
    }
    for(int i=n-2;i>=0;i--){
        chmin(nb[i],nb[i+1]);
    }
    cout << dfs(0,0) << endl;
    return 0;
}


#include <algorithm>
#include <bitset>
#include <cassert>
#include <chrono>
#include <climits>
#include <cmath>
#include <complex>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <iomanip>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <cstdint>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef pair<int,int> pii;
#define MP make_pair
#define PB push_back
#define inf 1000000007
#define rep(i,n) for(int i = 0; i < (int)(n); ++i)
#define all(x) (x).begin(),(x).end()

template<typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val){
    std::fill( (T*)array, (T*)(array+N), val );
}

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

template<class T> inline bool chmin(T &a, T b){
    if(a>b){
        a = b;
        return true;
    }
    return false;
}
int a[300010][2];
int b[300010];
pair<int,int> na[300010][2];
int nb[300010];

map<pair<int,int>,int> mp;

ll dfs(int i,int j){
    if(mp.find(MP(i,j))!=mp.end()){
        return mp[MP(i,j)];
    }
    int k = max(i,j);
    int nk = nb[k];
    int ni = na[i][0].first;
    int ri = na[i][0].second;
    int nj = na[j][1].first;
    int rj = na[j][1].second;
    // cerr << i << " " << j << " " << ni << " " << nj << " " << nk << endl;
    if(nk > ni|| nk > nj){
        if(nk>ni){
            return mp[MP(i,j)] = dfs(ni,j) + 1;
        }else{
            return mp[MP(i,j)] = dfs(i,nj) + 1;
        }
    }
    if(nk!=inf){
        if(ri<=nk&&rj<=nk){
            return mp[MP(i,j)] = max(dfs(nk,nk) + 1,dfs(ni,nj) + 2);
        }else{
            return mp[MP(i,j)] = dfs(nk,nk) + 1;
        }
    }else{
        if(ni==inf&&nj==inf){
            return 0;
        }
        if(ni<nj){
            return mp[MP(i,j)] = dfs(ni,j) + 1;
        }else{
            return mp[MP(i,j)] = dfs(i,nj) + 1;
        }
    }

}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int n;
    cin >> n;
    map<ll,int> s[2],u;
    rep(j,2){
        rep(i,n){
            cin >> a[i][j];
        }
    }
    ll c = 0;
    Fill(na,MP(inf,inf));
    Fill(nb,inf);
    rep(j,2){
        s[j][0] = n;
        s[j][1] = n;
        for(int i=n-1;i>=0;i--){
            c += a[i][j];
            if(s[j].find(c)!=s[j].end()){
                na[i][j] = MP(s[j][c],i);
            }else{
                na[i][j] = MP(inf,inf);
            }
            s[j][c] = i;
        }
        for(int i=n-2;i>=0;i--){
            chmin(na[i][j],na[i+1][j]);
        }
    }
    c = 0;
    u[0] = n;
    for(int i=n-1;i>=0;i--){
        c += a[i][0]+a[i][1];
        if(u.find(c)!=u.end()){
            nb[i] = u[c];
        }else{
            nb[i] = inf;
        }
        u[c] = i;
    }
    for(int i=n-2;i>=0;i--){
        chmin(nb[i],nb[i+1]);
    }
    cout << dfs(0,0) << endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 3.1e5;

int64_t a[2][N];
int n;
map<int64_t, int> last[3];
int nx[3][N];
map<pair<int, int>, int> f;

int dfs(pair<int, int> p) {
    const int &x = p.first, &y = p.second;
    if (x <= 0 && y <= 0) return 0;
    if (f.count(p)) return f[p];
    int& ans = f[p];
    int z2 = nx[2][min(x, y)];
    if (z2 >= 0) ans = max(ans, dfs({z2, z2}) + 1);
    if (nx[0][x] > nx[1][y] && nx[0][x] >= 0)
        ans = max(ans, dfs({nx[0][x], y}) + 1);
    else if (nx[1][y] >= 0)
        ans = max(ans, dfs({x, nx[1][y]}) + 1);
    return ans;
}

int main() {
    scanf("%d", &n);
    for (int i = 0;  i < 2; ++i)
        for (int j = 1; j <= n; ++j) {
            int x;
            scanf("%d", &x);
            a[i][j] = x;
        }
    int64_t s[3] = {0, 0, 0};
    for (int i = 0; i < 3; ++i) last[i][0] = 0, nx[i][0] = -1;

    for (int i = 1; i <= n; ++i) {
        s[0] += a[0][i];
        s[1] += a[1][i];
        s[2] += a[0][i] + a[1][i];
        for (int j = 0; j < 3; ++j) {
            nx[j][i] = nx[j][i - 1];
            if (last[j].count(s[j])) {
                nx[j][i] = max(nx[j][i], last[j][s[j]]);
            }
            last[j][s[j]] = i;
        }
    }
    f[{0, 0}] = 0;
    cout << dfs({n, n}) << endl;
}


#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/rope>

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

typedef long long ll;
typedef long double ld;
typedef complex<ld> cd;

typedef pair<int, int> pi;
typedef pair<ll,ll> pl;
typedef pair<ld,ld> pd;

typedef vector<int> vi;
typedef vector<ld> vd;
typedef vector<ll> vl;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<cd> vcd;

template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

#define FOR(i, a, b) for (int i=a; i<(b); i++)
#define F0R(i, a) for (int i=0; i<(a); i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= a; i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)

#define sz(x) (int)(x).size()
#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound
#define all(x) x.begin(), x.end()

const int MOD = 1000000007;
const ll INF = 1e18;
const int MX = 300001;

namespace io {
    template<typename Test, template<typename...> class Ref>
    struct is_specialization : std::false_type {};

    template<template<typename...> class Ref, typename... Args>
    struct is_specialization<Ref<Args...>, Ref>: std::true_type {};
    // https://stackoverflow.com/questions/16337610/how-to-know-if-a-type-is-a-specialization-of-stdvector

    void setIn(string s) { freopen(s.c_str(),"r",stdin); }
    void setOut(string s) { freopen(s.c_str(),"w",stdout); }
    void setIO(string s = "") {
        ios_base::sync_with_stdio(0); cin.tie(0);
        if (sz(s)) { setIn(s+".in"), setOut(s+".out"); }
    }

    // INPUT

    // double input seems slow on CF
    void re(double& x) { string t; cin >> t; x = stod(t); }
    void re(ld& x) { string t; cin >> t; x = stold(t); }
    template<class T> void re(T& x) { cin >> x; }
    template<class Arg, class... Args> void re(Arg& first, Args&... rest) {
        re(first); re(rest...);
    }
    template<class T1, class T2> istream& operator>>(istream& is, pair<T1,T2>& p) {
        is >> p.f >> p.s; return is;
    }
    template<class T> istream& operator>>(istream& is, vector<T>& a) {
        F0R(i,sz(a)) is >> a[i];
        return is;
    }

    // OUTPUT

    template<class T> void pr(const T& x) { cout << x << '\n'; }
    template<class Arg, class... Args> void pr(const Arg& first, const Args&... rest) {
        cout << first << ' '; pr(rest...);
    }
    template<class T1, class T2> ostream& operator<<(ostream& os, const pair<T1,T2>& a) {
        os << '{' << a.f << ", " << a.s << '}'; return os;
    }
    template<class T> ostream& operator<<(ostream& os, const vector<T>& a) {
        os << '{';
        F0R(i,sz(a)) {
            if (i) {
                os << ", ";
                if (is_specialization<T, vector>::value) os << '\n';
            }
            os << a[i];
        }
        os << '}';
        return os;
    }
}

using namespace io;

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM =
            chrono::steady_clock::now()
            .time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

template<class T> using um = unordered_map<ll, T, custom_hash>;
template<class T> using ht = gp_hash_table<ll, T, custom_hash>;

template<class T> T get(ht<T>& u, ll x) {
   if (u.find(x) == u.end()) return -1;
   return u[x];
}

ht<int> h;

int n, val[3][MX];
vl a[2];
map<ll,int> m[3];

int solve(int a, int b) {
    if (min(a,b) == -1) return -1;

    ll t = (ll)MX*a+b;
    int res = get(h,t);
    if (res != -1) return res;

    res = 0;
    int v = val[2][min(a,b)];
    res = max(res,solve(v,v)+1);

    int x = val[0][a], y = val[1][b];
    if (x < y) res = max(res,solve(a,y)+1);
    else res = max(res,solve(x,b)+1);

    return h[t] = res;
}

int main() {
    setIO(); re(n);
    F0R(i,2) {
        a[i].resize(n+1);
        FOR(j,1,n+1) {
            re(a[i][j]);
            a[i][j] += a[i][j-1];
        }
    }
    F0R(i,3) {
        val[i][0] = -1;
        m[i][0] = 0;
    }
    FOR(j,1,n+1) {
        F0R(i,3) val[i][j] = val[i][j-1];

        if (m[0].count(a[0][j])) val[0][j] = max(val[0][j],m[0][a[0][j]]);
        m[0][a[0][j]] = j;

        if (m[1].count(a[1][j])) val[1][j] = max(val[1][j],m[1][a[1][j]]);
        m[1][a[1][j]] = j;

        if (m[2].count(a[0][j]+a[1][j])) val[2][j] = max(val[2][j],m[2][a[0][j]+a[1][j]]);
        m[2][a[0][j]+a[1][j]] = j;
    }
    cout << solve(n,n);
}

/*
* (Actually read this pls)
    * Rlly bad errors: int overflow, array bounds
    * Less bad errors: special cases (n=1?), set tle
    * Common sense: do smth instead of nothing
*/


#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=3e5+2;
vector<pair<pair<int,int>,int> > ex[N];
int n,nxt[2][2][N],sum[2][N],ans[N];
void con(int x,int y,int val){
	ans[max(x,y)]=max(ans[max(x,y)],val);
	ex[min(x,y)].push_back({{x,y},val});
}
void go(int x,int y,int val){
	if(x<n){
		con(x+1,y,val);
		if(nxt[1][0][x]<N){
			con(nxt[1][0][x],y,val+1);
		}
	}
	if(y<n){
		con(x,y+1,val);
		if(nxt[0][1][y]<N){
			con(x,nxt[0][1][y],val+1);
		}
	}
	if(x==y&&x<n){
		con(x+1,y+1,val);
		if(nxt[1][1][x]<N){
			con(nxt[1][1][x],nxt[1][1][x],val+1);
		}
	}
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	int m,i,j,k,l,z;
	cin>>n;
	for(i=0;i<2;i++){
		for(j=1;j<=n;j++){
			cin>>sum[i][j];
			sum[i][j]+=sum[i][j-1];
		}
	}
	for(i=0;i<2;i++){
		for(j=0;j<2;j++){
			if(!i&&!j){
				continue;
			}
			unordered_map<int,int> occ;
			for(k=0;k<=n;k++){
				nxt[i][j][k]=N;
				z=0;
				if(i){
					z+=sum[0][k];
				}
				if(j){
					z+=sum[1][k];
				}
//				cout<<z<<' ';
				if(occ.count(z)){
					nxt[i][j][occ[z]]=k;
				}
				occ[z]=k;
			}
//			cout<<'\n';
//			for(k=0;k<=n;k++){
//				cout<<nxt[i][j][k]<<' ';
//			}
//			cout<<'\n';
		}
	}
	for(i=0;i<=n;i++){
		go(i,i,ans[i]);
		j=N;
		k=N;
		for(l=0;l<ex[i].size();l++){
			if(ex[i][l].first.first==i&&ex[i][l].second==ans[i]+1){
				k=min(k,ex[i][l].first.second);
			}
			if(ex[i][l].first.second==i&&ex[i][l].second==ans[i]+1){
				j=min(j,ex[i][l].first.first);
			}
		}
		if(j<N){
			go(j,i,ans[i]+1);
		}
		if(k<N){
			go(i,k,ans[i]+1);
		}
	}
	cout<<ans[n];
}


#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
const ll mod = 998244353;
const ll INF = mod * mod;
typedef pair<int, int>P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-12;
const ld pi = acos(-1.0);

ll mod_pow(ll a, ll n, ll m = mod) {
	a %= m;
	ll res = 1;
	while (n) {
		if (n & 1)res = res * a%m;
		a = a * a%m; n >>= 1;
	}
	return res;
}

struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n%mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint &a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint &a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint &a, modint b) { a.n = ((ll)a.n*b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, int n) {
	if (n == 0)return modint(1);
	modint res = (a*a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p%a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }
const int max_n = 1 << 18;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}

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

void solve() {
	int n; cin >> n;
	vector<vector<ll>> v(2, vector<ll>(n));
	rep(i, 2)rep(j, n)cin >> v[i][j];
	vector<pair<P, int>> up,dow;

	vector<int> r0(n,mod), r1(n,mod),r2(n,mod);
	map<ll, int> mp;
	ll sum = 0;
	mp[sum] = 0;
	rep(j, n) {
		sum += v[0][j];
		if (mp.find(sum) != mp.end()) {
			r0[mp[sum]] = j;
		}
		mp[sum] = j+1;
	}

	mp.clear(); sum = 0;
	mp[sum] = 0;
	rep(j, n) {
		sum += v[1][j];
		if (mp.find(sum) != mp.end()) {
			r1[mp[sum]] = j;
		}
		mp[sum] = j+1;
	}
	mp.clear(); sum = 0;
	mp[sum] = 0;
	rep(j, n) {
		sum += v[0][j] + v[1][j];
		if (mp.find(sum) != mp.end()) {
			r2[mp[sum]] = j;
		}
		mp[sum] = j+1;
	}

	vector<int> to0(n), to1(n), to2(n);
	int ri = mod;
	per(i, n) {
		ri = min(ri, r0[i]);
		to0[i] = ri;
	}
	ri = mod;
	per(i, n) {
		ri = min(ri, r1[i]);
		to1[i] = ri;
	}
	ri = mod;
	per(i, n) {
		ri = min(ri, r2[i]);
		to2[i] = ri;
	}

	vector<P> vs;
	vs.push_back({ 0,0 });
	int ans = 0;
	while (vs.size()) {
		vector<P> nex;
		for (P p : vs) {
			int l = p.first;
			int r = p.second;
			//cout<<ans<<" "<<l<<" "<<r<<"\n";
			if (r<n) {
				int nr = to1[r] + 1;
				if (nr <= n) {
					nex.push_back({ l,nr });
				}
			}
			if (l<n) {
				int nl = to0[l] + 1;
				if (nl <= n) {
					nex.push_back({ nl,r });
				}
			}
			if (max(l, r) < n) {
				int to = to2[max(l, r)] + 1;
				if (to <=n) {
					nex.push_back({ to,to });
				}
			}
		}
		sort(all(nex));
		vs.clear();
		int le = mod;
		rep(i, nex.size()) {
			if (le > nex[i].second) {
				vs.push_back(nex[i]);
				le = nex[i].second;
			}
		}
		ans++;
	}
	cout << ans - 1 << "\n";
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(7);
	//init_f();
	//init();
	//experi();
	//int t; cin >> t; rep(i, t)solve();
	solve();
	stop
		return 0;
}


#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
const ll mod = 998244353;
const ll INF = mod * mod;
typedef pair<int, int>P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-12;
const ld pi = acos(-1.0);

ll mod_pow(ll a, ll n, ll m = mod) {
	a %= m;
	ll res = 1;
	while (n) {
		if (n & 1)res = res * a%m;
		a = a * a%m; n >>= 1;
	}
	return res;
}

struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n%mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint &a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint &a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint &a, modint b) { a.n = ((ll)a.n*b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, int n) {
	if (n == 0)return modint(1);
	modint res = (a*a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p%a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }
const int max_n = 1 << 18;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}

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

void solve() {
	int n; cin >> n;
	vector<vector<ll>> v(2, vector<ll>(n));
	rep(i, 2)rep(j, n)cin >> v[i][j];
	vector<pair<P, int>> up, dow;

	vector<int> r0(n, mod), r1(n, mod), r2(n, mod);
	map<ll, int> mp;
	ll sum = 0;
	mp[sum] = 0;
	rep(j, n) {
		sum += v[0][j];
		if (mp.find(sum) != mp.end()) {
			//up.push_back({ {j,mp[sum]},-2 });
			r0[mp[sum]] = j;
		}
		mp[sum] = j + 1;
	}

	mp.clear(); sum = 0;
	mp[sum] = 0;
	rep(j, n) {
		sum += v[1][j];
		if (mp.find(sum) != mp.end()) {
			r1[mp[sum]] = j;
		}
		mp[sum] = j + 1;
	}
	mp.clear(); sum = 0;
	mp[sum] = 0;
	int tmp = 0;
	rep(j, n) {
		sum += v[0][j] + v[1][j];
		if (mp.find(sum) != mp.end()) {
			r2[mp[sum]] = j;
			tmp++;
		}
		mp[sum] = j + 1;
	}

	vector<int> to0(n+1,mod), to1(n+1,mod), to2(n+1,mod);
	int ri = mod;
	per(i, n) {
		ri = min(ri, r0[i]);
		to0[i] = ri;
	}
	ri = mod;
	per(i, n) {
		ri = min(ri, r1[i]);
		to1[i] = ri;
	}
	ri = mod;
	per(i, n) {
		ri = min(ri, r2[i]);
		to2[i] = ri;
	}

	vector<P> vs;
	vs.push_back({ 0,0 });
	int ans = 0;
	while (vs.size()) {
		vector<P> nex;
		for (P p : vs) {
			int l = p.first;
			int r = p.second;
			//cout << ans << " " << l << " " << r << "\n";
			int nl = to0[l] + 1;
			int nr = to1[r] + 1;
			if (nl > n&&nr > n) {
				//
			}
			else if (nl > n) {
				nex.push_back({ l,nr });
			}
			else if (nr > n) {
				nex.push_back({ nl,r });
			}
			else {
				if (l < r&&nl < nr) {
					nex.push_back({ nl,r });
				}
				else if (l > r&&nl > nr) {
					nex.push_back({ l,nr });
				}
				else {
					nex.push_back({ l,nr });
					nex.push_back({ nl,r });

				}
			}
			if (max(l, r) < n) {
				int to = to2[max(l, r)] + 1;
				if (to <= n) {
					nex.push_back({ to,to });
				}
			}
		}
		sort(all(nex));
		vs.clear();
		int le = mod;
		rep(i, nex.size()) {
			if (le > nex[i].second) {
				vs.push_back(nex[i]);
				le = nex[i].second;
			}
		}
		ans++;
	}
	cout << ans - 1 << "\n";
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(7);
	//init_f();
	//init();
	//experi();
	//int t; cin >> t; rep(i, t)solve();
	solve();
	stop
		return 0;
}


#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
const ll mod = 998244353;
const ll INF = mod * mod;
typedef pair<int, int>P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-12;
const ld pi = acos(-1.0);

ll mod_pow(ll a, ll n, ll m = mod) {
	a %= m;
	ll res = 1;
	while (n) {
		if (n & 1)res = res * a%m;
		a = a * a%m; n >>= 1;
	}
	return res;
}

struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n%mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint &a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint &a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint &a, modint b) { a.n = ((ll)a.n*b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, int n) {
	if (n == 0)return modint(1);
	modint res = (a*a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p%a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }
const int max_n = 1 << 18;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}

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

void solve() {
	int n; cin >> n;
	vector<vector<ll>> v(2, vector<ll>(n));
	rep(i, 2)rep(j, n)cin >> v[i][j];
	vector<pair<P, int>> up, dow;

	vector<int> r0(n, mod), r1(n, mod), r2(n, mod);
	map<ll, int> mp;
	ll sum = 0;
	mp[sum] = 0;
	rep(j, n) {
		sum += v[0][j];
		if (mp.find(sum) != mp.end()) {
			//up.push_back({ {j,mp[sum]},-2 });
			r0[mp[sum]] = j;
		}
		mp[sum] = j + 1;
	}

	mp.clear(); sum = 0;
	mp[sum] = 0;
	rep(j, n) {
		sum += v[1][j];
		if (mp.find(sum) != mp.end()) {
			r1[mp[sum]] = j;
		}
		mp[sum] = j + 1;
	}
	mp.clear(); sum = 0;
	mp[sum] = 0;
	int tmp = 0;
	rep(j, n) {
		sum += v[0][j] + v[1][j];
		if (mp.find(sum) != mp.end()) {
			r2[mp[sum]] = j;
			tmp++;
		}
		mp[sum] = j + 1;
	}

	vector<int> to0(n+1,mod), to1(n+1,mod), to2(n+1,mod);
	int ri = mod;
	per(i, n) {
		ri = min(ri, r0[i]);
		to0[i] = ri;
	}
	ri = mod;
	per(i, n) {
		ri = min(ri, r1[i]);
		to1[i] = ri;
	}
	ri = mod;
	per(i, n) {
		ri = min(ri, r2[i]);
		to2[i] = ri;
	}

	vector<P> vs;
	vs.push_back({ 0,0 });
	int ans = 0;
	while (vs.size()) {
		vector<P> nex;
		for (P p : vs) {
			int l = p.first;
			int r = p.second;

			int nl = to0[l] + 1;
			int nr = to1[r] + 1;
			if (nl > n&&nr > n) {
				//
			}
			else if (nl > n) {
				nex.push_back({ l,nr });
			}
			else if (nr >= n) {
				nex.push_back({ nl,r });
			}
			else {
				if (l < r&&nl < nr) {
					//
				}
				else if (l > r&&nl > nr) {
					//
				}
				else {
					nex.push_back({ l,nr });
					nex.push_back({ nl,r });

				}
			}
			if (max(l, r) < n) {
				int to = to2[max(l, r)] + 1;
				if (to <= n) {
					nex.push_back({ to,to });
				}
			}
		}
		sort(all(nex));
		vs.clear();
		int le = mod;
		rep(i, nex.size()) {
			if (le > nex[i].second) {
				vs.push_back(nex[i]);
				le = nex[i].second;
			}
		}
		ans++;
	}
	cout << ans - 1 << "\n";
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(7);
	//init_f();
	//init();
	//experi();
	//int t; cin >> t; rep(i, t)solve();
	solve();
	stop
		return 0;
}


#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
const ll mod = 998244353;
const ll INF = mod * mod;
typedef pair<int, int>P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-12;
const ld pi = acos(-1.0);

ll mod_pow(ll a, ll n, ll m = mod) {
	a %= m;
	ll res = 1;
	while (n) {
		if (n & 1)res = res * a%m;
		a = a * a%m; n >>= 1;
	}
	return res;
}

struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n%mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint &a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint &a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint &a, modint b) { a.n = ((ll)a.n*b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, int n) {
	if (n == 0)return modint(1);
	modint res = (a*a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p%a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }
const int max_n = 1 << 18;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}

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

void solve() {
	int n; cin >> n;
	vector<vector<ll>> v(2, vector<ll>(n));
	rep(i, 2)rep(j, n)cin >> v[i][j];
	vector<pair<P, int>> up,dow;

	vector<int> r0(n,mod), r1(n,mod),r2(n,mod);
	map<ll, int> mp;
	ll sum = 0;
	mp[sum] = 0;
	rep(j, n) {
		sum += v[0][j];
		if (mp.find(sum) != mp.end()) {
			//up.push_back({ {j,mp[sum]},-2 });
			r0[mp[sum]] = j;
		}
		mp[sum] = j+1;
	}

	mp.clear(); sum = 0;
	mp[sum] = 0;
	rep(j, n) {
		sum += v[1][j];
		if (mp.find(sum) != mp.end()) {
			r1[mp[sum]] = j;
		}
		mp[sum] = j+1;
	}
	mp.clear(); sum = 0;
	mp[sum] = 0;
	int tmp = 0;
	rep(j, n) {
		sum += v[0][j] + v[1][j];
		if (mp.find(sum) != mp.end()) {
			r2[mp[sum]] = j;
			tmp++;
		}
		mp[sum] = j+1;
	}

	vector<int> to0(n), to1(n), to2(n);
	int ri = mod;
	per(i, n) {
		ri = min(ri, r0[i]);
		to0[i] = ri;
	}
	ri = mod;
	per(i, n) {
		ri = min(ri, r1[i]);
		to1[i] = ri;
	}
	ri = mod;
	per(i, n) {
		ri = min(ri, r2[i]);
		to2[i] = ri;
	}

	vector<P> vs;
	vs.push_back({ 0,0 });
	int ans = 0;
	while (vs.size()) {
		vector<P> nex;
		for (P p : vs) {
			int l = p.first;
			int r = p.second;
			//cout<<ans<<" "<<l<<" "<<r<<"\n";
			if (r<n&&(l >= r||l==n||to0[l]+1>n)) {
				int nr = to1[r] + 1;
				if (nr <= n) {
					nex.push_back({ l,nr });
				}
			}
			if (l<n&&(l <= r||r==n||to1[r]+1>n)) {
				int nl = to0[l] + 1;
				if (nl <= n) {
					nex.push_back({ nl,r });
				}
			}
			if (max(l, r) < n) {
				int to = to2[max(l, r)] + 1;
				if (to <=n) {
					nex.push_back({ to,to });
				}
			}
		}
		sort(all(nex));
		vs.clear();
		int le = mod;
		rep(i, nex.size()) {
			if (le > nex[i].second) {
				vs.push_back(nex[i]);
				le = nex[i].second;
			}
		}
		ans++;
	}
	cout << ans - 1 << "\n";
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(7);
	//init_f();
	//init();
	//experi();
	//int t; cin >> t; rep(i, t)solve();
	solve();
	stop
		return 0;
}


// ...
#ifndef LOCAL
#define NDEBUG
#endif
#include<climits>
#include<cassert>
#include<vector>
#include<algorithm>
#include<functional>
#include<iostream>
#include<map>

/**
 * Given an array a of integers, with inclusive prefix sum = v.
 * For each index i, result[i] is the minimum j such that there exists an subarray with sum 0 in a[i:j],
 * or INT_MAX if there's no such value j.
 */
std::vector<int> /* jump index */ proc(std::vector<int64_t> v){
	std::map<int64_t,int> m; // value -> last index >= current
	std::vector<int> ans(v.size()+1,INT_MAX); // INT_MAX: no jump
	for(auto i=(int)v.size();i;--i){
		auto [iter,succ]=m.insert({v[i-1],i});
		if(!succ){
			ans[i]=iter->second;
			iter->second=i;
		}
	}

	int i=0;
	auto [iter,succ]=m.insert({0LL,0});
	if(!succ){
		ans[i]=iter->second;
	}

	// minsuffix ans
	for(auto i=(int)ans.size()-1;i--;)
		ans[i]=std::min(ans[i],ans[i+1]);
	return ans;
}

std::vector<int> p1,p2,ps;

/**
 * Memoize the computed value of f.
 */
std::vector<std::map<int,int>> fmem;

/**
 * f[start1][start2] is the maximum number of disjoint rectangles included in
 * row1[start1:] and row2[start2:].
 *
 * To simplify some case handling, INT_MIN is returned if start1 or start2 is INT_MAX.
 */
int f(int x,int y){
	if(x==INT_MAX or y==INT_MAX)
		return INT_MIN;

	auto iter=fmem[x].find(y);
	if(iter!=end(fmem[x]))return iter->second;

	int ans;
	if(x==y){
		ans=std::max({0, f(ps[x],ps[y])+1, f(p1[x],y)+1, f(x,p2[y])+1});
	}else{
		int const z=std::max(x,y);
		int const pz=ps[z];
		ans=std::max(f(z,z),f(pz,pz)+1); // compute f(z,z) and f(pz,pz) unconditionally

		if(x<y){
			if(p1[x]<p1[y])
				ans=std::max(ans,f(p1[x],y)+1);
		}else{
			if(p2[y]<p2[x])
				ans=std::max(ans,f(x,p2[y])+1);
		}
	}

	assert(std::cerr <<x<<' '<<y<<' '<<ans<<'\n');
	fmem[x].insert({y,ans});
	return ans;
}

int main(){
	std::ios::sync_with_stdio(0);std::cin.tie(0);
	int n;std::cin>>n;

	// Read input and store the inclusive prefix sum in v1 and v2.
	std::vector<int64_t> v1(n),v2(n);
	for(auto vv:{&v1,&v2}){
		int64_t s=0;
		for(auto& x:*vv){
			std::cin>>x;
			s+=x;
			x=s;
		}
	}

	// Compute vs (inclusive prefix sum of v1+v2)
	std::vector<int64_t> vs(n);
	std::transform(begin(v1),end(v1),begin(v2),begin(vs),std::plus<int64_t>{});

	/*
	 * v1, v2, vs is the inclusive prefix sum of the value of the
	 * (first row/second row/sum of the two rows) respectively.
	 */
	p1=proc(v1);
	p2=proc(v2);
	ps=proc(vs);

	fmem.resize(n+1);
	std::cout<<f(0,0)<<'\n';
}


// I didn't prove that the run time of this solution is small enough. Please hack if possible.
// [I didn't read the editorial or see any failed test cases]
#ifndef LOCAL
#define NDEBUG
#endif
#include<climits>
#include<cassert>
#include<vector>
#include<algorithm>
#include<functional>
#include<iostream>
#include<map>

std::vector<int> /* jump index */ proc(std::vector<int64_t> v /* prefix sums */ ){
	std::map<int64_t,int> m;
	std::vector<int> ans(v.size()+1,INT_MAX); // INT_MAX: no jump
	for(auto i=(int)v.size();i;--i){
		auto [iter,succ]=m.insert({v[i-1],i});
		if(!succ){
			ans[i]=iter->second;
			iter->second=i;
		}
	}

	int i=0;
	auto [iter,succ]=m.insert({0LL,0});
	if(!succ){
		ans[i]=iter->second;
	}

	// minsuffix ans
	for(auto i=(int)v.size()-1;i--;)
		v[i]=std::min(v[i],v[i+1]);
	return ans;
}

std::vector<int> p1,p2,ps;

std::vector<std::map<int,int>> fmem;

int f(int x,int y){
	if(x==INT_MAX or y==INT_MAX)
		return INT_MIN;

	auto iter=fmem[x].find(y);
	if(iter!=end(fmem[x]))return iter->second;

	int ans;
	if(x==y){
		ans=std::max({0, f(ps[x],ps[y])+1, f(p1[x],y)+1, f(x,p2[y])+1});
	}else{
		int const z=std::max(x,y);
		int const pz=ps[z];
		ans=std::max(f(z,z),f(pz,pz)+1); // compute f(z,z) and f(pz,pz) unconditionally

		if(x<y){
			if(p1[x]<p1[y])
				ans=std::max(ans,f(p1[x],y)+1);
		}else{
			if(p2[y]<p2[x])
				ans=std::max(ans,f(x,p2[y])+1);
		}
	}

	assert(std::cerr <<x<<' '<<y<<' '<<ans<<'\n');
	fmem[x].insert({y,ans});
	return ans;
}

int main(){
	std::ios::sync_with_stdio(0);std::cin.tie(0);
	int n;std::cin>>n;

	std::vector<int64_t> v1(n),v2(n);
	for(auto vv:{&v1,&v2}){
		int64_t s=0;
		for(auto& x:*vv){
			std::cin>>x;
			s+=x;
			x=s;
		}
	}

	std::vector<int64_t> vs(n);
	std::transform(begin(v1),end(v1),begin(v2),begin(vs),std::plus<int64_t>{});

	p1=proc(v1);
	p2=proc(v2);
	ps=proc(vs);

	fmem.resize(n+1);
	std::cout<<f(0,0)<<'\n';
}


/*
I have read the editorial. Even when I know that the solution is O(n) (by reading some first
lines of the editorial) I still can't figure out how to solve it.
{I should feel bad about myself because this is a simple optimization trick (instead of
f(x) = 0|1, f monotonically increasing, let g = min {x : f(x) = 1}) - definitely simpler than convex hull
or Knuth optimization.}
*/

#ifndef LOCAL
#define NDEBUG
#endif
#include<climits>
#include<cassert>
#include<vector>
#include<algorithm>
#include<functional>
#include<iostream>
#include<map>

std::vector<int> /* jump index */ proc(std::vector<int64_t> v /* prefix sums, inclusive */ ){
	std::map<int64_t,int> m; // value -> last index >= current
	std::vector<int> ans(v.size()+1,INT_MAX); // INT_MAX: no jump
	for(auto i=(int)v.size();i;--i){
		auto [iter,succ]=m.insert({v[i-1],i});
		if(!succ){
			ans[i]=iter->second;
			iter->second=i;
		}
	}

	int i=0;
	auto [iter,succ]=m.insert({0LL,0});
	if(!succ){
		ans[i]=iter->second;
	}

	// minsuffix ans
	for(auto i=(int)ans.size()-1;i--;)
		ans[i]=std::min(ans[i],ans[i+1]);
	return ans;
}

int main(){
	std::ios::sync_with_stdio(0);std::cin.tie(0);
	int n;std::cin>>n;

	std::vector<int64_t> v1(n),v2(n);
	for(auto vv:{&v1,&v2}){
		int64_t s=0;
		for(auto& x:*vv){
			std::cin>>x;
			s+=x;
			x=s;
		}
	}

	std::vector<int64_t> vs(n);
	std::transform(begin(v1),end(v1),begin(v2),begin(vs),std::plus<int64_t>{});

	auto const p1=proc(v1);
	auto const p2=proc(v2);
	auto const ps=proc(vs);

	std::vector<int> g(n+1,0);
	struct zz{
		int nextind;
		int val;
	};
	std::vector<zz> g1(n+1,{INT_MAX,0}),g2(n+1,{INT_MAX,0});
	g[0]=0;

	auto const smax=[](int& a,int b){ if(b>a){a=b;return true;} return false; };
	auto const smin=[](int& a,int b){ if(b<a){a=b;return true;} return false; };

	for(int i=0;i<n;++i){
		auto proc2=[&](int x,int y,int cnt){
			if(x==INT_MAX or y==INT_MAX)
				return;
			if(x==y){
				if(smax(g[x],cnt)){
					if(g1[x].val<=cnt) g1[x]={INT_MAX,0};
					if(g2[x].val<=cnt) g2[x]={INT_MAX,0};
				}
			}else if(x<y){
				if(cnt>g[x]) if(y<g2[x].nextind) g2[x]={y,cnt};
			}else{
				if(cnt>g[y]) if(x<g1[y].nextind) g1[y]={x,cnt};
			}
		};

		proc2(p1[i],i,g[i]+1);
		proc2(i,p2[i],g[i]+1);
		proc2(ps[i],ps[i],g[i]+1);
		proc2(i+1,i+1,g[i]);

		if(g1[i].nextind<INT_MAX){
			auto [nxt,cnt]=g1[i];
			proc2(nxt,i+1,cnt);
			proc2(nxt,p2[i],cnt+1);
		}
		if(g2[i].nextind<INT_MAX){
			auto [nxt,cnt]=g2[i];
			proc2(i+1,nxt,cnt);
			proc2(p1[i],nxt,cnt+1);
		}
	}

	std::cout<<g[n]<<'\n';
}


/*
...
*/

#ifndef LOCAL
#define NDEBUG
#endif
#include<climits>
#include<cassert>
#include<vector>
#include<algorithm>
#include<functional>
#include<iostream>
#include<map>

std::vector<int> /* jump index */ proc(std::vector<int64_t> v /* prefix sums, inclusive */ ){
	std::map<int64_t,int> m; // value -> last index >= current
	std::vector<int> ans(v.size()+1,INT_MAX); // INT_MAX: no jump
	for(auto i=(int)v.size();i;--i){
		auto [iter,succ]=m.insert({v[i-1],i});
		if(!succ){
			ans[i]=iter->second;
			iter->second=i;
		}
	}

	int i=0;
	auto [iter,succ]=m.insert({0LL,0});
	if(!succ){
		ans[i]=iter->second;
	}

	// minsuffix ans
	for(auto i=(int)ans.size()-1;i--;)
		ans[i]=std::min(ans[i],ans[i+1]);
	return ans;
}

int main(){
	std::ios::sync_with_stdio(0);std::cin.tie(0);
	int n;std::cin>>n;

	std::vector<int64_t> v1(n),v2(n);
	for(auto vv:{&v1,&v2}){
		int64_t s=0;
		for(auto& x:*vv){
			std::cin>>x;
			s+=x;
			x=s;
		}
	}

	std::vector<int64_t> vs(n);
	std::transform(begin(v1),end(v1),begin(v2),begin(vs),std::plus<int64_t>{});

	auto const p1=proc(v1);
	auto const p2=proc(v2);
	auto const ps=proc(vs);

	std::vector<int> g(n+1,0);
	struct zz{
		int nextind;
		int val;
	};
	std::vector<zz> g1(n+1,{INT_MAX,0}),g2(n+1,{INT_MAX,0});
	g[0]=0;

	auto const smax=[](int& a,int b){ if(b>a){a=b;return true;} return false; };
	auto const smin=[](int& a,int b){ if(b<a){a=b;return true;} return false; };

	for(int i=0;i<n;++i){
		auto proc2=[&](int x,int y,int cnt){
			if(x==INT_MAX or y==INT_MAX)
				return;
			if(x==y){
				if(smax(g[x],cnt)){
					if(g1[x].val<=cnt) g1[x]={INT_MAX,0};
					if(g2[x].val<=cnt) g2[x]={INT_MAX,0};
				}
			}else if(x<y){
				if(cnt>g[x]) if(y<g2[x].nextind) g2[x]={y,cnt};
			}else{
				if(cnt>g[y]) if(x<g1[y].nextind) g1[y]={x,cnt};
			}
		};

		proc2(i+1,i+1,g[i]);
		proc2(p1[i],i,g[i]+1);
		proc2(i,p2[i],g[i]+1);
		proc2(ps[i],ps[i],g[i]+1);

		if(g1[i].nextind<INT_MAX){
			auto [nxt,cnt]=g1[i];
			proc2(nxt,i+1,cnt);
			proc2(nxt,p2[i],cnt+1);
		}
		if(g2[i].nextind<INT_MAX){
			auto [nxt,cnt]=g2[i];
			proc2(i+1,nxt,cnt);
			proc2(p1[i],nxt,cnt+1);
		}
	}

	std::cout<<g[n]<<'\n';
}


/*
I have read the editorial. Even when I know that the solution is O(n) (by reading some first
lines of the editorial) I still can't figure out how to solve it.
{I should feel bad about myself because this is a simple optimization trick (instead of
f(x) = 0|1, f monotonically increasing, let g = min {x : f(x) = 1}) - definitely simpler than convex hull
or Knuth optimization.}
*/

#ifndef LOCAL
#define NDEBUG
#endif
#include<climits>
#include<cassert>
#include<vector>
#include<algorithm>
#include<functional>
#include<iostream>
#include<map>

std::vector<int> /* jump index */ proc(std::vector<int64_t> v /* prefix sums, inclusive */ ){
	std::map<int64_t,int> m; // value -> last index >= current
	std::vector<int> ans(v.size()+1,INT_MAX); // INT_MAX: no jump
	for(auto i=(int)v.size();i;--i){
		auto [iter,succ]=m.insert({v[i-1],i});
		if(!succ){
			ans[i]=iter->second;
			iter->second=i;
		}
	}

	int i=0;
	auto [iter,succ]=m.insert({0LL,0});
	if(!succ){
		ans[i]=iter->second;
	}

	// minsuffix ans
	for(auto i=(int)ans.size()-1;i--;)
		ans[i]=std::min(ans[i],ans[i+1]);
	return ans;
}

int main(){
	std::ios::sync_with_stdio(0);std::cin.tie(0);
	int n;std::cin>>n;

	std::vector<int64_t> v1(n),v2(n);
	for(auto vv:{&v1,&v2}){
		int64_t s=0;
		for(auto& x:*vv){
			std::cin>>x;
			s+=x;
			x=s;
		}
	}

	std::vector<int64_t> vs(n);
	std::transform(begin(v1),end(v1),begin(v2),begin(vs),std::plus<int64_t>{});

	auto const p1=proc(v1);
	auto const p2=proc(v2);
	auto const ps=proc(vs);

	std::vector<int> g(n+1,0),g1(n+1,INT_MAX),g2(n+1,INT_MAX);
	g[0]=0;

	auto const smax=[](int& a,int b){ if(b>a){a=b;return true;} return false; };
	auto const smin=[](int& a,int b){ if(b<a){a=b;return true;} return false; };

	for(int i=0;i<n;++i){
		auto proc2=[&](int x,int y,int cnt){
			if(x==INT_MAX or y==INT_MAX)
				return;
			if(x==y){
				if(smax(g[x],cnt))
					g1[x]=g2[x]=INT_MAX;
			}else if(x<y){
				if(cnt>g[x]) smin(g2[x],y);
			}else{
				if(cnt>g[y]) smin(g1[y],x);
			}
		};

		proc2(p1[i],i,g[i]+1);
		proc2(i,p2[i],g[i]+1);
		proc2(ps[i],ps[i],g[i]+1);
		proc2(i+1,i+1,g[i]);

		if(g1[i]<INT_MAX){
			int nxt=g1[i];
			proc2(nxt,i+1,g[i]);
			proc2(nxt,nxt,g[i]+1);
			proc2(nxt,p2[i],g[i]+2);
		}
		if(g2[i]<INT_MAX){
			int nxt=g2[i];
			proc2(i+1,nxt,g[i]);
			proc2(nxt,nxt,g[i]+1);
			proc2(p1[i],nxt,g[i]+2);
		}
	}

	std::cout<<g[n]<<'\n';
}


/*
I have read the editorial. Even when I know that the solution is O(n) (by reading some first
lines of the editorial) I still can't figure out how to solve it.
{I should feel bad about myself because this is a simple optimization trick (instead of
f(x) = 0|1, f monotonically increasing, let g = min {x : f(x) = 1}) - definitely simpler than convex hull
or Knuth optimization.}
*/

#ifndef LOCAL
#define NDEBUG
#endif
#include<climits>
#include<cassert>
#include<vector>
#include<algorithm>
#include<functional>
#include<iostream>
#include<map>

std::vector<int> /* jump index */ proc(std::vector<int64_t> v /* prefix sums, inclusive */ ){
	std::map<int64_t,int> m; // value -> last index >= current
	std::vector<int> ans(v.size()+1,INT_MAX); // INT_MAX: no jump
	for(auto i=(int)v.size();i;--i){
		auto [iter,succ]=m.insert({v[i-1],i});
		if(!succ){
			ans[i]=iter->second;
			iter->second=i;
		}
	}

	int i=0;
	auto [iter,succ]=m.insert({0LL,0});
	if(!succ){
		ans[i]=iter->second;
	}

	// minsuffix ans
	for(auto i=(int)ans.size()-1;i--;)
		ans[i]=std::min(ans[i],ans[i+1]);
	return ans;
}

int main(){
	std::ios::sync_with_stdio(0);std::cin.tie(0);
	int n;std::cin>>n;

	std::vector<int64_t> v1(n),v2(n);
	for(auto vv:{&v1,&v2}){
		int64_t s=0;
		for(auto& x:*vv){
			std::cin>>x;
			s+=x;
			x=s;
		}
	}

	std::vector<int64_t> vs(n);
	std::transform(begin(v1),end(v1),begin(v2),begin(vs),std::plus<int64_t>{});

	auto const p1=proc(v1);
	auto const p2=proc(v2);
	auto const ps=proc(vs);

	std::vector<int> g(n+1,0);
	struct zz{
		int nextind;
		int val;
	};
	std::vector<zz> g1(n+1,{INT_MAX,0}),g2(n+1,{INT_MAX,0});
	g[0]=0;

	auto const smax=[](int& a,int b){ if(b>a){a=b;return true;} return false; };
	auto const smin=[](int& a,int b){ if(b<a){a=b;return true;} return false; };

	for(int i=0;i<n;++i){
		auto proc2=[&](int x,int y,int cnt){
			if(x==INT_MAX or y==INT_MAX)
				return;
			if(x==y){
				if(smax(g[x],cnt)){
					if(g1[x].val<=cnt) g1[x]={INT_MAX,0};
					if(g2[x].val<=cnt) g2[x]={INT_MAX,0};
				}
			}else if(x<y){
				if(cnt>g[x]) if(cnt>g2[x].val) g2[x]={y,cnt};
			}else{
				if(cnt>g[y]) if(cnt>g1[y].val) g1[y]={x,cnt};
			}
		};

		proc2(p1[i],i,g[i]+1);
		proc2(i,p2[i],g[i]+1);
		proc2(ps[i],ps[i],g[i]+1);
		proc2(i+1,i+1,g[i]);

		if(g1[i].nextind<INT_MAX){
			auto [nxt,cnt]=g1[i];
			proc2(nxt,i+1,cnt);
			proc2(nxt,p2[i],cnt+1);
		}
		if(g2[i].nextind<INT_MAX){
			auto [nxt,cnt]=g2[i];
			proc2(i+1,nxt,cnt);
			proc2(p1[i],nxt,cnt+1);
		}
	}

	std::cout<<g[n]<<'\n';
}


#ifndef LOCAL
#define NDEBUG
#endif
#include<climits>
#include<cassert>
#include<vector>
#include<algorithm>
#include<functional>
#include<iostream>
#include<map>

std::vector<int> /* jump index */ proc(std::vector<int64_t> v /* prefix sums, inclusive */ ){
	std::map<int64_t,int> m; // value -> last index >= current
	std::vector<int> ans(v.size()+1,INT_MAX); // INT_MAX: no jump
	for(auto i=(int)v.size();i;--i){
		auto [iter,succ]=m.insert({v[i-1],i});
		if(!succ){
			ans[i]=iter->second;
			iter->second=i;
		}
	}

	int i=0;
	auto [iter,succ]=m.insert({0LL,0});
	if(!succ){
		ans[i]=iter->second;
	}

	// minsuffix ans
	for(auto i=(int)ans.size()-1;i--;)
		ans[i]=std::min(ans[i],ans[i+1]);
	return ans;
}

int main(){
	std::ios::sync_with_stdio(0);std::cin.tie(0);
	int n;std::cin>>n;

	std::vector<int64_t> v1(n),v2(n);
	for(auto vv:{&v1,&v2}){
		int64_t s=0;
		for(auto& x:*vv){
			std::cin>>x;
			s+=x;
			x=s;
		}
	}

	std::vector<int64_t> vs(n);
	std::transform(begin(v1),end(v1),begin(v2),begin(vs),std::plus<int64_t>{});

	auto const p1=proc(v1);
	auto const p2=proc(v2);
	auto const ps=proc(vs);

	std::vector<int> g(n+1,0);
	struct zz{
		int nextind;
		int val;
	};
	auto const nextind_cmp=[](zz a,zz b){return a.nextind<b.nextind;};
	std::vector<std::vector<zz>> g1(n+1),g2(n+1);

	g[0]=0;

	for(int i=0;i<n;++i){
		auto proc2=[&](int x,int y,int cnt){
			if(x==INT_MAX or y==INT_MAX)
				return;
			if(x==y){
				g[x]=std::max(g[x],cnt);
			}else if(x<y){
				g2[x].push_back({y,cnt});
			}else{
				g1[y].push_back({x,cnt});
			}
		};

		proc2(i+1,i+1,g[i]);
		proc2(p1[i],i,g[i]+1);
		proc2(i,p2[i],g[i]+1);
		proc2(ps[i],ps[i],g[i]+1);

		g1[i].erase(std::remove_if(begin(g1[i]),end(g1[i]),[gi=g[i]](zz z){return z.val<=gi;}),end(g1[i]));
		g2[i].erase(std::remove_if(begin(g2[i]),end(g2[i]),[gi=g[i]](zz z){return z.val<=gi;}),end(g2[i]));

		if(not g1[i].empty()){
			auto [nxt,cnt]=*std::min_element(begin(g1[i]),end(g1[i]),nextind_cmp);
			proc2(nxt,i+1,cnt);
			proc2(nxt,p2[i],cnt+1);
		}
		if(not g2[i].empty()){
			auto [nxt,cnt]=*std::min_element(begin(g2[i]),end(g2[i]),nextind_cmp);
			proc2(i+1,nxt,cnt);
			proc2(p1[i],nxt,cnt+1);
		}
	}

	std::cout<<g[n]<<'\n';
}


/*
I have read the editorial. Even when I know that the solution is O(n) (by reading some first
lines of the editorial) I still can't figure out how to solve it.
{I should feel bad about myself because this is a simple optimization trick (instead of
f(x) = 0|1, f monotonically increasing, let g = min {x : f(x) = 1}) - definitely simpler than convex hull
or Knuth optimization.}
*/

#ifndef LOCAL
#define NDEBUG
#endif
#include<climits>
#include<cassert>
#include<vector>
#include<algorithm>
#include<functional>
#include<iostream>
#include<map>

std::vector<int> /* jump index */ proc(std::vector<int64_t> v /* prefix sums, inclusive */ ){
	std::map<int64_t,int> m; // value -> last index >= current
	std::vector<int> ans(v.size()+1,INT_MAX); // INT_MAX: no jump
	for(auto i=(int)v.size();i;--i){
		auto [iter,succ]=m.insert({v[i-1],i});
		if(!succ){
			ans[i]=iter->second;
			iter->second=i;
		}
	}

	int i=0;
	auto [iter,succ]=m.insert({0LL,0});
	if(!succ){
		ans[i]=iter->second;
	}

	// minsuffix ans
	for(auto i=(int)ans.size()-1;i--;)
		ans[i]=std::min(ans[i],ans[i+1]);
	return ans;
}

int main(){
	std::ios::sync_with_stdio(0);std::cin.tie(0);
	int n;std::cin>>n;

	std::vector<int64_t> v1(n),v2(n);
	for(auto vv:{&v1,&v2}){
		int64_t s=0;
		for(auto& x:*vv){
			std::cin>>x;
			s+=x;
			x=s;
		}
	}

	std::vector<int64_t> vs(n);
	std::transform(begin(v1),end(v1),begin(v2),begin(vs),std::plus<int64_t>{});

	auto const p1=proc(v1);
	auto const p2=proc(v2);
	auto const ps=proc(vs);

	std::vector<int> g(n+1,0),g1(n+1,INT_MAX),g2(n+1,INT_MAX);
	g[0]=0;

	auto const smax=[](int& a,int b){ if(b>a){a=b;return true;} return false; };
	auto const smin=[](int& a,int b){ if(b<a){a=b;return true;} return false; };

	for(int i=0;i<n;++i){
		auto proc2=[&](int x,int y,int cnt){
			if(x==INT_MAX or y==INT_MAX)
				return;
			if(x==y){
				if(smax(g[x],cnt))
					g1[x]=g2[x]=INT_MAX;
			}else if(x<y){
				if(cnt>g[x]) smin(g2[x],y);
			}else{
				if(cnt>g[y]) smin(g1[y],x);
			}
		};

		proc2(p1[i],i,g[i]+1);
		proc2(i,p2[i],g[i]+1);
		proc2(ps[i],ps[i],g[i]+1);
		proc2(i+1,i+1,g[i]);

		if(g1[i]<INT_MAX){
			int nxt=g1[i];
			proc2(nxt,i+1,g[i]+1);
			proc2(nxt,p2[i],g[i]+2);
		}
		if(g2[i]<INT_MAX){
			int nxt=g2[i];
			proc2(i+1,nxt,g[i]+1);
			proc2(p1[i],nxt,g[i]+2);
		}
	}

	std::cout<<g[n]<<'\n';
}


// I didn't prove that the run time of this solution is small enough. Please hack if possible.
// [I didn't read the editorial or see any failed test cases]
#ifndef LOCAL
#define NDEBUG
#endif
#include<climits>
#include<cassert>
#include<vector>
#include<algorithm>
#include<functional>
#include<iostream>
#include<map>

std::vector<int> /* jump index */ proc(std::vector<int64_t> v /* prefix sums, inclusive */ ){
	std::map<int64_t,int> m; // value -> last index >= current
	std::vector<int> ans(v.size()+1,INT_MAX); // INT_MAX: no jump
	for(auto i=(int)v.size();i;--i){
		auto [iter,succ]=m.insert({v[i-1],i});
		if(!succ){
			ans[i]=iter->second;
			iter->second=i;
		}
	}

	int i=0;
	auto [iter,succ]=m.insert({0LL,0});
	if(!succ){
		ans[i]=iter->second;
	}

	// minsuffix ans
	for(auto i=(int)ans.size()-1;i--;)
		ans[i]=std::min(ans[i],ans[i+1]);
	return ans;
}

std::vector<int> p1,p2,ps;

std::vector<std::map<int,int>> fmem;

int f(int x,int y){
	if(x==INT_MAX or y==INT_MAX)
		return INT_MIN;

	auto iter=fmem[x].find(y);
	if(iter!=end(fmem[x]))return iter->second;

	int ans;
	if(x==y){
		ans=std::max({0, f(ps[x],ps[y])+1, f(p1[x],y)+1, f(x,p2[y])+1});
	}else{
		int const z=std::max(x,y);
		int const pz=ps[z];
		ans=std::max(f(z,z),f(pz,pz)+1); // compute f(z,z) and f(pz,pz) unconditionally

		if(x<y){
			if(p1[x]<p1[y])
				ans=std::max(ans,f(p1[x],y)+1);
		}else{
			if(p2[y]<p2[x])
				ans=std::max(ans,f(x,p2[y])+1);
		}
	}

	assert(std::cerr <<x<<' '<<y<<' '<<ans<<'\n');
	fmem[x].insert({y,ans});
	return ans;
}

int main(){
	std::ios::sync_with_stdio(0);std::cin.tie(0);
	int n;std::cin>>n;

	std::vector<int64_t> v1(n),v2(n);
	for(auto vv:{&v1,&v2}){
		int64_t s=0;
		for(auto& x:*vv){
			std::cin>>x;
			s+=x;
			x=s;
		}
	}

	std::vector<int64_t> vs(n);
	std::transform(begin(v1),end(v1),begin(v2),begin(vs),std::plus<int64_t>{});

	p1=proc(v1);
	p2=proc(v2);
	ps=proc(vs);

	fmem.resize(n+1);
	std::cout<<f(0,0)<<'\n';
}


#include <bits/stdc++.h>

using namespace std;

#define DEBUG(x) cerr<<#x<<": "<<x<<endl;
#define DEBUG_VEC(v) cerr<<#v<<":";for(int i=0;i<v.size();i++) cerr<<" "<<v[i]; cerr<<endl;
#define DEBUG_MAT(v) cerr<<#v<<endl;for(int i=0;i<v.size();i++){for(int j=0;j<v[i].size();j++) {cerr<<v[i][j]<<" ";}cerr<<endl;}
typedef long long ll;
// #define int ll

#define vi vector<int>
#define vl vector<ll>
#define vii vector< vector<int> >
#define vll vector< vector<ll> >
#define vs vector<string>
#define pii pair<int,int>
#define pis pair<int,string>
#define psi pair<string,int>
#define pll pair<ll,ll>
template<class S, class T> pair<S, T> operator+(const pair<S, T> &s, const pair<S, T> &t) { return pair<S, T>(s.first + t.first, s.second + t.second); }
template<class S, class T> pair<S, T> operator-(const pair<S, T> &s, const pair<S, T> &t) { return pair<S, T>(s.first - t.first, s.second - t.second); }
template<class S, class T> ostream& operator<<(ostream& os, pair<S, T> p) { os << "(" << p.first << ", " << p.second << ")"; return os; }
#define X first
#define Y second
#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 rrep(i,n) for(int i=(int)(n)-1;i>=0;i--)
#define rrep1(i,n) for(int i=(int)(n);i>0;i--)
#define REP(i,a,b) for(int i=a;i<b;i++)
#define in(x, a, b) (a <= x && x < b)
#define all(c) c.begin(),c.end()
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a = b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a = b; return 1; } return 0; }
#define UNIQUE(v) v.erase(std::unique(v.begin(), v.end()), v.end());
const ll inf = 1000000001;
const ll INF = (ll)1e18 + 1;
const long double pi = 3.1415926535897932384626433832795028841971L;
#define Sp(p) cout<<setprecision(25)<< fixed<<p<<endl;
//int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
//int dx2[8] = { 1,1,0,-1,-1,-1,0,1 }, dy2[8] = { 0,1,1,1,0,-1,-1,-1 };
vi dx = {1, 0, -1, 0}, dy = {0, 1, 0, -1};
vi dx2 = { 1,1,0,-1,-1,-1,0,1 }, dy2 = { 0,1,1,1,0,-1,-1,-1 };
#define fio() cin.tie(0); ios::sync_with_stdio(false);
const ll MOD = 1000000007;
//const ll MOD = 998244353;
// #define mp make_pair
//#define endl '\n'

vector<pii> calc(vl a) {
    set<pii> st;
    vector<pii> res;
    ll sum = 0;
    st.insert(pll(sum, 0));
    rep (i, a.size()) {
        sum += a[i];
        auto itr = st.lower_bound(pll(sum, -1));
        if (itr != st.end() and itr->first == sum) {
            int l = itr->second;
            int r = i + 1;
            res.push_back(pii(l, r));
            st.erase(itr);
        }
        st.insert(pll(sum, i + 1));
    }
    sort(all(res));

    priority_queue<pii> pq;
    rep (i, res.size()) {
        while (pq.size()) {
            pii ri = pq.top();
            if (ri.first >= res[i].second) pq.pop();
            else break;
        }
        pq.push(pii(res[i].second, i));
    }

    vector<pii> res2;
    while (pq.size()) {
        int i = pq.top().second;
        pq.pop();
        res2.push_back(res[i]);
    }
    sort(all(res2));
    return res2;
}

vii doubling(vector<pii> a) {
    int m = 20;
    int n = a.size();
    vii res(n, vi(m));

    rep (i, n) {
        res[i][0] = i;
    }

    for (int j = 0; j < m - 1; j++) {
        rep (i, n) {
            int ni = res[i][j];
            ni++;
            if (ni == n) {
                res[i][j + 1] = n;
            }
            res[i][j + 1] = res[ni][j];
        }
    }
    return res;
}

signed main() {
    fio();
    int n;
    cin >> n;

    vll t(2, vl(n));
    rep (i, 2) {
        rep (j, n) {
            cin >> t[i][j];
        }
    }

    vector<vector<pii>> a(2);
    rep (i, 2) a[i] = calc(t[i]);

    vii b(2, vi(n, -1));
    rep (i, 2) {
        rep (j, a[i].size()) {
            b[i][a[i][j].first] = a[i][j].second;
        }
    }

    vl temp(n);
    rep (i, n) temp[i] = t[0][i] + t[1][i];
    vector<pii> both = calc(temp);

    vi both_b(n, -1);
    rep (i, both.size()) {
        both_b[both[i].first] = both[i].second;
    }

    vii next(2, vi(n + 1));
    rep (i, 2) {
        rep (j, n + 1) {
            auto itr1 = lower_bound(all(a[i]), pii(j + 1, -inf));
            auto itr2 = lower_bound(all(both), pii(j + 1, -inf));
            int l1, l2;
            if (itr1 == a[i].end()) l1 = n;
            else l1 = itr1->first;
            if (itr2 == both.end()) l2 = n;
            else l2 = itr2->first;
            next[i][j] = min(l1, l2);
        }
    }

    vector<map<int, int>> dp(n + 1);
    dp[0][0] = 0;
    // vector<set<int>> qu(n + 1);
    // qu[0].insert(0);
    int ans = 0;
    rep (i, n + 1) {
        while (dp[i].size()) {
            pii jc = *dp[i].begin();
            dp[i].erase(dp[i].begin());
            int j = jc.first;
            int now = jc.second;
            chmax(ans, now);
            if (i <= j and i != n) {
                int ni = next[0][i];
                if (dp[ni].count(j) == 0 or dp[ni][j] < now) {
                    dp[ni][j] = now;
                }

                if (b[0][i] != -1) {
                    int ni = b[0][i];
                    if (dp[ni].count(j) == 0 or dp[ni][j] < now + 1) {
                        dp[ni][j] = now + 1;
                    }
                }
            }
            if (j <= i and j != n) {
                int nj = next[1][j];
                if (dp[i].count(nj) == 0 or dp[i][nj] < now) {
                    dp[i][nj] = now;
                }

                if (b[1][j] != -1) {
                    int nj = b[1][j];
                    if (dp[i].count(nj) == 0 or dp[i][nj] < now + 1) {
                        dp[i][nj] = now + 1;
                    }
                }
            }
            if (i == j and i != n) {
                if (both_b[i] != -1) {
                    int ni = both_b[i];
                    int nj = both_b[i];
                    if (dp[ni].count(nj) == 0 or dp[ni][nj] < now + 1) {
                        dp[ni][nj] = now + 1;
                    }
                }
            }
        }
    }

    cout << ans << endl;
}


#include <bits/stdc++.h>

using namespace std;

#define DEBUG(x) cerr<<#x<<": "<<x<<endl;
#define DEBUG_VEC(v) cerr<<#v<<":";for(int i=0;i<v.size();i++) cerr<<" "<<v[i]; cerr<<endl;
#define DEBUG_MAT(v) cerr<<#v<<endl;for(int i=0;i<v.size();i++){for(int j=0;j<v[i].size();j++) {cerr<<v[i][j]<<" ";}cerr<<endl;}
typedef long long ll;
// #define int ll

#define vi vector<int>
#define vl vector<ll>
#define vii vector< vector<int> >
#define vll vector< vector<ll> >
#define vs vector<string>
#define pii pair<int,int>
#define pis pair<int,string>
#define psi pair<string,int>
#define pll pair<ll,ll>
template<class S, class T> pair<S, T> operator+(const pair<S, T> &s, const pair<S, T> &t) { return pair<S, T>(s.first + t.first, s.second + t.second); }
template<class S, class T> pair<S, T> operator-(const pair<S, T> &s, const pair<S, T> &t) { return pair<S, T>(s.first - t.first, s.second - t.second); }
template<class S, class T> ostream& operator<<(ostream& os, pair<S, T> p) { os << "(" << p.first << ", " << p.second << ")"; return os; }
#define X first
#define Y second
#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 rrep(i,n) for(int i=(int)(n)-1;i>=0;i--)
#define rrep1(i,n) for(int i=(int)(n);i>0;i--)
#define REP(i,a,b) for(int i=a;i<b;i++)
#define in(x, a, b) (a <= x && x < b)
#define all(c) c.begin(),c.end()
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a = b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a = b; return 1; } return 0; }
#define UNIQUE(v) v.erase(std::unique(v.begin(), v.end()), v.end());
const ll inf = 1000000001;
const ll INF = (ll)1e18 + 1;
const long double pi = 3.1415926535897932384626433832795028841971L;
#define Sp(p) cout<<setprecision(25)<< fixed<<p<<endl;
//int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
//int dx2[8] = { 1,1,0,-1,-1,-1,0,1 }, dy2[8] = { 0,1,1,1,0,-1,-1,-1 };
vi dx = {1, 0, -1, 0}, dy = {0, 1, 0, -1};
vi dx2 = { 1,1,0,-1,-1,-1,0,1 }, dy2 = { 0,1,1,1,0,-1,-1,-1 };
#define fio() cin.tie(0); ios::sync_with_stdio(false);
const ll MOD = 1000000007;
//const ll MOD = 998244353;
// #define mp make_pair
//#define endl '\n'

vector<pii> calc(vl a) {
    set<pii> st;
    vector<pii> res;
    ll sum = 0;
    st.insert(pll(sum, 0));
    rep (i, a.size()) {
        sum += a[i];
        auto itr = st.lower_bound(pll(sum, -1));
        if (itr != st.end() and itr->first == sum) {
            int l = itr->second;
            int r = i + 1;
            res.push_back(pii(l, r));
            st.erase(itr);
        }
        st.insert(pll(sum, i + 1));
    }
    sort(all(res));

    priority_queue<pii> pq;
    rep (i, res.size()) {
        while (pq.size()) {
            pii ri = pq.top();
            if (ri.first >= res[i].second) pq.pop();
            else break;
        }
        pq.push(pii(res[i].second, i));
    }

    vector<pii> res2;
    while (pq.size()) {
        int i = pq.top().second;
        pq.pop();
        res2.push_back(res[i]);
    }
    sort(all(res2));
    return res2;
}

vii doubling(vector<pii> a) {
    int m = 20;
    int n = a.size();
    vii res(n, vi(m));

    rep (i, n) {
        res[i][0] = i;
    }

    for (int j = 0; j < m - 1; j++) {
        rep (i, n) {
            int ni = res[i][j];
            ni++;
            if (ni == n) {
                res[i][j + 1] = n;
            }
            res[i][j + 1] = res[ni][j];
        }
    }
    return res;
}

signed main() {
    fio();
    int n;
    cin >> n;

    vll t(2, vl(n));
    rep (i, 2) {
        rep (j, n) {
            cin >> t[i][j];
        }
    }

    vector<vector<pii>> a(2);
    rep (i, 2) a[i] = calc(t[i]);

    vl temp(n);
    rep (i, n) temp[i] = t[0][i] + t[1][i];
    vector<pii> both = calc(temp);

    // vector<vii> d(2);
    // rep (i, 2) {
    //     d[i] = doubling(a[i]);
    // }

    vector<map<int, int>> dp(n + 1);
    dp[0][0] = 0;
    // vector<set<int>> qu(n + 1);
    // qu[0].insert(0);
    int ans = 0;
    rep (i, n + 1) {
        while (dp[i].size()) {
            // int j = *qu[i].begin();
            // qu[i].erase(qu[i].begin());
            pii jc = *dp[i].begin();
            dp[i].erase(dp[i].begin());
            int j = jc.first;
            int now = jc.second;
            chmax(ans, now);
            if (i <= j and i != n) {
                if (dp[i + 1].count(j) == 0 or dp[i + 1][j] < now) {
                    dp[i + 1][j] = now;
                    // qu[i + 1].insert(j);
                }

                auto itr = lower_bound(all(a[0]), pii(i, -1));
                if (itr != a[0].end() and itr->first == i) {
                    int ni = itr->second;
                    if (dp[ni].count(j) == 0 or dp[ni][j] < now + 1) {
                        dp[ni][j] = now + 1;
                        // qu[ni].insert(j);
                    }
                }
            }
            if (j <= i and j != n) {
                if (dp[i].count(j + 1) == 0 or dp[i][j + 1] < now) {
                    dp[i][j + 1] = now;
                    // qu[i].insert(j + 1);
                }

                auto itr = lower_bound(all(a[1]), pii(j, -1));
                if (itr != a[1].end() and itr->first == j) {
                    int nj = itr->second;
                    if (dp[i].count(nj) == 0 or dp[i][nj] < now + 1) {
                        dp[i][nj] = now + 1;
                        // qu[i].insert(nj);
                    }
                }
            }
            if (i == j and i != n) {
                auto itr = lower_bound(all(both), pii(i, -1));
                if (itr != both.end() and itr->first == i) {
                    int ni = itr->second;
                    int nj = itr->second;
                    if (dp[ni].count(nj) == 0 or dp[ni][nj] < now + 1) {
                        dp[ni][nj] = now + 1;
                        // qu[ni].insert(nj);
                    }
                }
            }
        }
    }

    cout << ans << endl;
}


#include <bits/stdc++.h>

using namespace std;

#define DEBUG(x) cerr<<#x<<": "<<x<<endl;
#define DEBUG_VEC(v) cerr<<#v<<":";for(int i=0;i<v.size();i++) cerr<<" "<<v[i]; cerr<<endl;
#define DEBUG_MAT(v) cerr<<#v<<endl;for(int i=0;i<v.size();i++){for(int j=0;j<v[i].size();j++) {cerr<<v[i][j]<<" ";}cerr<<endl;}
typedef long long ll;
// #define int ll

#define vi vector<int>
#define vl vector<ll>
#define vii vector< vector<int> >
#define vll vector< vector<ll> >
#define vs vector<string>
#define pii pair<int,int>
#define pis pair<int,string>
#define psi pair<string,int>
#define pll pair<ll,ll>
template<class S, class T> pair<S, T> operator+(const pair<S, T> &s, const pair<S, T> &t) { return pair<S, T>(s.first + t.first, s.second + t.second); }
template<class S, class T> pair<S, T> operator-(const pair<S, T> &s, const pair<S, T> &t) { return pair<S, T>(s.first - t.first, s.second - t.second); }
template<class S, class T> ostream& operator<<(ostream& os, pair<S, T> p) { os << "(" << p.first << ", " << p.second << ")"; return os; }
#define X first
#define Y second
#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 rrep(i,n) for(int i=(int)(n)-1;i>=0;i--)
#define rrep1(i,n) for(int i=(int)(n);i>0;i--)
#define REP(i,a,b) for(int i=a;i<b;i++)
#define in(x, a, b) (a <= x && x < b)
#define all(c) c.begin(),c.end()
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a = b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a = b; return 1; } return 0; }
#define UNIQUE(v) v.erase(std::unique(v.begin(), v.end()), v.end());
const ll inf = 1000000001;
const ll INF = (ll)1e18 + 1;
const long double pi = 3.1415926535897932384626433832795028841971L;
#define Sp(p) cout<<setprecision(25)<< fixed<<p<<endl;
//int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
//int dx2[8] = { 1,1,0,-1,-1,-1,0,1 }, dy2[8] = { 0,1,1,1,0,-1,-1,-1 };
vi dx = {1, 0, -1, 0}, dy = {0, 1, 0, -1};
vi dx2 = { 1,1,0,-1,-1,-1,0,1 }, dy2 = { 0,1,1,1,0,-1,-1,-1 };
#define fio() cin.tie(0); ios::sync_with_stdio(false);
const ll MOD = 1000000007;
//const ll MOD = 998244353;
// #define mp make_pair
//#define endl '\n'

vector<pii> calc(vl a) {
    set<pii> st;
    vector<pii> res;
    ll sum = 0;
    st.insert(pll(sum, 0));
    rep (i, a.size()) {
        sum += a[i];
        auto itr = st.lower_bound(pll(sum, -1));
        if (itr != st.end() and itr->first == sum) {
            int l = itr->second;
            int r = i + 1;
            res.push_back(pii(l, r));
            st.erase(itr);
        }
        st.insert(pll(sum, i + 1));
    }
    sort(all(res));

    priority_queue<pii> pq;
    rep (i, res.size()) {
        while (pq.size()) {
            pii ri = pq.top();
            if (ri.first >= res[i].second) pq.pop();
            else break;
        }
        pq.push(pii(res[i].second, i));
    }

    vector<pii> res2;
    while (pq.size()) {
        int i = pq.top().second;
        pq.pop();
        res2.push_back(res[i]);
    }
    sort(all(res2));
    return res2;
}

vii doubling(vector<pii> a) {
    int m = 20;
    int n = a.size();
    vii res(n, vi(m));

    rep (i, n) {
        res[i][0] = i;
    }

    for (int j = 0; j < m - 1; j++) {
        rep (i, n) {
            int ni = res[i][j];
            ni++;
            if (ni == n) {
                res[i][j + 1] = n;
            }
            res[i][j + 1] = res[ni][j];
        }
    }
    return res;
}

signed main() {
    fio();
    int n;
    cin >> n;

    vll t(2, vl(n));
    rep (i, 2) {
        rep (j, n) {
            cin >> t[i][j];
        }
    }

    vector<vector<pii>> a(2);
    rep (i, 2) a[i] = calc(t[i]);

    vii b(2, vi(n, -1));
    rep (i, 2) {
        rep (j, a[i].size()) {
            b[i][a[i][j].first] = a[i][j].second;
        }
    }

    vl temp(n);
    rep (i, n) temp[i] = t[0][i] + t[1][i];
    vector<pii> both = calc(temp);

    vi both_b(n, -1);
    rep (i, both.size()) {
        both_b[both[i].first] = both[i].second;
    }

    vii next(2, vi(n + 1));
    rep (i, 2) {
        rep (j, n + 1) {
            auto itr1 = lower_bound(all(a[i]), pii(j + 1, -inf));
            auto itr2 = lower_bound(all(both), pii(j + 1, -inf));
            int l1, l2;
            if (itr1 == a[i].end()) l1 = n;
            else l1 = itr1->first;
            if (itr2 == both.end()) l2 = n;
            else l2 = itr2->first;
            next[i][j] = min(l1, l2);
        }
    }

    vector<map<int, int>> dp(n + 1);
    dp[0][0] = 0;
    // vector<set<int>> qu(n + 1);
    // qu[0].insert(0);
    int ans = 0;
    rep (i, n + 1) {
        while (dp[i].size()) {
            pii jc = *dp[i].begin();
            dp[i].erase(dp[i].begin());
            int j = jc.first;
            int now = jc.second;
            chmax(ans, now);
            if (i <= j and i != n) {
                // int ni = next[0][i];
                int ni = i + 1;
                if (dp[ni].count(j) == 0 or dp[ni][j] < now) {
                    dp[ni][j] = now;
                }

                if (b[0][i] != -1) {
                    int ni = b[0][i];
                    if (dp[ni].count(j) == 0 or dp[ni][j] < now + 1) {
                        dp[ni][j] = now + 1;
                    }
                }
            }
            if (j <= i and j != n) {
                // int nj = next[1][j];
                int nj = j + 1;
                if (dp[i].count(nj) == 0 or dp[i][nj] < now) {
                    dp[i][nj] = now;
                }

                if (b[1][j] != -1) {
                    int nj = b[1][j];
                    if (dp[i].count(nj) == 0 or dp[i][nj] < now + 1) {
                        dp[i][nj] = now + 1;
                    }
                }
            }
            if (i == j and i != n) {
                if (both_b[i] != -1) {
                    int ni = both_b[i];
                    int nj = both_b[i];
                    if (dp[ni].count(nj) == 0 or dp[ni][nj] < now + 1) {
                        dp[ni][nj] = now + 1;
                    }
                }
            }
        }
    }

    cout << ans << endl;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

char map[5500][5500];
int h[5500][5500],n,m,ans=0;

bool cmp(int a,int b)
{
    return a>b;
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++) scanf("%s",map[i]);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(map[i-1][j-1]=='1') h[j][i]=h[j-1][i]+1;
        }
    }
    for(int i=1;i<=m;i++)
    {
        sort(h[i]+1,h[i]+n+1,cmp);
        for(int j=1;j<=n;j++)
        {
            if(h[i][j]==0) break;
            ans=max(ans,h[i][j]*j);
        }
    }
    printf("%d\n",ans);
    return 0;
}


#include<cstdio>
#include<cstring>
#include<iostream>
#define N 5010
using namespace std;
int f[N][N],n,m,ans=0;
int a[N][N],b[N][N];
char map[N][N];
int main()
{
	int i,j;
	scanf("%d %d",&n,&m);
	for(i=1;i<=n;i++)
	{
		getchar();
		for(j=1;j<=m;j++)
			scanf("%c",&map[i][j]);
	}
	for(i=1;i<=n;i++)
		for(j=1;j<=m;j++)
			if(map[i][j]=='1')
			{
				a[i][j]=a[i][j-1]+1;
				for(int k=1;k<=a[i][j];k++)b[j][k]++;
			}
	/*for(i=1;i<=n;i++)
	{
		for(j=1;j<=m;j++)
			printf("%d ",a[i][j]);
		puts("");
	}
	for(j=1;j<=m;j++)
	{
		for(i=1;i<=n;i++)
			printf("%d ",b[j][i]);
		printf("\n");
	}*/
	for(j=1;j<=m;j++)
		for(i=1;i<=n;i++)
			ans=max(ans,b[j][i]*i);
	printf("%d",ans);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<iostream>
#define N 5010
using namespace std;
int f[N][N],n,m,ans=0;
int a[N][N],b[N][N];
char map[N][N];
int main()
{
	int i,j;
	scanf("%d %d",&n,&m);
	for(i=1;i<=n;i++)
		scanf("%s",map[i]+1);
	for(i=1;i<=n;i++)
		for(j=1;j<=m;j++)
			if(map[i][j]=='1')
			{
				a[i][j]=a[i][j-1]+1;
				b[j][a[i][j]]++;
			}
	for(j=1;j<=m;j++)
		for(i=n-1;i>=1;i--)
			b[j][i]+=b[j][i+1];
	for(j=1;j<=m;j++)
		for(i=1;i<=m;i++)
			ans=max(ans,b[j][i]*i);
 	printf("%d",ans);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<iostream>
#define N 5010
using namespace std;
int f[N][N],n,m,ans=0;
int a[N][N],b[N][N];
char map[N][N];
int main()
{
	int i,j;
	scanf("%d %d",&n,&m);
	for(i=1;i<=n;i++)
	{
		getchar();
		for(j=1;j<=m;j++)
			scanf("%c",&map[i][j]);
	}
	for(i=1;i<=n;i++)
		for(j=1;j<=m;j++)
			if(map[i][j]=='1')
			{
				a[i][j]=a[i][j-1]+1;
				//b[j][a[i][j]]++;
				for(int k=1;k<=a[i][j];k++)b[j][k]++;
			}
	/*for(i=1;i<=n;i++)
	{
		for(j=1;j<=m;j++)
			printf("%d ",a[i][j]);
		puts("");
	}
	for(j=1;j<=m;j++)
	{
		for(i=1;i<=n;i++)
			printf("%d ",b[j][i]);
		printf("\n");
	}*/
	for(j=1;j<=m;j++)
		for(i=1;i<=m;i++)
			ans=max(ans,b[j][i]*i);
	printf("%d",ans);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<iostream>
#define N 5010
using namespace std;
int f[N][N],n,m,ans=0;
int a[N][N],b[N][N];
char map[N][N];
int main()
{
	int i,j;
	scanf("%d %d",&n,&m);
	for(i=1;i<=n;i++) scanf("%s",map[i]+1);
	for(i=1;i<=n;i++)
		for(j=1;j<=m;j++)
			if(map[i][j]=='1')
			{
				a[i][j]=a[i][j-1]+1;
				b[j][a[i][j]]++;
			}
	for(j=1;j<=m;j++)
	{
		int c=0;
		for(i=m;i>=1;i--)
		{
			c+=b[j][i];
			ans=max(ans,c*i);
 		}
	}
	printf("%d",ans);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<iostream>
#define N 5010
using namespace std;
int f[N][N],n,m,ans=0;
int a[N][N],b[N][N];
char map[N][N];
int main()
{
	int i,j;
	scanf("%d %d",&n,&m);
	for(i=1;i<=n;i++)
	{
		getchar();
		for(j=1;j<=m;j++)
		{
			scanf("%c",&map[i][j]);
			if(map[i][j]=='1')
			{
				a[i][j]=a[i][j-1]+1;
				b[j][a[i][j]]++;
			}
		}
	}
	/*for(i=1;i<=n;i++)
	{
		for(j=1;j<=m;j++)
			printf("%d ",a[i][j]);
		puts("");
	}
	for(j=1;j<=m;j++)
	{
		for(i=1;i<=n;i++)
			printf("%d ",b[j][i]);
		printf("\n");
	}*/
	for(j=1;j<=m;j++)
	{
		int c=0;
		for(i=m;i>=1;i--)
		{
			c+=b[j][i];
			ans=max(ans,c*i);
 		}
	}
	printf("%d",ans);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<iostream>
#define N 5010
using namespace std;
int f[N][N],n,m,ans=0;
int a[N][N],b[N][N];
char map[N][N];
int main()
{
	int i,j;
	scanf("%d %d",&n,&m);
	for(i=1;i<=n;i++)
	{
		getchar();
		for(j=1;j<=m;j++)
		{
			scanf("%c",&map[i][j]);
			if(map[i][j]=='1')
			{
				a[i][j]=a[i][j-1]+1;
				b[j][a[i][j]]++;
			}
		}
	}
	for(j=1;j<=m;j++)
		for(i=m;i>=1;i--)
			b[j][i]+=b[j][i+1];
	/*for(i=1;i<=n;i++)
	{
		for(j=1;j<=m;j++)
			printf("%d ",a[i][j]);
		puts("");
	}
	for(j=1;j<=m;j++)
	{
		for(i=1;i<=n;i++)
			printf("%d ",b[j][i]);
		printf("\n");
	}*/
	for(j=1;j<=m;j++)
		for(i=1;i<=m;i++)
			ans=max(ans,b[j][i]*i);
 printf("%d",ans);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<iostream>
#define N 5010
using namespace std;
int f[N][N],n,m,ans=0;
int a[N][N],b[N][N];
char map[N][N];
int main()
{
	int i,j;
	scanf("%d %d",&n,&m);
	for(i=1;i<=n;i++)
	{
		getchar();
		for(j=1;j<=m;j++)
			scanf("%c",&map[i][j]);
	}
	for(i=1;i<=n;i++)
		for(j=1;j<=m;j++)
			if(map[i][j]=='1')
			{
				a[i][j]=a[i][j-1]+1;
				b[j][a[i][j]]++;
			}
	/*for(i=1;i<=n;i++)
	{
		for(j=1;j<=m;j++)
			printf("%d ",a[i][j]);
		puts("");
	}*/
	for(j=1;j<=m;j++)
		for(i=1;i<=n;i++)
			ans=max(ans,b[j][i]*i);
	printf("%d",ans);
	return 0;
}


#include <iostream>
#include <string>
#include <vector>
using namespace std;

int main()
{
  std::ios::sync_with_stdio(false);
  int n, m;
  cin>>n>>m;
  string s;
  int right[n][m];

  for(int i=0; i<n; i++)
  {
    cin>>s;
    right[i][m-1]=s[m-1]-'0';
    for(int j=m-2; j>=0; j--)
    {
      if(s[j]=='0')
	right[i][j]=0;
      else right[i][j]=right[i][j+1]+1;
    }
  }

  int gmax=0;
  for(int i=0; i<m; i++)
  {
    vector<int> temp(m+1, 0);

    for(int j=0; j<n; j++)
    {
      temp[right[j][i]]++;
    }

    int ans=0, count=0, dummy;
    for(int j=m; j>0; j--)
    {
      if(temp[j]!=0)
      {
	count+=temp[j];
	dummy=count*j;
	if(dummy>ans)
	  ans=dummy;
      }
    }

    if(ans>gmax)
      gmax=ans;
  }

  cout<<gmax<<endl;
}


#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;

int main()
{
  int n, m;
  scanf("%d %d",&n, &m);
  string s;
  int arr[n];
  for(int i=0; i<n; i++)
  {
    arr[i]=0;
    cin>>s;
    for(int j=0; j<m; j++)
    {
      if(s[j]=='1')
	arr[i]++;
    }
  }
  int maxArea=0, temp=0;
  for(int i=0; i<n; i++)
  {
    temp=1;
    for(int j=i-1; j>=0; j--)
    {
      if(arr[j]<arr[i])
	break;
      temp++;
    }

    for(int j=i+1; j<n; j++)
    {
      if(arr[j]<arr[i])
	break;
      temp++;
    }

    temp*=arr[i];
    if(temp>maxArea)
      maxArea=temp;
  }
  printf("%d\n",maxArea);
}


#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;

int main()
{
  int n, m;
  scanf("%d %d",&n, &m);
  string s;
  int arr[n][m], right[n][m];

  for(int i=0; i<n; i++)
  {
    cin>>s;
    for(int j=0; j<m; j++)
      arr[i][j]=s[j]-'0';
  }

  for(int i=n-1; i>=0; i--)
  {
    right[i][m-1]=arr[i][m-1];
    for(int j=m-2; j>=0; j--)
    {
      if(arr[i][j]==0)
	right[i][j]=0;
      else right[i][j]=right[i][j+1]+1;
    }
  }

  int gmax=0;
  for(int i=0; i<m; i++)
  {
    int temp[m+1];
    for(int j=0; j<=m; j++)
      temp[j]=0;

    for(int j=0; j<n; j++)	// sorint g done
    {
      temp[right[j][i]]++;
    }

    int ans=0, count=0, dummy;
    for(int j=m; j>0; j--)
    {
      if(temp[j]!=0)
      {
	count+=temp[j];
	dummy=count*j;
	if(dummy>ans)
	  ans=dummy;
      }
    }
    if(ans>gmax)
      gmax=ans;
  }

  printf("%d\n",gmax);
}


#include <iostream>
#include <stdio.h>
#include <string>
#include <vector>
using namespace std;

int main()
{
  int n, m;
  scanf("%d %d",&n, &m);
  string s;
  int right[n][m];

  for(int i=0; i<n; i++)
  {
    cin>>s;
    right[i][m-1]=s[m-1]-'0';
    for(int j=m-2; j>=0; j--)
    {
      if(s[j]=='0')
	right[i][j]=0;
      else right[i][j]=right[i][j+1]+1;
    }
  }

  int gmax=0;
  for(int i=0; i<m; i++)
  {
    vector<int> temp(m+1, 0);

    for(int j=0; j<n; j++)
    {
      temp[right[j][i]]++;
    }

    int ans=0, count=0, dummy;
    for(int j=m; j>0; j--)
    {
      if(temp[j]!=0)
      {
	count+=temp[j];
	dummy=count*j;
	if(dummy>ans)
	  ans=dummy;
      }
    }

    if(ans>gmax)
      gmax=ans;
  }

  printf("%d\n",gmax);
}


#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;

#define gc getchar_unlocked

int main()
{
  int n, m;
  scanf("%d %d",&n, &m);
  string s="";
  int right[n][m], x=m;
  char ch;
  for(int i=0; i<n; i++)
  {
    x=m;
    s="";
    ch=gc();
    while(ch!='\n')
    {
      s+=ch;
      ch=gc();
    }
    right[i][m-1]=s[m-1]-'0';
    for(int j=m-2; j>=0; j--)
    {
      if(s[j]=='0')
	right[i][j]=0;
      else right[i][j]=right[i][j+1]+1;
    }
  }

  int gmax=0, temp[m+1];
  for(int i=0; i<m; i++)
  {
    for(int j=0; j<=m; j++)
      temp[j]=0;

    for(int j=0; j<n; j++)
    {
      temp[right[j][i]]++;
    }

    int ans=0, count=0, dummy;
    for(int j=m; j>0; j--)
    {
      if(temp[j]!=0)
      {
	count+=temp[j];
	dummy=count*j;
	if(dummy>ans)
	  ans=dummy;
      }
    }

    if(ans>gmax)
      gmax=ans;
  }

  printf("%d\n",gmax);
}


#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;

int main()
{
  int n, m;
  scanf("%d %d",&n, &m);
  string s;
  int right[n][m];

  for(int i=0; i<n; i++)
  {
    cin>>s;
    right[i][m-1]=s[m-1]-'0';
    for(int j=m-2; j>=0; j--)
    {
      if(s[j]=='0')
	right[i][j]=0;
      else right[i][j]=right[i][j+1]+1;
    }
  }

  int gmax=0, temp[m+1];
  for(int i=0; i<m; i++)
  {
    for(int j=0; j<=m; j++)
      temp[j]=0;

    for(int j=0; j<n; j++)	// sorint g done
    {
      temp[right[j][i]]++;
    }

    int ans=0, count=0, dummy;
    for(int j=m; j>0; j--)
    {
      if(temp[j]!=0)
      {
	count+=temp[j];
	dummy=count*j;
	if(dummy>ans)
	  ans=dummy;
      }
    }
    if(ans>gmax)
      gmax=ans;
  }

  printf("%d\n",gmax);
}


#include <iostream>
#include <string>
#include <vector>
using namespace std;

int main()
{
  std::ios_base::sync_with_stdio(false);
  int n, m;
  cin>>n>>m;
  string s;
  int right[n][m];

  for(int i=0; i<n; i++)
  {
    cin>>s;
    right[i][m-1]=s[m-1]-'0';
    for(int j=m-2; j>=0; j--)
    {
      if(s[j]=='0')
	right[i][j]=0;
      else right[i][j]=right[i][j+1]+1;
    }
  }

  int gmax=0;
  for(int i=0; i<m; i++)
  {
    vector<int> temp(m+1, 0);

    for(int j=0; j<n; j++)
    {
      temp[right[j][i]]++;
    }

    int ans=0, count=0, dummy;
    for(int j=m; j>0; j--)
    {
      if(temp[j]!=0)
      {
	count+=temp[j];
	dummy=count*j;
	if(dummy>ans)
	  ans=dummy;
      }
    }

    if(ans>gmax)
      gmax=ans;
  }

  cout<<gmax<<endl;
}


#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
int result[5010][5010];
int a[5010];
char s[5010][5010];
int main(){
		int n,m,i,j;
		cin>>n>>m;
		for(i=1;i<=n;i++){
			cin>>s[i];
		}
		char c;
		unsigned long  ans=0;
		for(j=0;j<m;j++) {
			vector<int> k;
			for(i=1;i<=n;i++) {
				if(s[i][j]=='1') {
					result[i][j+1]=result[i][j]+1;
					k.push_back(result[i][j+1]);
				}
				else result[i][j+1]=0;
			}
			sort(k.begin(),k.end());  // contains a zero
			for(int t=0;t<k.size();t++){
				ans = max(ans,k[t]*(k.size()-t));
			}
		}
		cout<<ans<<endl;
		return 0;
}


#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
int result[5010][5010];
int a[5010];
char s[5010][5010];
bool cmp(int x,int y)
{
	return (x>y);
}
int main(){
		int n,m,i,j;
		cin>>n>>m;
		for(i=1;i<=n;i++){
			cin>>s[i];
		}
		char c;
		int ans=0;
		for(j=0;j<m;j++) {
			int k=0;
			for(i=1;i<=n;i++) {
				if(s[i][j]=='1') {
					k++;
					result[i][j+1]=result[i][j]+1;
					a[k]=result[i][j+1];
				}
				else result[i][j+1]=0;
			}
			sort(a+1,a+k+1);  // contains a zero
			for(int t=1;t<=k;t++){
				ans = max(ans,a[t]*(k-t+1));
			}
		}
		cout<<ans<<endl;
		return 0;
}


#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
int result[5010][5010];
char s[5010][5010];
int main(){
		ios_base::sync_with_stdio(0);
		int n,m,i,j;
		cin>>n>>m;
		for(i=1;i<=n;i++){
			cin>>s[i];
		}
		unsigned long  ans=0;
		for(j=0;j<m;j++) {
			vector<int> k;
			for(i=1;i<=n;i++) {
				if(s[i][j]=='1') {
					result[i][j+1]=result[i][j]+1;
					k.push_back(result[i][j+1]);
				}
			}
			sort(k.begin(),k.end());  // contains a zero
			for(int t=0;t<k.size();t++){
				if (ans<k[t]*(k.size()-t))
					ans = k[t]*(k.size()-t);
			}
		}
		cout<<ans<<endl;
		return 0;
}


#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
int result[5010][5010];
int a[5010];
char s[5010][5010];
int main(){
		int n,m,i,j;
		cin>>n>>m;
		for(i=1;i<=n;i++){
			cin>>s[i];
		}
		char c;
		unsigned long  ans=0;
		for(j=0;j<m;j++) {
			vector<int> k;
			for(i=1;i<=n;i++) {
				if(s[i][j]=='1') {
					result[i][j+1]=result[i][j]+1;
					k.push_back(result[i][j+1]);
				}
				else result[i][j+1]=0;
			}
			sort(k.begin(),k.end());  // contains a zero
			for(int t=0;t<k.size();t++){
				if (ans<k[t]*(k.size()-t))
					ans = k[t]*(k.size()-t);
			}
		}
		cout<<ans<<endl;
		return 0;
}


#include<iostream>
#include<vector>
#include<algorithm>
#include<cstring>

using namespace std;

const int MAXN = 10000;
const int MAXM = 10000;
int N, M;
char C[MAXN][MAXM];

int nxt0[MAXN];

int go() {
		for(int i = 0; i < N; i++) C[i][M] = '0';

			memset(nxt0, -1, sizeof(nxt0));
				int res = 0;

					for(int a = 0; a < M; a++) {
								vector<int> lens;
										for(int i = 0; i < N; i++) {
														if(nxt0[i] < a) {
																			nxt0[i] = a;
																							while(C[i][nxt0[i]] != '0') nxt0[i] ++;
																										}
																	lens.push_back(nxt0[i] - a);
																			}

												sort(lens.begin(), lens.end());

														for(int i = 0; i < N; i++) {
																		int v = lens[i] * (N - i);
																					if(v > res) res = v;
																							}
															}
						return res;
}

int main() {
		ios_base::sync_with_stdio(0);
			cin >> N >> M;
				for(int i = 0; i < N; i++) cin >> C[i];

					cout << go() << '\n';
}


#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
int result[5010][5010];
int a[5010];
char s[5010][5010];
bool cmp(int x,int y)
{
	return (x>y);
}
int main(){
		int n,m,i,j;
		cin>>n>>m;
		for(i=1;i<=n;i++){
			for(j=1;j<=m;j++){
				cin>>s[i][j];
			}
		}
		char c;
		int ans=0;
		for(j=1;j<=m;j++) {
			int k=0;
			for(i=1;i<=n;i++) {
				if(s[i][j]=='1') {
					k++;
					result[i][j]=result[i][j-1]+1;
					a[k]=result[i][j];
				}
				else result[i][j]=0;
			}
			sort(a+1,a+k+1,cmp);  // contains a zero
			for(int m=1;m<=k;m++){
				ans = max(ans,a[m]*m);
			}
		}
		cout<<ans<<endl;
		return 0;
}


#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
int result[5010][5010];
int a[5010];
char s[5010][5010];
bool cmp(int x,int y)
{
	return (x>y);
}
int main(){
		int n,m,i,j;
		cin>>n>>m;
		for(i=1;i<=n;i++){
			cin>>s[i];
		}
		char c;
		int ans=0;
		for(j=0;j<m;j++) {
			int k=0;
			for(i=1;i<=n;i++) {
				if(s[i][j]=='1') {
					k++;
					result[i][j+1]=result[i][j]+1;
					a[k]=result[i][j+1];
				}
				else result[i][j+1]=0;
			}
			sort(a+1,a+k+1,cmp);  // contains a zero
			for(int m=1;m<=k;m++){
				ans = max(ans,a[m]*m);
			}
		}
		cout<<ans<<endl;
		return 0;
}


#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
int result[5010][5010];
int a[5010];
char s[5010][5010];
bool cmp(int x,int y)
{
	return (x>y);
}
int main(){
		int n,m,i,j;
		cin>>n>>m;
		for(i=1;i<=n;i++){
			cin>>s[i];
		}
		char c;
		int ans=0;
		for(j=1;j<=m;j++) {
			int k=0;
			for(i=1;i<=n;i++) {
				if(s[i][j]=='1') {
					k++;
					result[i][j]=result[i][j-1]+1;
					a[k]=result[i][j];
				}
				else result[i][j]=0;
			}
			sort(a+1,a+k+1,cmp);  // contains a zero
			for(int m=1;m<=k;m++){
				ans = max(ans,a[m]*m);
			}
		}
		cout<<ans<<endl;
		return 0;
}


//Bokan ga bokka--nn!!
//Daily Lunch Special Tanoshii !!
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <functional>
#include <iostream>
#include <map>
#include <set>
using namespace std;
typedef pair<int,int> P;
typedef pair<int,P> P1;
typedef pair<P,P> P2;
typedef long long ll;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
#define INF 2000000000
#define s(x) scanf("%d",&x)
#define rep(i,x) for(int i=0;i<x;i++)
char f[5005];
vector<int>rightt[5005];
int main()
{
	int n,m;
	scanf("%d %d",&n,&m);
	for(int i=0;i<n;i++)
	{
			scanf("%s",f);
			int le;
			bool len=false;
			for(int j=0;j<m;j++)
			{
					if(!len && f[j]=='1')
					{
						len=true;
						le=j;
					}
					if(len && f[j]=='0')
					{
							len=false;
							rightt[le].pb(j-1);
					}
			}
			if(len)
			{
					rightt[le].pb(m-1);
			}
	}
	vector<int>s;
	int ret=0;
	for(int i=0;i<m;i++)
	{
		for(int j=0;j<rightt[i].size();j++) s.pb(rightt[i][j]);
		sort(s.begin(),s.end(),greater<int>());
		int cur=0;
		int pointt=0;
		while(cur<s.size())
		{
			while(pointt<s.size() && s[cur]==s[pointt]) pointt++;
			ret=max(ret,(pointt)*(s[cur]-i+1));

			//printf("%d %d\n",(pointt-cur),(rightt[i][cur]-i+1));
			cur=pointt;
		}
	}
	printf("%d\n",ret);
	cin >> ret;

}


//Bokan ga bokka--nn!!
//Daily Lunch Special Tanoshii !!
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <functional>
#include <iostream>
#include <map>
#include <set>
using namespace std;
typedef pair<int,int> P;
typedef pair<int,P> P1;
typedef pair<P,P> P2;
typedef long long ll;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
#define INF 2000000000
#define s(x) scanf("%d",&x)
#define rep(i,x) for(int i=0;i<x;i++)
char f[5005];
vector<int>rightt[5005];
int main()
{
	int n,m;
	scanf("%d %d",&n,&m);
	for(int i=0;i<n;i++)
	{
			scanf("%s",f);
			int le;
			bool len=false;
			for(int j=0;j<m;j++)
			{
					if(!len && f[j]=='1')
					{
						len=true;
						le=j;
					}
					if(len && f[j]=='0')
					{
							len=false;
							rightt[le].pb(j-1);
					}
			}
			if(len)
			{
					rightt[le].pb(m-1);
			}
	}
	int ret=0;
	for(int i=0;i<m;i++)
	{
		int cur=0;
		int pointt=0;
		while(cur<rightt[i].size())
		{
			while(pointt<rightt[i].size() && rightt[i][cur]==rightt[i][pointt]) pointt++;
			ret=max(ret,(pointt-cur)*(rightt[i][cur]-i+1));

			//printf("%d %d\n",(pointt-cur),(rightt[i][cur]-i+1));
			cur=pointt;
		}
	}
	printf("%d\n",ret);
	cin >> ret;

}


//Bokan ga bokka--nn!!
//Daily Lunch Special Tanoshii !!
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <functional>
#include <iostream>
#include <map>
#include <set>
using namespace std;
typedef pair<int,int> P;
typedef pair<int,P> P1;
typedef pair<P,P> P2;
typedef long long ll;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
#define INF 2000000000
#define s(x) scanf("%d",&x)
#define rep(i,x) for(int i=0;i<x;i++)
char f[5005][5005];
int v[5005]={};
int main()
{
	int n,m;
	scanf("%d %d",&n,&m);
	for(int i=0;i<n;i++)
	{
			scanf("%s",f[i]);
			for(int j=0;j<m;j++)
			{
					if(f[i][j]=='1') v[i]++;
			}
	}
	int ret=0;
	for(int i=0;i<n;i++)
	{
			int least=6000;
			for(int j=i;j<n&&least;j++)
			{
					least=min(least,v[j]);
					ret=max(ret,least*(j-i+1));
			}
	}
	printf("%d\n",ret);
}