#include <bits/stdc++.h>
using namespace std;
using i64 = int_fast64_t;
using ui64 = uint_fast64_t;
using db = long double;
using pii = pair<int, int>;
using pli = pair<int_fast64_t, int>;
using pll = pair<int_fast64_t, int_fast64_t>;
using pdi = pair<double, int>;
template <class T>
using vct = vector<T>;
template <class T>
using heap = priority_queue<T>;
template <class T>
using minheap = priority_queue<T, vector<T>, greater<T>>;
template <class T>
constexpr T inf = numeric_limits<T>::max() / 2 - 1;
constexpr int dx[9] = {1, 0, -1, 0, 1, -1, -1, 1, 0};
constexpr int dy[9] = {0, 1, 0, -1, 1, 1, -1, -1, 0};
constexpr long double gold = 1.618033988;
constexpr long double eps = 1e-15;
struct setupper {
  setupper() {
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);
    std::cerr.tie(nullptr);
    std::cout << fixed << setprecision(10);
    std::cerr << fixed << setprecision(2);
  }
} setupper_;
namespace std {
template <class T>
void hash_combine(size_t &seed, T const &key) {
  seed ^= hash<T>()(key) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
template <class T, class U>
struct hash<pair<T, U>> {
  size_t operator()(pair<T, U> const &pr) const {
    size_t seed = 0;
    hash_combine(seed, pr.first);
    hash_combine(seed, pr.second);
    return seed;
  }
};
template <class Tup, size_t index = tuple_size<Tup>::value - 1>
struct hashval_calc {
  static void apply(size_t &seed, Tup const &tup) {
    hashval_calc<Tup, index - 1>::apply(seed, tup);
    hash_combine(seed, get<index>(tup));
  }
};
template <class Tup>
struct hashval_calc<Tup, 0> {
  static void apply(size_t &seed, Tup const &tup) {
    hash_combine(seed, get<0>(tup));
  }
};
template <class... T>
struct hash<tuple<T...>> {
  size_t operator()(tuple<T...> const &tup) const {
    size_t seed = 0;
    hashval_calc<tuple<T...>>::apply(seed, tup);
    return seed;
  }
};
}  // namespace std
template <class T, class U>
ostream &operator<<(ostream &s, pair<T, U> p) {
  return s << p.first << " " << p.second;
}
template <class T>
ostream &operator<<(ostream &s, vct<T> v) {
  for (auto i = begin(v); i != end(v); ++i) {
    if (i != begin(v)) s << " ";
    s << *i;
  }
  return s;
}
template <class T>
void dump_func(T x) {
  cerr << x << '\n';
}
template <class T, class... Rest>
void dump_func(T x, Rest... rest) {
  cerr << x << ",";
  dump_func(rest...);
}
template <class T = int>
T read() {
  T x;
  return cin >> x, x;
}
template <class T>
void write(T x) {
  cout << x << '\n';
}
template <class T, class... Rest>
void write(T x, Rest... rest) {
  cout << x << ' ';
  write(rest...);
}
void writeln() {}
template <class T, class... Rest>
void writeln(T x, Rest... rest) {
  cout << x << '\n';
  writeln(rest...);
}
namespace updater {
template <class T>
static void add(T &x, const T &y) {
  x += y;
}
template <class T>
static void ext_add(T &x, const T &y, size_t w) {
  x += y * w;
}
template <class T>
static void mul(T &x, const T &y) {
  x *= y;
}
template <class T>
static void ext_mul(T &x, const T &y, size_t w) {
  x *= (T)pow(y, w);
}
template <class T>
static bool chmax(T &x, const T &y) {
  return x < y ? x = y, true : false;
}
template <class T>
static bool chmin(T &x, const T &y) {
  return x > y ? x = y, true : false;
}
};  // namespace updater
using updater::chmax;
using updater::chmin;
template <class T>
T minf(const T &x, const T &y) {
  return min(x, y);
}
template <class T>
T mixf(const T &x, const T &y) {
  return max(x, y);
}
bool bit(i64 n, uint8_t e) { return (n >> e) & 1; }
i64 mask(i64 n, uint8_t e) { return n & ((1 << e) - 1); }
int ilog(uint64_t x, uint64_t b = 2) { return x ? 1 + ilog(x / b, b) : -1; }
template <class F>
i64 binry(i64 ok, i64 ng, const F &fn) {
  while (abs(ok - ng) > 1) {
    i64 mid = (ok + ng) / 2;
    (fn(mid) ? ok : ng) = mid;
  }
  return ok;
}
template <class A, size_t N, class T>
void init(A (&array)[N], const T &val) {
  fill((T *)array, (T *)(array + N), val);
}
template <class T>
T cmprs(T &v) {
  T tmp = v, ret = v;
  sort(begin(tmp), end(tmp));
  tmp.erase(unique(begin(tmp), end(tmp)), end(tmp));
  for (auto i = begin(ret); i != end(ret); ++i)
    *i = lower_bound(begin(tmp), end(tmp), *i) - begin(tmp);
  return ret;
}
template <class T>
void read_vct(vector<T> &v, size_t n = 0) {
  v.resize(n);
  if (n) {
    for (size_t i = 0; i < n; ++i) cin >> v[i];
  } else {
    T input;
    while (cin >> input, input) {
      v.emplace_back(input);
    }
  }
}
template <class A, size_t N>
void read_ary(A (&array)[N], size_t n = N) {
  for (size_t i = 0; i < n; ++i) cin >> array[i];
}
int n, k;
int a[1 << 7];
i64 dp[1 << 7][1 << 17];
bool visited[1 << 7][1 << 17];
i64 solve(int h, int r) {
  if (h == n) return r == 0;
  if (r < 0) return 0;
  if (visited[h][r]) return dp[h][r];
  visited[h][r] = true;
  i64 res = 0;
  for (int j = 0; j <= a[h] and j <= r; ++j) {
    (res += solve(h + 1, r - j)) %= 1000000007LL;
  }
  return dp[h][r] = res;
}
signed main() {
  cin >> n >> k;
  read_ary(a, n);
  writeln(solve(0, k));
}
