#include<bits/stdc++.h>
using namespace std;



#define pb                push_back
#define ppb               pop_back
#define pf                push_front
#define ppf               pop_front
#define all(x)            (x).begin(),(x).end()
#define uniq(v)           (v).erase(unique(all(v)),(v).end())
#define sz(x)             (ll)((x).size())
#define pii               pair<ll,ll>
#define piii              pair<pair<ll,ll>,ll>
#define Piii              pair<ll,pair<ll,ll>>
#define p_queue(a)        priority_queue<a, vector<a>, greater<a>>
#define mp                make_pair
#define se                second
#define fi                first
#define vi(a)             vector<a>
#define vvi(a)            vector <vector <a> >
#define pie               3.14159265358979323846
#define for0(i,a,b)       for(ll i=a;i<b;i++)
#define for1(i,a,b)       for(ll i=a;i<=b;i++)
#define mem1(a)           memset(a,-1,sizeof(a))
#define mem0(a)           memset(a,0,sizeof(a))

//#define nsetbits(x)        __builtin_popcountll(x)


//#include <ext/pb_ds/assoc_container.hpp> 
//#include <ext/pb_ds/tree_policy.hpp> 
//using namespace __gnu_pbds; 
// 
//template <typename num_t>
//using ordered_set = tree<num_t, null_type, less<num_t>, rb_tree_tag, tree_order_statistics_node_update>;
//mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
//auto dist=uniform_int_distribution<ll>(l,r);

//typedef ll ll;
typedef long long ll;

const ll inf = 1000000007;
const ll mod = 1000000007;
const ll MOD = 998244353;
const ll INF = 1e18 + 18;


vector<ll> dx={-1LL, 0LL, 1LL, 0LL}, dy={0LL, 1LL, 0LL, -1LL};
//vector<ll> dx={-1, -1, 0, 1, 1, 1, 0, -1}, dy={0, 1, 1, 1, 0, -1, -1, -1};


//string vowels = "aeiou";
//string consonants = "bcdfghjklmnpqrstvwxyz";
//string numbers = "0123456789";
//string alpha = "abcdefghijklmnopqrstuvwxyz";

void updateRange(vector<ll> & tree , vector<ll> & lazy , ll node, ll start, ll end, ll l, ll r, ll val)
{
    if(lazy[node] != 0)
    { 
        // This node needs to be updated
        tree[node] += lazy[node];    // Update it
//        min_tree[node] += lazy[node];
        if(start != end)
        {
            lazy[node*2] += lazy[node];                  // Mark child as lazy
            lazy[node*2+1] += lazy[node];                // Mark child as lazy
        }
        lazy[node] = 0;                                  // Reset it
    }
    if(start > end or start > r or end < l)              // Current segment is not within range [l, r]
        return;
    if(start >= l and end <= r)
    {
        // Segment is fully within range
        tree[node] += val;
//        min_tree[node] += val;
        if(start != end)
        {
            // Not leaf node
            lazy[node*2] += val;
            lazy[node*2+1] += val;
        }
        return;
    }
    ll mid = (start + end) / 2;
    updateRange(tree,lazy,node*2, start, mid, l, r, val);        // Updating left child
    updateRange(tree,lazy,node*2 + 1, mid + 1, end, l, r, val);   // Updating right child
    tree[node] = min(tree[node*2] , tree[node*2+1]);        // Updating root with max value
//	min_tree[node] = min(min_tree[2*node] , min_tree[2*node + 1]); 
}

ll queryRange(vector<ll> & tree , vector<ll> & lazy , ll node, ll start, ll end, ll l, ll r)
{
    if(start > end or start > r or end < l)
        return INF;         // Out of range
    if(lazy[node] != 0)
    {
        // This node needs to be updated
        tree[node] += lazy[node];            // Update it
//        min_tree[node] += lazy[node];
        if(start != end)
        {
            lazy[node*2] += lazy[node];         // Mark child as lazy
            lazy[node*2+1] += lazy[node];    // Mark child as lazy
        }
        lazy[node] = 0;                 // Reset it
    }
    if(start >= l and end <= r)             // Current segment is totally within range [l, r]
        return tree[node];
    ll mid = (start + end) / 2;
    ll p1 = queryRange(tree,lazy,node*2, start, mid, l, r);         // Query left child
    ll p2 = queryRange(tree,lazy,node*2 + 1, mid + 1, end, l, r); // Query right child
    return min(p1,p2);
}


void test_case(){

	
	ll n;
	cin>>n;
	vector<ll> arr(n+1);
	vector<pii> neg;
	ll ans = 0;
	ll suma = 0;
	vector<ll> tree(4*(n+1)),lazy(4*(n+1));
	for(ll i=1;i<=n;i++){
		cin>>arr[i];
		if(arr[i] >= 0){
//			update seg tree;
//			updateRange(tree,min_tree,lazy,1,1,n,i,i,arr[i]);
			ans += 1;
			suma += arr[i];
		}
		else{
			neg.pb(mp(arr[i],i));
		}
		updateRange(tree,lazy,1,1,n,i,i,suma);
	}
	sort(all(neg));
	reverse(all(neg));
	for(pii pair : neg){
		ll i = pair.se;
		ll val = pair.fi;
//		cout<<i<<" "<<val<<endl;
		ll pref_sum = (i == 1) ? 0 : queryRange(tree,lazy,1,1,n,i-1,i-1);
		ll suff_min = (i == n) ? INF : queryRange(tree,lazy,1,1,n,i+1,n);
//		cout<<pref_sum<<" "<<suff_min<<endl;
		if(pref_sum + val >= 0 && suff_min+val >= 0){
			ans += 1;
//			update seg tree;
			updateRange(tree,lazy,1,1,n,i,n,val);
		}
	}
	cout<<ans<<endl;
	
	
	


}



void intialize(){

	ios::sync_with_stdio(false);
  	cin.tie(0);
  	cout.tie(0);

}

void preprocess(){

	
	

}

void codejam(ll t){
	cout<<"Case #"<<t<<": ";
}

int main(){
//	clock_t start,end;
//	start = clock();
   	intialize();
   	preprocess();
   	cout<<fixed<<setprecision(16);
//	string a;
//	getline(cin,a);
   	test_case();
//	ll t;
//	cin>>t;
//	for(ll te=1;te<=t;te++){
////		codejam(te);
//		test_case();
//	}
//	end = clock();
//	double time_taken = double(end - start) / double(CLOCKS_PER_SEC);
//    cout << "Time taken by program is : " << fixed << time_taken << setprecision(10);
//    cout << " sec " << endl;


	return 0;
}

/*

to_string() ---> converts number to string;

stoi()   ------> converts string to number;

substr(i,l)  -----> gives substring starting from index 'i' of len 'l';

__builtin_popcountll(x)   -----> gives no.of setbits in x;

order_of_key: The number of items in a set that are strictly smaller than k

find_by_order: It returns an iterator to the ith largest element

ll f = upper_bound(all(g[x]),r) - lower_bound(all(g[x]),l);
it gives the frequency of element x in the range [L,R]

*/



