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)

use proconio::{fastout, input};
// use proconio::marker::*;
use std::collections::BTreeMap;

#[fastout]
fn main() {
   input! {
      n: usize,
      s: usize,
      a: [usize; n]
   }

   let mut dp = vec![BTreeMap::<usize, usize>::new(); n + 1];
   dp[0].insert(0, 1);
   for &a in a.iter() {
      for i in (0..n).rev() {
         let map = dp[i].clone();
         for (j, k) in map.iter() {
            dp[i + 1].entry(j + a).and_modify(|v| *v += k).or_insert(*k);
         }
      }
   }
   let mut ans = Mint::new(0);
   for i in 1..=n {
      if let Some(v) = dp[i].get(&s) {
         ans += Mint::new(2).pow(n - i) * (*v as i64);
      }
   }
   println!("{}", ans);
}

const MOD: i64 = 1000000007;
#[derive(Copy, Clone)]
pub struct Mint {
   x: i64,
}
impl Mint {
   fn new(x: i64) -> Self {
      Mint {
         x: (x % MOD + MOD) % MOD,
      }
   }
   fn pow(self, n: usize) -> Self {
      match n {
         0 => Mint::new(1),
         _ => {
            let mut a = self.pow(n >> 1);
            a *= a;
            if n & 1 == 1 {
               a *= self;
            }
            a
         }
      }
   }
   fn inv(self) -> Self { self.pow((MOD - 2) as usize) }
}
impl std::ops::Neg for Mint {
   type Output = Mint;
   fn neg(self) -> Self::Output { Self::new(-self.x) }
}
impl std::ops::AddAssign<Mint> for Mint {
   fn add_assign(&mut self, rhs: Self) {
      self.x += rhs.x;
      if self.x >= MOD {
         self.x -= MOD;
      }
   }
}
impl std::ops::AddAssign<i64> for Mint {
   fn add_assign(&mut self, rhs: i64) { *self += Mint::new(rhs); }
}
impl<T> std::ops::Add<T> for Mint
where
   Mint: std::ops::AddAssign<T>,
{
   type Output = Self;
   fn add(self, other: T) -> Self {
      let mut res = self;
      res += other;
      res
   }
}
impl std::ops::SubAssign<Mint> for Mint {
   fn sub_assign(&mut self, rhs: Self) {
      self.x += MOD - rhs.x;
      if self.x >= MOD {
         self.x -= MOD;
      }
   }
}
impl std::ops::SubAssign<i64> for Mint {
   fn sub_assign(&mut self, rhs: i64) { *self -= Mint::new(rhs); }
}
impl<T> std::ops::Sub<T> for Mint
where
   Mint: std::ops::SubAssign<T>,
{
   type Output = Self;
   fn sub(self, other: T) -> Self {
      let mut res = self;
      res -= other;
      res
   }
}
impl std::ops::MulAssign<Mint> for Mint {
   fn mul_assign(&mut self, rhs: Self) {
      self.x *= rhs.x;
      self.x %= MOD;
   }
}
impl std::ops::MulAssign<i64> for Mint {
   fn mul_assign(&mut self, rhs: i64) { *self *= Mint::new(rhs); }
}
impl<T> std::ops::Mul<T> for Mint
where
   Mint: std::ops::MulAssign<T>,
{
   type Output = Self;
   fn mul(self, other: T) -> Self {
      let mut res = self;
      res *= other;
      res
   }
}
impl std::ops::DivAssign<Mint> for Mint {
   fn div_assign(&mut self, rhs: Self) { *self *= rhs.inv(); }
}
impl std::ops::DivAssign<i64> for Mint {
   fn div_assign(&mut self, rhs: i64) { *self *= Mint::new(rhs).inv(); }
}
impl<T> std::ops::Div<T> for Mint
where
   Mint: std::ops::DivAssign<T>,
{
   type Output = Self;
   fn div(self, other: T) -> Self {
      let mut res = self;
      res /= other;
      res
   }
}
impl<T> From<T> for Mint
where
   i64: From<T>,
{
   fn from(x: T) -> Mint { Mint::new(i64::from(x)) }
}
impl std::fmt::Display for Mint {
   fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.x) }
}