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 Java (OpenJDK 11.0.6) (judge verdict: Time Limit Exceeded)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class Main {
    static int N;
    static int S;
    static int[] A;
    static long t = (long) (1<<30) % 998244353;

    public static void main(String[] args) throws NumberFormatException, IOException {
        read();
    }



    static class ListSet {
        List<Integer> list = new ArrayList<>();

        public ListSet() {
        }

        public void addSet(int set) {
            list.add(set);
        }

        public void union(ListSet listset) {
            if (listset == null) {
                return;
            }
            for (int set : listset.list) {
                this.list.add(set);
            }
        }

        public static ListSet unionSet(ListSet L, ListSet Q) {
            if (L == null && Q == null) {
                return null;
            }
            ListSet res = new ListSet();
            res.union(L);
            res.union(Q);
            return res;
        }

        public ListSet clone() {
            ListSet listset = new ListSet();
            for (int set : this.list) {
                listset.list.add(set);
            }
            return listset;
        }

        public static ListSet unionEle(ListSet L, int elment) {
            if (L == null) {
                return null;
            }
            ListSet res = new ListSet();
            for (int set : L.list) {
                res.addSet(set+1);
            }
            if (res.list.isEmpty()) {
                res.list.add(1);
            }
            return res;
        }

        @Override
        public String toString() {
            return "ListSet [list=" + list + "]";
        }

    }

    private static void read() throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] word = br.readLine().split(" ");
        N = Integer.parseInt(word[0]);
        S = Integer.parseInt(word[1]);
        word = br.readLine().split(" ");
        A = new int[N];
        for (int i = 0; i < N; i++) {
            A[i] = Integer.valueOf(word[i]);
        }
        ListSet[][] F = new ListSet[N][S + 1];

        for (int s = 0; s <= S; s++) {
            F[0][s] = null;
        }
        F[0][0] = new ListSet();
        ListSet listset = new ListSet();
        listset.addSet(1);

        if (A[0] <= S)
            F[0][A[0]] = listset;

        for (int i = 1; i < N; i++) {
            F[i][0] = new ListSet();
            for (int j = 1; j <= S; j++) {
                ListSet Q = null;
                if (j >= A[i]) {
                    Q = ListSet.unionEle(F[i - 1][j - A[i]], i);
                }
                F[i][j] = ListSet.unionSet(F[i - 1][j], Q);
            }
        }
        List<Integer > tmp = F[N - 1][S] == null ? new ArrayList<Integer>() : F[N - 1][S].list;
        long res = 0;
        for (int size : tmp) {
            int leftsize = N - size;
            res = (res + mypower(2, leftsize)) % 998244353;
        }
        System.out.println(res);
        br.close();
    }

    public static long mypower(int base, int power) {
        int i = 0;
        long res = 1;
        while (i < power) {
            i = i + 30;

            if (i > power) {
                res = (res * (long) Math.pow(2, power - (i - 30))) % 998244353;
            } else {
                res = (res *t) % 998244353;
            }

        }

        return res;
    }

}