#include <bits/stdc++.h>
using namespace std;
template <typename A, typename B>
inline bool chmax(A &a, B b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <typename A, typename B>
inline bool chmin(A &a, B b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
using ll = long long;
using pii = pair<int, int>;
constexpr ll INF = 1ll << 30;
constexpr ll longINF = 1ll << 60;
constexpr ll MOD = 998244353;
constexpr bool debug = 0;
template <int M>
struct ModInt {
 public:
  using value_type = long long;
  ModInt(value_type val = 0) : val(val < 0 ? (M - (-val % M)) % M : val % M) {}
  explicit operator bool() const noexcept { return val; }
  bool operator==(const ModInt &rhs) const noexcept { return val == rhs.val; }
  bool operator!=(const ModInt &rhs) const noexcept { return !(*this == rhs); }
  ModInt operator+() const noexcept { return ModInt(*this); }
  ModInt operator-() const noexcept { return ModInt(0) -= *this; }
  ModInt operator+(const ModInt &rhs) const noexcept {
    return ModInt(*this) += rhs;
  }
  ModInt operator-(const ModInt &rhs) const noexcept {
    return ModInt(*this) -= rhs;
  }
  ModInt operator*(const ModInt &rhs) const noexcept {
    return ModInt(*this) *= rhs;
  }
  ModInt operator/(const ModInt &rhs) const noexcept {
    return ModInt(*this) /= rhs;
  }
  ModInt &operator+=(const ModInt &rhs) noexcept {
    val += rhs.val;
    if (val >= M) val -= M;
    return *this;
  }
  ModInt &operator-=(const ModInt &rhs) noexcept {
    if (val < rhs.val) val += M;
    val -= rhs.val;
    return *this;
  }
  ModInt &operator*=(const ModInt &rhs) noexcept {
    val = val * rhs.val % M;
    return *this;
  }
  ModInt &operator/=(const ModInt &rhs) noexcept {
    *this *= rhs.inverse();
    return *this;
  }
  ModInt pow(value_type n) const {
    ModInt res = 1, x = val;
    if (n < 0) {
      x = x.inverse();
      n = -n;
    }
    while (n) {
      if (n & 1) res *= x;
      x *= x;
      n >>= 1;
    }
    return res;
  }
  ModInt inverse() const {
    long long a = val, a1 = 1, a2 = 0, b = M, b1 = 0, b2 = 1;
    while (b > 0) {
      value_type q = a / b, r = a % b;
      value_type nb1 = a1 - q * b1, nb2 = a2 - q * b2;
      a = b;
      b = r;
      a1 = b1;
      b1 = nb1;
      a2 = b2;
      b2 = nb2;
    }
    assert(a == 1);
    return a1;
  }
  const value_type &get() const noexcept { return val; }
  static decltype(M) get_mod() noexcept { return M; }
  friend std::ostream &operator<<(std::ostream &os, const ModInt &rhs) {
    return os << rhs.val;
  }
  friend std::istream &operator>>(std::istream &is, ModInt &rhs) {
    value_type x;
    is >> x;
    rhs = ModInt(x);
    return is;
  }

 private:
  value_type val;
};
using mint = ModInt<MOD>;
int main() {
  int N, S;
  cin >> N >> S;
  vector<int> A(N);
  for (int i = (0); i < (N); ++i) scanf("%d", &A[i]);
  vector<vector<vector<mint>>> dp(N + 1,
                                  vector<vector<mint>>(S + 1, vector<mint>(3)));
  dp[0][0][0] = 1;
  for (int i = (0); i < (N + 1); ++i) {
    for (int j = (0); j < (S + 1); ++j) {
      for (int k = (0); k < (3); ++k) {
        if (i < N) dp[i + 1][j][k] += dp[i][j][k];
        if (k < 3) dp[i][j][k + 1] += dp[i][j][k];
        if (i < N && k == 1 && j + A[i] <= S)
          dp[i + 1][j + A[i]][k] += dp[i][j][k];
      }
    }
  }
  cout << dp[N][S][2] << endl;
  return 0;
}
