// Original C++ solution (slower):
#include <bits/stdc++.h>



using namespace std;

#define all(a)a.begin(),a.end()

using ll=long long;

const int INF = 1<<30;

const ll INFll =1LL<<62;

const int mod = int(1e9)+7;

using P = pair<ll,ll>;

using ld=long double;



int main(){

    ll U=3010;

    ll MOD=998244353;

    ll n,s;cin >>n>>s;

    vector<ll>a(n);

    for (int i = 0; i < n; ++i) {

        cin >>a[i];

    }

    vector<vector<ll>>dp(n+1,vector<ll>(U+1,0));

    dp[0][0]=1;

    for (int i = 0; i < n; ++i) {

        for (int j = 0; j < U; ++j) {

            dp[i+1][j]+=dp[i][j]*2%MOD;

            dp[i+1][j]%=MOD;

            if(j+a[i]>U)continue;

            dp[i+1][j+a[i]]+=dp[i][j];

            dp[i+1][j+a[i]]%=MOD;

        }

    }

    cout <<dp[n][s]<<endl;

    return 0;

}

// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

using namespace std;

#define all(a)a.begin(),a.end()

using ll=long long;

const int INF = 1<<30;

const ll INFll =1LL<<62;

//const int mod= int(1e9)+7;

const int mod=998244353;

using P = pair<int,int>;

using Pll = pair<ll,ll>;

using ld=long double;

using V=vector<int>;

using Vl=vector<ll>;

using VV=vector<vector<int>>;

using VVl=vector<vector<ll>>;



// modint: mod 計算を int を扱うように扱える構造体

template<int MOD> struct Fp {

    long long val;

    constexpr Fp(long long v = 0) noexcept : val(v % MOD) {

        if (val < 0) val += MOD;

    }

    constexpr int getmod() { return MOD; }

    constexpr Fp operator - () const noexcept {

        return val ? MOD - val : 0;

    }

    constexpr Fp operator + (const Fp& r) const noexcept { return Fp(*this) += r; }

    constexpr Fp operator - (const Fp& r) const noexcept { return Fp(*this) -= r; }

    constexpr Fp operator * (const Fp& r) const noexcept { return Fp(*this) *= r; }

    constexpr Fp operator / (const Fp& r) const noexcept { return Fp(*this) /= r; }

    constexpr Fp& operator += (const Fp& r) noexcept {

        val += r.val;

        if (val >= MOD) val -= MOD;

        return *this;

    }

    constexpr Fp& operator -= (const Fp& r) noexcept {

        val -= r.val;

        if (val < 0) val += MOD;

        return *this;

    }

    constexpr Fp& operator *= (const Fp& r) noexcept {

        val = val * r.val % MOD;

        return *this;

    }

    constexpr Fp& operator /= (const Fp& r) noexcept {

        long long a = r.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);

        }

        val = val * u % MOD;

        if (val < 0) val += MOD;

        return *this;

    }

    constexpr bool operator == (const Fp& r) const noexcept {

        return this->val == r.val;

    }

    constexpr bool operator != (const Fp& r) const noexcept {

        return this->val != r.val;

    }

    friend constexpr ostream& operator << (ostream &os, const Fp<MOD>& x) noexcept {

        return os << x.val;

    }

    friend constexpr Fp<MOD> modpow(const Fp<MOD> &a, long long n) noexcept {

        if (n == 0) return 1;

        auto t = modpow(a, n / 2);

        t = t * t;

        if (n & 1) t = t * a;

        return t;

    }

};

using mint = Fp<mod>;



int main(){

    int n,s;cin >>n>>s;

    V a(n);

    for (int i = 0; i < n; ++i) {

        cin >>a[i];

    }

    vector<vector<mint>>dp(n+1,vector<mint>(s+1,0));

    dp[0][0]=1;

    for (int i = 0; i < n; ++i) {

        for (int j = 0; j <=s; ++j) {

            dp[i+1][j]+=dp[i][j]*2;

            if(j+a[i]<=s){

                dp[i+1][j+a[i]]+=dp[i][j];

            }

        }

    }

    cout <<dp[n][s]<<endl;

}




// Fastest known solution for this problem: