#include <bits/stdc++.h>
#define rep(i, n) for(int i=0; i<(n); i++)
#define all(x) (x).begin(), (x).end()
#define bit(x) (1L << (x))
using ll = long long;
using namespace std;

template<typename T>
vector<T> make_v(size_t a,T b){return vector<T>(a,b);}
 
template<typename... Ts>
auto make_v(size_t a,Ts... ts){
        return vector<decltype(make_v(ts...))>(a,make_v(ts...));
}

constexpr int default_mod = 998244353;
constexpr bool default_isPrime = true;

template<int Mod = default_mod, bool IsPrime = default_isPrime>
class mint {
        ll n_;
public:
        constexpr mint(ll n): n_{n} { 
                if (n >= Mod) {
                        n_ %= Mod;
                } else {
                        n_ = (n_ % Mod + Mod) % Mod;
                }
        }

        constexpr mint() : n_{0} {}

        constexpr operator int() const { return n_; }
        constexpr operator ll() const { return n_; }

        constexpr mint& operator==(const mint& n) {
                return n_ == n.n_;
        }

        constexpr mint& operator=(const mint& n) {
                n_ = n.n_;
                return *this;
        }

        constexpr mint& operator+=(const mint& n) {
                if ((n_ += n.n_) >= Mod) n_ -= Mod;
                return *this;
        }

        constexpr mint& operator-=(const mint& n) {
                if ((n_ -= n.n_) < 0) n_ += Mod;
                return *this;
        }
        
        constexpr mint& operator*=(const mint& n) {
                if ((n_ *= n.n_) >= Mod) n_ %= Mod;
                return *this;
        }

        constexpr mint& operator/=(const mint& n) {
                return *this *= n.inverse();
        }

        constexpr typename enable_if<IsPrime, mint>::type inverse() const {
                ll a = n_, b = Mod, u = 1, v = 0;
                while (b) {
                        ll t = a / b;
                        a -= t * b; swap(a, b);
                        u -= t * v; swap(u, v);
                }
                return mint(u);
        }

        constexpr mint operator+(mint n) const { return mint(*this) += n; }
        constexpr mint operator-(mint n) const { return mint(*this) -= n; }
        constexpr mint operator*(mint n) const { return mint(*this) *= n; }
        constexpr mint operator/(mint n) const { return mint(*this) /= n; }

};

template<int Mod = default_mod, bool IsPrime = default_isPrime>
ostream& operator<<(ostream& os, mint<Mod, IsPrime> const& n) {
        os << (int)n;
        return os;
}

template<int Mod = default_mod, bool IsPrime = default_isPrime>
mint<Mod, IsPrime> fact(int n) {
        static vector<mint<Mod, IsPrime>> v {1};

        if (n >= static_cast<int>(v.size())) {
                const int from = v.size(), to = n + 1024;
                v.reserve(to);
                for (int i = from; i < to; i++) {
                        v.push_back(v.back() * mint<Mod, IsPrime>(i));
                }
        }
        
        return v[n];
}

template<int Mod = default_mod, bool IsPrime = default_isPrime>
mint<Mod, IsPrime> comb(int n, int r) {
        if (r < 0 || n < r) {
                return 0;
        } else {
                return fact<Mod, IsPrime>(n) / fact<Mod, IsPrime>(r) / fact<Mod, IsPrime>(n - r);
        }
}

using mi = mint<>;

template<typename T>
T pow(T x, int n) {
        if (n == 0) {
                return T(1);
        } else {
                T rest = n % 2 ? x : T(1);
                return pow(x * x, n / 2) * rest;
        }
}

int main() {
        int n, s;
        cin >> n >> s;

        vector<int> a(n);
        rep (i, n) cin >> a[i];

        auto dp = make_v(n + 1, s + 1, mi(0));
        dp[0][0] = pow(mi(2), n);

        rep (i, n) rep (j, s + 1) {
                if (j + a[i] <= s) {
                        dp[i + 1][j + a[i]] += dp[i][j] / mi(2);
                }
                dp[i + 1][j] += dp[i][j];
        }

        cout << dp[n][s] << endl;
                
        return 0;
}


Measured memory_bytes: 73748