/*
贪心策略:
如果检查的那天不用加,那就不加
反之加上尽可能多的钱
如何确定这个值?
处理出前缀和,第i天可以加的钱=d-[i+1,n]天里前缀和的最大值
加上这个值后,要再一次更新前缀和数组,用线段树维护前缀和数组即可
*/
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define N 200005
ll n,d,a[N],sum[N];
vector<int>v;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
ll lazy[N<<2],Max[N<<2];
void pushdown(int rt){
lazy[rt<<1]+=lazy[rt];
lazy[rt<<1|1]+=lazy[rt];
Max[rt<<1]+=lazy[rt];
Max[rt<<1|1]+=lazy[rt];
lazy[rt]=0;
}
void build(int l,int r,int rt){
if(l==r){Max[rt]=sum[l];return;}
int m=l+r>>1;
build(lson);build(rson);
Max[rt]=max(Max[rt<<1],Max[rt<<1|1]);
}
void update(int L,int R,int v,int l,int r,int rt){
if(L<=l && R>=r){
Max[rt]+=v;lazy[rt]+=v;return;
}
pushdown(rt);
int m=l+r>>1;
if(L<=m)update(L,R,v,lson);
if(R>m)update(L,R,v,rson);
Max[rt]=max(Max[rt<<1],Max[rt<<1|1]);
}
ll query(int L,int R,int l,int r,int rt){
if(L<=l && R>=r)return Max[rt];
int m=l+r>>1;
pushdown(rt);
ll res=-0x3f3f3f3f3f3f3f3f;
if(L<=m)res=max(res,query(L,R,lson));
if(R>m)res=max(res,query(L,R,rson));
return res;
}
int main(){
cin>>n>>d;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++){
sum[i]=sum[i-1]+a[i];
if(sum[i]>d){
cout<<-1;return 0;
}
}
build(1,n,1);
for(int i=1;i<=n;i++)
if(a[i]==0)v.push_back(i);
int ans=0;
for(auto pos:v){
ll cur=query(pos,pos,1,n,1);
if(cur>=0)continue;
ans++;
ll mx=query(pos,n,1,n,1);
ll dif=d-mx;
if(dif+cur<0){
cout<<-1<<'\n';return 0;
}
update(pos+1,n,dif,1,n,1);
}
cout<<ans<<'\n';
}