#include <bits/stdc++.h>
#pragma GCC optimize("O2")
using namespace std;
struct IoSetup {
  IoSetup() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(15);
    cerr << fixed << setprecision(15);
  }
} iosetup;
int gcd(int a, int b) {
  if (a > b) swap(a, b);
  return a == 0 ? b : gcd(b % a, a);
}
long long gcd(long long a, long long b) {
  if (a > b) swap(a, b);
  return a == 0 ? b : gcd(b % a, a);
}
int lcm(int a, int b) { return (a / gcd(a, b)) * b; }
long long lcm(long long a, long long b) { return (a / gcd(a, b)) * b; }
inline long long pow(int a, int b) {
  long long ans = 1;
  for (int((i)) = ((int)0); ((i)) < ((int)((int)b)); ((i))++) ans *= a;
  return ans;
}
inline long long pow(long long a, long long b) {
  long long ans = 1;
  for (int((i)) = ((int)0); ((i)) < ((int)((int)b)); ((i))++) ans *= a;
  return ans;
}
inline long long pow(int a, long long b) {
  long long ans = 1;
  for (int((i)) = ((int)0); ((i)) < ((int)((int)b)); ((i))++) ans *= a;
  return ans;
}
inline long long pow(long long a, int b) {
  long long ans = 1;
  for (int((i)) = ((int)0); ((i)) < ((int)((int)b)); ((i))++) ans *= a;
  return ans;
}
template <typename T, typename U>
inline bool amin(T &x, U y) {
  return (y < x) ? (x = y, true) : false;
}
template <typename T, typename U>
inline bool amax(T &x, U y) {
  return (x < y) ? (x = y, true) : false;
}
template <typename C>
inline void _cin(C &c) {
  cin >> c;
}
template <typename T, typename U>
inline void _cin(pair<T, U> &p) {
  cin >> p.first;
  cin >> p.second;
}
template <typename C>
inline void _cout(const C &c) {
  cout << c;
}
template <typename T, typename U>
inline void _cout(const pair<T, U> &p) {
  cout << p.first << ' ' << p.second;
}
void in() {}
template <typename T, class... U>
void in(T &t, U &...u) {
  _cin(t);
  in(u...);
}
void out() { cout << "\n"; }
template <typename T, class... U>
void out(const T &t, U... u) {
  _cout(t);
  if (sizeof...(u)) cout << ' ';
  out(u...);
}
template <typename C>
inline void in(vector<C> &v, int N = -1) {
  if (((int)(v).size()) != 0) {
    int M = (N == -1) ? ((int)(v).size()) : N;
    for (int((i)) = ((int)0); ((i)) < ((int)((int)M)); ((i))++) _cin(v[i]);
  } else {
    C c;
    for (int((i)) = ((int)0); ((i)) < ((int)((int)N)); ((i))++)
      v.emplace_back((_cin(c), c));
  }
}
template <typename C>
inline void in(C v[], int N) {
  for (int((i)) = ((int)0); ((i)) < ((int)((int)N)); ((i))++) _cin(v[i]);
}
template <typename C>
inline void out(const vector<C> &v, int N = -1) {
  int M = (N == -1) ? ((int)(v).size()) : N;
  for (int((i)) = ((int)0); ((i)) < ((int)((int)M)); ((i))++) {
    cout << ((i) ? " " : "");
    _cout(v[i]);
  }
  cout << "\n";
}
template <typename C>
inline void out(C v[], int N) {
  for (int((i)) = ((int)0); ((i)) < ((int)((int)N)); ((i))++) {
    cout << ((i) ? " " : "");
    _cout(v[i]);
  }
  cout << "\n";
}
template <typename C>
inline void vector_debug(const vector<C> &v, int N = -1) {
  cout << "{";
  int M = (N == -1) ? ((int)(v).size()) : N;
  for (int((i)) = ((int)0); ((i)) < ((int)((int)M)); ((i))++) {
    cout << ((i) ? ", " : "");
    _cout(v[i]);
  }
  cout << "}" << endl;
}
template <typename C>
inline void vector_debug(C v[], int N) {
  cout << "{";
  for (int((i)) = ((int)0); ((i)) < ((int)((int)N)); ((i))++) {
    cout << ((i) ? ", " : "");
    _cout(*(v + i));
  }
  cout << "}" << endl;
}
void dbg_out() { cout << endl; }
template <typename T, class... U>
void dbg_out(const T &t, U... u) {
  _cout(t);
  if (sizeof...(u)) cout << ", ";
  dbg_out(u...);
}
template <typename C, class... U>
void dbg_out(const vector<C> &v, U... u) {
  vector_debug(v);
  if (sizeof...(u)) cout << ", ";
  dbg_out(u...);
}
template <typename C, class... U>
void dbg_out(const vector<vector<C>> &v, U... u) {
  cout << "{ ";
  for (int((i)) = ((int)0); ((i)) < ((int)((int)((int)(v).size()))); ((i))++) {
    if (i) cout << ", ";
    vector_debug(v[i]);
  }
  cout << " }";
  if (sizeof...(u)) cout << ", ";
  dbg_out(u...);
}
template <typename C>
inline C vmax(const vector<C> &v) {
  C n = v[0];
  for (int((i)) = ((int)0); ((i)) < ((int)((int)((int)(v).size()))); ((i))++)
    amax(n, v[i]);
  return n;
}
template <typename C>
inline C vmax(C v[], int N) {
  C n = v[0];
  for (int((i)) = ((int)0); ((i)) < ((int)((int)N)); ((i))++) amax(n, v[i]);
  return n;
}
template <typename C>
inline C vmin(const vector<C> &v) {
  C n = v[0];
  for (int((i)) = ((int)0); ((i)) < ((int)((int)((int)(v).size()))); ((i))++)
    amin(n, v[i]);
  return n;
}
template <typename C>
inline C vmin(C v[], int N) {
  C n = v[0];
  for (int((i)) = ((int)0); ((i)) < ((int)((int)N)); ((i))++) amin(n, v[i]);
  return n;
}
template <typename C>
inline C vsum(const vector<C> &v) {
  C n = 0;
  for (int((i)) = ((int)0); ((i)) < ((int)((int)((int)(v).size()))); ((i))++)
    n += v[i];
  return n;
}
template <typename C>
inline C vsum(C v[], int N) {
  C n = 0;
  for (int((i)) = ((int)0); ((i)) < ((int)((int)N)); ((i))++) n += v[i];
  return n;
}
template <typename T>
struct BinaryIndexedTree {
  vector<T> data;
  BinaryIndexedTree(int sz) { data.assign(++sz, 0); }
  T sum(int k) {
    T ret = 0;
    for (++k; k > 0; k -= k & -k) ret += data[k];
    return (ret);
  }
  void add(int k, T x) {
    for (++k; k < data.size(); k += k & -k) data[k] += x;
  }
};
int main() {
  int N, K;
  in(N, K);
  vector<int> a(N);
  in(a, N);
  if (K == 0) {
    out(1);
    exit(0);
  }
  BinaryIndexedTree<long long> bit(K + 10);
  bit.add(0, 1);
  for (int((i)) = ((int)0); ((i)) < ((int)((int)N)); ((i))++) {
    for (int((j)) = ((int)((int)K + 1)) - 1; ((j)) >= ((int)0); ((j))--) {
      if (j == 0) continue;
      long long add = bit.sum(j - 1);
      add -= j - a[i] > 0 ? bit.sum(j - a[i] - 1) : 0;
      add %= 1000000007;
      bit.add(j, add);
    }
  }
  out(bit.sum(K) - bit.sum(K - 1));
}
