#include <bits/stdc++.h>
#pragma comment(linker, "/stack:512000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,tune=native")
#pragma GCC optimize("unroll-loops")
using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
mt19937_64 gen(time(nullptr));
ll const mod = 1e9 + 7;
namespace {
ll mul(ll a, ll b) {
  ll val = a * b - (ll)((ld)a * b / mod) * mod;
  if (val < 0) val += mod;
  if (val >= mod) val -= mod;
  return val;
}
ll poww(ll a, ll b) {
  ll val = 1;
  a %= mod;
  while (b > 0) {
    if (b % 2) val = mul(a, val);
    a = mul(a, a);
    b >>= 1;
  }
  return val % mod;
}
ll inv(ll a) { return poww(a, mod - 2); }
}  // namespace
struct segtree {
  struct node {
    node(ll x) : val(x){};
    node() : val(0){};
    ll val = 0;
    ll lazy = 0;
    void apply(int tl, int tr, ll add) {
      val += add * (tr - tl + 1);
      if (val > mod) val %= mod;
      lazy += add;
      if (lazy > mod) lazy %= mod;
    }
  };
  void push(int u, int tl, int tr) {
    if (t[u].lazy != 0) {
      int tm = (tl + tr) / 2;
      t[u * 2].apply(tl, tm, t[u].lazy);
      t[u * 2 + 1].apply(tm + 1, tr, t[u].lazy);
      t[u].lazy = 0;
    }
  }
  node merge(const node& a, const node& b) const {
    ll val = a.val + b.val;
    if (val > 0) val %= mod;
    return node(val);
  }
  node get(int u, int tl, int tr, int l, int r) {
    if (r < l || tl > r || tr < l) {
      return neutral;
    }
    if (l <= tl && tr <= r) {
      return t[u];
    } else {
      push(u, tl, tr);
      int tm = (tl + tr) / 2;
      return merge(get(u * 2, tl, tm, l, r), get(u * 2 + 1, tm + 1, tr, l, r));
    }
  }
  template <typename... M>
  void upd(int u, int tl, int tr, int l, int r, const M&... m) {
    if (r < l || tl > r || tr < l) {
      return;
    }
    if (l <= tl && tr <= r) {
      t[u].apply(tl, tr, m...);
    } else {
      push(u, tl, tr);
      int tm = (tl + tr) / 2;
      upd(u * 2, tl, tm, l, r, m...);
      upd(u * 2 + 1, tm + 1, tr, l, r, m...);
      t[u] = merge(t[u * 2], t[u * 2 + 1]);
    }
  }
  template <class T>
  void build(int u, int tl, int tr, vector<T>& v) {
    if (tl == tr) {
      node tmp(v[tl]);
      t[u] = tmp;
    } else {
      int tm = (tl + tr) / 2;
      build(u * 2, tl, tm, v);
      build(u * 2 + 1, tm + 1, tr, v);
      t[u] = merge(t[u * 2], t[u * 2 + 1]);
    }
  }
  void casual_build(int u, int tl, int tr) {
    if (tl == tr) {
      return;
    } else {
      int tm = (tl + tr) / 2;
      casual_build(u * 2, tl, tm);
      casual_build(u * 2 + 1, tm + 1, tr);
      t[u] = merge(t[u * 2], t[u * 2 + 1]);
    }
  }
  segtree(ll n) : n(n) { t.resize(4 * n); }
  template <class T>
  segtree(vector<T>& v) : n(v.size()) {
    t.resize(4 * n);
    build(1, 0, n - 1, v);
  }
  node get(int l, int r) { return get(1, 0, n - 1, l, r); }
  template <typename... M>
  void upd(int l, int r, const M&... m) {
    upd(1, 0, n - 1, l, r, m...);
  }
  int n;
  vector<node> t;
  node neutral;
};
int const maxn = 2e5 + 5;
signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  ll n, k;
  cin >> n >> k;
  vector<ll> a(n);
  for (ll i = 0; i < n; i++) cin >> a[i];
  vector<segtree*> dp(n + 1);
  for (int i = 0; i <= n; i++) {
    dp[i] = new segtree(k + 1);
  }
  auto& st = *dp[0];
  st.upd(k, k, 1);
  for (ll i = 0; i < n; i++) {
    ll x = a[i];
    auto& new_st = *dp[i + 1];
    for (int y = 0; y < k + 1; y++) {
      ll kek = st.get(y, y).val;
      ll l = max(0LL, y - x);
      ll r = y;
      new_st.upd(l, r, kek);
    }
    st = new_st;
  }
  cout << st.get(0, 0).val << endl;
  return 0;
}
