// Slower C++ solution:
#include <bits/stdc++.h>

using namespace std;

#define repr(i,a,b) for(int i=a;i<b;i++)

#define rep(i,n) for(int i=0;i<n;i++)

#define reprrev(i,a,b) for(int i=b-1;i>=a;i--) // [a, b)

#define reprev(i,n) reprrev(i,0,n)

typedef long long ll;

typedef unsigned long long ull;

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; }



/* attention

    long longのシフト演算には気をつけよう

    タイポした時のデバッグが死ぬほどきつくなるので変数名は最低3字くらい使った方がいいかも

    sizeは(int)とキャストしよう

    ごちゃごちゃ場合分けを考える前に全探索は考えましたか？

    詰まった時に、別の分野の問題として考え直す（これdpでは？、グラフとしてみればいいのでは？）

    多くの問題はパターンマッチだが、パターンに落とし込むまでが難しく、そのための訓練としてわからない問題をあれこれ色々な角度から考察してみるのではないか

    cin.tie(0);

    ios::sync_with_stdio(false);<- これら、printfとかと併用しない方が良さそう



*/



const ll mod = 1e9+7;



void chmod(ll &M){

    if(M >= mod) M %= mod;

    else if(M < 0){

        M += (abs(M)/mod + 1)*mod;

        M %= mod;

    }

}



int getl(int i, int N) { return i==0? N-1:i-1; };

int getr(int i, int N) { return i==N-1? 0:i+1; };



/* <--------------------------------------------> */





int main(void){

    cin.tie(0);

    ios::sync_with_stdio(false);



    int N, K; cin >> N >> K;

    vector<int> a(N+1);

    repr(i, 1, N+1) cin >> a[i];



    vector<vector<ll>> dp(N+5, vector<ll>(K+5, 0));

    dp[0][0]=1;



    vector<ll> cum(K+5, 0);

    repr(i, 1, N+1){

        cum[0]=dp[i-1][0];

        repr(j, 1, K+1) { cum[j]=cum[j-1]+dp[i-1][j]; chmod(cum[j]); }

        rep(j, K+1){

            int t=max(0, j-a[i]);

            dp[i][j]=cum[j]-(t==0? 0:cum[t-1]);

            chmod(dp[i][j]);

        }

    }

    cout << dp[N][K] << endl;

    

    return 0;

}


// Faster C++ solution for the same problem (measured speedup: 1.179749098911979x):
#include <bits/stdc++.h>

using namespace std;

#define repr(i,a,b) for(int i=a;i<b;i++)

#define rep(i,n) for(int i=0;i<n;i++)

#define reprrev(i,a,b) for(int i=b-1;i>=a;i--) // [a, b)

#define reprev(i,n) reprrev(i,0,n)

typedef long long ll;

typedef unsigned long long ull;

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; }



/* attention

    long longのシフト演算には気をつけよう

    タイポした時のデバッグが死ぬほどきつくなるので変数名は最低3字くらい使った方がいいかも

    sizeは(int)とキャストしよう

    cin.tie(0);

    ios::sync_with_stdio(false);<- これら、printfとかと併用しない方が良さそう



*/



const ll mod = 1e9+7;



void chmod(ll &M){

    if(M >= mod) M %= mod;

    else if(M < 0){

        M += (abs(M)/mod + 1)*mod;

        M %= mod;

    }

}



ll modpow(ll x, ll n){

    if(n==0) return 1;

    ll res=modpow(x, n/2);



    if(n%2==0) return res*res%mod;

    else return res*res%mod*x%mod;

}



int getl(int i, int N) { return i==0? N-1:i-1; };

int getr(int i, int N) { return i==N-1? 0:i+1; };





// 線分 ab の偏角 返り値は[-π, π]

double argument(const pair<double, double> &a, const pair<double, double> &b){

    double ax=a.first, ay=a.second, bx=b.first, by=b.second;

    return atan2(by-ay, bx-ax);

}



/* <-----------------------------------------------------------------------------------> */

/* <-----------------------------------------------------------------------------------> */

/* <-----------------------------------------------------------------------------------> */

/* <-----------------------------------------------------------------------------------> */



int n, k;

ll dp[110][100005];



int main(){

    cin.tie(nullptr);

    ios::sync_with_stdio(false);



    cin >> n >> k;

    vector<int> a(n+1, 0);

    vector<ll> cum(k+5, 0);

    repr(i, 1, n+1) cin >> a[i];

    dp[0][0] = 1;

    

    repr(i, 1, n+1){

        rep(j, k+1) { cum[j] = dp[i-1][j] + (j==0? 0:cum[j-1]); chmod(cum[j]); }

        rep(j, k+1) { dp[i][j] = cum[j] - (j-a[i]-1<0? 0:cum[j-a[i]-1]); chmod(dp[i][j]); }

    }

    cout << dp[n][k] << endl;



    return 0;

}