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 C++ (GCC 9.2.1) (judge verdict: Accepted)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i,n) for (int i = 0; i < (int)(n); i++)
#define irep(i,a,b) for(typeof(i) i = (a); i < (b); ++i)
#define itrep(it,c) for(auto it = (c).begin(); it != (c).end(); ++it)

// MOD p でいくつクラス
#define MOD 998244353
class mll {
	unsigned long long val = 0;
public:
	mll(long long y = 0) : val(((y % MOD) + MOD) % MOD) {}
	mll operator + (const mll& y) { return mll(*this) += y; }
	mll& operator += (const mll& y) {
		val = (val + y.val) % MOD;
		return *this;
	}
	mll operator - (const mll& y) { return mll(*this) -= y; }
	mll& operator -= (const mll& y) {
		val = (val - y.val + MOD) % MOD;
		return *this;
	}
	mll operator * (const mll& y) { return mll(*this) *= y; }
	mll& operator *= (const mll& y) {
		val = (val * y.val) % MOD;
		return *this;
	}
	mll operator / (const mll& y) { return mll(*this) /= y; }
	mll& operator /= (const mll& y) {
		long long a = y.val, b = MOD, u = 1, v = 0;
		while (b) {
			long long t = a / b;
			a -= t * b; swap(a, b);
			u -= t * v; swap(u, v);
		}
		mll c = val * u; // この計算でoverflowしないか？
		val = c.val;
		return *this;
	}
	bool operator >= (const mll& y) {
		return this->val >= y.val;
	}
	mll pow(long long t) const {
		if (!t) return 1;
		mll a = pow(t >> 1);
		a *= a;
		if (t & 1) a *= *this;
		return a;
	}
	unsigned long long getVal() {
		return val;
	}
	friend ostream& operator <<(ostream& os, mll& y) {
		os << y.val;
		return os;
	}
};
#undef MOD

vector<int> A;
vector<vector<mll> > dp;
vector<vector<bool> > F;

void ask(int i, int j) { // dp[i][j] をセットする。し終わったらreturn
	if (F[i][j]) return;
	ask(i - 1, j);
	dp[i][j] = dp[i - 1][j];
	if (j >= A[i - 1]) {
		ask(i - 1, j - A[i - 1]);
		dp[i][j] += dp[i - 1][j - A[i - 1]] / 2;
	}
	F[i][j] = true;
	return;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);

	int N, S;
	cin >> N >> S;
	A = vector<int>(N, 0);
	for (int i = 0; i < N; i++) {
		cin >> A[i];
	}
	sort(A.begin(), A.end());
	dp = vector<vector<mll> >(N + 1, vector<mll>(S + 1, 0));
	F = vector<vector<bool> >(N + 1, vector<bool>(S + 1, false));

	// i = 0;
	dp[0][0] = mll(2).pow(N); // dp[0][0] には、(0個,1ケース)を入れる。dp[0][j>0] はempty
	for (int j = 0; j <= S; j++) {
		F[0][j] = true;
	}
	// DP
	ask(N, S);

	cout << dp[N][S].getVal() << endl;
	return(0);
}