Problem:
Problem D: 僕の友達は小さい
僕には、たくさんの友達がいる。どの友達も、とても小さい。
僕は、よく友達と一緒に出かける。何人かの友達をリュックに入れて、一緒に出かける。
僕は毎朝、その日一緒に出かける友達を決める。空のリュックに、１人ずつ友達を入れていく。
僕は、あまり力が強くない。だから、同時に運べる友達の重さには限界がある。
僕は、重さの限界を超えないように友達を入れていく。どの順番で入れていくかは気分次第。
僕は、入れられる友達がまだ残っている限り、入れるのを止めない。決して止めない。
……ところで、リュックに入った友達の組み合わせは、全部で何パターンあるんだろう？
Input
N W
w
1
w
2
.
.
.
w
n
入力の１行目には、整数
N
（1 ≤
N
≤ 200）と整数
W
（1 ≤
W
≤ 10,000）が、この順に空白区切りで書かれている。整数
N
は友達の数を、整数
W
は同時に運べる重さの限界をあらわす。重さの合計が
W
より大きいと運ぶことはできない。
続く
N
行には、友達の重さをあらわす整数が書かれている。整数
w
i
（1 ≤
w
i
≤ 10,000）が、
i
番目の友達の重さをあらわす。
Output
最終的にリュックに入っている友達の組み合わせは何通り考えられるか。その総数を1,000,000,007
で割った余りを出力せよ。なお1,000,000,007 は素数である。
「誰もリュックに入っていない」も１通りとして数えることに注意せよ。
Sample Input 1
4 8
1
2
7
9
Sample Output 1
2
Sample Input 2
4 25
20
15
20
15
Sample Output 2
4
Sample Input 3
6 37
5
9
13
18
26
33
Sample Output 3
6

Submitted solutions:

code_snippet: #include <vector>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
const int mod = 1000000007;
int N, W;
int main() {
	cin >> N >> W;
	vector<int> a(N);
	for (int i = 0; i < N; i++) cin >> a[i];
	sort(a.begin(), a.end());
	int ret = 0, sum = 0;
	for (int i = 0; i < N; i++) {
		if (i >= 1) sum += a[i - 1];
		if (sum > W) break;
		vector<vector<int> > dp(N - i, vector<int>(W - sum + 1, 0));
		dp[0][0] = 1;
		for (int j = 0; j < N - i - 1; j++) {
			for (int k = 0; k <= W - sum; k++) {
				dp[j + 1][k] += dp[j][k];
				if (k >= a[j + i + 1]) {
					dp[j + 1][k] += dp[j][k - a[j + i + 1]];
					if (dp[j + 1][k] >= mod) dp[j + 1][k] -= mod;
				}
			}
		}
		for (int k = 0; k <= W - sum; k++) {
			if (k > W - sum - a[i]) {
				ret += dp[N - i - 1][k];
				if (ret >= mod) ret -= mod;
			}
		}
	}
	sum += a[N - 1];
	if (sum <= W) {
		ret++;
		if (ret >= mod) ret -= mod;
	}
	cout << ret << endl;
	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 10932
final_rank: 6

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define ll long long
#define fi first
#define se second
const int MOD=1e9+7;
const int N=205;
const int W=1e4+5;
int dp[N][W];
void add(int &x,int y){
    x+=y;
    if(x>=MOD) x-=MOD;
}
int main(){
    ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
    int n,w;
    cin>>n>>w;
    int sum=0;
    vector<int> a(n+1);
    for(int i=1;i<=n;i++) cin>>a[i],sum+=a[i];
    sort(a.begin()+1,a.end());
    int sumw=0;
    int ans=0;
    int mn=a[1];
    if(sum<=w || mn>w){
        cout<<1<<'\n';
        return 0;
    }
    for(int s=0;s<=n;s++){
        if(sumw>w) break;
        int maxw=w-sumw;
        vector<vector<int>> dp(n-s+2,vector<int>(w-sumw+2));
        dp[0][0]=1;
        for(int i=s;i<n;i++){
            for(int wei=0;wei<=maxw;wei++){
                if(wei+a[i+1]<=maxw){
                    add(dp[i-s+1][wei+a[i+1]],dp[i-s][wei]);
                }
                add(dp[i-s+1][wei],dp[i-s][wei]);
            }
        }
        for(int wei=0;wei<=maxw;wei++){
            if(wei+sumw+a[s]>w) add(ans,dp[n-s][wei]);
        }

        sumw+=a[s];
    }
    cout<<ans<<'\n';
}
accuracy: 1
time_ms: 40
memory_kb: 10856
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(v) (v).begin(),(v).end()
#define pb(a) push_back(a)
#define rep(i, n) for(int i=0;i<n;i++)
#define foa(e, v) for(auto&& e : v)
using ll = long long;
const ll MOD7 = 1000000007, MOD998 = 998244353, INF = (1LL << 60);
#define dout(a) cout<<fixed<<setprecision(10)<<a<<endl;

const ll mod = MOD7;

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    ll n, w;
    cin >> n >> w;
    vector<ll> a(n);
    rep(i, n) cin >> a[i];
    sort(all(a));
    ll sum = 0;
    ll ans = 0;
    {
        vector<ll> dp(w + 1, 0LL);
        dp[0] = 1;
        for(int j = 1; j < n; j ++) {
            for(int k = w; k >= a[j]; k --) {
                dp[k] += dp[k - a[j]];
                if(dp[k] >= mod) dp[k] -= mod;
            }
        }
        for(int j = w - a[0] + 1; j <= w; j ++) {
            ans += dp[j];
            if(ans >= mod) ans -= mod;
        }
    }
    a.pb(w + 1);
    rep(i, n) {
        sum += a[i];
        if(sum > w) break;
        vector<ll> dp(w + 1, 0LL);
        dp[sum] = 1;
        for(int j = i + 2; j < n; j ++) {
            for(int k = w; k >= a[j]; k --) {
                dp[k] += dp[k - a[j]];
                if(dp[k] >= mod) dp[k] -= mod;
            }
        }
        for(int j = w - a[i + 1] + 1; j <= w; j ++) {
            ans += dp[j];
            if(ans >= mod) ans -= mod;
        }
    }
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3544
final_rank: 2

code_snippet: #include<bits/stdc++.h>
using namespace std;
using ll = long long;
vector<int> dx = {0,1,0,-1};
vector<int> dy = {1,0,-1,0};
const int mod = 1000000007;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int N,W;
    cin >> N >> W;
    vector<int> data(N);
    for (int i = 0; i < N;i++){
        cin >> data[i];
    }
    vector<vector<int>> dp = vector<vector<int>>(N+1, vector<int>(W+1));
    dp[N][0] = 1;
    for (int i = 0; i < N;i++){
        vector<vector<int>> dp2 = vector<vector<int>>(N+1, vector<int>(W+1));
        for (int j = 0; j <= N;j++){
            for (int k = 0; k <= W;k++){
                if (j == N){
                    dp2[i][k] += dp[j][k];
                    dp2[i][k] %= mod;
                }
                else{
                    if (data[i] < data[j]){
                        dp2[i][k] += dp[j][k];
                        dp2[i][k] %= mod;
                    }
                    else{
                        dp2[j][k] += dp[j][k];
                        dp2[j][k] %= mod;
                    }
                }
                if (k+data[i] <= W){
                    dp2[j][k+data[i]] += dp[j][k];
                    dp2[j][k+data[i]] %= mod;
                }
            }
        }
        swap(dp,dp2);
    }
    int ans = 0;
    for (int j = 0; j <= N;j++){
        for (int k = 0; k <= W;k++){
            if (j == N || W-k < data[j]){
                ans += dp[j][k];
                ans %= mod;
            }
        }
    }
    cout << ans << endl;
}
accuracy: 1
time_ms: 1490
memory_kb: 18920
final_rank: 13

code_snippet: #include<bits/stdc++.h>
#define int long long
#define matsuri pair<int,int>
const int iris = 1e9+7;
//const int iris = 998244353;
using namespace std;

void solve()
{
	int n,w;
	cin>>n>>w;
	vector<int> arr(n);
	for(int &x:arr)
		cin>>x;
	sort(arr.begin(), arr.end());
	int ans=0;
	for(int i=0;i<=n;i++)
	{
		vector<int> dp(w+1);
		int sum=0;
		for(int j=0;j<i;j++)
			sum+=arr[j];
		if(sum>w)
			break;
		dp[sum]=1;
		
		for(int j=i+1;j<n;j++)
			for(int k=w;k>=arr[j];k--)
				dp[k]=(dp[k]+dp[k-arr[j]])%iris;
		for(int k=w;k>=0 && (i==n || w-k<arr[i]);k--)
			ans=(ans+dp[k])%iris;
	}
	cout<<ans<<'\n';
}

signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);

	int T=1;
	//cin>>T;
	while(T--)
		solve();

	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3460
final_rank: 1

code_snippet: #line 1 "library/Template/template.hpp"
#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}
#line 2 "library/Utility/fastio.hpp"
#include <unistd.h>
namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf

uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio

using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */
#line 3 "sol.cpp"

#line 2 "library/Math/modint.hpp"

template <unsigned mod = 1000000007> struct fp {
    unsigned v;
    static constexpr int get_mod() {
        return mod;
    }
    constexpr unsigned inv() const {
        assert(v != 0);
        int x = v, y = mod, p = 1, q = 0, t = 0, tmp = 0;
        while (y > 0) {
            t = x / y;
            x -= t * y, p -= t * q;
            tmp = x, x = y, y = tmp;
            tmp = p, p = q, q = tmp;
        }
        if (p < 0)
            p += mod;
        return p;
    }
    constexpr fp(ll x = 0) : v(x >= 0 ? x % mod : (mod - (-x) % mod) % mod) {}
    fp operator-() const {
        return fp() - *this;
    }
    fp pow(ull t) {
        fp res = 1, b = *this;
        while (t) {
            if (t & 1)
                res *= b;
            b *= b;
            t >>= 1;
        }
        return res;
    }
    fp &operator+=(const fp &x) {
        if ((v += x.v) >= mod)
            v -= mod;
        return *this;
    }
    fp &operator-=(const fp &x) {
        if ((v += mod - x.v) >= mod)
            v -= mod;
        return *this;
    }
    fp &operator*=(const fp &x) {
        v = ull(v) * x.v % mod;
        return *this;
    }
    fp &operator/=(const fp &x) {
        v = ull(v) * x.inv() % mod;
        return *this;
    }
    fp operator+(const fp &x) const {
        return fp(*this) += x;
    }
    fp operator-(const fp &x) const {
        return fp(*this) -= x;
    }
    fp operator*(const fp &x) const {
        return fp(*this) *= x;
    }
    fp operator/(const fp &x) const {
        return fp(*this) /= x;
    }
    bool operator==(const fp &x) const {
        return v == x.v;
    }
    bool operator!=(const fp &x) const {
        return v != x.v;
    }
    friend istream &operator>>(istream &is, fp &x) {
        return is >> x.v;
    }
    friend ostream &operator<<(ostream &os, const fp &x) {
        return os << x.v;
    }
};

template <unsigned mod> void rd(fp<mod> &x) {
    fastio::rd(x.v);
}
template <unsigned mod> void wt(fp<mod> x) {
    fastio::wt(x.v);
}

template <typename T> T Inv(ll n) {
    static const int md = T::get_mod();
    static vector<T> buf({0, 1});
    assert(n > 0);
    n %= md;
    while (SZ(buf) <= n) {
        int k = SZ(buf), q = (md + k - 1) / k;
        buf.push_back(buf[k * q - md] * q);
    }
    return buf[n];
}

template <typename T> T Fact(ll n, bool inv = 0) {
    static const int md = T::get_mod();
    static vector<T> buf({1, 1}), ibuf({1, 1});
    assert(n >= 0 and n < md);
    while (SZ(buf) <= n) {
        buf.push_back(buf.back() * SZ(buf));
        ibuf.push_back(ibuf.back() * Inv<T>(SZ(ibuf)));
    }
    return inv ? ibuf[n] : buf[n];
}

template <typename T> T nPr(int n, int r, bool inv = 0) {
    if (n < 0 || n < r || r < 0)
        return 0;
    return Fact<T>(n, inv) * Fact<T>(n - r, inv ^ 1);
}
template <typename T> T nCr(int n, int r, bool inv = 0) {
    if (n < 0 || n < r || r < 0)
        return 0;
    return Fact<T>(n, inv) * Fact<T>(r, inv ^ 1) * Fact<T>(n - r, inv ^ 1);
}
template <typename T> T nHr(int n, int r, bool inv = 0) {
    return nCr<T>(n + r - 1, r, inv);
}

/**
 * @brief Modint
 */
#line 5 "sol.cpp"
using Fp = fp<>;

int main() {
    int n, W;
    read(n, W);
    vector<int> a(n);
    read(a);
    sort(ALL(a));

    Fp ret;
    rep(i, 0, n + 1) {
        int sum = 0;
        rep(j, 0, i) sum += a[j];
        if (sum > W or (i != n and W - a[i] + 1 < 0))
            continue;
        vector<Fp> from(W + 1);
        from[sum] = 1;
        rep(j, i + 1, n) {
            vector<Fp> to(W + 1);
            rep(k, 0, W + 1) {
                to[k] += from[k];
                if (k + a[j] <= W)
                    to[k + a[j]] += from[k];
            }
            swap(from, to);
        }
        rep(k, (i == n ? 0 : W - a[i] + 1), W + 1) ret += from[k];
    }
    print(ret);
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3528
final_rank: 3

code_snippet: #line 1 "library/Template/template.hpp"
#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}
#line 2 "library/Utility/fastio.hpp"
#include <unistd.h>
namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf

uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio

using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */
#line 3 "sol.cpp"

#line 2 "library/Math/modint.hpp"

template <unsigned mod = 1000000007> struct fp {
    unsigned v;
    static constexpr int get_mod() {
        return mod;
    }
    constexpr unsigned inv() const {
        assert(v != 0);
        int x = v, y = mod, p = 1, q = 0, t = 0, tmp = 0;
        while (y > 0) {
            t = x / y;
            x -= t * y, p -= t * q;
            tmp = x, x = y, y = tmp;
            tmp = p, p = q, q = tmp;
        }
        if (p < 0)
            p += mod;
        return p;
    }
    constexpr fp(ll x = 0) : v(x >= 0 ? x % mod : (mod - (-x) % mod) % mod) {}
    fp operator-() const {
        return fp() - *this;
    }
    fp pow(ull t) {
        fp res = 1, b = *this;
        while (t) {
            if (t & 1)
                res *= b;
            b *= b;
            t >>= 1;
        }
        return res;
    }
    fp &operator+=(const fp &x) {
        if ((v += x.v) >= mod)
            v -= mod;
        return *this;
    }
    fp &operator-=(const fp &x) {
        if ((v += mod - x.v) >= mod)
            v -= mod;
        return *this;
    }
    fp &operator*=(const fp &x) {
        v = ull(v) * x.v % mod;
        return *this;
    }
    fp &operator/=(const fp &x) {
        v = ull(v) * x.inv() % mod;
        return *this;
    }
    fp operator+(const fp &x) const {
        return fp(*this) += x;
    }
    fp operator-(const fp &x) const {
        return fp(*this) -= x;
    }
    fp operator*(const fp &x) const {
        return fp(*this) *= x;
    }
    fp operator/(const fp &x) const {
        return fp(*this) /= x;
    }
    bool operator==(const fp &x) const {
        return v == x.v;
    }
    bool operator!=(const fp &x) const {
        return v != x.v;
    }
    friend istream &operator>>(istream &is, fp &x) {
        return is >> x.v;
    }
    friend ostream &operator<<(ostream &os, const fp &x) {
        return os << x.v;
    }
};

template <unsigned mod> void rd(fp<mod> &x) {
    fastio::rd(x.v);
}
template <unsigned mod> void wt(fp<mod> x) {
    fastio::wt(x.v);
}

template <typename T> T Inv(ll n) {
    static const int md = T::get_mod();
    static vector<T> buf({0, 1});
    assert(n > 0);
    n %= md;
    while (SZ(buf) <= n) {
        int k = SZ(buf), q = (md + k - 1) / k;
        buf.push_back(buf[k * q - md] * q);
    }
    return buf[n];
}

template <typename T> T Fact(ll n, bool inv = 0) {
    static const int md = T::get_mod();
    static vector<T> buf({1, 1}), ibuf({1, 1});
    assert(n >= 0 and n < md);
    while (SZ(buf) <= n) {
        buf.push_back(buf.back() * SZ(buf));
        ibuf.push_back(ibuf.back() * Inv<T>(SZ(ibuf)));
    }
    return inv ? ibuf[n] : buf[n];
}

template <typename T> T nPr(int n, int r, bool inv = 0) {
    if (n < 0 || n < r || r < 0)
        return 0;
    return Fact<T>(n, inv) * Fact<T>(n - r, inv ^ 1);
}
template <typename T> T nCr(int n, int r, bool inv = 0) {
    if (n < 0 || n < r || r < 0)
        return 0;
    return Fact<T>(n, inv) * Fact<T>(r, inv ^ 1) * Fact<T>(n - r, inv ^ 1);
}
template <typename T> T nHr(int n, int r, bool inv = 0) {
    return nCr<T>(n + r - 1, r, inv);
}

/**
 * @brief Modint
 */
#line 5 "sol.cpp"
using Fp = fp<998244353>;

int main() {
    int n, W;
    read(n, W);
    vector<int> a(n);
    read(a);
    sort(ALL(a));

    Fp ret;
    rep(i, 0, n + 1) {
        int sum = 0;
        rep(j, 0, i) sum += a[j];
        if (sum > W or (i != n and W - a[i] + 1 < 0))
            continue;
        vector<Fp> from(W + 1);
        from[sum] = 1;
        rep(j, i + 1, n) {
            vector<Fp> to(W + 1);
            rep(k, 0, W + 1) {
                to[k] += from[k];
                if (k + a[j] <= W)
                    to[k + a[j]] += from[k];
            }
            swap(from, to);
        }
        rep(k, (i == n ? 0 : W - a[i] + 1), W + 1) ret += from[k];
    }
    print(ret);
    return 0;
}
accuracy: 0.5
time_ms: 10
memory_kb: 3504
final_rank: 19

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef long double ld;
typedef pair<ll, ll> pll;
const ll MOD = 1000000007;
#define rep(i, N) for(ll i = 0; i < (ll)N; i++)
#define ALL(V)  (V).begin(), (V).end()
ll dx[8] = {-1, -1, -1, 0, 0, 1, 1, 1};
ll dy[8] = {-1, 0, 1, -1, 1, -1, 0, 1};

ll N, W;
vector<ll> V;

void test() {
    ll ans = 0;
    rep (bit, (1LL<<N)) {
        vector<ll> tmp, tukawanai;
        
        ll tmpSum = 0;
        rep (i, N) {
            if (bit & (1LL<<i)) {
                tmp.push_back(V[i]);
                tmpSum += V[i];
            } else {
                tukawanai.push_back(V[i]);
            }
        }
        if (tmpSum > W) continue;
        bool flag = false;
        rep (i, tukawanai.size()) {
            if (W - tmpSum >= tukawanai[i]) flag = true;
        }
        if (flag) continue;
        // rep (i, tmp.size()) cout << tmp[i] << endl;
        // cout << endl;
        ans++;
    }
    cerr << ans << endl;
}

int main() {
    cin >> N >> W;
    rep (i, N) {
        ll a; cin >> a;
        V.push_back(a);
    }
    // test();
    sort(ALL(V));
    vector<vector<vector<ll>>> dp(2, vector<vector<ll>>(W + 1, vector<ll>(N + 1, 0)));
    dp[0][0][0] = 1;
    ll mae = 0;
    ll ato = 1;
    rep (i, N) {
        rep (j, W + 1) {
            rep (k, N) {
                dp[ato][j][k] = 0;
            }
        }
        rep (j, W + 1) {
            rep (k, N) {
                if (i == k) {
                    if (j - V[i] >= 0) dp[ato][j][k + 1] += dp[mae][j - V[i]][k], dp[ato][j][k + 1] %= MOD;
                    dp[ato][j][k] += dp[mae][j][k], dp[ato][j][k] %= MOD;
                } else {
                    if (j - V[i] >= 0) dp[ato][j][k] += dp[mae][j - V[i]][k], dp[ato][j][k] %= MOD;
                    dp[ato][j][k] += dp[mae][j][k], dp[ato][j][k] %= MOD;
                }
            }
        }
        mae = 1 - mae;
        ato = 1 - ato;
    }
    ll ans = 0;
    rep (j, W + 1) {
        rep (k, N + 1) {
            if (k == N) {
                ans += dp[mae][j][k], ans %= MOD;
            } else {
                if (j + V[k] > W) ans += dp[mae][j][k], ans %= MOD;
            }
        }
    }

    // rep (k, N + 1) {
    //     cout << k << endl;
    //     rep (j, W + 1) {
    //         cout << dp[mae][j][k] << ' ';
    //     }
    //     cout << endl;
    // }
    // test();
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 1320
memory_kb: 51164
final_rank: 18

code_snippet: #line 2 "cp-library/src/cp-template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull  = unsigned long long;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
template < class T > bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; }
template < class T > bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; }
template < class T, class U > T ceil (T x, U y) { return (x > 0 ? (x + y - 1) / y :           x / y); }
template < class T, class U > T floor(T x, U y) { return (x > 0 ?           x / y : (x - y + 1) / y); }
int popcnt(i32 x) { return __builtin_popcount(x); }
int popcnt(u32 x) { return __builtin_popcount(x); }
int popcnt(i64 x) { return __builtin_popcountll(x); }
int popcnt(u64 x) { return __builtin_popcountll(x); }

#line 2 "cp-library/src/utility/rep_itr.hpp"
template < class T > struct itr_rep {
    T i, d;
    constexpr itr_rep(const T i) noexcept : i(i), d(1) {}
    constexpr itr_rep(const T i, const T d) noexcept : i(i), d(d) {}
    void operator++() noexcept { i += d; }
    constexpr int operator*() const noexcept { return i; }
    constexpr bool operator!=(const itr_rep x) const noexcept { return d > 0 ? i < x.i : i > x.i; }
};

template < class T > struct rep {
    const itr_rep< T > s, t;
    constexpr rep(const T t) noexcept : s(0), t(t) {}
    constexpr rep(const T s, const T t) noexcept : s(s), t(t) {}
    constexpr rep(const T s, const T t, const T d) noexcept : s(s, d), t(t, d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};

template < class T > struct revrep {
    const itr_rep < T > s, t;
    constexpr revrep(const T t) noexcept : s(t - 1, -1), t(-1, -1) {}
    constexpr revrep(const T s, const T t) noexcept : s(t - 1, -1), t(s - 1, -1) {}
    constexpr revrep(const T s, const T t, const T d) noexcept : s(t - 1, -d), t(s - 1, -d) {}
    constexpr auto begin() const noexcept { return s; }
    constexpr auto end  () const noexcept { return t; }
};
#line 3 "cp-library/src/utility/io.hpp"

/* 128bit integer */
istream& operator>>(istream& is, i128& x) {
    std::string s; is >> s;
    int pm = (s[0] == '-');
    x = 0;
    for(int i : rep(pm, int(s.size()))) x = x * 10 + (s[i] - '0');
    if(pm) x *= -1;
    return is;
}
ostream& operator<<(ostream& os, const i128& x) {
    if(x == 0) return os << '0';
    i128 y = x;
    if(y < 0) { os << '-'; y *= -1; }
    std::vector<int> ny;
    while(y > 0) { ny.push_back(y % 10); y /= 10; }
    for(int i : revrep(ny.size())) os << ny[i];
    return os;
}

template < class S, class T > istream& operator>>(istream& is,       std::pair< S, T >& x) { is >> x.first        >> x.second; return is; }
template < class S, class T > ostream& operator<<(ostream& os, const std::pair< S, T >& x) { os << x.first << " " << x.second; return os; }

namespace scanner {
    struct sca {
        template < class T > operator T() {
            T s; std::cin >> s; return s;
        }
    };
    struct vec {
        int n;
        vec(int n) : n(n) {}
        template < class T > operator std::vector< T >() {
            std::vector< T > v(n);
            for(T& x : v) std::cin >> x;
            return v;
        }
    };
    struct mat {
        int h, w;
        mat(int h, int w) : h(h), w(w) {}
        template < class T > operator std::vector< std::vector< T > >() {
            std::vector m(h, std::vector< T >(w));
            for(std::vector< T >& v : m) for(T& x : v) std::cin >> x;
            return m;
        }
    };
    struct speedup {
        speedup() {
            std::cin.tie(0);
            std::ios::sync_with_stdio(0);
        }
    } speedup_instance;
}
scanner::sca in() { return scanner::sca(); }
scanner::vec in(int n) { return scanner::vec(n); }
scanner::mat in(int h, int w) { return scanner::mat(h, w); }

namespace printer {
    void precision(int d) { std::cout << std::fixed << std::setprecision(d); }
    void flush() { std::cout.flush(); }
}

template < class T >
ostream& operator<<(ostream& os, const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) { os << a[i]; if(i != n - 1) os << ' '; }
    return os;
}

int print() { std::cout << '\n'; return 0; }
template < class head, class... tail > int print(head&& h, tail&&... t) {
    std::cout << h; if(sizeof...(tail)) std::cout << ' ';
    return print(std::forward<tail>(t)...);
}
template < class T > int print_n(const std::vector< T > a) {
    int n = a.size();
    for(int i : rep(n)) std::cout << a[i] << "\n";
    return 0;
}


#line 2 "cp-library/src/utility/key_val.hpp"

template < class K, class V >
struct key_val {
    K key; V val;
    key_val() {}
    key_val(K key, V val) : key(key), val(val) {}
    template < std::size_t Index >
    std::tuple_element_t< Index, key_val >& get() {
        if constexpr (Index == 0) return key;
        if constexpr (Index == 1) return val;
    }
};

namespace std {

template < class K, class V > struct tuple_size < key_val< K, V > > : integral_constant< size_t, 2 > {};
template < class K, class V > struct tuple_element < 0, key_val< K, V > > { using type = K; };
template < class K, class V > struct tuple_element < 1, key_val< K, V > > { using type = V; };

}
#line 2 "cp-library/src/utility/vec_op.hpp"
template < class T > key_val< int, T > max_of(const vector< T >& a) {
    int i = std::max_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class T > key_val< int, T > min_of(const vector< T >& a) {
    int i = std::min_element(a.begin(), a.end()) - a.begin();
    return {i, a[i]};
}
template < class S, class T > S sum_of(const vector< T >& a) {
    S sum = 0;
    for(const T x : a) sum += x;
    return sum;
}
template < class S, class T > vector< S > freq_of(const vector< T >& a, T L, T R) {
    vector< S > res(R - L, S(0));
    for(const T x : a) res[x - L] += 1;
    return res;
}
template < class S, class T > struct prefix_sum {
    vector< S > s;
    prefix_sum(const vector< T >& a) : s(a) {
        s.insert(s.begin(), S(0));
        for(int i : rep(a.size())) s[i + 1] += s[i];
    }
    // [L, R)
    S sum(int L, int R) { return s[R] - s[L]; }
};
#line 3 "cp-library/src/utility/heap.hpp"

template < class T > using heap_min = std::priority_queue< T, std::vector< T >, std::greater< T > >;
template < class T > using heap_max = std::priority_queue< T, std::vector< T >, std::less< T > >;

#line 27 "cp-library/src/cp-template.hpp"

#line 1 "cp-library/src/algorithm/bin_search.hpp"
template < class T, class F >
T bin_search(T ok, T ng, F f) {
    while(abs(ng - ok) > 1) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}

template < class T, class F >
T bin_search_real(T ok, T ng, F f, int step = 80) {
    while(step--) {
        T mid = (ok + ng) / 2;
        (f(mid) ? ok : ng) = mid;
    }
    return ok;
}
#line 2 "cp-library/src/algorithm/argsort.hpp"

template < class T > std::vector< int > argsort(const std::vector< T > &a) {
    std::vector< int > ids((int)a.size());
    std::iota(ids.begin(), ids.end(), 0);
    std::sort(ids.begin(), ids.end(), [&](int i, int j) {
        return a[i] < a[j] || (a[i] == a[j] && i < j);
    });
    return ids;
}
#line 1 "macro.hpp"
namespace macro {

using size_type = int;
template < class container > void  sort(container& a) { std::sort(std:: begin(a), std:: end(a)); }
template < class container > void rsort(container& a) { std::sort(std::rbegin(a), std::rend(a)); }
template < class container > void reverse(container& a) { std::reverse(std::begin(a), std::end(a)); }
template < class container > void unique(container& a) {
    std::sort(std::begin(a), std::end(a));
    a.erase(std::unique(std::begin(a), std::end(a)), std::end(a));
}
template < class container > container  sorted(const container& a) { container b = a;  sort(b); return std::move(b); }
template < class container > container rsorted(const container& a) { container b = a; rsort(b); return std::move(b); }
template < class container, class compare > void sort(container& a, const compare& cmp) { std::sort(std::begin(a), std::end(a), cmp); }
template < class container, class compare > container sorted(const container& a, const compare& cmp) { container b = a; sort(b, cmp); return std::move(b); }
template < class container, class value > size_type lower_bound(const container& a, const value& x) { return std::lower_bound(std::begin(a), std::end(a), x) - std::begin(a); }
template < class container, class value > size_type upper_bound(const container& a, const value& x) { return std::upper_bound(std::begin(a), std::end(a), x) - std::begin(a); }

const std::vector<std::pair<size_type, size_type>> dir4 = { {+1,  0}, {-1,  0}, { 0, +1}, { 0, -1} };
const std::vector<std::pair<size_type, size_type>> dir8 = { {-1, -1}, {-1,  0}, {-1, +1}, { 0, -1}, { 0, +1}, {+1, -1}, {+1,  0}, {+1, +1} };

#ifdef _DEBUG
#define debug(x) std::cout << "[" << __LINE__ << "] " << #x << ": " << x << std::endl
#else
#define debug(x)
#endif

template < class container > void concat(container& a, const container& b) {
    a.insert(std::end(a), std::begin(b), std::end(b));
}
std::vector<size_type> iota(const size_type n) {
    std::vector<size_type> I(n);
    std::iota(std::begin(I), std::end(I), 0);
    return I;
}
template < class container > std::vector<size_type> sort_idx(const container& a) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return a[i] < a[j] or (a[i] == a[j] and i < j); });
    return I;
}
template < class container, class compare > std::vector<size_type> sort_idx(const container& a, const compare& cmp) {
    const size_type n = a.size();
    std::vector<size_type> I = iota(n);
    std::sort(std::begin(I), std::end(I), [&](size_type i, size_type j) { return cmp(a[i], a[j]) or (a[i] == a[j] and i < j); });
    return std::move(I);
}

struct grid {
    using size_type = int;
    size_type H, W;
    grid(const size_type H, const size_type W) : H(H), W(W) {}
    bool contains(const size_type i, const size_type j) {
        return 0 <= i and i < H and 0 <= j and j < W;
    }
};

} // namespace macro

using namespace macro;
#line 2 "cp-library/src/number/modint.hpp"
struct modinfo { uint mod, root, isprime; };
template < modinfo const &ref >
struct modint {
    static constexpr uint const &mod = ref.mod;
    static constexpr uint const &root = ref.root;
    static constexpr uint const &isprime = ref.isprime;
    uint v = 0;
    constexpr modint& s(uint v) { this->v = v < mod ? v : v - mod; return *this; }
    constexpr modint(ll v = 0) { s(v % mod + mod); }
    modint operator-() const { return modint() - *this; }
    modint& operator+=(const modint& rhs) { return s(v + rhs.v); }
    modint& operator-=(const modint& rhs) { return s(v + mod - rhs.v); }
    modint& operator*=(const modint& rhs) { v = ull(v) * rhs.v % mod; return *this; }
    modint& operator/=(const modint& rhs) { return *this *= inv(rhs); }
    modint operator+(const modint& rhs) const { return modint(*this) += rhs; }
    modint operator-(const modint& rhs) const { return modint(*this) -= rhs; }
    modint operator*(const modint& rhs) const { return modint(*this) *= rhs; }
    modint operator/(const modint& rhs) const { return modint(*this) /= rhs; }
    friend modint pow(modint x, ll n) { modint res(1); while(n > 0) { if(n & 1) res *= x; x *= x; n >>= 1; } return res; }
    friend modint inv(modint v) {
        if(isprime) {
            return pow(v, mod - 2);
        } else {
            ll a = v.v, b = modint::mod, x = 1, y = 0, t;
            while(b > 0) { t = a / b; swap(a -= t * b, b); swap(x -= t * y, y); }
            return modint(x);
        }
    }
    friend modint operator+(int x, const modint& y) { return modint(x) + y; }
    friend modint operator-(int x, const modint& y) { return modint(x) - y; }
    friend modint operator*(int x, const modint& y) { return modint(x) * y; }
    friend modint operator/(int x, const modint& y) { return modint(x) / y; }
    friend istream& operator>>(istream& is, modint& m) { ll x; is >> x; m = modint(x); return is; }
    friend ostream& operator<<(ostream& os, const modint& m) { return os << m.v; }
    bool operator==(const modint& r) const { return v == r.v; }
    bool operator!=(const modint& r) const { return v != r.v; }
    static uint get_mod() { return mod; }
    static int is_prime() { return isprime; }
};
constexpr modinfo base998244353 { 998244353, 3, 1 };
constexpr modinfo base1000000007 { 1000000007, 0, 1 };
using mint998244353 = modint< base998244353 >;
using mint1000000007 = modint< base1000000007 >;
#line 4 "A.cpp"
using mint = mint1000000007;

int main() {
    int N = in(), W = in();
    vector<int> w = in(N);
    sort(w);

    auto f = [&](int p) {
        int sum = 0;
        for(int i : rep(p)) sum += w[i];

        vector dp(W + 1, mint(0));
        if(sum <= W) dp[sum] = 1;
        for(int i : rep(p + 1, N)) {
            vector nt = dp;
            for(int s = 0; s <= W; s++)
                if(s + w[i] <= W) nt[s + w[i]] += dp[s];
            dp = move(nt);
        }

        mint res = 0;
        for(int x = max(0, W - w[p] + 1); x <= W; x++) res += dp[x];
        return res;
    };

    mint ans = 0;
    for(int i : rep(N)) ans += f(i);
    if(sum_of<int>(w) <= W) ans += 1;
    print(ans);
}
accuracy: 1
time_ms: 220
memory_kb: 3536
final_rank: 4

code_snippet: #include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
const int mod = 1000000007;
int N, W;
int w[201];
ll dp[2][10001][202];
int main() {
  cin >> N >> W;
  for (int i = 0; i < N; i++)
    cin >> w[i];
  memset(dp, 0, sizeof(dp)); // Initialize entire dp table to 0
  for (int j = 0; j <= W; j++) {
    for (int k = 0; k <= N; k++) {
      if (j <= W && (k == N || w[k] + j > W))
        dp[N % 2][j][k] = 1;
    }
  }
  for (int i = N - 1; i >= 0; i--) {
    int cur = (i + 1) % 2;
    int nxt = (i) % 2;
    for (int j = 0; j <= W; j++) {
      for (int k = 0; k <= N; k++) {
        int nmwidx = (k == N || w[k] > w[i]) ? i : k; // Calculate nmwidx once
        dp[nxt][j][k] = dp[cur][j][nmwidx];
        if (j + w[i] <= W)
          dp[nxt][j][k] += dp[cur][j + w[i]][k];
        dp[nxt][j][k] %= mod;
      }
    }
  }
  cout << dp[0][0][N] << endl;
  return 0;
}
accuracy: 1
time_ms: 1010
memory_kb: 34660
final_rank: 14

code_snippet: #include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
const int mod = 1000000007;
int N, W;
int w[201];
ll dp_cur[10001][202], dp_nxt[10001][202];

int main() {
    cin >> N >> W;
    for (int i = 0; i < N; i++)
        cin >> w[i];
    memset(dp_cur, 0, sizeof(dp_cur));
    memset(dp_nxt, 0, sizeof(dp_nxt));
    for (int j = 0; j <= W; j++) {
        for (int k = 0; k <= N; k++) {
            if (j <= W && (k == N || w[k] + j > W))
                dp_cur[j][k] = 1;
            else
                dp_cur[j][k] = 0;
        }
    }
    for (int i = N - 1; i >= 0; i--) {
        for (int j = 0; j <= W; j++) {
            for (int k = 0; k <= N; k++) {
                dp_nxt[j][k] = dp_cur[j][k];
                int nmwidx = k;
                if (k == N || w[k] > w[i])
                    nmwidx = i;
                dp_nxt[j][k] += dp_cur[j][nmwidx];
                if (j + w[i] <= W)
                    dp_nxt[j + w[i]][k] += dp_cur[j][k];
                if (dp_nxt[j][k] >= mod)
                    dp_nxt[j][k] %= mod;
            }
            if (j + w[i] > W)
                break;
        }
        memcpy(dp_cur, dp_nxt, sizeof(dp_cur));  // copy dp_nxt to dp_cur
        memset(dp_nxt, 0, sizeof(dp_nxt));  // reset dp_nxt
    }
    cout << dp_cur[0][N] << endl;
    return 0;
}
accuracy: 0.05
time_ms: 10
memory_kb: 34668
final_rank: 20

code_snippet: #include <iostream>
#include <algorithm>
using namespace std;

const long long mod = 1000000007;
long long N, W;
long long w[1 << 18];
long long dp[209][10009];

long long solve(int pos) {
	long long init = 0;
	for (int i = 1; i <= pos - 1; i++) init += w[i];
	if (init > W) return 0;
	if (pos == N + 1 && init <= W) return 1;

	// DP Init
	for (int i = pos; i <= N; i++) {
		for (int j = 0; j <= W; j++) dp[i][j] = 0;
	}
	dp[pos][init] = 1;

	// DP Main
	for (int i = pos + 1; i <= N; i++) {
		for (int j = 0; j <= W; j++) {
			if (dp[i - 1][j] == 0) continue;
			dp[i][j] = (dp[i][j] + dp[i - 1][j]) % mod;
			if (j + w[i] <= W) dp[i][j + w[i]] = (dp[i][j + w[i]] + dp[i - 1][j]) % mod;
		}
	}
	long long Return = 0;
	for (int i = W - w[pos] + 1; i <= W; i++) Return += dp[N][i];
	return Return % mod;
}

int main() {
	// Step 1. Input
	cin >> N >> W;
	for (int i = 1; i <= N; i++) cin >> w[i];
	sort(w + 1, w + N + 1);

	// Step 2. Brute Force
	long long Answer = 0;
	for (int i = 1; i <= N + 1; i++) Answer += solve(i);
	cout << Answer % mod << endl;
	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 19496
final_rank: 8

code_snippet: #include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
const int mod = 1000000007;
int N, W;
int w[201];
ll dp[2][10001][202];
int main() {
  cin >> N >> W;
  for (int i = 0; i < N; i++)
    cin >> w[i];
  for (int j = 0; j <= W; j++) {
    for (int k = 0; k <= N; k++) {
      if (j <= W && (k == N || w[k] + j > W))
        dp[N % 2][j][k] = 1;
      else
        dp[N % 2][j][k] = 0;
    }
  }
  for (int i = N - 1; i >= 0; i--) {
    int cur = (i + 1) % 2;
    int nxt = (i) % 2;
    for (int j = 0; j <= W; j++) {
      for (int k = 0; k <= N; k++) {
        dp[nxt][j][k] = 0;
        int nmwidx = k;
        if (k == N || w[k] > w[i])
          nmwidx = i;
        dp[nxt][j][k] += dp[cur][j][nmwidx];
        if (j + w[i] <= W)
          dp[nxt][j][k] += dp[cur][j + w[i]][k];
        dp[nxt][j][k] %= mod;
      }
    }
  }
  cout << dp[0][0][N] << endl;
  return 0;
}
accuracy: 1
time_ms: 1030
memory_kb: 34628
final_rank: 15

code_snippet: #include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
const int mod = 1000000007;
int N, W;
int w[201];
ll dp[2][10001][202];
int main() {
  cin >> N >> W;
  for (int i = 0; i < N; i++)
    cin >> w[i];
  for (int j = 0; j < 10001; j++) {
    for (int k = 0; k <= N; k++) {
      if (j <= W && (k == N || w[k] + j > W))
        dp[N % 2][j][k] = 1;
      else
        dp[N % 2][j][k] = 0;
    }
  }
  for (int i = N - 1; i >= 0; i--) {
    int cur = (i + 1) % 2;
    int nxt = (i) % 2;
    for (int j = 0; j < 10001; j++) {
      for (int k = 0; k <= N; k++) {
        dp[nxt][j][k] = 0;
        int nmwidx = k;
        if (k == N || w[k] > w[i])
          nmwidx = i;
        dp[nxt][j][k] += dp[cur][j][nmwidx];
        if (j + w[i] <= W)
          dp[nxt][j][k] += dp[cur][j + w[i]][k];
        dp[nxt][j][k] %= mod;
      }
    }
  }
  cout << dp[0][0][N] << endl;
  return 0;
}
accuracy: 1
time_ms: 1060
memory_kb: 34644
final_rank: 16

code_snippet: #include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
const int mod = 1000000007;
int N, W;
int w[201];
ll dp[2][10001][202];
int main() {
  cin >> N >> W;
  for (int i = 0; i < N; i++)
    cin >> w[i];
  for (int j = 0; j < 10001; j++) {
    for (int k = 0; k <= N; k++) {
      if (j <= W && (k == N || w[k] + j > W))
        dp[N & 1][j][k] = 1;
      else
        dp[N & 1][j][k] = 0;
    }
  }
  for (int i = N - 1; i >= 0; i--) {
    int cur = (i + 1) % 2;
    int nxt = (i) % 2;
    for (int j = 0; j < 10001; j++) {
      for (int k = 0; k <= N; k++) {
        dp[nxt][j][k] = 0;
        int nmwidx = k;
        if (k == N || w[k] > w[i])
          nmwidx = i;
        dp[nxt][j][k] += dp[cur][j][nmwidx];
        if (j + w[i] <= W)
          dp[nxt][j][k] += dp[cur][j + w[i]][k];
        dp[nxt][j][k] %= mod;
      }
    }
  }
  cout << dp[0][0][N] << endl;
  return 0;
}
accuracy: 1
time_ms: 1240
memory_kb: 34660
final_rank: 17

code_snippet: #include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
typedef long long ll;
const int mod = 1000000007;
int N, W;
int w[201];
ll dp[2][10001][202];
int main() {
  cin >> N >> W;
  for (int i = 0; i < N; i++)
    cin >> w[i];
  for (int j = 0; j < 10001; j++) {
    for (int k = 0; k <= N; k++) {
      if (j <= W && (k == N || w[k] + j > W))
        dp[N % 2][j][k] = 1;
      else
        dp[N % 2][j][k] = 0;
    }
  }
  for (int i = N - 1; i >= 0; i--) {
    int cur = (i + 1) % 2;
    int nxt = (i) % 2;
    for (int j = 0; j < 10001; j++) {
      for (int k = 0; k <= N; k++) {
        dp[nxt][j][k] = 0;
        int nmwidx = k;
        if (k == N || w[k] > w[i])
          nmwidx = i;
        dp[nxt][j][k] += dp[cur][j][nmwidx];
        if (j + w[i] <= W)
          dp[nxt][j][k] += dp[cur][j + w[i]][k];
        if (dp[nxt][j][k] >= mod)
          dp[nxt][j][k] -= mod;
      }
    }
  }
  cout << dp[0][0][N] << endl;
  return 0;
}
accuracy: 1
time_ms: 960
memory_kb: 34660
final_rank: 12

code_snippet: #include <bits/stdc++.h>

using namespace std;

using ll = long long;

ll dp[210][10100];

void clear()
{
	for (int i = 0; i < 210; ++i)
	{
		for (int j = 0; j < 10100; ++j)
		{
			dp[i][j] = 0;
		}
	}
	return;
}

const ll wmax = 10100;
const ll MOD = 1e9 + 7;

int main()
{
	ll N, W; cin >> N >> W;
	vector<ll> weight(N);
	for (int i = 0; i < N; ++i) {cin >> weight[i];}
	sort(weight.begin(), weight.end());
	
	ll res = 0;
	
	for (int ban = 0; ban < N; ++ban) 
	{
		ll psum = 0;
		for (int i = 0; i < ban; ++i)
		{
			psum += weight[i];
		}
		if (psum > W) {continue;}
		
		clear();
		dp[ban+1][psum] = 1;
		for (int i = ban+1; i < N; ++i)
		{
			ll w = weight[i];
			
			for (int pw = 0; pw < wmax; ++pw)
			{
				dp[i+1][pw] += dp[i][pw];
				
				if (pw + w >= wmax) {continue;}
				dp[i+1][pw+w] += dp[i][pw];
				dp[i+1][pw+w] %= MOD;
			}
		}
		
		
		for (int pw = W - weight[ban] + 1; pw <= W; ++pw)
		{
			res += dp[N][pw];
			res %= MOD;
		}
		
	}
	
	ll wsum = 0;
	for (int i = 0; i < N; ++i) {wsum += weight[i];}
	if (wsum <= W) {res++; res %= MOD;}
	
	cout << res << endl;
	
	return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 20016
final_rank: 10

code_snippet: #include<cstdio>
#include<iostream>
#include<algorithm>
namespace IO{
	template<typename T> inline void rd(T &x){
		x=0;bool f=0;char c=0;
		while(c<'0'||c>'9') f|=c=='-',c=getchar();
		while('0'<=c&&c<='9') x=x*10+(c^48),c=getchar();
		x=f?-x:x;
	}
	template<typename T,typename ...Args> inline void rd(T &x,Args &...args){rd(x),rd(args...);}
	template<typename T> inline void wt(char c,T x){
		int stk[114],top=0;
		if(x<0) x=-x,putchar('-');
		do stk[++top]=x%10,x/=10; while(x);
		while(top) putchar(stk[top--]+'0');
		putchar(c);
	}
	template<typename T,typename ...Args> inline void wt(char c,T &x,Args &...args){wt(c,x),wt(c,args...);}
};
using namespace IO;
using namespace std;
const int INF = 1e9;
const int P = 1e9 + 7;
const int N=207,M=1e4+7;
int f[2][M][N];
int n,m;
int w[N];
inline int cmp(int x,int y){return x>y;}
int main(){
	rd(n,m);
	for(int i=1;i<=n;i++) rd(w[i]);
	sort(w+1,w+1+n,cmp);
	w[0]=INF;
	f[0][0][0]=1;
	for(int i=1;i<=n;i++){
		for(int j=0;j<=m;j++){
			for(int k=0;k<=i;k++)f[i&1][j][k]=0;
		}
		for(int j=0;j<=m;j++){
			for(int k=0;k<=i;k++){
				if(j>=w[i]) f[i&1][j][k]=(f[i&1][j][k]+f[(i-1)&1][j-w[i]][k])%P;
				f[i&1][j][i]=(f[i&1][j][i]+f[(i-1)&1][j][k])%P;
			}
		}
	}
	int res=0;
	for(int i=0;i<=m;i++){
		for(int j=0;j<=n;j++) res=(res+f[n&1][i][j]*(w[j]>m-i))%P;
	}
	wt('\n',res);
	return 0;
}
accuracy: 1
time_ms: 750
memory_kb: 19480
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define elif else if

constexpr int mod=1e9+7;
int main(){
  int n,w;
  cin>>n>>w;
  vector<int>a(n);
  for(int i=0;i<n;i++)cin>>a[i];
  sort(a.begin(),a.end());
  vector<vector<int>>dp(n+1,vector<int>(w+1,0));
  dp[0][0]=1;
  int ans=0;
  for(int i=n-1;i>=0;i-=1){
    int s=0;
    for(int j=0;j<i;j++)s+=a[j];
    for(int j=w-a[i]+1-s;j<w-s+1;j++){
      if(j>=0){
        for(int k=0;k<n-i;k++){
          ans+=dp[k][j];
          ans%=mod;
        }
      }
    }
    if(i==0)continue;
    for(int k=n-i;k>=0;k-=1){
      for(int j=0;j<=w;j++){
        if(j+a[i]<=w){
          dp[k+1][j+a[i]]+=dp[k][j];
          dp[k+1][j+a[i]]%=mod;
        }
      }
    }
  }

  int s=0;
  for(int i=0;i<n;i++)s+=a[i];
  if(s<=w)ans+=1;
  cout<<ans%mod<<endl;
}
accuracy: 1
time_ms: 320
memory_kb: 11032
final_rank: 9

code_snippet: #define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <iostream>
#include <stack>
#include <queue>
#include <algorithm>
#include <functional>
#include <set>
#include <map>
#include <string>
#include <vector>
#include <cmath>
#include<sstream>
#include<list>
#include<iomanip>
#include <cstdlib>
#include <cstring>
#include <stack>
#include <bitset>
#include <cassert>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
const int INF = 1000000000;
const long long LINF = 3e18 + 7;
const int MAX_N = 200010;
const int MAX_W = 10002;
const int MAX_ARRAYK = 100000;
double PI = 3.14159265358979323846;
//using ll = long long;

// https://drken1215.hatenablog.com/entry/2020/10/16/150700

int mod = 1000000007;
int dp[210][10010];
int N, W;
int A[10010];

int main() {

	cin >> N >> W;

	for (int i = 0; i < N; i++) {
		cin >> A[i];
	}
	sort(A, A + N);

	dp[0][0] = 1;
	for (int i = 0; i < N; i++) {
		int a = A[N - i - 1];
		for (int w = 0; w <= W; w++) {
			dp[i + 1][w] = (dp[i + 1][w] + dp[i][w]) % mod;
			if (w + a <= W) {
				dp[i + 1][w + a] = (dp[i + 1][w + a] + dp[i][w]) % mod;
			}
		}
	}

	int res = 0;
	int S = 0;
	for (int i = 0; i < N; i++) {
		int temp = 0;
		for (int w = max(0, W - S - A[i] + 1); w <= W - S; w++) {
			temp = (dp[N - i - 1][w] + temp) % mod;
		}
		res = (res + temp) % mod;
		S += A[i];
	}
	if (S <= W) res += 1;
	cout << res % mod << endl;

	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 10916
final_rank: 5