Problem:
Score : 600 points

Problem Statement

Given are a sequence of N integers A_1, A_2, \ldots, A_N and a positive integer S.

For a pair of integers (L, R) such that 1\leq L \leq R \leq N, let us define f(L, R) as follows:

f(L, R) is the number of sequences of integers (x_1, x_2, \ldots , x_k) such that L \leq x_1 < x_2 < \cdots < x_k \leq R and A_{x_1}+A_{x_2}+\cdots +A_{x_k} = S.

Find the sum of f(L, R) over all pairs of integers (L, R) such that 1\leq L \leq R\leq N. Since this sum can be enormous, print it modulo 998244353.

Constraints

All values in input are integers.

1 \leq N \leq 3000

1 \leq S \leq 3000

1 \leq A_i \leq 3000

Input

Input is given from Standard Input in the following format:

N S
A_1 A_2 ... A_N

Output

Print the sum of f(L, R), modulo 998244353.

Sample Input 1

3 4
2 2 4

Sample Output 1

5

The value of f(L, R) for each pair is as follows, for a total of 5.

f(1,1) = 0

f(1,2) = 1 (for the sequence (1, 2))

f(1,3) = 2 (for (1, 2) and (3))

f(2,2) = 0

f(2,3) = 1 (for (3))

f(3,3) = 1 (for (3))

Sample Input 2

5 8
9 9 9 9 9

Sample Output 2

0

Sample Input 3

10 10
3 1 4 1 5 9 2 6 5 3

Sample Output 3

152

Solution in Rust (1.15.1) (judge verdict: Time Limit Exceeded)

#![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);
}