#![allow(unused)]

use std::io::{Read, StdinLock};
use std::iter::{FromIterator, Iterator};
use std::str::{FromStr};
use std::string::String;

macro_rules! debug {
    ($($a:expr),*) => {
	println!(concat!($(stringify!($a), " = {:?}, "),*), $($a),*);
    }
}

pub fn read_bytes<T: FromIterator<char>>(s: &mut StdinLock) -> T {
    s.bytes()
        .map(|c| c.unwrap() as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect::<T>()
}

pub fn reads(s: &mut StdinLock) -> String {
    read_bytes::<String>(s)
}

pub fn read<T: FromStr>(s: &mut StdinLock) -> T {
    reads(s).parse().ok().unwrap()
}

//==============================================================================
//
// Problem specific code
//
//==============================================================================

const M: i64 = 998244353;

#[derive(Debug, Clone, Copy)]
struct Trace {
    i_min: usize,
    i_max: usize,
    sum: i64,
}

fn recurse(
    ais: &Vec<usize>,
    dp: &Vec<Vec<Option<Trace>>>,
    l: usize,
    i: usize,
    w: usize,
) -> i64 {
    match dp[i][w] {
        None => 0,
        Some(t) => {
            if t.i_max < l {
                0
            } else if t.i_min >= l {
                t.sum
            } else {
                if w < ais[i - 1] {
                    recurse(ais, dp, l, i - 1, w)
                } else {
                    recurse(ais, dp, l, i - 1, w)
                        + recurse(ais, dp, l, i - 1, w - ais[i - 1])
                }
            }
        }
    }
}

fn main() {
    let sin = std::io::stdin();
    let mut sin = sin.lock();

    let n: usize = read(&mut sin);
    let s: usize = read(&mut sin);
    let ais: Vec<usize> = (0..n).map(|_| read(&mut sin)).collect();

    let mut dp = (0..(n + 1)).map(|i| {
        (0..(s + 1)).map(|w| {
            if w == 0 {
                Some(Trace { i_min: i, i_max: i, sum: 1 })
            } else {
                None
            }
        }).collect::<Vec<_>>()
    }).collect::<Vec<_>>();

    for i in 0..n {
        for w in 1..(s + 1) {
            dp[i + 1][w] = if w < ais[i] {
                dp[i][w]
            } else {
                match (dp[i][w - ais[i]], dp[i][w]) {
                    (None, None) => None,
                    (Some(t), None) => Some(Trace { i_max: i, .. t }),
                    (None, opt @ Some(_)) => opt,
                    (Some(ref t), Some(ref u)) => Some(Trace {
                        i_min: std::cmp::min(t.i_min, u.i_min),
                        i_max: i,
                        sum: (t.sum + u.sum) % M,
                    })
                }
            }
        }
    }

//    for i in 0..(n + 1) {
//        let dpi = (0..(s + 1)).map(|w| {
//            match dp[i][w] {
//                None => (0, 0, 0),
//                Some(t) => (t.i_min, t.i_max, t.sum)
//            }
//        }).collect::<Vec<_>>();
//        debug!(i, dpi);
//    }

    let ans = (0..(n + 1)).fold(0i64, |ra, r| {
        let x = (0..(r + 1)).fold(0i64, |la, l| {
            (la + recurse(&ais, &dp, l, r, s)) % M
        });
        (ra + x) % M
    });

    println!("{}", ans);
}

