#include <bits/stdc++.h>

using namespace std;

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	
	int n;
	cin >> n;
	long long m;
	cin >> m;
	vector<int> a(n);
	for(int i=0;i<n;i++) cin >> a[i];
	
	long long mod=1000000007;
	
	int fs=5050505;
	vector<long long> fact(fs),ifact(fs),invs(fs);
	{
		fact[0]=ifact[0]=fact[1]=ifact[1]=invs[1]=1;
		for(int i=2;i<fs;i++){
			fact[i]=fact[i-1]*i%mod;
			invs[i]=mod-invs[mod%i]*(mod/i)%mod;
			ifact[i]=ifact[i-1]*invs[i]%mod;
		}
	}
	
	long long sum=0;
	for(int i=0;i<n;i++) sum+=a[i];
	//x^sum/(1-x)^(sum+n)
	//|binom(-sum-n,m-sum)| = binom(sum+n+(m-sum)-1,m-sum) = binom(n+m-1,m-sum)
	// = binom(n+m-1,n-1+sum)
	long long res=1;
	for(int i=0;i<(n+sum);i++){
		res=res*(n+m-i)%mod;
		res=res*invs[(i+1)]%mod;
	}
	cout << res << "\n";
	return 0;
}
//Utkarsh.25dec
#include <bits/stdc++.h>
#include <chrono>
#include <random>
#define ll long long int
#define ull unsigned long long int
#define pb push_back
#define mp make_pair
#define mod 998244353
#define rep(i,n) for(ll i=0;i<n;i++)
#define loop(i,a,b) for(ll i=a;i<=b;i++)
#define vi vector <int>
#define vs vector <string>
#define vc vector <char>
#define vl vector <ll>
#define all(c) (c).begin(),(c).end()
#define max3(a,b,c) max(max(a,b),c)
#define min3(a,b,c) min(min(a,b),c)
#define deb(x) cerr<<#x<<' '<<'='<<' '<<x<<'\n'
using namespace std;
#include <ext/pb_ds/assoc_container.hpp> 
#include <ext/pb_ds/tree_policy.hpp> 
using namespace __gnu_pbds; 
#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
// ordered_set s ; s.order_of_key(val)  no. of elements strictly less than val
// s.find_by_order(i)  itertor to ith element (0 indexed)
typedef vector<vector<ll>> matrix;
ll power(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
ll modInverse(ll a){return power(a,mod-2);}
const int N=500023;
bool vis[N];
vector <int> adj[N];
ll fact[N];
ll invfact[N];
ll inv[N];
void factorialsComputation()
{
    inv[0]=inv[1]=1;
    fact[0]=fact[1]=1;
    invfact[0]=invfact[1]=1;
    for(int i=2;i<N;i++)
    {
        inv[i]=(inv[mod%i]*(mod-mod/i))%mod;
        fact[i]=(fact[i-1]*i)%mod;
        invfact[i]=(invfact[i-1]*inv[i])%mod;
    }
}
ll ncr(ll n,ll r)
{
    ll ans=fact[n]*invfact[r];
    ans%=mod;
    ans*=invfact[n-r];
    ans%=mod;
    return ans;
}
void solve()
{
    ll n,m;
    cin>>n>>m;
    ll dp[m+1][15];
    memset(dp,0,sizeof(dp));
    for(int i=0;i<=m;i++)
    {
        for(int high=0;high<14;high++)
        {
            // dp[i][high];
            if(i==0)
            {
                dp[i][high]=1;
                continue;
            }
            if(high==0)
            {
                if(i<=n && i%2==0)
                    dp[i][high]=ncr(n,i);
                continue;
            }
            int got=(1<<high);
            for(int use=0;use<5000;use+=2)
            {
                if(got*use>i || use>n)
                    break;
                else
                {
                    dp[i][high]+=(dp[i-got*use][high-1]*ncr(n,use));
                    dp[i][high]%=mod;
                }
            }
        }
    }
    cout<<dp[m][13]<<'\n';
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #else 
    #define ONLINE_JUDGE 0
    #endif
    int T=1;
    //cin>>T;
    int t=0;
    factorialsComputation();
    while(t++<T)
    {
        //cout<<"Case #"<<t<<":"<<' ';
        solve();
        //cout<<'\n';
    }
    cerr << "Time : " << 1000 * ((double)clock()) / (double)CLOCKS_PER_SEC << "ms\n";
}