Problem:
Score : 600 points

Problem Statement

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

For a non-empty subset T of the set \{1, 2, \ldots , N \}, let us define f(T) as follows:

f(T) is the number of different non-empty subsets \{x_1, x_2, \ldots , x_k \} of T such that A_{x_1}+A_{x_2}+\cdots +A_{x_k} = S.

Find the sum of f(T) over all 2^N-1 subsets T of \{1, 2, \ldots , N \}. Since the 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(T) modulo 998244353.

Sample Input 1

3 4
2 2 4

Sample Output 1

6

For each T, the value of f(T) is shown below. The sum of these values is 6.

f(\{1\}) = 0

f(\{2\}) = 0

f(\{3\}) = 1 (One subset \{3\} satisfies the condition.)

f(\{1, 2\}) = 1 (\{1, 2\})

f(\{2, 3\}) = 1 (\{3\})

f(\{1, 3\}) = 1 (\{3\})

f(\{1, 2, 3\}) = 2 (\{1, 2\}, \{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

3296

Solution in Rust (1.42.0) (judge verdict: Wrong Answer)

const MOD: i64 = 998244353;

fn g(x: i64, set: &[i64], mut mask: usize, mut unused: usize, cache: &mut [i64]) -> i64 {
    let mut sum = 0;
    unused -= 1;
    while mask < set.len() {
        let a = set[mask];
        let remainder = x - a;
        if remainder < 0 {
            return sum;
        } else if remainder > 0 {
            let cache_idx = remainder as usize * set.len() + mask;
            if cache[cache_idx] == -1 {
                cache[cache_idx] = g(remainder, set, mask+1, unused, cache);
            };
            sum += cache[cache_idx];
        } else if remainder == 0 {
            sum += 1 << unused;
        }
        sum = sum % MOD;
        mask += 1;
    }
    return sum;
}

fn solve(_n: usize, s: i64, mut a: Vec<i64>) -> i64 {
    a.sort();
    let mut cache = vec![-1; s as usize * a.len()];
    //f(s, &a, 0, &mut cache)
    g(s, &a, 0, a.len(), &mut cache)
}

fn main() {
    let mut io = IO::new();

    let n = io.read();
    let s = io.read();
    let a = gen(n, || io.read()).collect();

    let ans = solve(n, s, a);
    io.writeln(ans);
}



// PROCON LIBRARY //

pub trait Num: Sized {
    fn to_i(self) -> isize;
    fn to_u(self) -> usize { self.to_i() as usize }
    fn off<T: Num>(self, other: T) -> usize { (self.to_i() + other.to_i()).to_u() }
}
impl Num for usize { fn to_i(self) -> isize { self as isize } }
impl Num for isize { fn to_i(self) -> isize { self as isize } }
impl Num for u32 { fn to_i(self) -> isize { self as isize } }
impl Num for i32 { fn to_i(self) -> isize { self as isize } }
impl Num for u64 { fn to_i(self) -> isize { self as isize } }
impl Num for i64 { fn to_i(self) -> isize { self as isize } }

pub struct IdxIterMut<'a, T> {
    iter: std::iter::Enumerate<std::slice::IterMut<'a, T>>,
}

impl<'a, T> Iterator for IdxIterMut<'a, T> {
    type Item=(usize, &'a mut T);
    fn next(&mut self) -> Option<(usize, &'a mut T)> {
        self.iter.next().map(|(i, v)| (i+1, v))
    }
}

pub struct IdxIter<'a, T> {
    iter: std::iter::Enumerate<std::slice::Iter<'a, T>>,
}

impl<'a, T> Iterator for IdxIter<'a, T> {
    type Item=(usize, &'a T);
    fn next(&mut self) -> Option<(usize, &'a T)> {
        self.iter.next().map(|(i, v)| (i+1, v))
    }
}

pub trait SliceExt<T> {
    fn at<I: Num>(&mut self, i: I) -> &mut T;
    fn iter_idx(&self) -> IdxIter<'_, T>;
    fn iter_idx_mut(&mut self) -> IdxIterMut<'_, T>;
}
impl<T> SliceExt<T> for [T] {
    fn at<I: Num>(&mut self, i: I) -> &mut T {
        &mut self[i.to_u() + 1]
    }
    fn iter_idx(&self) -> IdxIter<'_, T> {
        IdxIter {
            iter: self.iter().enumerate(),
        }
    }
    fn iter_idx_mut(&mut self) -> IdxIterMut<'_, T> {
        IdxIterMut {
            iter: self.iter_mut().enumerate(),
        }
    }
}

pub fn gen<T, F: FnMut() -> T>(n: usize, mut f: F) -> impl Iterator<Item=T> {
    (0..n).map(move |_| f())
}

pub struct IO(
    std::io::BufReader<std::io::StdinLock<'static>>,
    std::io::BufWriter<std::io::StdoutLock<'static>>
);

impl IO {
    pub fn new() -> IO {
        IO(
            std::io::BufReader::new(Box::leak(Box::new(std::io::stdin())).lock()),
            std::io::BufWriter::new(Box::leak(Box::new(std::io::stdout())).lock())
        )
    }
    pub fn write<D: std::fmt::Display>(&mut self, v: D) {
        use std::io::Write;
        write!(self.1, "{}", v).unwrap();
    }
    pub fn writeln<D: std::fmt::Display>(&mut self, v: D) {
        use std::io::Write;
        writeln!(self.1, "{}", v).unwrap();
    }
    pub fn write_many<D: std::fmt::Display>(&mut self, vs: impl std::iter::IntoIterator<Item=D>) {
        for v in vs {
            self.writeln(v);
        }
    }
    pub fn read<T: std::str::FromStr>(&mut self) -> T {
        use std::io::Read;
        let buf = self
            .0
            .by_ref()
            .bytes()
            .map(|b| b.unwrap())
            .skip_while(|&b| b == b' ' || b == b'\n' || b == b'\r' || b == b'\t')
            .take_while(|&b| b != b' ' && b != b'\n' && b != b'\r' && b != b'\t')
            .collect::<Vec<_>>();
        unsafe { std::str::from_utf8_unchecked(&buf) }
            .parse()
            .ok()
            .expect("Parse error.")
    }
    pub fn read_ascii(&mut self) -> u8 {
        use std::io::Read;
        self
            .0
            .by_ref()
            .bytes()
            .map(|b| b.unwrap())
            .skip_while(|&b| b == b' ' || b == b'\n' || b == b'\r' || b == b'\t')
            .next()
            .expect("Parse error")
    }
    pub fn read_raw_ascii(&mut self) -> u8 {
        use std::io::Read;
        self
            .0
            .by_ref()
            .bytes()
            .map(|b| b.unwrap())
            .next()
            .expect("Parse error")
    }
    pub fn vec<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.read()).collect()
    }
    pub fn chars(&mut self) -> Vec<char> {
        self.read::<String>().chars().collect()
    }
    pub fn pairs<T: std::str::FromStr>(&mut self, n: usize) -> Vec<(T, T)> {
        (0..n).map(|_| (self.read(), self.read())).collect()
    }
}