#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>

#define F first
#define S second
#define int long long
#define ll long long
//#define int  unsigned long long
#define pb push_back
//#define double long double

using namespace std;
using namespace __gnu_pbds;
typedef  tree< int , null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
const int mod = 998244353;
const int N = 1000005;
const int K = 25;
int a[N], d[N], v1[N], v2[N];
pair < pair < int, int >, pair < int, int > > calc(multiset < int > s1, multiset < int > s2, pair < int, int > z){
    int r = z.F;
    int x = z.S;
    int s = 0;
  //  cout << r << " " << x << " " << s1.size() << " " << s2.size() << endl;
    for (auto j: s1) s += j;
    if (s <= x){
        r += s1.size();
        auto it = s1.end();
        it--;
        return {{r, -s + x},{r - 1, x - s + max(*it, abs(*s2.begin()))}};
    }
    int y = x;
    auto it = s1.begin();
    int cnt = 0;
    while(y >= *it){
        y -= *it;
        it++;
        cnt++;
    }
    it = s1.end();
    it--;
    if (s <= abs(*s2.begin()) + x && !s1.empty()){
        r += s1.size() - 1;
        if (cnt == s1.size() - 1) return {{r, -s + max(*it, abs(*s2.begin())) + x},{r - 1, 1e15}};
        return {{r, -s + abs(*s2.begin()) + x},{r - 1, 1e15}};
    }
    while(!s1.empty() && *s1.begin() <= x){
        x -= *s1.begin();
        r++;
        s1.erase(s1.begin());
    }
    if (s1.size() == 1){
        return {{r, x}, {r - 1, 1e15}};
    }
    return {{r + (int)s1.size() - 2, 1e15}, {r + (int)s1.size() - 3, 1e15}};
}
main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
   // freopen("input.txt", "r", stdin);
    int n;
    cin >> n;
    srand(time(NULL));
    for (int i = 1; i <= n; i++){
        if (i == 1) v1[i] = rand() % 10 + 1;
        else v1[i] = v1[i - 1] + rand() % 500;
    }
    for (int i = 1; i <= n; i++){
        if (i == 1) v2[i] = rand() % 10 + 1;
        else v2[i] = v2[i - 1] + rand() % 500;
    }
    reverse(v2 + 1, v2 + n + 1);
    for (int i = 1; i <= n; i++){
        a[i] = v1[i] + v2[i];
       // cout << a[i] << " ";
        cin >> a[i];
        d[i] = a[i] - a[i - 1];
    }
    d[n + 1] = -a[n];
    n++;
    int c1, c2;
    c1 = c2 = 0;
    multiset < int > s1, s2;
    int t = 0;
    int ans = 0;
    d[0] = -1;
    int z = 0;
    int c = 0;
    int ub = 0;
    pair < pair < int, int >, pair < int, int > > cs;
    vector < pair < int, int > > td;;
    for (int i = 0; i <= n; i++){
        if (d[i] == 0) continue;
        td.pb({d[i], a[i]});
    }
    n = td.size();
    for (int i = n - 1; i >= 0; i--){
        if (td[i].F == 0) continue;
        if (td[i].F > 0) ans++;
        if (td[i].F > 0) s1.insert(td[i].F); else{
            if (td[i + 1].F > 0){
                cs.F.S = min(cs.F.S, ub);
                cs.S.S = min(cs.S.S, ub);
                auto v1 = calc(s1, s2, cs.F);
                auto v2 = calc(s1, s2, cs.S);
                cs.F.F = cs.F.S = cs.S.F = cs.S.S = 0;
                cs.F.F = max(v1.F.F, v2.F.F);
                cs.S.F = cs.F.F - 1;
                if (v1.F.F == cs.F.F) cs.F.S = max(cs.F.S, v1.F.S);
                if (v2.F.F == cs.F.F) cs.F.S = max(cs.F.S, v2.F.S);
                if (v1.S.F == cs.S.F) cs.S.S = max(cs.S.S, v1.S.S);
                if (v2.S.F == cs.S.F) cs.S.S = max(cs.S.S, v2.S.S);
                if (v1.F.F == cs.S.F) cs.S.S = max(cs.S.S, v1.F.S);
                if (v2.F.F == cs.S.F) cs.S.S = max(cs.S.S, v2.F.S);
                ub = td[i].S;
                while(!s2.empty()) s2.erase(s2.begin());
                while(!s1.empty()) s1.erase(s1.begin());
                //cout << cs.F.F << " " << cs.F.S << " -- " << cs.S.F << " " << cs.S.S << endl;
            }
            s2.insert(td[i].F);
        }
    }
    cout << ans - cs.F.F;
}


Measured memory_bytes: 36716