/**
 * @author pr4shan7 (प्रशांत)
 */
// everything has a cost!

#ifdef _MAVERICK
#define _DEBUG
#else
#pragma GCC optimize("Ofast", "unroll-loops", "omit-frame-pointer", "inline")
#pragma GCC option("arch=native", "tune=native", "no-zero-upper")
#pragma GCC target("avx,avx2,fma")
// #pragma GCC reset_options
#endif

#ifndef _DEBUG
#define NDEBUG
#endif

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>

using namespace std;
using namespace __gnu_pbds;

#define endl '\n'
// #define cerr cout
// #define int long long
// #define double long double

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> pb_set;
typedef unordered_set<int> usi;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<int> vi;
typedef set<int> si;
typedef long long ll;
#define pb push_back
#define x first
#define y second
#define cai static_cast<int>
#define cad static_cast<double>
#define cal static_cast<long long>
#define all(z) z.begin(), z.end()
#define tr(cont, itm) for (auto&& itm : cont)
#define rep(in, beg, sz) for (int in = beg; in < sz; in++)
#define rrep(in, sz, beg) for (int in = sz - 1; in >= beg; in--)
#define rtr(cont, itr) for (auto itr = cont.end() - 1; itr >= cont.begin(); itr--)

#ifdef _DEBUG
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)

template <typename... T> inline void debug_out(const T&...);
#else
#define debug(...) 42
#endif

template <typename T> inline istream& operator>>(istream& in, vector<T>& ar);
template <typename T> inline ostream& operator<<(ostream& out, const vector<T>& ar);
template <typename T> constexpr inline T pow(long long, long long, const T);

const int N = 1e5 + 5;
const int INF = 1e9;
const int MV = 998244353;

// beautiful things don't ask for attention

ll ans{}; int n;
vector<vector<bool>> dp;
void get(vi& arr, int i, int sum, ii& p) 
{ 
    if (i == 0 && sum != 0 && dp[0][sum]) 
    { 
        if(p.x==-1) {p.x=i;p.y=i;} else p.y=i;
        ans+=(1LL*(p.y+1)*(n-p.x))%MV;
        debug(p.y,p.x,ans);
        return; 
    } 
  
    if (i == 0 && sum == 0) 
    { 
    		ans+=(1LL*(p.y+1)*(n-p.x))%MV;
    		debug(p.y,p.x,ans);
        return; 
    } 
  
    if (dp[i-1][sum]) 
    { 
        
        ii b = p; 
        get(arr, i-1, sum, b); 
    } 
  
    if (sum >= arr[i] && dp[i-1][sum-arr[i]]) 
    { 
        if(p.x==-1) {p.x=i;p.y=i;} else p.y=i;
        get(arr, i-1, sum-arr[i], p); 
    } 
} 
  
void solve(vi& arr, int n, int sum) 
{   dp.resize(n,vector<bool> (sum+1,false));
    for (int i=0; i<n; ++i) 
    { 
        dp[i][0] = true; 
    } 
  
    if (arr[0] <= sum) 
       dp[0][arr[0]] = true; 
  
    for (int i = 1; i < n; ++i) 
        for (int j = 0; j < sum + 1; ++j) 
            dp[i][j] = (arr[i] <= j) ? dp[i-1][j] || 
                                       dp[i-1][j-arr[i]] 
                                     : dp[i - 1][j]; 
    if (dp[n-1][sum] == false) 
    { 
        return;
    } 
  
    ii p{-1,-1};
    get(arr, n-1, sum, p);
} 

int32_t main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

#ifdef _MAVERICK
	freopen("in.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
	freopen("err.txt", "w", stderr);
#endif

	int s; cin >> n>>s;
	vi ar(n); cin >> ar;
	solve(ar,n,s);
	cout << ans;


	return 0;
}


#ifdef _DEBUG
template <typename... T>
inline void debug_out(const T&... args) { ((cerr << ' ' << args), ...); cerr << endl; }
#endif

template <typename T>
inline istream& operator>>(istream& in, vector<T>& ar) {
	for (auto& i : ar) in >> i;
	return in;
}

template <typename T>
inline ostream& operator<<(ostream& out, const vector<T>& ar) {
	for (int i = 0; i < ar.size() - 1; i++) out << ar[i] << ' ';
	out << ar[ar.size() - 1];
	return out;
}

template <typename T>
constexpr inline T pow(long long a, long long b, const T mv) {
	long long res = 1;
	a %= mv;
	while (b) {
		if (b & 1)
			res = (res * a) % mv;
		b >>= 1;
		a = (a * a) % mv;
	}
	return res;
}

// get busy living or get busy dying
