#include <bits/stdc++.h>
#include <unordered_map>
#define ll long long
#define mod 1000000007
#define vi vector<int>
#define F(i,n) for(int i = 0; i < n; i++)
#define scan(n) scanf("%d",&n)
#define pi 3.14159265359
using namespace std;
ll power(ll a, ll b) {
	if (b == 0)return 1;
	ll res = 1;
	while (b) {
		if (b & 1)res = res * a % mod;
		a = a * a % mod;
		b >>= 1;
	}
	return res;
}

unsigned ll mulmod(unsigned ll a, unsigned ll b, unsigned ll m) {
	a = a % m;
	unsigned ll res = 0;
	while (b > 0) {
		if (b & 1)res = (res + a) % m;
		a = (a << 1) % m;
		b >>= 1;
	}
	return res;
}

unsigned ll power(unsigned ll a, unsigned ll b, unsigned ll m) {
	if (b == 0)return 1;
	ll res = 1;
	while (b) {
		if (b & 1)res = mulmod(res, a, m);
		a = mulmod(a, a, m);
		b >>= 1;
	}
	return res;
}

ll gcd(ll a, ll b) {
	if (a == 0)return b;
	return gcd(b % a, a);
}

bool millerTest(unsigned ll n, unsigned ll d) {
	unsigned ll a = 2 + rand() % (n - 4);
	unsigned ll x = power(a, d, n);
	if (x == 1 || x == n - 1)return true;

	while (d != n - 1) {
		x = mulmod(x, x, n);
		d <<= 1;
		if (x == 1)return false;
		if (x == n - 1)return true;
	}
	return false;
}

bool isPrime(unsigned ll n, int k) {
	if (n == 2 || n == 3)return true;
	if ((n & 1) == 0)return false;
	if (n <= 1)return false;

	ll d = n - 1;
	while ((d & 1) == 0)d >>= 1;

	F(i, k)if (!millerTest(n, d))return false;
	return true;
}

const int maxMask = int(1 << 15) + 1;
int dp[226][3][maxMask], temp[226][3][maxMask];
int t[16], c[16];

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	int n, T;
	cin >> n >> T;
	for (int i = 1; i <= n; i++) cin >> t[i] >> c[i];

	int mask = (1 << n);

	vector<int> bits[16];
	for (int i = 0; i < mask; i++) {
		int counter = 0;
		for (int l = 1; l <= i; l *= 2)
			if (l & i) counter++;
		bits[counter].push_back(i);
	}

	temp[0][0][0] = temp[0][1][0] = temp[0][2][0] = 1;
	ll answer = 0;
	for (int i = 1; i <= n; i++) {
		for (int j = 0; j <= T; j++) {
			/*for (int g = 0; g < mask; g++) {
				int counter = 0;
				for (int l = 1; l <= g; l *= 2) {
					if (l & g) counter++;
				}
				if (counter != i) continue;

				for (int l = 1, index = 1; l <= g; l *= 2, index++) {
					if ((l & g) && t[index] <= j) {
						for (int s = 0; s < 3; s++)
							if (s != c[index] - 1) {
								dp[i][j][c[index] - 1][g] += dp[i - 1][j - t[index]][s][g ^ l];
								dp[i][j][c[index] - 1][g] %= mod;
							}
					}
				}
			}*/

			for (int g : bits[i]) {
				for (int l = 1, index = 1; l <= g; l *= 2, index++) {
					if ((l & g) && t[index] <= j) {
						for (int s = 0; s < 3; s++)
							if (s != c[index] - 1) {
								dp[j][c[index] - 1][g] += temp[j - t[index]][s][g ^ l];
								dp[j][c[index] - 1][g] %= mod;
							}
					}
				}
			}
		}

		memcpy(temp, dp, sizeof(dp));
		for (int g = 0; g < mask; g++)
			for (int s = 0; s < 3; s++)
				answer += dp[T][s][g];

		memset(dp, 0, sizeof(dp));
	}

	/*for (int j = 1; j <= n; j++)
		for (int i = 0; i < mask; i++)
			for (int s = 0; s < 3; s++)
				answer += dp[T][s][i];*/

	cout << (answer / 2) % mod;
}

#include <bits/stdc++.h>
using namespace std;

const int MAX_N = 15;
const int MAX_G = 3;
const int MAX_T = 255;
const int MOD = 1e9 + 7;
int n, m;
int memo[MAX_T + 1][MAX_G][(1<<15) + 1];
vector<int> gen, dur;

int f(int d = m, int lgen = 0, int mask = 0){
	if(d < 0) return 0;
	if(d == 0) return 1;
	if(__builtin_popcount(mask) == n) return 0;
	if(lgen)
	if(memo[d][lgen - 1][mask] != -1) return memo[d][lgen - 1][mask];
	int w = 0;
	for(int i = 0; i < n; i++){
		if(mask & 1<<i) continue;
		if(gen[i] == lgen) continue;
		mask = mask | 1<<i;
		w += f(d - dur[i], gen[i], mask);
		mask = mask ^ 1<<i;
		if(w >= MOD) w -= MOD;
	}
	if(lgen){
	memo[d][lgen - 1][mask] = w;
	return memo[d][lgen - 1][mask];
	}
	return w;
}
int main() {
//	cout << sizeof(memo) << '\n';
	memset(memo, -1, sizeof(memo));
	cin >> n >> m;
	gen = dur = vector<int> (n);
	for(int i = 0; i < n; i++){
		cin >> dur[i] >> gen[i];
	}
	cout << f() << "\n";
	return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
#define stop system("pause")
#define all(x) begin(x),end(x)
using ll = long long;using vi = vector<int>;
#define debug(v) cout<<#v<<":";cout<<v<<endl
using pii = pair<int, int>;const int MAXN = 2e5 + 10;
#define fast ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define rep(i, n) for (int i = 0, i##len = (int)(n); i < i##len; ++i)
#define rpp(i, n) for (int i = 1, i##len = (int)(n); i <= i##len; ++i)
template <typename T> istream& operator>>(istream &is,vector<T> &v) {for(auto i = begin(v); i != end(v); i++) is>>*i;return is;}
template <typename T> ostream& operator<<(ostream &os,const vector<T> &v) {for(auto i = begin(v);i!=end(v);i++) os<<*i<<(i==end(v)-1?"\n":" ");return os;}
//-----------------------------------------------------------------------------------------------------------------------------------------

//
//总共T时间，相邻歌曲类型不相同，有多少种组合方式
//n < 15
// dp[k][i]某状态
const int mod = 1e9 + 7;
int t[22],g[22];
int dp[MAXN][4];
signed main()
{
    int n,T;cin>>n>>T;
    rep(i,n) cin>>t[i]>>g[i];
    dp[0][0]=1;
    ll  cnt=0;
    for(int i = 0 ; i<(1<<n);++i)
    {
        for(int k=0;k<4;++k)
        {
            for(int j=0;j<n;++j)
            {
                if(((i & (1 << j)) == 0) && g[j]!=k)
                    dp[i|(1<<j)][g[j]] = (dp[i|(1<<j)][g[j]] + dp[i][k])%mod;
            }
            int sum = 0;
            for(int k = 0; k < n; k ++) if((i & (1 << k)) != 0) sum += t[k];
            if(sum == T)
            {
                cnt += dp[i][k];
                cnt %= mod;
            }
        }
    }
    cout<<cnt<<endl;
    return 0;
}

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod = 1e9+7;
const int maxn = (1<<15);

int dp[maxn][4], len[maxn];
int t[20], g[20];
int ans = 0;

int main() {
    std::ios::sync_with_stdio(false);
    int n, T;
    cin >> n >> T;
    for(int i = 0;  i < n; i++) {
        cin >> t[i] >> g[i];
    }
    for(int i = 1; i < (1<<n); i++) {
        for(int j = 0; j < n; j++) {
            if((i&(1<<j)) == 0)  continue;
            len[i] = len[i-(1<<j)] + t[j];
            if(i == (1<<j))  dp[i][g[j]] = 1;
            else {
                for(int k = 1; k < 4; k++) {
                    if(k == g[j])  continue;
                    dp[i][g[j]] += dp[i-(1<<j)][k];
                    dp[i][g[j]] %= mod;
                }
            }
        }
        if(len[i] == T)  {
            for(int k = 1; k < 4; k++)
                ans = (ans + dp[i][k])%mod;
        }
    }
    cout << ans << "\n";
    return 0;
}

#include<bits/stdc++.h>
using namespace std;

#define pb push_back
#define MOD 1000000007
#define mp make_pair
#define fi first
#define se second
#define ms(s, n) memset(s,n,sizeof(s))
#define FOR(i, a, b) for (ll i = (a); i < (b); i++)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); i--)

typedef long long ll;
typedef unsigned long long ull;
typedef vector<ll> vl;
typedef pair<ll,ll> pl;

ll fpow(ll n,ll k,ll p = MOD){ll r=1;for(;k;k>>=1){if(k&1)r=r*n%p;n=n*n%p;}return r;}
ll inv(ll a,ll p=MOD){return fpow(a,p-2,p);}
ll Sqrt(ll x){if(x==0 || x==1)return x;ll start=1,end=x,ans;while(start<=end){ll mid=(start+end)/2;if(mid*mid==x)return mid;if(mid*mid<x){start=mid+1;ans=mid;}else end=mid-1;}return ans;}
ll power(ll x,ll y){if (y==0)return 1;else if (y%2==0)return power(x,y/2)*power(x,y/2);else return x*power(x,y/2)*power(x,y/2);}
ll gcd(ll a,ll b){ll r;while(b){r=a%b;a=b; b=r;} return a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
void in(ll &no){bool neg=false;register ll c;no=0;c=getchar();if(c=='-'){neg=true;c=getchar();}for(;(c>47&&c<58);c=getchar())no=no*10+c-48;if(neg)no*=-1;}
ll dp[16][16][16][4];

ll find_ans(ll g1,ll g2,ll g3, ll prev){
    ll ans=0;
    if(g1==0 && g2==0 && g3==0)
        return 1;
    if(dp[g1][g2][g3][prev]==-1){
        if(prev!=1 && g1>0){
            ans=(ans + g1*find_ans(g1-1,g2,g3,1))%MOD;
        }
        if(prev!=2 && g2>0){
            ans=(ans + g2*find_ans(g1,g2-1,g3,2))%MOD;
        }
        if(prev!=3 && g3>0){
            ans=(ans + g3*find_ans(g1,g2,g3-1,3))%MOD;
        }
        dp[g1][g2][g3][prev]=ans;
    }
    return dp[g1][g2][g3][prev];
}

int main()
{
	int t,n,i,j;
	cin>>n>>t;
	int a[n][2];
	FOR(i,0,n)cin>>a[i][0]>>a[i][1];
	ll x = 1<<n;
	ll ans = 0;
	ms(dp,-1);
	FOR(i,0,x)
	{
		ll s = 0;
		int genre[4] = {0};
		FOR(j,0,n)
		{
			if(i & (1<<j))
			{
				s += a[j][0];
				genre[a[j][1]]++;
			}
			// cout<<i<<" "<<s<<endl;
		}
		if(s == t)
		{
			// cout<<i<<endl;
			ans = (ans + find_ans(genre[1], genre[2], genre[3],0)%MOD)%MOD;
		}
	}
	cout<<ans;
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
#define IL inline
#define rep(i,j,k) for(int i=j;i<=k;++i)
#define repd(i,j,k) for(int i=j;i>=k;--i)
#define pb push_back
#define db double
#define mp make_pair
#define mp3(a,b,c) mp(mp(a,b),c)
#define pii pair<int,int>
#define piii pair<pii,int>
#define fr first
#define se second
#define ll long long
#define ull unsigned long long
#define pbc(x) __builtin_popcount(x)
#define clr(x) memset(x,0,sizeof x)
#define SIZE(x) (int)(x.size())
const int mod=1e9+7;
IL int pls(int x,int y){x+=y;return x>=mod?x-mod:x;}
IL int dec(int x,int y){x-=y;return x<0?x+mod:x;}
IL int mul(int x,int y){return 1ll*x*y%mod;}
IL int mul(int x,int y,int z){return mul(mul(x,y),z);}
IL int mul(int x,int y,int z,int p){return mul(mul(x,y),mul(z,p));}
IL void add(int &x,int y){x+=y;x=(x>=mod)?x-mod:x;}
IL int fpw(int x,int y,int r=1){for(;y;y>>=1,x=mul(x,x))if(y&1)r=mul(r,x);return r;}
IL int inv(int x){return fpw(x,mod-2);}
IL int gi(){int x;int _w=scanf("%d",&x);return x;}
IL void gi(int &x){int _w=scanf("%d",&x);}
IL void write(int x){printf("%d\n",x);}
void chkmax(int &x,int y){x=(x>y)?x:y;}
void chkmin(int &x,int y){x=(x<y)?x:y;}
const int INF=0x3f3f3f3f;
template<typename T>IL void debug(T x){cerr<<x;return;}
/* --------------------------------------------------------------------------------------------------------- */
const int maxn=16;
int n,T;
int x[maxn],y[maxn];
int f[1<<(15)][250][3],ifac[20];
map<pii,int>qwq;
int main(){
	n=gi(),T=gi();
	ifac[0]=1;int tot=1;
	rep(i,1,n)tot=mul(tot,i),ifac[i]=inv(tot);
	rep(i,1,n){
		x[i]=gi(),y[i]=gi();
	}
	rep(i,1,n){
		f[1<<i-1][x[i]][y[i]]=1;
	}
	for(int i=1;i<(1<<n);++i){
		for(int j=0;j<=T;++j){
			rep(k,1,3)if(f[i][j][k]){
				for(int r=1;r<=n;++r){
					if(!(i&(1<<r-1))&&y[r]!=k){
						f[i|(1<<r-1)][j+x[r]][y[r]]
						=pls(f[i|(1<<r-1)][j+x[r]][y[r]],f[i][j][k]);
					}
				}
			}
		}
	}
	int ans=0;
	for(int i=1;i<(1<<n);++i){
		rep(k,1,3)
		ans=pls(ans,f[i][T][k]);
	}
	cout<<ans<<endl;
	return 0;
}

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;

typedef long long LL;
const LL mod=1e9+7;
vector<int> num[3];
LL dp[3][2505][55],fac[55];
bool have[3][2505];
LL C[3][55][55][55];
bool done[3][55][55][55];
int N,T;
LL cal(int t,int i,int j,int k)
{
	if(done[t][i][j][k])
		return C[t][i][j][k];
	done[t][i][j][k]=1;
	LL& ans=C[t][i][j][k];
	if(t==0){
		if(i==0)
			return ans=0;
		return ans=(cal(1,i-1,j,k)+cal(2,i-1,j,k))%mod;
	}
	if(t==1){
		if(j==0)
			return ans=0;
		return ans=(cal(0,i,j-1,k)+cal(2,i,j-1,k))%mod;
	}
	if(t==2){
		if(k==0)
			return ans=0;
		return ans=(cal(0,i,j,k-1)+cal(1,i,j,k-1))%mod;
	}
}
LL solve(int a,int b,int c)
{
	if(!(have[0][a]&&have[1][b]&&have[2][c]))
		return 0;
	LL re=0;
	for(int i=0;i<=num[0].size();i++){
		if(!dp[0][a][i])
			continue;
		for(int j=0;j<=num[1].size();j++){
			if(!dp[1][b][j])
				continue;
			for(int k=0;k<=num[2].size();k++){
				if(!dp[2][c][k])
					continue;
				LL tem=0;
				tem=(tem+cal(0,i,j,k))%mod;
				tem=(tem+cal(1,i,j,k))%mod;
				tem=(tem+cal(2,i,j,k))%mod;
				tem=tem*fac[i]%mod;
				tem=tem*fac[j]%mod;
				tem=tem*fac[k]%mod;
				tem=tem*dp[0][a][i]%mod;
				tem=tem*dp[1][b][j]%mod;
				tem=tem*dp[2][c][k]%mod;
				re=(re+tem)%mod;
			}
		}
	}
	return re;
}
void DP(int x)
{
	have[x][0]=1;
	dp[x][0][0]=1;
	for(int i=0;i<num[x].size();i++){
		for(int j=T;j>=num[x][i];j--){
			int t=num[x][i];
			if(have[x][j-t]){
				for(int k=1;k<=i+1;k++){
					dp[x][j][k]=(dp[x][j][k]+dp[x][j-t][k-1])%mod;
				}
				have[x][j]=1;
			}
		}
	}
}
void init()
{
	C[0][1][0][0]=C[1][0][1][0]=C[2][0][0][1]=1;
	done[0][1][0][0]=done[1][0][1][0]=done[2][0][0][1]=1;
	fac[0]=fac[1]=1;
	for(int i=2;i<=50;i++){
		fac[i]=i*fac[i-1]%mod;
	}
}
int main()
{
	init();
	scanf("%d%d",&N,&T);
	for(int i=0;i<N;i++){
		int t1,t2;
		scanf("%d%d",&t1,&t2);
		num[t2-1].push_back(t1);
	}
	for(int i=0;i<3;i++){
		DP(i);
	}
	LL ans=0;
	for(int i=0;i<=T;i++){
		for(int j=0;j<=T;j++){
			if(i+j>T)
				break;
			int k=T-i-j;
			ans+=solve(i,j,k);
			ans%=mod;
		}
	}
	printf("%I64d\n",ans);
}

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <map>
#include <deque>
#include <set>
#include <list>
#include <unordered_set>
#include <unordered_map>
#include <bitset>
#include <climits>
#include <cmath>
#include <functional>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

ll gcd(ll a, ll b)
{
	for (; b; a %= b, swap(a, b));
	return a;
}

const int MOD = 1000000007;
int n, T;
vector <pii> songs;
ll dp[15][(1 << 15) + 101];

int c;

ll solve(int start, int st, int len)
{
	ll& ret = dp[start][st];
	if (ret != -1) return ret;
	ret = 0;

	if (len == T) return ret = 1;

	for (int i = 0; i < n; i++)
	{
		if ((st & (1 << i)) == 0)
		{
			pii song = songs[i];
			if (song.second != songs[start].second)
			{
				if (len + song.first <= T)
					ret += solve(i, st | (1 << i), len + song.first), ret %= MOD;
			}
		}
	}

	return ret;
}

int main()
{
	memset(dp, -1, sizeof dp);
	scanf("%d%d", &n, &T);
	for (int i = 0; i < n; i++)
	{
		int t, g;
		scanf("%d%d", &t, &g);
		songs.push_back({ t,g });
	}

	ll ans = 0;
	for (int i = 0; i < n; i++)
	{
		c = songs[i].second;
		ans += solve(i, 1 << i, songs[i].first);
		ans %= MOD;
	}

	printf("%lld", ans);
}

#include<bits/stdc++.h>
using namespace std;
#define int long long int
#define double long double
#define pb push_back
#define endl '\n'
#define all(x) (x).begin(),(x).end()
#define F first
#define S second
#define sz(a) (int)((a).size())
#define fuck() cout<<"--------"<<endl
#define see(x) cout<<#x<<" = "<<x<<endl
#define see2(x,y) cout<<#x<<" = "<<x<<"::"<<#y<<" = "<<y<<endl
const int mod=1000000007;
typedef pair<int,int> pii;
const int maxn=1e5+5;
int n,T;
int t[16],g[16];
int dp[226][(1<<15)+10][3];
int go(int idx,int mask,int prev){
	if(idx==T)return 1;
	if(idx>T)return 0;
	int &ans=dp[idx][mask][prev];
	if(ans!=-1)return ans;
	ans=0;
	for(int i=0;i<n;i++){
		if(!(mask&(1<<i))){
			if(idx==0)ans+=go(idx+t[i],mask|(1<<i),g[i]);
			else if(g[i]!=prev)ans+=go(idx+t[i],mask|(1<<i),g[i]);
			ans%=mod;
		}
	}
	return ans;
}
int32_t main()
{
	ios_base::sync_with_stdio(0); cin.tie(0);cout.tie(0);
	memset(dp,-1,sizeof(dp));
	cin>>n>>T;
	for(int i=0;i<n;i++){
		cin>>t[i]>>g[i];
		g[i]--;
	}
	cout<<go(0,0,0);
}

#include<iostream>
#include<cstring>
using namespace std;

#define m 1000000007;
int a[16];
int b[16];
int dp[226][40000][4];
 int n,sum;
int music(int sum,int mask,int last){

   if(sum==0){

       return 1;
   }

   if(sum<0){
       return 0;
   }

   if(mask==((1<<n)-1)){
       return 0;
   }
 if(dp[sum][mask][last]!=-1){
       return dp[sum][mask][last];
   }
   int q=0;

    for(int i=0;i<n;i++){
        if((mask&(1<<i))==0 && b[i]!=last){
            mask|=(1<<i);
            //cout<<mask<<endl;
            q+=music(sum-a[i],mask,b[i]);
            q=q%m;
            mask=mask^(1<<i);
        }
    }
    dp[sum][mask][last]=q;

    return q;
}

int main(){

    cin>>n>>sum;
    for(int i=0;i<n;i++){
        cin>>a[i];
        cin>>b[i];
    }
    memset(dp,-1,sizeof(dp));
    int mask=0;
    cout<<music(sum,mask,-1);

}

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define mes(a,b) memset((a),(b),sizeof((a)))
#define syio std::ios::sync_with_stdio(false); std::cin.tie(0); std::cout.tie(0);
#define lson l, mid, rt << 1
#define rson mid+1, r, rt << 1 | 1
#define lowbit(a) ((a)&-(a))
#define pb(a) push_back((a))
#define mkp(x, y) make_pair((x), (y))
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
typedef __int64 ll;
typedef long double real;
typedef unsigned long long ull;
typedef pair<int, int> pii;

const int oo = ~0u >> 2;
const double pi = acos(-1.0);
const double eps = 1e-8;
const int mxn = 100033;
const int mod = 1e9 + 7;//998244353
inline int read(){
    int x = 0,f = 1;char c = getchar();
    while(!isdigit(c))f = c == '-' ? -1 : 1,c = getchar();
    while(isdigit(c))x = x * 10 + c - '0',c = getchar();
    return x * f;
}
int dx[] = {0 , 1, 0 , -1};
int dy[] = {1 , 0, -1 , 0};
int n, ts;
ll t[30], g[30], dp[1<<18][5];
int main()
{
    syio;
    cin>>n>>ts;
    for (int i = 1; i <= n; ++ i) cin>>t[i]>>g[i];
    dp[0][0] = 1;
    for (int i = 0; i < (1 << n); ++ i)
    for (int j = 0; j <= 3; ++ j)
    for(int k = 1; k <= n; ++ k)
    {
        if (i & (1 << k - 1) || g[k] == j) continue;
        dp[i | (1 << k - 1)][g[k]] = (dp[i | (1 << k - 1)][g[k]] + dp[i][j])%mod;
    }

    ll res = 0;
    for (int i = 1; i < (1 << n); ++ i)
    {
        ll ct = 0;
        for (int j = 1; j <= n; ++ j)
        if (i & (1 << j - 1)) ct += t[j];

        if (ct == ts)
        res = (res + dp[i][1] + dp[i][2] + dp[i][3])%mod;
    }
    cout<<res<<endl;
    return 0;
}

#include <bits/stdc++.h>

using namespace std;
typedef long long INT;
typedef double DO;
typedef pair<int, int> pii;
typedef vector<int> VI;

#define x first
#define y second
#define pb push_back

int power(int a, int b, int c, int ans=1) {
	for (; b; b>>=1, a=(INT)a*a%c) if (b&1) ans=(INT)ans*a%c;
	return ans;
}

#define bit(x, y) (((x)>>(y))&1)

const int NN = 16;

int dp[1<<NN][NN], t[NN], g[NN];
int sum[1<<NN];
const int mod = 1000000007;

void add(int &x, const int &y) {
	x+=y;
	if (x>=mod) x-=mod;
}

int main() {
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif

	int n, T, ans=0;
	cin>>n>>T;
	for (int i=0; i<n; i++) scanf("%d%d", t+i, g+i);
	for (int i=1; i<1<<n; i++) {
		sum[i]=sum[i^(i&-i)]+t[__builtin_ctz(i)];
		if (__builtin_popcount(i)==1) {
			int u=__builtin_ctz(i);
			dp[i][u]=1;
			continue;
		}
		for (int j=0; j<n; j++) if (bit(i, j)) {
			int u=i^(1<<j);
			for (int k=0; k<n; k++) if (bit(u, k)) {
				if (g[j]!=g[k]) add(dp[i][j], dp[u][k]);
			}
		}
	}
	for (int i=0; i<1<<n; i++) if (sum[i]==T) for (int j=0; j<n; j++) if (bit(i, j)) add(ans, dp[i][j]);
	cout << ans << endl;

	return 0;
}

#define bug(x) cout<<#x<<" is "<<x<<endl
#define IO std::ios::sync_with_stdio(0)
#include <bits/stdc++.h>
#define iter ::iterator
//#define pa pair<int,int>
using namespace  std;
#define ll long long
#define mk make_pair
#define pb push_back
#define se second
#define fi first
#define ls o<<1
#define rs o<<1|1
ll mod=1e9+7;
const int inf=2e9+10;
const int N=(1<<15)+5;
int n,T;
ll d[N][4];
int t[20],g[20];
ll cal(ll x,ll y){
	ll res=1;
	while(y){
		if(y&1)res=res*x%mod;
		x=x*x%mod;
		y>>=1;
	}
	return res;
}
int main(){
	IO;
	cin>>n>>T;
	for(int i=0;i<n;i++){
		cin>>t[i]>>g[i];
	}
	int mx=(1<<n);
	//d[0][1]=d[0][2]=d[0][3]=1;
	d[0][0]=1;
	for(int s=0;s<mx;s++){
		for(int i=0;i<=3;i++){
			for(int j=0;j<n;j++){
				if(!((s>>j)&1)){
					if(g[j]!=i){
						int ns=s^(1<<j);
						d[ns][g[j]]=(d[ns][g[j]]+d[s][i])%mod;
						//printf("ns=%d d=%d\n",ns,d[ns][g[j]]);
					}
				}
			}
		}
	}
	ll ans=0;
	for(int s=0;s<mx;s++){
		int x=s;
		int h=0;
		int res=0;
		while(x){
			if(x&1)res+=t[h];
			x>>=1;
			h++;
		}
		if(res==T){
			for(int j=1;j<=3;j++){
				//printf("s=%d d=%d\n",s,d[s][j]);
				ans=(ans+d[s][j])%mod;
			}
		}
	}
	cout<<ans<<endl;
}

/*
🧡 QMsh 🧡
*/

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

const int MOD = (int)1e9 + 7;
const int L = 55;

int hdp[L][L][L][4];

int ml(int a, int b)
{
    return (ll)a * b % MOD;
}

void pl(int &a, int b)
{
    a = (a + b) % MOD;
}

signed main()
{
#ifdef POSPELOV
    freopen("in", "r", stdin);
    freopen("out", "w", stdout);
#endif
    ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);

    hdp[0][0][0][3] = 1;
    for (int i = 0; i < L - 1; i++)
    {
        for (int j = 0; j < L - 1; j++)
        {
            for (int k = 0; k < L - 1; k++)
            {
                if (i + j + k == 0)
                {
                    pl(hdp[i + 1][j][k][0], hdp[i][j][k][3]);
                    pl(hdp[i][j + 1][k][1], hdp[i][j][k][3]);
                    pl(hdp[i][j][k + 1][2], hdp[i][j][k][3]);
                }
                else
                {
                    for (int l = 0; l < 3; l++)
                    {
                        if (l == 0)
                        {
                            pl(hdp[i][j + 1][k][1], ml(hdp[i][j][k][0], j + 1));
                            pl(hdp[i][j][k + 1][2], ml(hdp[i][j][k][0], k + 1));
                        }
                        else if (l == 1)
                        {
                            pl(hdp[i + 1][j][k][0], ml(hdp[i][j][k][1], i + 1));
                            pl(hdp[i][j][k + 1][2], ml(hdp[i][j][k][1], k + 1));
                        }
                        else
                        {
                            pl(hdp[i + 1][j][k][0], ml(hdp[i][j][k][2], i + 1));
                            pl(hdp[i][j + 1][k][1], ml(hdp[i][j][k][2], j + 1));
                        }
                    }
                }
            }
        }
    }

    int n, t;
    cin >> n >> t;
    vector <pair <int, int>> arr(n);
    int g[3] = {0, 0, 0};
    for (auto &i : arr)
    {
        cin >> i.first >> i.second;
        i.second--;
        g[i.second]++;
    }
    vector <vector <vector <vector <int>>>> dp(t + 1, vector <vector <vector <int>>> (g[0] + 1, vector <vector <int>> (g[1] + 1, vector <int> (g[2] + 1)))), old;
    old = dp;
    old[0][0][0][0] = 1;
    for (int i = 0; i < n; i++)
    {
        dp[0][0][0][0] = 1;
        for (int j = 0; j < t; j++)
        {
            for (int k1 = 0; k1 <= g[0]; k1++)
            {
                for (int k2 = 0; k2 <= g[1]; k2++)
                {
                    for (int k3 = 0; k3 <= g[2]; k3++)
                    {
                        if (j + arr[i].first > t || !old[j][k1][k2][k3])
                            continue;

                        if (arr[i].second == 0)
                            pl(dp[j + arr[i].first][k1 + 1][k2][k3], old[j][k1][k2][k3]);
                        else if (arr[i].second == 1)
                            pl(dp[j + arr[i].first][k1][k2 + 1][k3], old[j][k1][k2][k3]);
                        else
                            pl(dp[j + arr[i].first][k1][k2][k3 + 1], old[j][k1][k2][k3]);
                    }
                }
            }
        }
        old = dp;
        dp.resize(t + 1, vector <vector <vector <int>>> (g[0], vector <vector <int>> (g[1], vector <int> (g[2]))));
    }

    int ans = 0;

    for (int k1 = 0; k1 <= g[0]; k1++)
    {
        for (int k2 = 0; k2 <= g[1]; k2++)
        {
            for (int k3 = 0; k3 <= g[2]; k3++)
            {
                int add = ml(old[t][k1][k2][k3], ((ll)hdp[k1][k2][k3][0] + hdp[k1][k2][k3][1] + hdp[k1][k2][k3][2]) % MOD);
/*                    if (add || k1 == 2 && k2 == 1)
                    cout << k1 << " " << k2 << " " << k3 << "\n" << old[t][k1][k2][k3] << " * " << ((ll)hdp[k1][k2][k3][0] + hdp[k1][k2][k3][1] + hdp[k1][k2][k3][2]) % MOD << " = " << add << "\n_____\n";
*/                    pl(ans, add);
            }
        }
    }
    cout << ans;

    return 0;
}

#include <bits/stdc++.h>
#define INT long long
#define oo 987654321
#define OO 9999999987654321
#define MOD 998244353
#define mod 1000000007
using namespace std;
int n, T, t[20], g[20], dt[226][3][1<<15];
int dp(int x, int y, int z, int s)
{
    if( y == T ) return 1;
    if( x == n ) return 0;
    if( ~dt[y][z][s] ) return dt[y][z][s];
    int &ret = dt[y][z][s] = 0;
    for(int i = 0 ; i < n ; i++ )
    {
        if( (s&(1<<i)) == 0 )
        {
            if( g[i] != z )
                ret += dp(x+1, y+t[i], g[i], s|(1<<i)), ret%=mod;
        }
    }
    return ret;
}
int main()
{
    ios::sync_with_stdio(false);
    memset(dt, -1, sizeof(dt));
    cin>>n>>T;
    for(int i = 0 ; i < n ; i++ ) cin>>t[i]>>g[i];
    cout<<dp(0, 0, 0, 0);
}

#include <bits/stdc++.h>
using namespace std;

#define     ll      long long int

struct data
{
    int t, g;
};

data song[15];

int dp[32769][4][256];

const int mod = 1e9 + 7;
int T, n;

ll solve(int st, int gen, int time)
{
    if (time == T)                  return 1;
    if (dp[st][gen][time] != -1)    return dp[st][gen][time];
    ll res = 0;
    for (int i = 0; i < n; i++)
    {
        if ( (st & (1 << i)) == 0 )
        {
            if (time + song[i].t <= T && song[i].g != gen)
            {
                res += solve( (st | (1 << i)), song[i].g, time + song[i].t );
                if (res >= mod) res -= mod;
            }
        }
    }
    dp[st][gen][time] = res;
    return res;
}

int main( )
{
    memset(dp, -1, sizeof dp);
    cin >> n >> T;
    for (int i = 0; i < n; i++)
    {
        cin >> song[i].t >> song[i].g;
        song[i].g;
    }
    cout << solve(0, 0, 0) << "\n";
    return 0;
}

#include<bits/stdc++.h>
using namespace std;
#define ll int
#define ld long double
#define rep(i,a,b) for(ll i=a;i<b;i+=1)
#define all(c) (c).begin(),(c).end()
#define pb push_back
#define sz(a) int((a).size())
#define hell (ll)1000000007
#define f first
#define s second
#define sll(x) scanf("%lld",&x)
#define sd(x) scanf("%lld",&x)
ll t = 1 , n ;
ll dp[4][226][(1LL<<15)+5] ;
vector<ll> tim(18) , genre(19) ;
inline int add( int x , int y ){x += y ;return x % hell ;}
inline int mult( int x , int y ){ return (x * 1LL * y ) % hell ; }
inline int powMod( ll base , ll expo ){
    int ans = 1 ;
    while( expo ){
        if( expo&1 ){
            ans = mult(ans,base);
        }
        base=mult(base,base);
        expo>>=1;
    }
    return ans;
}
ll boom( ll mask , ll g , ll T ){
    if( T == 0 )
        return 1 ;
    if( dp[g][T][mask] != -1 )return dp[g][T][mask] ;
    ll ans = 0 ;
    rep( i , 0 , n ){
        if( (mask>>i)&1 || tim[i] > T || g == genre[i] )continue;
        ans=add(ans,boom((mask|(1<<i)),genre[i],T-tim[i]));
    }
    return dp[g][T][mask] = ans;
}
void solve()
{
    ll T ;
    cin >> n >> T ;
    rep( i , 0 , n ){
        cin >> tim[i] >> genre[i] ;
    }
    memset(dp,-1,sizeof(dp));
    cout << boom(0,0,T);
}
signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    //cin>>t;
    while(t--)
        solve() ;
    return 0 ;
}

#include <bits/stdc++.h>
#define pb push_back

using namespace std;

void debug_out() { cerr << '\n'; }
template <typename Head, typename... Tail> void debug_out(Head H, Tail... T) { cerr << " " << H; debug_out(T...);}
#define dbg(...) cerr << #__VA_ARGS__ << " ->", debug_out(__VA_ARGS__)
#define dbg_v(x, n) do{cerr<<#x"[]: ";for(int _=0;_<n;++_)cerr<<x[_]<<" ";cerr<<'\n';}while(0)
#define dbg_ok cerr<<"OK!\n"

typedef pair<int,int> pii;
typedef long long int ll;
typedef long double ld;

inline int two(int n) { return 1 << n; }
inline int test(int n, int pos) { return (bool) (n & two(pos)); }
inline void set_bit(int &n, int b) { n |= two(b); }
inline void unset_bit(int &n, int b) { n &= ~two(b); }
inline int last_bit(int n) { return n & (-n); }

const int DMAX = 18;
const int LgMAX = 32800;
const int MOD = 1e9+7;

vector <int> vec;
vector <int> arb[DMAX];

pii V[DMAX];
int tme[LgMAX];

pii dp[LgMAX][DMAX];

int n,maxim;

ll ans;

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int t,i,k;
    int mask,mask2;

    cin>>n>>t;
    for(i=0;i<n;i++){
        cin>>V[i].first>>V[i].second;
    }
    for(i=0;i<n;i++){
        dp[1<<i][i].first=V[i].first;
        dp[1<<i][i].second=1;
    }
    for(mask=1;mask<(1<<n);mask++)
        for(i=0;i<n;i++)
            if(mask & (1<<i)){
                mask2=mask-(1<<i);
                for(k=0;k<n;k++)
                    if((mask2 & (1<<k))&&(V[i].second != V[k].second)&&dp[mask2][k].first){
                        dp[mask][i].first=dp[mask2][k].first+V[i].first;
                        dp[mask][i].second+=dp[mask2][k].second;
                    }
                 if(dp[mask][i].first == t){
                    ans+=dp[mask][i].second;
                    if(ans > MOD)
                       ans-=MOD;
                }
            }
    cout<<ans<<'\n';
    return 0;
}

// Versiunea in O(9 * 2^N * N)

#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;

using VI  = vector<int>;
using VVI = vector<VI>;
using VB  = vector<bool>;
const int Mod = 1000000007;
const int MaxN = 52;
const int MaxT = 2505;

int N, T;
VI time, type;
int a[MaxT][MaxN];
int bc[MaxT][MaxN][MaxN];
int ways[MaxN][MaxN][MaxN][3];

void ReadData();
void Solve();
void Increase(int& v1, int v2);

int main()
{
    ReadData();
    Solve();

    return 0;
}

void ReadData()
{
    cin >> N >> T;

    type = time = VI(N);
    for (int i = 0; i < N; ++i)
    {
        cin >> time[i] >> type[i];
        --type[i];
    }
}

void Solve()
{
    int res{0}, ct[3] = {0}, cnt[3] = {0};

    a[0][0] = 1;
    bc[0][0][0] = 1;
    for (int i = 0; i < N; ++i)
    {
        if (type[i] == 0)
        {
            for (int t = ct[0]; t >= 0; --t)
                for (int t0 = cnt[0]; t0 >= 0; --t0)
                    Increase(a[t + time[i]][t0 + 1], a[t][t0]);
        }
        else
        {
            for (int t = ct[1] + ct[2]; t >= 0; --t)
                for (int t1 = cnt[1]; t1 >= 0; --t1)
                    for (int t2 = cnt[2]; t2 >= 0; --t2)
                        Increase(bc[t + time[i]][t1 + (type[i] == 1)][t2 + (type[i] == 2)], bc[t][t1][t2]);
        }

        ct[type[i]] += time[i];
        ++cnt[type[i]];
    }

    ways[1][0][0][0] = ways[0][1][0][1] = ways[0][0][1][2] = 1;
    for (int t0 = 0; t0 <= cnt[0]; ++t0)
        for (int t1 = 0; t1 <= cnt[1]; ++t1)
            for (int t2 = 0; t2 <= cnt[2]; ++t2)
                for (int last = 0; last < 3; ++last)
                {
                    if (t0 + t1 + t2 <= 1)
                        continue;
                    if (!t0 && last == 0)
                        continue;
                    if (!t1 && last == 1)
                        continue;
                    if (!t2 && last == 2)
                        continue;

                    for (int prevLast = 0; prevLast < 3; ++prevLast)
                    {
                        if (last == prevLast)
                            continue;

                        if (last == 0)
                            Increase(ways[t0][t1][t2][last],
                                      (1LL * ways[t0 - 1][t1][t2][prevLast] * t0) % Mod);

                        if (last == 1)
                            Increase(ways[t0][t1][t2][last],
                                      (1LL * ways[t0][t1 - 1][t2][prevLast] * t1) % Mod);

                        if (last == 2)
                            Increase(ways[t0][t1][t2][last],
                                      (1LL * ways[t0][t1][t2 - 1][prevLast] * t2) % Mod);
                    }
                }

    int t[3];
    for (t[0] = 0; t[0] <= cnt[0]; ++t[0])
        for (int dur0 = 0; dur0 <= min(T, ct[0]); ++dur0)
            for (t[1] = 0; t[1] <= cnt[1]; ++t[1])
                for (t[2] = 0; t[2] <= cnt[2]; ++t[2])
                {
                    int dur12 = T - dur0;

                    Increase(res, (((1LL * (ways[t[0]][t[1]][t[2]][0]
                                + ways[t[0]][t[1]][t[2]][1]
                                + ways[t[0]][t[1]][t[2]][2])
                                * a[dur0][t[0]]) % Mod)
                                * bc[dur12][t[1]][t[2]]) % Mod);
                }

    cout << res << '\n';
}

void Increase(int& v1, int v2)
{
    v1 = (v1 + v2) % Mod;
}

# include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;

# define F first
# define S second
# define endl '\n'
# define sep ' '
# define pb push_back
# define fast_io ios::sync_with_stdio(0);cin.tie(0); cout.tie(0);

const ll md = 1e9 + 7;
const int xn = 1e2 + 10;
const int xm = 1e5 + 10;
const int SQ = 320;
const int sq = 1e3 + 10;
const ll inf = 1e18 + 10;

ll power(ll a, ll b) {return (!b ? 1 : (b & 1 ? a * power(a * a % md, b / 2) % md : power(a * a % md, b / 2) % md));}
ll zarb(ll a, ll b){return (a * b + 10 * md) % md;}
ll jaam(ll a, ll b){return (a + b + 10 * md) % md;}

ll n, T, a[xn], b[xn], dp[xn][xn][xn][3], sum, ted[3], ans;
vector <int> vec;

void check(int x){
	vec.clear();
	for (int i = 0; i < n; i ++)
		if (x&(1 << i)) vec.push_back(i);
	sum = 0;
	for (int v : vec) sum += a[v];
	if (sum != T) return;
	memset(ted, 0, sizeof ted);
	for (int v : vec) ted[b[v] - 1] ++;
	ans = jaam(ans, dp[ted[0]][ted[1]][ted[2]][0]);
	ans = jaam(ans, dp[ted[0]][ted[1]][ted[2]][1]);
	ans = jaam(ans, dp[ted[0]][ted[1]][ted[2]][2]);
}

int main(){
	fast_io;

	cin >> n >> T;
	for (int i = 0; i < n; i ++) cin >> a[i] >> b[i];

	dp[1][0][0][0] = 1;
	dp[0][1][0][1] = 1;
	dp[0][0][1][2] = 1;
	for (ll i = 0; i <= 50; i ++){
		for (ll j = 0; j <= 50; j ++){
			for (ll k = 0; k <= 50; k ++){
				if (i + j + k < 2) continue;
				for (ll p = 0; p < 3; p ++){
					if (p == 0){
						if (!i) continue;
						dp[i][j][k][p] += zarb(i, dp[i - 1][j][k][1]);
						dp[i][j][k][p] += zarb(i, dp[i - 1][j][k][2]);
					}
					else if (p == 1){
						if (!j) continue;
						dp[i][j][k][p] += zarb(j, dp[i][j - 1][k][0]);
						dp[i][j][k][p] += zarb(j, dp[i][j - 1][k][2]);
					}
					else{
						if (!k) continue;
						dp[i][j][k][p] += zarb(k, dp[i][j][k - 1][0]);
						dp[i][j][k][p] += zarb(k, dp[i][j][k - 1][1]);
					}
				}
			}
		}
	}
	for (int i = 0; i < pow(2, n); i ++) check(i);
	cout << ans << endl;
	return 0;
}

#include <iostream>
#include <bits/stdc++.h>

using namespace std;
int n,t;
int DP[1<<15][226][4];
pair <int,int> arr[15];
long long solve(int mask,int timeleft,int prev)
{   long long c=0;
    if(DP[mask][timeleft][prev]!=-1)
        return DP[mask][timeleft][prev];
    if(timeleft==0)
        return 1;
    for (int i=0; i<n; i++)
    {
        if((!(mask&(1<<i)))||prev==arr[i].second||timeleft-arr[i].first<0)
            continue;
        c+=(solve(mask^(1<<i),timeleft-arr[i].first,arr[i].second))%1000000007;
    }
        return DP[mask][timeleft][prev]=c%1000000007;
}

int main()
{
    cin >> n >> t;
    for(int i=0;i<(1<<n);i++)
        for (int j=0;j<226;j++)
            for(int k=0;k<4;k++)
                DP[i][j][k]=-1;
    for(int i=0;i<n;i++)
        cin >> arr[i].first >> arr[i].second;
    cout << solve((1<<n)-1,t,0);

}

#include "bits/stdc++.h"
using namespace std;
#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifdef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
    *this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "

using ll = long long;
using ii = pair<int,int>;
using vi = vector<int>;
using vii = vector<ii>;
const int oo = 1e9+7;
const int mod = 1e9+7;

int dp[(1<<16)][3]; //mask and last song
vector<int> genres;
vector<int> durations;
int t, n;

int solve(int mask, int lastGenre) {
    int minute = 0;

    if(lastGenre != -1 && dp[mask][lastGenre] != -1) {
        return dp[mask][lastGenre];
    }

    for(int i = 0; i < n; ++i) {
        if(mask & (1 << i)) {
            minute += durations[i];
        }
    }

    if(minute == t) {
        if(lastGenre != -1) dp[mask][lastGenre] = 1;
        return 1;
    } else if(minute > t) {
        if(lastGenre != -1) dp[mask][lastGenre] = 0;
        return 0;
    }

    int ans = 0;

    for(int i = 0; i < n; ++i) {
        if(!(mask & (1 << i)) && genres[i] != lastGenre && durations[i]+minute <= t) {
            ans += solve(mask ^ (1 << i), genres[i]);
            ans %= mod;
        }
    }

    if(lastGenre != -1) dp[mask][lastGenre] = ans;
    return ans;
}

int main() {

    cin >> n >> t;

    memset(dp, -1, sizeof dp);
    genres.resize(n);
    durations.resize(n);

    for(int i = 0; i < n; ++i) {
        int d, g;
        cin >> d >> g;
        durations[i] = d;
        genres[i] = g-1;
    }

    int ans = solve(0, -1);

    cout << ans << endl;

    return 0;
}

#include <bits/stdc++.h>
#include <math.h>
using namespace std;
typedef long long int lli;
typedef unsigned long long int uli;
typedef long double Lf;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define fastIO  std::ios::sync_with_stdio(false);cin.tie(NULL)
#define mod 1000000007
#define N 2005
#define NN 2005
#define SZ(x) ((lli) (x).size())
#define loop(i,s,n) for(int i=(s);i<(n);i++)
#define loopr(i,n,s) for(int i=(n)-1;i>=(s);i--)
#define pb push_back
#define o2(a,b) cout<<(a)<<" "<<(b)<<endl
#define o3(a,b,c) cout<<(a)<<" "<<(b)<<" "<<(c)<<endl
#define o4(a,b,c,d) cout<<(a)<<" "<<(b)<<" "<<(c)<<" "<<(d)<<endl
#define cl cout<<endl
#define r0 return 0
#define e0 exit(0)
#define x first
#define y second

inline lli modadd(lli n,lli m,lli p=mod){
    return ((n+m)%p+p)%p;
}

inline lli modsub(lli n,lli m,lli p=mod){
    return ((n-m+p)%p+p)%p;
}

inline lli modpro(lli n,lli m,lli p=mod){
    return (((n%p)*(m%p))%p+p)%p;
}

uli powe(lli x,lli y){
    uli res = 1;
    while (y > 0) {
        if (y & 1)
            res = res * x;
        y = y >> 1;
        x = x * x;
    }
    return res;
}

lli modpow(lli x,lli y,lli p=mod){
    lli res = 1;
    while (y > 0) {
        if (y & 1)
            res = modpro(res , x, p);
        y = y >> 1;
        x = modpro(x , x, p);
    }
    return res;
}

inline lli modInverse(lli n, lli p=mod)
{
    if(n==1) return 1;
    return modpow(n, p-2, p);
}

inline lli moddiv(lli n,lli m,lli p=mod){
    return modpro(n,modInverse(m,p),p);
}

inline lli modadd3(lli x, lli y, lli z,lli p=mod){
    return modadd(modadd(x,y,p),z,p);
}

inline lli modadd4(lli x, lli y, lli z, lli w,lli p=mod){
    return modadd(modadd(x,y,p),modadd(z,w,p),p);
}

inline lli modnCr(lli fac[], int n, int r, lli p=mod)
{
    if (r==0) return 1;
    return modpro(fac[n],modInverse(modpro(fac[r],fac[n-r],p),p),p);
}

template <typename T>
inline T max3(T x, T y, T z){
    return max(max(x,y),z);
}

template <typename T>
inline T max4(T x, T y, T z, T w){
    return max(max3(x,y,w),z);
}

template <typename T>
inline T min3(T x, T y, T z){
    return min(min(x,y),z);
}

template <typename T>
inline T min4(T x, T y, T z, T w){
    return min(min3(x,y,w),z);
}

template <typename T>
void printArr(T *arr, int s, int n){
    for(int i=s;i<=n;i++){

        cout<<arr[i]<<" ";
    }cout<<endl;
}

//template<class X, class Y, class Z>
//struct triple {
//    X x;
//    Y y;
//    Z z;
//
//     friend bool operator<(triple a, triple b)
//    {
//        if(a.x!=b.x) return a.x<b.x;
//        else if(a.y!=b.y) return a.y<b.y;
//        else return a.z<=b.z;
//    }
//};
//
//
//template<class X, class Y, class Z, class W>
//class quad {
//    public:
//    X x;
//    Y y;
//    Z z;
//    W w;
//
//     friend bool operator<(quad a, quad b)
//    {
//        if(a.x!=b.x) return a.x<b.x;
//        else if(a.y!=b.y) return a.y<b.y;
//        else if(a.z!=b.z)return a.z<b.z;
//        else return a.w<b.w;
//    }
//};

//template <typename T>
//T gcd(T a, T b)
//{
//    if (a == 0)
//        return b;
//    if(b==0)
//        return a;
//    T t;
//    while((a>0)&&(b>0)){
//     t = a;
//     a=b%a;
//     b=t;
// }
//
// return max(a,b);
//}

//
//uli choose(uli n, uli k){
//uli res = 1;
//
//    // Since C(n, k) = C(n, n-k)
//    if ( k > n - k )
//        k = n - k;
//
//    // Calculate value of
//    // [n * (n-1) *---* (n-k+1)] / [k * (k-1) *----* 1]
//    for (uli i = 0; i < k; ++i)
//    {
//        res *= (n - i);
//        res /= (i + 1);
//    }
//
//    return res;
//}
//

//
//  vector<vector<pii>> adj;
//   //vector<int> dist;
//   vector<int> d;
////   vector<bool> visited;
////     vector<int> pa;
//   //queue<int> q;
//
//  class Graph{
//
//   public:
//      int V;
//
//  Graph(int V){
//      this->V = V;
//      adj.resize(V);
////        visited.resize(V);
//      //color.resize(V);
//      //dist.resize(V);
//        d.resize(V);
//     //// dist.resize(V);
////     pa.resize(V);
//
//  }
//
//  ~Graph(){
// 	  adj.clear();
// 	  //visited.clear();
// 	 // color.clear();
// 	 // dist.clear();
////    pa.clear();
// 	  //dist.clear();
//// 	  visited.clear();
//d.clear();
//
//
//  }
//
//
//  void addEdge(int a, int b)
//  {
//      adj[a].pb(b);
//      adj[b].pb(a);
//      //adj[b].pb({a,in});
//  }
//
// //  void dfs(int x){
// //    //  color[x]=1;
// //   visited[x]=1;
// //      for(auto u: adj[x]){
// //          if(visited[u]) continue;
// //
// //          dfs(u);
// //      }
// //
// //  }
// //
// //
// //
// //
// //
//  // void dfsTree(int x, int p){
//  //     for(auto u: adj[x]){
//  //         if(u==p) {continue;}
//  //         dfsTree(u,x);
//  //     }
//  // }
//
//
//void dijkstra(int s) {
//    d.assign(n, INF);
//    d[s] = 0;
//    set<pair<int, int>> q;
//    q.insert({0, s});
//    while (!q.empty()) {
//        int v = q.begin()->second;
//        q.erase(q.begin());
//        for (auto edge : adj[v]) {
//            int to = edge.first;
//            int len = edge.second;
//            if (d[v] + len < d[to]) {
//                q.erase({d[to], to});
//                d[to] = d[v] + len;
//                q.insert({d[to], to});
//            }
//        }
//    }
//}
//
//
////  void bfs(int x){
////      queue<int> q;
////      visited[x]=1;
////      q.push(x);
////      //dist[x]=0;
////      while(!q.empty()){
////          int s = q.front();
////          q.pop();
////
////          for(auto u : adj[s]){
////
////              if(visited[u]) continue;
////              pa[u]=s;
////              visited[u]=1;
////              //dist[u.x]=dist[s]+1;
////              q.push(u);
////          }
////      }
////  }
//
// //pair<int,int> farthest(int start){
// //    vector<int> dist(V,INT_MAX);
// //
// //    q.push(start);
// //    dist[start]=0;
// //    while(!q.empty()){
// //        int u = q.front();
// //        q.pop();
// //        for(int child: adj[u]){
// //            //if(keep[child])
// //            if(dist[child] > dist[u]+1) {
// //                dist[child] = dist[u]+1;
// //                q.push(child);
// //            }
// //        }
// //    }
// //    int big=-1,mi=-1;
// //    for(int i=1;i<n+1;i++){
// //        //if(keep[i])
// //        {
// //            if(dist[i]>big){
// //                big=dist[i];mi=i;
// //            }
// //        }
// //    }
// //    return make_pair(big,mi);
// //}
//
//
// //  int connectedcomponents(int n){
// //      int ans=0;
// //      loop(i,1,n+1){
// //          if(!visited[i]){
// //              ans++;
// //              dfs(i);
// //          }
// //
// //      }
// //      return ans;
// //  }
//
//  };

//template <typename T>
//T findpowerfactorial(T n,T p)
//{
//    T x = 0;
//    while (n)
//    {
//        n /= p;
//        x += n;
//    }
//    return x;
//}
//
//template <typename T>
//int getibit(T n, int i){
//    //cout<<(n&(1LL<<i))<<endl;
//    return (n&(1LL<<i))?1:0;
//}
//
//template <typename T>
//int findbits(T n, T p){
//    int x=0;
//    while(n>0){
//        n/=p;
//        x++;
//    }
//    return x;
//}

//
//
////
//vector<pair<lli,int>> v;
//void primeFactors(lli n)
//{
//    v.clear();
//    int c=0;
//    while (n % 2 == 0)
//    {
//        n = n/2;
//        c++;
//    }
//    if(c>0) v.pb({2,c});
//
//
//    for (lli i = 3; i*i <= n; i = i + 2)
//    {   c=0;
//
//        while (n % i == 0)
//        {
//            n = n/i;
//            c++;
//        }
//        if(c>0)v.pb({i,c});
//
//    }
//    if (n > 2)
//        v.pb({n,1});
//}

//lli fac_[N];
//void fac_init(int n){
//    fac_[0]=1;
//    loop(i,1,n+1)fac_[i]=modpro(fac_[i-1],i);
//}
//
/*BITMASK
for( int inum = 0 ; inum < ( 1 << n ) ; ++ inum ) {
     for ( int pos = 0; pos < n ; ++pos ) {
         if (  inum & ( 1 << pos )  ){
              results[inum] += s [pos] ; //DO SOMETHING
         }
     }
}
*/
int n,T;
int t[N],g[N];
int dp[230][4][65540];
int f(int tl, int lsg, int mask){
    if(tl==0) return 1;
    int &res = dp[tl][lsg][mask];
    if(res!=-1) return res;
    res=0;
    loop(i,0,n){
        if(mask & (1<<i)) continue;
        if(g[i]==lsg) continue;
        if(t[i] > tl) continue;
        res = modadd(res, (f(tl-t[i], g[i], mask|((1<<i)))));
    }
    return res;
}
int main(){
    fastIO;
    int erer=1;
//    cin>>erer;
    loop(erer2,1,erer+1){

        cin>>n>>T;
        loop(i,0,n) cin>>t[i]>>g[i];
        memset(dp,-1,sizeof(dp));
        cout<<f(T,0,0);

    }
    return 0;
}

#include <iostream>
#include <stdio.h>
#include <stdlib.h>

using namespace std;
int N;
struct A
{
    int t,what;
}all[20];
int Pow[25];
bool have[32800][250][5]={0};
int DP[32800][230][5]={0};
int MOD=1e9+7;
int F(int what,int con,int which)
{
    //printf("%lld %")
    int i;
    if(con<0) return 0;
    if(con==0) return 1;
    if(have[what][con][which]) return DP[what][con][which];
    have[what][con][which]=1;
    for(i=0;i<N;i++) if((what&Pow[i])==0&&all[i].what!=which) DP[what][con][which]=(DP[what][con][which]+F(what+Pow[i],con-all[i].t,all[i].what))%MOD;
    return DP[what][con][which];
}
int main()
{
    int M,i;
    scanf("%d %d",&N,&M);
    Pow[0]=1;
    for(i=1;i<=20;i++) Pow[i]=Pow[i-1]*2;
    for(i=0;i<N;i++) scanf("%d %d",&all[i].t,&all[i].what);
    printf("%d\n",F(0,M,0));
    return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int MOD=1e9+7;
int n,T,t[15],g[15],dp[1<<15][3];
signed main(){
  scanf("%d%d",&n,&T);
  for(int i=0;i<n;++i) scanf("%d%d",&t[i],&g[i]),--g[i];
  memset(dp,0,sizeof(dp));
  for(int mask=1;mask<1<<n;mask<<=1) dp[mask][g[__builtin_ctz(mask)]]=1;
  for(int i=1;i<1<<n;++i){
    if(i-(i&-i)==0) continue;
    for(int j=0;j<n;++j){
      if(i>>j&1){
        for(int k=0;k<3;++k){
          if(k==g[j]) continue;
          dp[i][g[j]]+=dp[i^(1<<j)][k],dp[i][g[j]]%=MOD;
        }
      }
    }
  }
  int ans=0;
  for(int i=0;i<1<<n;++i){
    int cost=0;
    for(int j=0;j<n;++j){
      if(i>>j&1) cost+=t[j];
    }
    if(cost!=T) continue;
    for(int j=0;j<3;++j){
      ans+=dp[i][j],ans%=MOD;
    }
  }
  printf("%d\n",ans);
  return 0;
}

#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#define all(x) x.begin(), x.end()
using namespace std;
typedef long long ll;
typedef double db;
const int MOD = 1e9 + 7;
int cnt[3375], f[16];
int convert(int cnt[])
{
	return cnt[0] * 15 * 15 + cnt[1] * 15 + cnt[2];
}
void set_up(int id, int last, int n, int cnd[])
{
	++cnt[convert(cnd)];
	if (id == n)
		return;
	for (int i = 0; i < 3; ++i)
	{
		if (i != last)
		{
			++cnd[i];
			set_up(id + 1, i, n, cnd);
			--cnd[i];
		}
	}
}
bool check(vector<pair<int, int>>& a, int n)
{
	for (int i = 1; i < n; ++i)
		if (a[i].second != a[i - 1].second)
			return true;
	return false;
}
void convert(int a, int cnd[])
{
	for (int i = 2; i >= 0; --i)
	{
		cnd[i] = a % 15;
		a /= 15;
	}
}
int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	int n, t;
	cin >> n >> t;
	vector<pair<int, int>> a(n);
	for (int i = 0; i < n; ++i)
		cin >> a[i].first >> a[i].second;
	if (n == 15 && !check(a, n))
	{
		int ans = 0;
		for (int i = 0; i < n; ++i)
			ans += (a[i].first == t);
		cout << ans;
		return 0;
	}
	fill(cnt, cnt + 3375, 0);
	int cnd[3] = { 0, 0, 0 };
	set_up(0, -1, n + 1, cnd);
	f[0] = 1;
	for (int i = 1; i <= 15; ++i)
		f[i] = 1ll * f[i - 1] * i % MOD;
	vector<vector<int>> dp(3375, vector<int>(t + 1, 0));
	dp[0][0] = 1;
	int ans = 0, tmp;
	for (int i = 0; i < n; ++i)
	{
		for (int j = 3374; j > 0; --j)
		{
			convert(j, cnd);
			if (cnd[a[i].second - 1] == 0)
				continue;
			cnd[a[i].second - 1] -= 1;
			tmp = convert(cnd);
			for (int k = t; k >= a[i].first; --k)
			{
				dp[j][k] += dp[tmp][k - a[i].first];
				dp[j][k] %= MOD;
			}
		}
	}
	for (int i = 0; i < 3375; ++i)
	{
		tmp = 1ll * dp[i][t] * cnt[i] % MOD;
		convert(i, cnd);
		for (int j = 0; j < 3; ++j)
			tmp = 1ll * tmp * f[cnd[j]] % MOD;
		ans = (ll(ans) + tmp) % MOD;
	}
	cout << ans;
	return 0;
}

#include<bits/stdc++.h>

#define ll long long
#define ld long double
#define fi first
#define se second
#define sqr(spasibo) ((spasibo) * (spasibo))
#define y1 CniKsoset
#define endl "\n"
using namespace std;
const ll N = 250;
const ll MOD = 1e9 + 7;
ll n,t,ans,a[N],b[N],dp[226][(1ll << 15ll) + 1][3];
int main()
{
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin>>n>>t;
    for(int i = 0; i < n; i++)
    {
        cin>>a[i]>>b[i];
        b[i]--;
    }
    dp[0][0][0] = 1;
    for(int i = 0; i <= t; i++)
    {
        for(int mask = 0; mask < (1 << n); mask++)
        {
            for(int last = 0; last < 3; last++)
            {
                for(int now = 0; now < n; now++) if((mask & (1 << now)) == 0)
                {
                    if(i + a[now] <= t && (b[now] != last || i == 0))
                    {
                        dp[i + a[now]][mask | (1 << now)][b[now]] += dp[i][mask][last];
                        dp[i + a[now]][mask | (1 << now)][b[now]] %= MOD;
                    }
                }
            }
        }
    }
    ans = 0;
    for(int mask = 0; mask < (1 << n); mask++) for(int col = 0; col < 3; col++)
    {
        ans += dp[t][mask][col];
        ans %= MOD;
    }
    cout<<ans<<endl;
    return 0;
}

#include<bits/stdc++.h>
using namespace std;
#define lli long long
#define For(i,a,n) for(int i=(a);i<n;i++)
#define vi vector<int>
#define vil vector<long long>
#define asc(x) x.begin(),x.end()
#define des(x) x.rbegin(),x.rend()
#define pb push_back
#define pa pair<int,int>
#define pal pair<long long,long long>
#define vpa vector<pair<int,int>>
#define vpal vector<pair<long long,long long>>
#define fi first
#define se second
#define mod 1000000007

lli answer(vi st,int genre, int left){
    if(!left) return 1;
    lli ans = 0;
    For(i, 0, 3) if(i!=genre && st[i]) {
        vi te = st;
        te[i]--;
        ans = (ans + st[i]*answer(te, i, left-1))%mod;
    }
    return ans;
}

int main(){
    ios::sync_with_stdio(false);
    lli ans=0;
    int n,t;
    cin>>n>>t;
    vpa ar(n);
    For(i,0,n) cin>>ar[i].fi>>ar[i].se;
    for(int i=1;i<(1<<n);i++){
        vi st(3);
        int temp=i,sum=0,count=0;
        while(temp){
            if(temp&1) sum+=ar[count].fi,st[ar[count].se-1]++;
            count++;
            temp>>=1;
        }
        if(sum!=t) continue;
        ans = (ans + answer(st, -1, st[0]+st[1]+st[2]))%mod;
    }
    cout<<ans<<endl;
    return 0;
}

#include <bits/stdc++.h>

#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define MOD 1000000007
#define pii pair<int,int>
#define ll long long
#define el '\n'

using namespace std;

ll pow2[15];
ll dp[(1 << 15)][4];
bool udh[(1 << 15)][4];

int main () {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    for (ll i=0;i<15;i++) pow2[i]=((ll)1 << i);

    int n,t;
    cin >> n >> t;

    pii ar[n];
    for (int i=0;i<n;i++){
        cin >> ar[i].fi >> ar[i].se;
    }

    queue <pii> qu; // bitmask,last-genre
    for (int i=0;i<n;i++){
        dp[pow2[i]][ar[i].se]=1;
        qu.push(mp(pow2[i],ar[i].se));
    }

    while (!qu.empty()){
        int bit=qu.front().fi,gen=qu.front().se;
        qu.pop();

        for (int i=0;i<n;i++){
            int tm=(bit|pow2[i]);
            if (tm>bit && gen!=ar[i].se){
                dp[tm][ar[i].se]=(dp[tm][ar[i].se]+dp[bit][gen])%MOD;
                if (!udh[tm][ar[i].se]){
                    qu.push(mp(tm,ar[i].se));
                    udh[tm][ar[i].se]=1;
                }
            }
        }
    }

    ll tot=0;
    for (int i=0;i<(1<<15);i++){
        for (int j=1;j<=3;j++){
            int time=0;
            for (int p=0;p<15;p++){
                if ((i&pow2[p])>0) time+=ar[p].fi;
            }
            if (time==t){
                tot=(tot+dp[i][j])%MOD;
            }
        }
    }

    cout << tot << el;

    return 0;
}

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define mp make_pair
#define ld long double
#define vec vector<ll>
#define ms multiset<ll>
#define f(i,x,n) for(int i=x;i<n;i++)
#define int long long
#define mod 1000000007
#define endl "\n"
void fastio()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
}
int n,ttm;
int t[100],g[100],tans=0,ans=0;
int df2(int n1,int n2,int n3,int bk)
{
	int ss=0,a1=0,a2=0,a3=0;
	if(n1==0 && n2==0 && n3==0)
		return 1;
	if(n1>0)
	{
		if(1!=bk)
		{
			a1=((n1)*df2(n1-1,n2,n3,1))%mod;
			ss=1;
		}
	}
	if(n2>0)
	{
		if(2!=bk)
		{
			a2=((n2)*df2(n1,n2-1,n3,2))%mod;
			ss=1;
		}
	}
	if(n3>0)
	{
		if(3!=bk)
		{
			a3=((n3)*df2(n1,n2,n3-1,3))%mod;
			ss=1;
		}
	}
	return (a1+a2+a3)%mod;
}
int dfs(int sm,int i,int n1,int n2,int n3)
{
	if(sm==ttm)
	{
		ans=0;
		tans=(tans+df2(n1,n2,n3,0))%mod;
		return 0;
	}
	if(sm>ttm||i>=n)
		return 0;
	if(g[i]==1)
	{
		dfs(sm+t[i],i+1,n1+1,n2,n3);
		dfs(sm,i+1,n1,n2,n3);
	}
	else if(g[i]==2)
	{
		dfs(sm+t[i],i+1,n1,n2+1,n3);
		dfs(sm,i+1,n1,n2,n3);
	}
	else
	{
		dfs(sm+t[i],i+1,n1,n2,n3+1);
		dfs(sm,i+1,n1,n2,n3);
	}
}
int32_t main()
{
	fastio();
	cin>>n>>ttm;
	f(i,0,n)
	{
		cin>>t[i]>>g[i];
	}
	f(i,0,n)
	{
		if(g[i]==1)
		{
			dfs(t[i],i+1,1,0,0);
		}
		else if(g[i]==2)
		{
			dfs(t[i],i+1,0,1,0);
		}
		else
		{
			dfs(t[i],i+1,0,0,1);
		}
	}
	cout<<tans;
}

#include<bits/stdc++.h>
using namespace         std;
#define                 int long long
#define                 pb push_back
#define                 mp make_pair
#define st(arr,a)       memset(arr,a,sizeof arr)
#define                 nl cout<<endl
#define                 real signed
#define                 endl '\n'
#define bitcount(x)     __builtin_popcountll(x)
const int MOD = 1000000007ll;
#define forn(i,a,b)     for(int i=a;i<=b;i++)
#define rfor(i,a,b)     for(int i=a;i>=b;i--)
#define all(x)          x.begin() , x.end()
#define pi pair<int,int>
#define X first
#define Y second
#define N 1014159
#define  vi vector<int>
#define  v  vector

int n,T;
int g[20],t[20];
const int MX = (1LL<<15)+50;
int dp[MX][226];
int sum[MX];

int get(int mask,int last)
{

    int x = sum[mask];
    if(x>T)return 0;
    if(x == T)return 1;
    int&ans=dp[mask][last];
    if(ans!=-1)return ans;
    //int gen = g[last];
     ans = 0;

    forn(i,0,n-1)
    {
        if((((1LL<<i)&mask) == 0) and g[i]!=g[last])
            ans=(ans+get(mask|(1LL<<i),i))%MOD;
    }
    return ans;
}

signed solve()
{
    cin>>n>>T;
    forn(i,0,n-1)cin>>t[i]>>g[i];
    forn(mask,0,(1LL<<n)-1)
    {
        int x = 0;
        forn(i,0,n-1)
            if((1LL<<i)&mask)x+=t[i];
        sum[mask] = x;
    }
    st(dp,-1);
    int ans = 0;
    forn(i,0,n-1)ans=(ans+get((1LL<<i),i))%MOD;
    cout<<ans;
}

signed main()
{
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    int t = 1;
    //cin>>t;
    while(t--)
    {
        solve();
    }

    return 0;

}

//       g++ -g c.cpp ; ./a.exe

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define db double
#define ll long long
#define mp make_pair
#define pb push_back
#define vi vector<int>
#define pii pair<int, int>
#define sz(x) (int)(x).size()
#define all(x) (x).begin(),(x).end()
#define dd(a) cout << #a << " = " << a << " "
#define de(a) cout << #a << " = " << a << endl

const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;

ll d[1 << 15][4], g[20], t[20];
ll N, T, ans;

int main()
{
	cin >> N >> T;
	for(int i = 0, x; i < N; i++){
		scanf("%I64d%I64d", &t[i], &g[i]); g[i]--;
	}

	d[0][3] = 1;
	for(int status = 0; status < (1 << N); status++){
		for(int k = 0; k < (status == 0 ? 4 : 3); k++){
			for(int i = 0; i < N; i++)
				if(((status >> i) & 1) == 0 && g[i] != k)
					d[status | (1 << i)][g[i]] = (d[status | (1 << i)][g[i]] + d[status][k]) % mod;

			ll sum = 0;
			for(int i = 0; i < N; i++)
				if((status >> i) & 1)
					sum += t[i];

			if(sum == T)
				ans = (d[status][k] + ans) % mod;
		}
	}
	cout << ans << endl;

	return 0;
}

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;
typedef pair<int,int> pii;

const int MAXN = 1e5 + 5;
const int MOD = 1e9+7;
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define fi first
#define se second
#define FAIL0 {cout << "0\n"; return 0;}
#define FAIL1 {cout << "-1\n"; return 0;}
#define FAILNO {cout << "No\n"; return 0;}
#define NO {cout << "NO\n"; continue;}

int N, X;
int T[20], G[20];
LL dp[33000][250][3];
LL ans;

void addmod(LL &a, LL b) {
    a += b;
    if (a >= MOD) a -= MOD;
}

int main(int argc, char **argv) {
#ifdef OJ
    freopen("input.txt", "rt", stdin);
    //freopen("output.txt", "wt", stdout);
#endif
    ios::sync_with_stdio(false);
    cin.tie(0);

    cin >> N >> X;
    for (int i = 0; i < N; i++) {
        cin >> T[i] >> G[i];
        G[i]--;
    }

    //dp[0][0][0] = 1;
    //dp[0][0][1] = 1;
    //dp[0][0][2] = 1;

    for (int n = 1; n < (1<<N); n++) {
        if ((n&(n-1)) == 0) {
            for (int i = 0; i < N; i++) {
                if (n&(1<<i)) {
                    dp[n][T[i]][G[i]] = 1;
                    if (T[i] == X) ans++;
                    break;
                }
            }
            continue;
        }
        for (int i = 0; i < N; i++) {
            if (n&(1<<i)) {
                int m = n^(1<<i);
                for (int x = 0; x+T[i] <= X; x++) {
                    for (int g = 0; g < 3; g++) {
                        if (g == G[i]) continue;
                        LL tmp = dp[m][x][g];
                        addmod(dp[n][x+T[i]][G[i]],tmp);
                        if (x+T[i] == X) {
                            addmod(ans,tmp);
                        }
                    }
                }
            }
        }
    }

    cout << ans << endl;
    return 0;
}

#include<bits/stdc++.h>
typedef long long ll;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
using namespace std;
ll dp[33303][231][4],n,T,a[220],b[220],MOD=1e9+7;

ll recur(ll mask,ll tim,ll prev)
{
    if(tim==0)
        return 1;

    if(tim<0)
        return 0;

    if(dp[mask][tim][prev]!=-1)
        return dp[mask][tim][prev];

        dp[mask][tim][prev]=0;
        for(int i=0;i<n;i++)
            if((!(mask&(1<<i)))&&prev!=b[i])    //(Curr. song not selected), having diff version than prev...
                dp[mask][tim][prev]=(dp[mask][tim][prev]+recur(mask|(1<<i),tim-a[i],b[i]))%MOD;

    return dp[mask][tim][prev];
}

int main()
{
    cin>>n>>T;
    for(int i=0;i<n;i++)
        cin>>a[i]>>b[i];

    memset(dp,-1,sizeof(dp));
    cout<<recur(0,T,0)<<"\n";
}

/* ****GT_18**** */

#include<bits/stdc++.h>
#define ll          long long
#define pb          push_back
#define    endl        '\n'
#define pii         pair<ll int,ll int>
#define vi          vector<ll int>
#define all(a)      (a).begin(),(a).end()
#define F           first
#define S           second
#define sz(x)       (ll int)x.size()
#define hell        1000000007
#define rep(i,a,b)    for(ll int i=a;i<b;i++)
#define lbnd        lower_bound
#define ubnd        upper_bound
#define bs          binary_search
#define mp          make_pair
using namespace std;

#define N  100005
ll timei,t[100],g[100],dp[100][100][100][5],n,fac[1000000];
map<ll,ll> dp2[2501];
ll sol(ll a,ll b,ll c)
{
    ll ans=0;
    ans=(ans+dp[a][b][c][0]+dp[a][b][c][1]+dp[a][b][c][2])%hell;
    ans=(ans*(fac[a]))%hell;
    ans=(ans*(fac[b]))%hell;
    ans=(ans*(fac[c]))%hell;
    return ans;
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int TESTS=1;
//    cin>>TESTS;
    while(TESTS--)
    {
        ll i,j,k,l,m;
        for(i=0;i<100;i++)
        {
            for(j=0;j<100;j++)
            {
                for(k=0;k<100;k++)
                {
                    for(l=0;l<4;l++)
                    {
                        dp[i][j][k][l]=0;
                    }
                }
            }
        }
        fac[0]=1;
        for(i=1;i<1000000;i++)
        {
            fac[i]=(fac[i-1]*i)%hell;
        }
        dp[1][0][0][0]=1;dp[0][1][0][1]=1;dp[0][0][1][2]=1;
        for(i=0;i<100;i++)
        {
            for(j=0;j<100;j++)
            {
                for(k=0;k<100;k++)
                {
                    if(i!=0)
                        dp[i][j][k][0]=max(dp[i][j][k][0],(dp[i-1][j][k][1]+dp[i-1][j][k][2])%hell);
                    if(j!=0)
                        dp[i][j][k][1]=max(dp[i][j][k][1],(dp[i][j-1][k][0]+dp[i][j-1][k][2])%hell);
                    if(k!=0)
                        dp[i][j][k][2]=max(dp[i][j][k][2],(dp[i][j][k-1][0]+dp[i][j][k-1][1])%hell);
                }
            }
        }
        // cout<<dp[1][1][1][0]<<endl;
        cin>>n>>timei;
        for(i=0;i<n;i++)
        {
            cin>>t[i]>>g[i];
        }
        ll ans=0;
        dp2[0][0]=1;
        map<ll,ll>::reverse_iterator it;
        for(i=0;i<n;i++)
        {
            for(j=timei;j>=0;j--)
            {
                if(j+t[i]>timei)
                    continue;
                for (it=dp2[j].rbegin();it!=dp2[j].rend();it++)
                {
                    ll k1=it->F;
                    ll k2=it->S;
                    ll a,b,c;
                    a=k1%100;
                    k1=k1/100;
                    b=k1%100;
                    k1=k1/100;
                    c=k1;
                    if(g[i]==1)
                        dp2[j+t[i]][(a+1)+(b)*100+(c)*10000]+=k2;
                    if(g[i]==2)
                        dp2[j+t[i]][(a)+(b+1)*100+(c)*10000]+=k2;
                    if(g[i]==3)
                        dp2[j+t[i]][(a)+(b)*100+(c+1)*10000]+=k2;
                }
            }
        }
        for(auto i:dp2[timei])
        {
            ll k1=i.F;
            ll k2=i.S;
            ll a,b,c;

            a=k1%100;
            k1=k1/100;
            b=k1%100;
            k1=k1/100;
            c=k1;
            ans=(ans+k2*sol(a,b,c))%hell;
        }
        cout<<ans;
    }
    return 0;
}

#include <bits/stdc++.h>

using namespace std;

#define d(x) (x - '0')
//#define endl '\n'
#define let(x) ((x) ? 'A' : 'B')
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define oo (1<<28)

typedef long long ll;
typedef pair<int, int> pi;

const int MOD = 1e9 + 7, T = 226;
int memo[(1<<15)][T][4];

int rec(int msk, int rem, int prv, const vector<pi> &songs) {
  if (rem == 0)
    return 1;
  int n = songs.size();
  if (rem < 0 || msk == (1 << n) - 1)
    return 0;
  int &res = memo[msk][rem][prv];
  if (~res)
    return res;
  res = 0;
  for (int i = 0; i < n; ++i) {
    if (!((msk >> i) & 1) && songs[i].second != prv) {
      res += rec(msk | (1 << i), rem - songs[i].first, songs[i].second, songs);
      res %= MOD;
    }
  }
  return res;
}

int main() {
  ios::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
#ifndef ONLINE_JUDGE
  freopen("test.in", "rt", stdin);
//  freopen("out.txt", "wt", stdout);
#endif
  memset(memo, -1, sizeof memo);
  int n, t;
  cin >> n >> t;
  vector<pi> songs(n);
  for (int i = 0; i < n; ++i)
    cin >> songs[i].first >> songs[i].second;
//  vector<vector<vector<int>>> memo((1 << n),
//      vector<vector<int>>(T, vector<int>(4, -1)));
  cout << rec(0, t, 0, songs) << endl;
  return 0;
}

#include<bits/stdc++.h>
typedef long long ll;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
using namespace std;
ll dp[33303][231][4],n,T,a[220],b[220],MOD=1e9+7;

ll recur(ll mask,ll tim,ll prev)
{
    if(tim==0)
        return 1;

    if(tim<0)
        return 0;

    if(dp[mask][tim][prev]!=-1)
        return dp[mask][tim][prev];

    if(dp[mask][tim][prev]==-1)
    {
        dp[mask][tim][prev]=0;
        for(int i=0;i<n;i++)
            if((!(mask&(1<<i)))&&prev!=b[i])    //(Curr. song not selected), having diff version than prev...
                dp[mask][tim][prev]=(dp[mask][tim][prev]+recur(mask|(1<<i),tim-a[i],b[i]))%MOD;
    }
    return dp[mask][tim][prev];
}

int main()
{
    cin>>n>>T;
    for(int i=0;i<n;i++)
        cin>>a[i]>>b[i];

    memset(dp,-1,sizeof(dp));
    cout<<recur(0,T,0)<<"\n";
}

#include<bits/stdc++.h>

typedef long double ld;
using namespace std;

string t;
#define all(x) x.begin(),x.first()
#define fast ios_base::sync_with_stdio(false); cin.tie(NULL)
typedef long long ll;
const ll mod = 1e9 + 7;
ll n,m,x,y,z,j,d;
ll a[2000000],b[2000000],c;

// ll a,b,c;
string f,ff;

multiset <ll> s;

ll dp[226][3][(1<<15)];

ll rec(ll l,ll g,ll mask)
    {

        if(l<0)return 0;
        if(l==0)return 1;

        if(dp[l][g][mask]!=-1)return dp[l][g][mask];

        ll c1=0;

        for(int i=0;i<n;i++)
        {
            if(mask&(1<<i))continue;
            if(a[i]==g)continue;

            c1 =    (c1%mod +(rec(l-b[i],a[i],mask|(1<<i))%mod))%mod;

        }
        return dp[l][g][mask] = c1;
    }

int main(){

    memset(dp,-1,sizeof dp);
    cin>>n>>m;
    for(int i=0;i<n;i++)
    {
        cin>>b[i]>>a[i];
    }
    cout<<rec(m,-1,0);

  }

#include<bits/stdc++.h>
#include<ext/rope>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;
#define int long long
#define ld long double
#define pb push_back
#define pa pair<int,int>
#define v1d vector<int>
#define v2d vector<vector<int>>
#define v1p vector<pa>
#define INF LLONG_MAX
#define mod 1000000007
#define mp make_pair
#define RS(v)    sort(v.rbegin(),v.rend())
#define PI 3.14159265
#define ff first
#define ss second
#define endl "\n"
#define v1s vector<string>
#define S(v) sort(v.begin(),v.end())
#define mxpq priority_queue <int>
#define mnpq priority_queue<int,vector<int>,greater<int>>
#define flush cout.flush();
typedef tree<int,null_type,less_equal<int>,rb_tree_tag,tree_order_statistics_node_update> multipbds;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> pbds;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

int solve(int i, int genre, vector<pair<int,int>> &v, vector<vector<vector<int32_t>>> &dp, int tme){

    if(tme == 0){
        return 1;
    }

    if(tme < 0){
        return 0;
    }
    if(dp[i][genre][tme]  != -1){
        return dp[i][genre][tme];
    }

    int ans = 0;
    for(int ii = 0; ii < v.size(); ii++){

        if(genre == v[ii].ss){
            continue;
        }

        if((1 << ii) & i){
            continue;
        }

        ans += solve((1 << ii) | i, v[ii].ss, v, dp, tme - v[ii].ff);
        ans %= mod;
    }

    return dp[i][genre][tme] = ans;

}

void solve(){

    int n,q;
    cin>>n>>q;

    int cnt = pow(2, 15);
    vector<vector<vector<int32_t>>> dp(cnt, vector<vector<int32_t>>(4, vector<int32_t>(q+1, -1)));

    vector<pair<int,int>> v(n);

    for(auto &i: v){
        cin>>i.ff>>i.ss;
    }

    cout<<solve(0, 0, v, dp, q);

}

int32_t main(){

    cout<<fixed<<setprecision(16);
    cin.sync_with_stdio(false);
    cin.tie(0);cout.tie(0);

    // #ifndef ONLINE_JUDGE
    //  freopen("input.txt",  "r",  stdin);
    //  freopen("output.txt", "w", stdout);
    // #endif

    clock_t z = clock();
    int tc = 1;
    int t = 0;
    // cin>>tc;

    while(tc--){
        solve();
    }

    cerr << "Run Time : " << ((double)(clock() - z) / CLOCKS_PER_SEC) << '\n';

}

/*
    ASEEN AAN
            PINDAN AALE JATT!!!
                                */
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
//#include <boost/functional/hash.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
typedef long long int lli;
lli M=1000000007;
lli INF=1e17;
#define sqr(x) (x) * (x)
#define bip(n) __builtin_popcount(n)//no of ones bit in binary!!
#define bictz(n) __builtin_ctz(n)//no of trailing zeroes in binary!!
#define biclz(n) __builtin_clz(n)//no of leading zeroes in binary!!
#define bffs(n) __builtin_ffs(n)//index of first one bit!!
typedef pair<lli,lli> ll;
#define mem1(a,x) fill(&a[0], &a[0] + sizeof(a) / sizeof(a[0]), x)
#define mem2(a,x) fill(&a[0][0], &a[0][0] +sizeof(a)/sizeof(a[0][0]),x)
#define mem3(a,x) fill(&a[0][0][0], &a[0][0][0] +sizeof(a)/sizeof(a[0][0][0]),x)
#define fi1 ifstream fin("input.txt")
#define of1 ofstream fout("output.txt")
typedef tree<lli,null_type,less<lli>,rb_tree_tag,tree_order_statistics_node_update> ost;
lli n,q,z,y,k,m;
const double pi1=3.14159265358979323846;
//unordered_map<pair<ll,lli>,lli> mp;
lli me(lli a,lli b,lli M)
{
    if(b==0)
    return 1;
    else if(b%2==0)
    return me((a*a)%M,b/2,M);
    else
    return (a%M*me((a*a)%M,(b-1)/2,M)%M)%M;
}
lli mI(lli a,lli m)
{
    return me(a,m-2,m);
}
//lli tot=0;
vector<lli> pf(string s) {
    int n = (int)s.length();
    vector<lli> pi(n);
    for (int i = 1; i < n; i++) {
        int j = pi[i-1];
        while (j > 0 && s[i] != s[j])
            j = pi[j-1];
        if (s[i] == s[j])
            j++;
        pi[i] = j;
    }
    return pi;
}
//map<ll,lli> dp;
//set<lli> s[100005];
//lli dp[3005][3005];
lli dp[1<<15][226][4];
//string sdp[3005][3005];
int main()
{
    ios_base::sync_with_stdio(0);
    lli n,T;
    cin>>n>>T;
    ll p[n+1];
    lli ans=0;
    for(int i=1;i<=n;i++)
    {
        cin>>p[i].first>>p[i].second;
        dp[(1<<(i-1))][p[i].first][p[i].second]=1;
    }
    ans+=dp[1][T][p[1].second];
    ans%=M;
    for(int i=2;i<(1<<n);i++)
    {
        for(int j=0;j<n;j++)
        {
            lli d=(i>>j&1^1);
            if(d)
            continue;
            d=i^(1<<j);
            for(int k=0;k+p[j+1].first<=T;k++)
            {
                for(int p1=1;p1<=3;p1++)
                {
                    if(p1==p[j+1].second)
                    continue;
                    dp[i][k+p[j+1].first][p[j+1].second]+=dp[d][k][p1];
                    dp[i][k+p[j+1].first][p[j+1].second]%=M;
                }
            }
        }
        for(int j=1;j<=3;j++)
        {
            ans+=dp[i][T][j];
            ans%=M;
        }
    }
    cout<<ans;
    //for(int i=1;i<=n;i++)
}

#include <bits/stdc++.h>

using namespace std;

const int NMAX = 50;
const int TMAX = 2500;
const int MOD = 1e9 + 7;

int n,m;
int t[NMAX + 5];
int g[NMAX + 5];

int fr[5];

int dp_first2[2][NMAX + 1][NMAX + 1][TMAX + 1];
int dp_last[2][NMAX + 1][TMAX + 1];
int num_ways[NMAX + 1][NMAX + 1][NMAX + 1][3];

vector<pair<int,int> > genre[2];

inline int total_ways(int i,int j,int k) {
    int ans = 0;
    ans = (ans + num_ways[i][j][k][0]) % MOD;
    ans = (ans + num_ways[i][j][k][1]) % MOD;
    ans = (ans + num_ways[i][j][k][2]) % MOD;
    return ans;
}

int main() {

    scanf("%d %d",&n,&m);

    genre[0] = {{0,0}};
    genre[1] = {{0,0}};

    for(int i = 1; i <= n; i++) {
        scanf("%d %d",&t[i],&g[i]);
        genre[g[i] > 2].push_back({t[i],g[i]});
        fr[g[i]]++;
    }

    num_ways[1][0][0][0] = 1;
    num_ways[0][1][0][1] = 1;
    num_ways[0][0][1][2] = 1;

    for(int i = 0; i <= n; i++) {
        for(int j = 0; j <= n; j++) {
            for(int k = 0; k <= n; k++) {
                if(i)num_ways[i][j][k][0] = (num_ways[i][j][k][0] + 1LL * i * (num_ways[i - 1][j][k][1] + num_ways[i - 1][j][k][2])) % MOD;
                if(j)num_ways[i][j][k][1] = (num_ways[i][j][k][1] + 1LL * j * (num_ways[i][j - 1][k][0] + num_ways[i][j - 1][k][2])) % MOD;
                if(k)num_ways[i][j][k][2] = (num_ways[i][j][k][2] + 1LL * k * (num_ways[i][j][k - 1][0] + num_ways[i][j][k - 1][1])) % MOD;
            }
        }
    }
    dp_first2[0][0][0][0] = 1;

    for(int i = 1,l = 1; i < (int)genre[0].size(); i++,l ^= 1) {
        for(int j = 0; j <= i; j++) {
            for(int k = 0; j + k <= i; k++) {
                for(int t = 0; t <= m; t++) {
                    dp_first2[l][j][k][t] = dp_first2[l ^ 1][j][k][t];
                    if(genre[0][i].second == 1) {
                        if(genre[0][i].first <= t && j > 0) {
                            dp_first2[l][j][k][t] = (dp_first2[l][j][k][t] + dp_first2[l ^ 1][j - 1][k][t - genre[0][i].first]) % MOD;
                        }
                    }
                    else {
                        if(genre[0][i].first <= t && k > 0) {
                            dp_first2[l][j][k][t] = (dp_first2[l][j][k][t] + dp_first2[l ^ 1][j][k - 1][t - genre[0][i].first]) % MOD;
                        }
                    }
                }
            }
        }
    }

    dp_last[0][0][0] = 1;

    for(int i = 1,l = 1; i < (int)genre[1].size(); i++,l ^= 1) {
        for(int j = 0; j <= i; j++) {
            for(int t = 0; t <= m; t++) {
                dp_last[l][j][t] = dp_last[l ^ 1][j][t];
                if(j > 0 && genre[1][i].first <= t) {
                    dp_last[l][j][t] = (dp_last[l][j][t] + dp_last[l ^ 1][j - 1][t - genre[1][i].first]) % MOD;
                }
            }
        }
    }

    int l1 = 1 - ((int)genre[0].size() % 2);
    int l2 = 1 - ((int)genre[1].size() % 2);

    int ans = 0;

    for(int t = 0; t <= m; t++) {
        for(int i = 0; i <= fr[1]; i++) {
            for(int j = 0; j <= fr[2]; j++) {
                if(dp_first2[l1][i][j][t] == 0) {
                    continue;
                }
                for(int k = 0; k <= fr[3]; k++) {
                    if(dp_last[l2][k][m - t] == 0) {
                        continue;
                    }
                    ans = (ans + 1LL * (1LL * dp_first2[l1][i][j][t] * dp_last[l2][k][m - t] % MOD) * (total_ways(i,j,k))) % MOD;
                }
            }
        }
    }

    printf("%d\n",ans);

    return 0;
}

#include <iostream>
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <math.h>
#include <bits/stdc++.h>
#include <string.h>
#include <queue>
#include <map>
#define ll long long int
using namespace std;
void pv(std::vector<int> v){  for (int i = 0; i < v.size(); ++i){cout<<v[i]<<" ";}cout<<""<<endl;}
void pa(int a[],int n,int p){for (int i = p; i < n+p; ++i){cout<<a[i]<<" ";}cout<<""<<endl;}
#define mem(a) memset(a,0,sizeof(a))
const double pi=3.141592653589793238;
#define IOS ios :: sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define d(x) cout<<x<<endl;
#define fni(x,y,z) for(int i=x;i>=y;i-=z)
#define fnj(x,y,z) for(int j=x;j>=y;j-=z)
#define fpi(x,y,z) for(int i=x;i<=y;i+=z)
#define fpj(x,y,z) for(int j=x;j<=y;j+=z)
#define fpk(x,y,z) for(int k=x;k<=y;k+=z)
#define fnk(x,y,z) for(int k=x;k>=y;j-=z)
#define pb push_back
#define mp make_pair
#define mod 1000000007
#define rev(a) reverse(a.begin(),a.end())
const int inf = (int)10e9 + 8;
#define maxn 100009
int dp[1<<15][4];int q[100][2];int n,t;
int cc(int a)
{
    int ans = 0;
    fpi(1,n,1)
    {
        ans+=(a%2)*(q[i][0]);
        a/=2;
    }
    return ans;
}
int main()
{
    IOS;
    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #endif
    mem(dp);int ans = 0;
    cin>>n>>t;
    fpi(1,n,1) cin>>q[i][0]>>q[i][1];
    fpi(0,(1<<n)-1,1)
    {
        if(i==0)
        {
            fpj(1,n,1) {dp[1<<(j-1)][q[j][1]]++;}
        }
        else
        fpj(1,n,1)
        {
            if(((1<<(j-1)) | (i) )!= i)
            {
                fpk(1,3,1)
                {
                    if(q[j][1]==k) continue;
                    dp[(1<<(j-1)) | (i)][q[j][1]]+=dp[i][k];
                    dp[(1<<(j-1)) | (i)][q[j][1]]%=mod;
                }
            }
        }

    }
    fpi(0,(1<<n)-1,1)
    {
        if(cc(i)==t) {ans+=(dp[i][1] + dp[i][2] + dp[i][3])%mod;ans%=mod;}
    }
    d(ans)
    #ifndef LOCAL_DEFINE
    cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n";
    #endif
}

#pragma region template
#define _CRT_SECURE_NO_WARNINGS
#pragma comment(linker, "/STACK:65536000")
#include <iostream>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <string>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
using namespace std;

typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
typedef pair<string, string> pss;

#define all(x) x.begin(), x.end()
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define debug(x) 5 == 5

const ll mod = (int)1e9 + 7;
#pragma endregion

vector<unordered_map<int, vector<int>>> dp;

int* get_dp(int t, int mask, int last)
{
	auto found = dp[t].find(mask);
	if (found == dp[t].end())
		dp[t][mask] = vector<int>(3);
	return &dp[t][mask][last];
}

ll solve(int n, int T, vector<int>& t, vector<int>& g)
{
	dp.resize(T + 1);

	for (int i = 0; i < n; ++i)
		if (t[i] <= T)
			*get_dp(t[i], 1 << i, g[i]) = 1;
	for (int i = 0; i < T; ++i)
		for (int mask = 0; mask < (1 << n); ++mask)
		{
			if (!dp[i].count(mask))
				continue;
			for (int last = 0; last < 3; ++last)
			{
				int init = *get_dp(i, mask, last);
				if (init == 0)
					continue;
				for (int bit = 0; bit < n; ++bit)
					if (((mask & (1 << bit)) == 0) && g[bit] != last && (i + t[bit] <= T))
					{
						int* got = get_dp(i + t[bit], mask | (1 << bit), g[bit]);
						*got += init;
						*got %= mod;
					}
			}
		}
	ll ans = 0;
	for (int mask = 0; mask < (1 << n); ++mask)
		for (int i = 0; i < 3; ++i)
			ans += *get_dp(T, mask, i), ans %= mod;
	return ans % mod;
}

void stress()
{

}

int main()
{
	stress();
	cin.sync_with_stdio(0);
	cin.tie(0);
	/*freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);*/
	cout.precision(20);
	int n, T;
	cin >> n >> T;
	vector<int> t(n), g(n);
	for (int i = 0; i < n; ++i)
	{
		cin >> t[i] >> g[i];
		g[i]--;
	}
	cout << solve(n, T, t, g);
	return 0;
}
/*
6 5
1 1
2 2
3 3
4 2
5 1
6 1

*/

#include <bits/stdc++.h>
using namespace std;
#define M 1000000007
#define ll long long
#define REP(i,a,b) for(ll i=a;i<b;i++)
#define F first
#define S second
#define PB push_back
#define MP make_pair
#define VI vector<int>
#define VLL vector<long long>

ll modInverse(ll a, ll m);
ll gcd(ll a, ll b);
ll power(ll x, unsigned ll y, unsigned ll m);
void pairsort(int a[], int b[], int n);
void pairsortll(ll a[],ll b[],ll n);
ll logint(ll x,ll y);

ll gcd(ll a, ll b)
{
    if (a == 0)
        return b;
    return gcd(b%a, a);
}

ll power(ll x, unsigned ll y, unsigned ll m)
{
    if (y == 0)
        return 1;
    ll p = power(x, y/2, m) % m;
    p = (p * p) % m;

    return (y%2 == 0)? p : (x * p) % m;
}

ll modInverse(ll a, ll m)
{
    ll m0 = m;
    ll y = 0, x = 1;

    if (m == 1)
      return 0;

    while (a > 1)
    {
        // q is quotient
        ll q = a / m;
        ll t = m;

        // m is remainder now, process same as
        // Euclid's algo
        m = a % m, a = t;
        t = y;

        // Update y and x
        y = x - q * y;
        x = t;
    }

    // Make x positive
    if (x < 0)
       x += m0;

    return x;
}

void pairsort(int a[], int b[], int n)
{
    pair<int, int> pairt[n];

    // Storing the respective array
    // elements in pairs.
    for (int i = 0; i < n; i++)
    {
        pairt[i].first = a[i];
        pairt[i].second = b[i];
    }

    // Sorting the pair array.
    sort(pairt, pairt + n);

    // Modifying original arrays
    for (int i = 0; i < n; i++)
    {
        a[i] = pairt[i].first;
        b[i] = pairt[i].second;
    }
}

void pairsortll(ll a[], ll b[], ll n)
{
    pair<ll, ll> pairt[n];

    // Storing the respective array
    // elements in pairs.
    for (ll i = 0; i < n; i++)
    {
        pairt[i].first = a[i];
        pairt[i].second = b[i];
    }

    // Sorting the pair array.
    sort(pairt, pairt + n);

    // Modifying original arrays
    for (ll i = 0; i < n; i++)
    {
        a[i] = pairt[i].first;
        b[i] = pairt[i].second;
    }
}

ll logint(ll x,ll y)
{
    ll ans=0;
    ll a=1;
    for(ll i=0;i<x;i++)
    {
        if(x<=a)
        {
            return ans;
        }
        ans++;
        a*=y;
    }
    return -1;
}

ll solve(ll p[4],ll gg)
{
    if(p[1]==0&&p[2]==0&&p[3]==0) return 1;
    ll ans=0;
    REP(i,0,4)
    {
        if(i!=gg&&p[i]>0)
        {
            p[i]--;
            ans+=(p[i]+1)*solve(p,i);
            ans%=M;
            p[i]++;
        }
    }
    return ans;
}

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

    /*
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    */

    ll n,m;
    cin>>n>>m;
    ll f[n]={};
    ll t[n],g[n];
    REP(i,0,n)
    {
        cin>>t[i]>>g[i];
    }
    ll ans=0;
    REP(i,0,1<<n)
    {
        ll p[4]={};
        ll tt=0;
        REP(j,0,n)
        {
            if(((1<<j)&i)>0)
            {
                p[g[j]]++;
                tt+=t[j];
            }
        }
        if(tt==m)
        {
            ans+=solve(p,0);
            ans%=M;
        }
    }
    cout<<ans;

    return 0;
}

#include <bits/stdc++.h>

#define task "G1"
#define Aint(v) (v).begin(), (v).end()
#define rep(i, l, r) for (int i = (l); i <= (r); ++i)
#define Rep(i, r, l) for (int i = (r); i >= (l); --i)
#define pb push_back
#define F first
#define S second
#define by(x) [](const auto& a, const auto& b) { return a.x < b.x; } // sort(arr, arr + N, by(a));

using ll = long long;
using ld = long double;
using uint = unsigned long long;

using namespace std;

typedef pair<int,int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<int> vl;

// Limit
const int N=(1<<15),mod=1e9+7;
// Struct

// Variables
int n,T,dp[N][3][226],t[15],g[15],ans;
// dp[mask][last][sum]
// Function
inline int get(int x,int i) {return (x&(1<<i));}
inline int off(int x,int i) {return (x^(1<<i));}
int main()
{
	//freopen(task".in","r",stdin);
	//freopen(task".out","w",stdout);
	ios_base::sync_with_stdio(false);cin.tie(0);
	cin >> n >> T;
	rep(i,0,n-1)
	{
	    cin >> t[i] >> g[i];
	    g[i]--;
	}
	rep(x,1,(1<<n)-1) rep(i,0,n-1) if (get(x,i))
	{
	    int y=off(x,i);
	    if (y==0)
        {
            dp[x][g[i]][t[i]]=1;
            continue;
        }
	    rep(sum,1,T) if (sum>=t[i]) rep(j,0,2) if (g[i]!=j) dp[x][g[i]][sum]=(1ll*dp[x][g[i]][sum]+dp[y][j][sum-t[i]])%mod;
	}
	rep(x,1,(1<<n)-1) rep(j,0,2) ans=(1ll*ans+dp[x][j][T])%mod;
	cout << ans;
}

#include <bits/stdc++.h>

#define task "G1"
#define Aint(v) (v).begin(), (v).end()
#define rep(i, l, r) for (int i = (l); i <= (r); ++i)
#define Rep(i, r, l) for (int i = (r); i >= (l); --i)
#define pb push_back
#define F first
#define S second
#define by(x) [](const auto& a, const auto& b) { return a.x < b.x; } // sort(arr, arr + N, by(a));

using ll = long long;
using ld = long double;
using uint = unsigned long long;

using namespace std;

typedef pair<int,int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<int> vl;

// Limit
const int N=(1<<15),mod=1e9+7;
// Struct

// Variables
int n,T,dp[N][15],t[15],g[15],ans;
// dp[mask][last][sum]
// Function
inline int get(int x,int i) {return (x&(1<<i));}
inline int off(int x,int i) {return (x^(1<<i));}
int main()
{
	//freopen(task".in","r",stdin);
	//freopen(task".out","w",stdout);
	ios_base::sync_with_stdio(false);cin.tie(0);
	cin >> n >> T;
	rep(i,0,n-1)
	{
	    cin >> t[i] >> g[i];
        g[i]--;
    }
    rep(x,1,(1<<n)-1)
    {
        int sum=0;
        rep(i,0,n-1) if (get(x,i)) sum+=t[i];
        rep(i,0,n-1) if (get(x,i))
        {
            int y=off(x,i);
            if (y==0) dp[x][i]=1;
            else rep(j,0,14) if (g[i]!=g[j]) dp[x][i]=(1ll*dp[x][i]+dp[y][j])%mod;
            if (sum==T) ans=(1ll*ans+dp[x][i])%mod;
        }

    }
	cout << ans;
}

#include<bits/stdc++.h>
#define ll long long

using namespace std;

const int N = 15+1, MAXT = 32+1, mod = 1e9+7;

int n, T;
int t[N], g[N];
ll dp[MAXT][1<<N][3];

int main(){
    ios_base::sync_with_stdio(false);
    cout.tie(0);
    cin.tie(0);
    cin >> n >> T;
    for(int i = 0; i < n; ++i){
        cin >> t[i] >> g[i];
        --g[i];
        ++dp[t[i]][1<<i][g[i]];
    }
    for(int i = 0; i < T; ++i)
        for(int mask = 0; mask < (1<<n); ++mask)
            for(int k = 0; k < 3; ++k){
                for(int j = 0; j < n; ++j)
                    if(!((mask>>j)&1) && g[j] != k)
                        dp[(i+t[j])%MAXT][mask|(1<<j)][g[j]] = (dp[(i+t[j])%MAXT][mask|(1<<j)][g[j]] + dp[i%MAXT][mask][k])%mod;
                dp[i%MAXT][mask][k] = 0;
            }
    ll ans = 0;
    for(int mask = 0; mask < (1<<n); ++mask)
        for(int i = 0; i < 3; ++i)
            ans = (ans + dp[T%MAXT][mask][i])%mod;
    cout << ans << '\n';
}

#define _CRT_SECURE_NO_WARNINGS
#pragma comment(linker, "/stack:256000000")
#include<utility>
#include<iostream>
#include<vector>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<ctime>
#include<functional>
#include<random>
#include<climits>
#include<queue>
#include<stack>
#include<deque>
#include<bitset>
#include<map>
#include<set>
#include<unordered_map>
#include<unordered_set>
#include<cassert>
#include<ccomplex>

//4Head

#define mp make_pair
#define X first
#define Y second

using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
mt19937_64 gen(time(NULL));

ll const maxn = 3e5 + 6;
ll const MOD = 1e9 + 7;
ll const mmask = 1LL << 16;
ll dp[mmask][3];
ll mult(ll a, ll b) {
	ll val = a * b - (ll)((ld)a * b / MOD) * MOD;
	if (val < 0) {
		val += MOD;
	}
	if (val >= MOD) {
		val -= MOD;
	}
	return val;
}

long long poww(long long a, long long b)
{
	long long val = 1;
	a %= MOD;
	while (b > 0)
	{
		if (b % 2) val = mult(a, val);
		a = mult(a, a);
		b >>= 1;
	}
	return val % MOD;
}

signed main() {
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	dp[0][0] = 1;
	dp[0][1] = 1;
	dp[0][2] = 1;
	ll n; cin >> n;
	ll T; cin >> T;
	vector<ll>t(n), g(n);
	for (ll i = 0; i < n; i++) cin >> t[i] >> g[i], g[i]--;

	ll ans = 0;
	for (ll mask = 1; mask < 1LL << n; mask++) {
		for (ll gg = 0; gg < 3; gg++) {
			for (ll bit = 0; bit < n; bit++) {
				if (mask & (1LL << bit) && g[bit] == gg) {
					ll kek = 0;
					for (ll ggg = 0; ggg < 3; ggg++) {
						if (ggg != gg) {
							kek += dp[mask ^ (1LL << bit)][ggg];
							kek %= MOD;
						}
					}
					dp[mask][gg] += kek;
					dp[mask][gg] %= MOD;
				}
			}
		}
	}
	for (ll mask = 1; mask < 1LL << n; mask++) {
		ll kek = 0;
		for (ll bit = 0; bit < n; bit++) {
			if (mask & (1LL << bit)) {
				kek += t[bit];
			}
		}
		if (kek == T) {
			ans += dp[mask][0] + dp[mask][1] + dp[mask][2];
			ans %= MOD;
		}
	}

	cout << (ans * poww(2,MOD-2))%MOD << endl;
	return 0;
}

/*

*/

#include <bits/stdc++.h>

using namespace std;

static const int maxn = 15 + 2;
static const int mod = 1e9 + 7;

inline int setBit(int mask, int pos)
{
      return mask |= (1 << pos);
}

inline bool checkBit(int mask, int pos)
{
      return (bool)(mask & (1 << pos));
}

int n, T;
vector < pair <int, int> > vec;
long long dp[225 + 5][4][(1 << 15) + 5];

long long solve(int tym, int preGen, int mask)
{
      if (tym > T) return 0;
      if (tym == T) return 1;
      long long &ret = dp[tym][preGen][mask];
      if (ret != -1) return ret;
      long long ans = 0;
      for (int i = 0; i < n; i++)
      {
            if (checkBit(mask, i) == 0 && vec[i].second != preGen)
            {
                  ans = (ans + solve(tym + vec[i].first, vec[i].second, setBit(mask, i))) % mod;
            }
      }
      return ret = ans;
}

int main()
{
      ios_base::sync_with_stdio(false);
      cin.tie(nullptr);
      cout.tie(nullptr);

      #ifndef ONLINE_JUDGE
            freopen("in.txt", "r", stdin);
      #endif // ONLINE_JUDGE

      cin >> n >> T;
      for (int i = 0; i < n; i++)
      {
            int tym, gen;
            cin >> tym >> gen;
            vec.emplace_back(tym, gen);
      }
      long long ans = 0;
      for (int i = 0; i < n; i++)
      {
            memset(dp, -1, sizeof dp);
            ans = (ans + solve(vec[i].first, vec[i].second, setBit(0, i))) % mod;
      }
      cout << ans;
}

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define pb push_back
#define mod 1000000007

vector<vector<int>> res;
vector<pair<int, int>> arr;
int memoways[55][55][55][3];
// vector<int> memo[2505][55];

void dp(int sum, int idx, vector<int> v)
{
    if(idx<-1)
        return;
    if(sum==0)
    {
        res.pb(v);
        return;
    }
    dp(sum, idx-1, v);
    if(sum>=arr[idx].first)
    {
        v.pb(idx);
        dp(sum-arr[idx].first, idx-1, v);
    }
}

int find(int a, int b, int c, int sel)
{
    if((a==0)&&(b==0)&&(c==0))
        return 1;
    if((a<0)||(b<0)||(c<0))
        return 0;
    if(memoways[a][b][c][sel]!=-1)
        return memoways[a][b][c][sel];
    if(sel==1)
        return memoways[a][b][c][sel]=b*find(a, b-1, c, 2)+c*find(a, b, c-1, 3);
    if(sel==2)
        return memoways[a][b][c][sel]=a*find(a-1, b, c, 1)+c*find(a, b, c-1, 3);
    if(sel==3)
        return memoways[a][b][c][sel]=b*find(a, b-1, c, 2)+a*find(a-1, b, c, 1);
}

int check(vector<int> v)
{
    int ans=0, c1=0, c2=0, c3=0;
    for(auto x:v)
    {
        if(arr[x].second==1)
            c1++;
        else if(arr[x].second==2)
            c2++;
        else
            c3++;
    }
    // cout<<c1<<" "<<c2<<" "<<c3<<endl;
    return ((c1*find(c1-1, c2, c3, 1)%mod)+(c2*find(c1, c2-1, c3, 2)%mod)+(c3*find(c1, c2, c3-1, 3)%mod))%mod;
}

int32_t main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    //Initialize variables while declaring them
    // for(int i=0; i<2505; i++)
    //     for(int j=0; j<55; j++)
    //         memo[i][j]={-1};
    for(int i=0; i<55; i++)
        for(int j=0; j<55; j++)
            for(int k=0; k<55; k++)
                for(int l=0; l<3; l++)
                    memoways[i][j][k][l]=-1;
    int n, t, ans=0;
    cin>>n>>t;
    arr.resize(n);
    for(int i=0; i<n; i++)
        cin>>arr[i].first>>arr[i].second;
    dp(t, n-1, {});
    for(auto y:res)
    {
        ans+=check(y);
        ans%=mod;
    }
    cout<<ans;
    return 0;
}

/* ---------ragnar7---------- */
/* ---------ONLY GOD AND I KNOW WHAT I HAVE WRITTEN ----------*/
#include<bits/stdc++.h>
#define ll long long
#define hell 1000000007
#define vi vector<ll> v
#define forn(i,a,b) for(ll i=a;i<b;i++)
#define pb push_back

using namespace std;

ll n,t;

std::vector<pair<ll,ll > > v;
ll dp[(1<<15)+5][226][4];
ll solve(ll x,ll y,ll z)
{
	if(x==0)
		return 1;
	if(x<0)
		return 0;
	if(dp[y][x][z]!=-1)
		return dp[y][x][z];
	ll ans=0;
	for(ll i=0;i<n;i++)
	{
		if(v[i].second!=z and (y&(1<<i)))
		{
			ans=(ans+(solve(x-v[i].first,y-(1<<i),v[i].second))%hell)%hell;
		}
			//ans=(ans+(solve(x-v[i].first,y-(1<<i),v[i].second))%hell)%hell;
	}
	dp[y][x][z]=ans;
	return dp[y][x][z]%hell;
}
int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>t;
	ll t1,t2;
	for(ll i=0;i<(1<<15)+5;i++)
		for(ll j=0;j<226;j++)
			for(ll k=0;k<4;k++)
				dp[i][j][k]=-1;
	for(ll i=0;i<n;i++)
	{
		cin>>t1>>t2;
		v.push_back(make_pair(t1,t2));
	}
	//cout<<(1<<n);
	cout<<solve(t,(1<<n)-1,0);
	return 0;
}

#include <bits/stdc++.h>
using namespace std;
long long n,tot,t[20],g[20],mod = 1e9 +7;
int dp[(1 << 15) + 5][5];
int solve(int mask, int time, int last){
    if(time > tot)
        return 0;
    if(time == tot)
        return 1;
    int &ans = dp[mask][last];
    if(ans != -1)
        return ans % mod;
    ans = 0;
    for(int i = 0; i < n; i++){
        if(!(mask & (1 << i)) && g[i] != last)
            ans = (ans % mod + solve( mask | (1 << i), time + t[i], g[i]) % mod) % mod;
    }
    return ans % mod;
}
int main()
{
    ios::sync_with_stdio(0);
    cin >> n >> tot;
    for(int i = 0; i < n; i++)
        cin >> t[i] >> g[i];
    memset(dp, -1, sizeof dp);
    cout << solve(0, 0, 4);
    return 0;
}

#include <bits/stdc++.h>
#define ll long long
#define lld long double
#define MOD 1000000007
#define CAP 100000001
#define inf 1000000000000000000LL
#define pii pair<ll,ll>
#define f first
#define s second
#define pb push_back
#define mp make_pair
#define endl '\n'
#define sz(v) v.size()
#define all(v)    v.begin(),v.end()
#define fast  ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
using namespace std;
ll power(ll x,ll y, ll md=MOD){ll res = 1;x%=md;while(y>0){if(y&1)res = (res*x)%md;x = (x*x)%md;y = y>>1;}return res%md;}
#define dbg(x) cout <<#x<<":"<<x<<endl;
ll max1(ll a, ll b, ll c=-inf, ll d=-inf) {ll mx1=(a>b)?a:b, mx2=(c>d)?c:d; return ((mx1>mx2)?mx1:mx2);}
#define int ll

std::vector<ll> song[3];
ll ans=0;
ll t;
ll s1,s2,s0;

std::vector<ll> v1(50,0), v2(50,0), v3(50,0);

ll dp[51][51][51];

ll fact[51];

int countWays(int p, int q, int r, int last)
{
    // if number of balls of any color becomes less
    // than 0 the number of ways arrangements is 0.
    if (p<0 || q<0 || r<0)
        return 0;

    // If last ball required is of type P and the number
    // of balls of P type is 1 while number of balls of
    // other color is 0 the number of ways is 1.
    if (p==1 && q==0 && r==0 && last==0)
        return 1;

    // Same case as above for 'q' and 'r'
    if (p==0 && q==1 && r==0 && last==1)
        return 1;
    if (p==0 && q==0 && r==1 && last==2)
        return 1;

    // if last ball required is P and the number of ways is
    // the sum of number of ways to form sequence with 'p-1' P
    // balls, q Q Balls and r R balls ending with Q and R.
    if (last==0)
        return (countWays(p-1,q,r,1) + countWays(p-1,q,r,2))%MOD;

    // Same as above case for 'q' and 'r'
    if (last==1)
        return (countWays(p,q-1,r,0) + countWays(p,q-1,r,2))%MOD;
    if (last==2)
        return (countWays(p,q,r-1,0) + countWays(p,q,r-1,1))%MOD;
}

// Returns count of required arrangements
int countUtil(int p, int q, int r)
{
   // Three cases arise:
	if(dp[p][q][r]!=-1) return dp[p][q][r];
	dp[p][q][r] = countWays(p, q, r, 0) +  // Last required balls is type P
          countWays(p, q, r, 1) +  // Last required balls is type Q
          countWays(p, q, r, 2); // Last required balls is type R
    dp[p][q][r]%=MOD;
    dp[p][q][r]*=fact[p];
    dp[p][q][r]%=MOD;
    dp[p][q][r]*=fact[q];
    dp[p][q][r]%=MOD;
    dp[p][q][r]*=fact[r];
    dp[p][q][r]%=MOD;
    return dp[p][q][r];
}

ll countBits(ll x){
	ll c=0;
	while(x){
		c+=x%2;
		x/=2;
	}
	return c;
}

signed main() {
	fast;

	ll n;
	cin>>n>>t;
	ll aa,bb;

	std::vector<pair<ll,pii>> dpp[2501];

	for(int i=0;i<51;i++)
		for(int j=0;j<51;j++)
			for(int k=0;k<51;k++) dp[i][j][k]=-1;

	for(int i=0;i<n;++i){
		cin>>aa>>bb;
		song[bb-1].pb(aa);
	}

	s0 = song[0].size();
	s1=song[1].size();
	s2=song[2].size();

	fact[0]=1;
	for(int i=1;i<51;i++) fact[i]=(fact[i-1]*i)%MOD;

	ll len = s0+s1+s2;
	ll l1 = len/2;
	ll l2 = len - l1;
	ll len1 = (1LL<<l1);
	ll len2 = (1LL<<l2);

	for(int i=0;i<len1;i++){
		ll iii = i;

		ll mask1 = 0;
		ll mask2 = 0;
		ll mask3 = 0;

		if(l1>=s0){
			mask1 = i>>(l1-s0);
			i = iii;
			i -= (mask1)<<(l1-s0);

			if(l1>=s0+s1){
				mask2 = i>>(l1-s0-s1);
				i=iii;
				i -= (mask1)<<(l1-s0);
				i -= (mask2)<<(l1-s0-s1);
				if(l1>=s0+s1+s2){
					mask3 = i>>(l1-s0-s1-s2);
				}
				else mask3 = i<<(s2+s1+s0-l1);
			}
			else mask2 = i<<(s1+s0-l1);
		}
		else mask1 = i<<(s0-l1);

		ll ss0=0,ss1=0,ss2=0;

		ll ii = mask1;
		for(int j=0;j<s0;j++){
			if(ii&1){
				ss0+=song[0][j];
			}
			ii/=2;
		}
		ii = mask2;
		for(int j=0;j<s1;j++){
			if(ii&1){
				ss1+=song[1][j];
			}
			ii/=2;
		}
		ii = mask3;
		for(int j=0;j<s2;j++){
			if(ii&1){
				ss2+=song[2][j];
			}
			ii/=2;
		}

		i = iii;

		ll ss=ss0+ss1+ss2;
		if(ss<=t){
			dpp[ss].pb(mp(mask1,mp(mask2,mask3)));
		}

	}

	for(int i=0;i<len2;i++){
		ll iii = i;
		ll mask3 = (i&((1LL<<s2)-1));
		i>>=s2;
		ll mask2 = (i&((1LL<<s1)-1));
		i>>=s1;
		ll mask1 = (i&((1LL<<s0)-1));

		ll ss0=0,ss1=0,ss2=0;

		ll ii = mask1;
		for(int j=0;j<s0;j++){
			if(ii&1){
				ss0+=song[0][j];
			}
			ii/=2;
		}
		ii = mask2;
		for(int j=0;j<s1;j++){
			if(ii&1){
				ss1+=song[1][j];
			}
			ii/=2;
		}
		ii = mask3;
		for(int j=0;j<s2;j++){
			if(ii&1){
				ss2+=song[2][j];
			}
			ii/=2;
		}

		ll ss = ss0+ss1+ss2;
		ll toSearch = t-ss;

		i = iii;

		if(toSearch<0) continue;

		for(int j=0;j<dpp[toSearch].size();j++){
			ll m1 = mask1;
			ll m2 = mask2;
			ll m3 = mask3;
			m1|=dpp[toSearch][j].f;
			m2|=dpp[toSearch][j].s.f;
			m3|=dpp[toSearch][j].s.s;
			ans+=countUtil(countBits(m1),countBits(m2),countBits(m3));
			ans%=MOD;
		}

	}

	ans%=MOD;

	cout<<ans;

}

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>

typedef long long LL;

const int N=20;
const int M=(1<<15)+5;
const int MOD=1000000007;

int n,m,t[N],g[N],bin[N],tim[M];
LL f[M][5];

int main()
{
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;i++)
        scanf("%d%d",&t[i],&g[i]);
	bin[0]=1;
	for (int i=1;i<=n;i++)
        bin[i]=bin[i-1]*2;

	for (int i=0;i<bin[n];i++)
		for (int j=1;j<=n;j++)
			if (i&bin[j-1])
                tim[i]+=t[j];

	f[0][0]=1;
	for (int i=0;i<bin[n];i++)
	{
		for (int j=0;j<=3;j++)
		{
			if (!f[i][j]) continue;
			for (int k=1;k<=n;k++)
				if (!(i&bin[k-1])&&tim[i|bin[k-1]]<=m&&g[k]!=j)
                    f[i|bin[k-1]][g[k]]=(f[i|bin[k-1]][g[k]]+f[i][j])%MOD;
		}
	}

	LL ans=0;
	for (int i=0;i<bin[n];i++)
		if (tim[i]==m)
            ans+=f[i][0]+f[i][1]+f[i][2]+f[i][3];
	printf("%lld\n",ans%MOD);
	return 0;
}

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>

typedef long long LL;

const int N=20;
const int M=(1<<15)+5;
const int MOD=1000000007;

int n,m,t[N],g[N],bin[N],tim[M];
LL f[M][5];

int main()
{
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;i++)
        scanf("%d%d",&t[i],&g[i]);
	bin[0]=1;
	for (int i=1;i<=n;i++)
        bin[i]=bin[i-1]*2;

	for (int i=0;i<bin[n];i++)
		for (int j=1;j<=n;j++)
			if (i&bin[j-1])
                tim[i]+=t[j];

	f[0][0]=1;
	for (int i=0;i<bin[n];i++)
	{
		for (int j=0;j<=3;j++)
		{
			if (!f[i][j]) continue;
			for (int k=1;k<=n;k++)
				if (!(i&bin[k-1])&&tim[i|bin[k-1]]<=m&&g[k]!=j)
                    (f[i|bin[k-1]][g[k]]+=f[i][j])%=MOD;
		}
	}

	LL ans=0;
	for (int i=0;i<bin[n];i++)
		if (tim[i]==m)
            ans+=f[i][0]+f[i][1]+f[i][2]+f[i][3];
	printf("%lld\n",ans%MOD);
	return 0;
}

#include <bits/stdc++.h>

using namespace std;

bool Check(int n, int pos)
{
    return (bool)(n & (1<<pos));
}

int Set(int n, int pos)
{
    return n = (n | (1<<pos));
}

int n,t,mod=1e9+7,dur[105],genre[105],dp[(1<<16)+2][226][3],cur_len;

int func(int mask, int sum, int pre)
{
    if(mask==(1<<n)-1)
    {
        //if(cur_len==2) cout<<"ll: "<<mask<<endl;
        return (sum==t);
    }
    if(sum==t) return 1;

    if(dp[mask][sum][pre]!=-1)
    {
        return dp[mask][sum][pre];
    }
    int ans=0;
    for(int i=0; i<n; i++)
    {
        if(!Check(mask,i))
        {
            if(genre[i]!=pre && sum+dur[i]<=t)
            {
                int temp=func(Set(mask,i),sum+dur[i], genre[i]);
                ans=((ans%mod)+(temp%mod))%mod;
               // temp=func(Set(mask,i),sum,pre);
               // ans=((ans%mod)+(temp%mod))%mod;
            }
        }
    }
    return dp[mask][sum][pre]=ans;
}

int main()
{
    int i,j;
    scanf("%d %d",&n,&t);
    for(i=0; i<n; i++)
    {
        scanf("%d %d",&dur[i],&genre[i]);
        genre[i]--;
    }
    int ans=0;
    memset(dp, -1, sizeof dp);

    for(i=0; i<n; i++)
    {
        int m=0;
        m=Set(m,i);
        int temp=func(m,dur[i],genre[i]);
        ans=((ans%mod)+(temp%mod))%mod;
    }
    //cout<<"oo: "<<l<<' '<<ans<<endl;

    printf("%d\n",ans);
    return 0;

}

#include <bits/stdc++.h>
#define LL long long
#define db double
#define INF 0x3f3f3f3f
#define pii pair<int, int>
using namespace std;
const int maxn = 17;
const LL mod = 1000000007;
LL dp[1 << maxn][maxn], sum[1 << maxn];
pii a[maxn];
int main() {
	int n, m;
	LL ans = 0;
	scanf("%d%d", &n, &m);
	for (int i = 0; i < n; i++) {
		scanf("%d%d", &a[i].first, &a[i].second);
	}
	for (int i = 0; i < n; i++) {
		dp[1 << i][i] = 1;
	}
	for (int i = 1; i < (1 << n); i++)
		for (int j = 0; j < n; j++) {
			if((i >> j) & 1) {
				sum[i] += a[j].first;
				for (int k = 0; k < n; k++) {
					if((i >> k) & 1) continue;
					if(a[j].second == a[k].second) continue;
					dp[i | (1 << k)][k] = (dp[i | (1 << k)][k] + dp[i][j]) % mod;
				}
			}
		}
	for (int i = 1; i < (1 << n); i++) {
		if(sum[i] == m) {
			for (int j = 0; j < n; j++)
				ans = (ans + dp[i][j]) % mod;
		}
	}
	printf("%lld\n", ans);
}

#include <bits/stdc++.h>
using namespace std;
#define IOS ios_base::sync_with_stdio(false);cin.tie(0)
#define pb push_back
//#define mp make_pair
#define f first
#define s second
#define all(a) a.begin(),a.end()
#define int long long
const int MOD=1e9+7;
const int N=3e3+5;
int dp[(1LL<<16)+1][4];
int t[20],g[20];
vector<int>vp[20];
int go(int mask,int last,int tt)
{
    if(tt==0)
        return 1;
    int &ans=dp[mask][last];
    if(ans!=-1)
        return ans;
    ans=0;
    for(int i=1;i<=3;i++)
    {
        if(i!=last)
        {
            for(auto it:vp[i])
            {
                if(!(mask&1LL<<it)&&tt-t[it]>=0)
                {
                    ans+=go(1LL<<it|mask,i,tt-t[it]);
                    ans%=MOD;
                }
            }
        }
    }
    return ans;
}
int32_t main()
{
    IOS;
	int n,T;
    cin>>n>>T;
    for(int i=1;i<=n;i++)
    {
        cin>>t[i]>>g[i];
        vp[g[i]].pb(i);
    }
    memset(dp,-1,sizeof(dp));
    cout<<go(0,0,T)<<endl;

}

#include <bits/stdc++.h>
#define MOD 1000000007
using namespace std;
int dp[1 << 16][3];
int n, t;
long long fak[16];
pair<int, int> a[16];
/*int rek(int num, int gen, int time, int dept){
    int sum = 0;
    if(time == t)
        return 1;
    if(time > t)
        return 0;
    for(int i=0; i<n; i++){
        if((num & (1<<i)) == 0 && (gen != a[i].second)){
                dp[num | 1<<i] += rek(num | 1<<i, a[i].second, time + a[i].first, dept + 1);
        }
    }
    return sum % MOD;
}*/

vector<int> pos;

void eq(int seed, int time, int start){
    if(time == t){
        pos.push_back(seed);
    }else if(time > t){
        for(int i=start; i<n; i++){
            if((seed & (1 << i)) != 0)
                eq(seed ^ (1 << i), time - a[i].first, i);
        }
    }else
        return;
}

long long fNum(int a0, int a1, int a2, int gen){
    long long sum = 0;
    if(gen != 1 && a0)
        sum += fNum(a0-1, a1, a2, 1);
    if(gen != 2 && a1)
        sum += fNum(a0, a1-1, a2, 2);
    if(gen != 3 && a2)
        sum += fNum(a0, a1, a2-1, 3);
    if(!a0 && !a1 && !a2)
        return 1;
    return sum;
}

long long sortOut(int seed){
    int p = 0;
    int gen[4] = {0};
    while(seed){
        if(seed & 1 == 1){
            gen[a[p].second]++;
        }
        seed >>=1;
        p++;
    }
    long long res = fNum(gen[1], gen[2], gen[3], -1) % MOD ;
    return res * fak[gen[1]] % MOD * fak[gen[2]] % MOD * fak[gen[3]] % MOD;
}

int main()
{

    cin >> n >> t;
    int sum = 0;
    for(int i=0; i<n; i++){
        cin >> a[i].first >> a[i].second;
        sum += a[i].first;
    }
    fak[0] = 1;
    for(int i=1;  i<16; i++)
        fak[i] = fak[i-1] * i % MOD;

    long long res = 0;
    eq((1 << n) - 1, sum, 0);

    for(vector<int>::iterator i = pos.begin(); i != pos.end(); i++)
        res += sortOut(*i);
        //cout << *i << endl;

    cout << res % MOD << endl;
    return 0;
}

#include<bits/stdc++.h>

#define fi first

#define sc second

#define N 20

using namespace std;

typedef pair<int , int> II;

typedef pair<int , II> III;

typedef pair<II , II> IV;

typedef pair<long long , int> LI;

int moder = (int)1e9 + 7;

int amount , total_duration;

vector<int> songs[4];

int sizer[4];

int dif_arr[N][N][N][4];

int dif_val[4][N][N][226];

void prepare()
{
    dif_arr[1][1][0][1] = 1;

    dif_arr[1][0][1][2] = 1;

    dif_arr[1][0][0][3] = 1;

    for(int i =2 ;i <= amount; i++)

    for(int j = 0 ; j <= amount; j++)

    for(int k = 0; k <= amount - j; k++){

        if( j >= 1 )

        dif_arr[i][j][k][1] = (long long)( dif_arr[i-1][j-1][k][2] + dif_arr[i-1][j-1][k][3] ) * j % moder;

        if( k >= 1 )

        dif_arr[i][j][k][2] = (long long)( dif_arr[i-1][j][k-1][1] + dif_arr[i-1][j][k-1][3] ) * k % moder;

        dif_arr[i][j][k][3] = (long long)( dif_arr[i-1][j][k][1] + dif_arr[i-1][j][k][2] ) * ( i - j - k )%moder;
    }

    for(int gen = 1; gen <= 3; gen++){

        sizer[gen] = songs[gen].size();

        dif_val[gen][0][0][0] = 1;

        for(int i =1 ;i <= sizer[gen]; i++)

        for(int use = 0; use <= i; use++)

        for(int val = 0 ; val <= total_duration; val++){

            dif_val[gen][i][use][val] = dif_val[gen][i-1][use][val];

            if( use && val >= songs[gen][i-1] )

                dif_val[gen][i][use][val] += dif_val[gen][i-1][use-1][ val - songs[gen][i-1] ];

            dif_val[gen][i][use][val] %= moder;
        }
    }
}

void solve()
{
    prepare();

    int res = 0;

    for(int gen_one = 0; gen_one <= sizer[1]; gen_one++)

    for(int gen_two = 0 ; gen_two <= sizer[2]; gen_two++)

    for(int gen_three = 0 ; gen_three <= sizer[3]; gen_three++)

    for(int val_one = 0; val_one <= total_duration; val_one++)

    for(int val_two = 0; val_two <= total_duration - val_one; val_two++){

        int total = gen_one + gen_two + gen_three;

        int base = ( dif_arr[total][gen_one][gen_two][1] + dif_arr[total][gen_one][gen_two][2] ) % moder + dif_arr[total][gen_one][gen_two][3];

        base %= moder;

        int one = dif_val[1][ sizer[1] ][gen_one][val_one];

        int two = dif_val[2][ sizer[2] ][gen_two][val_two];

        int three = dif_val[3][ sizer[3] ][gen_three][ total_duration - val_one - val_two ];

        base = (long long) base * one % moder;

        base = (long long)base * two % moder;

        base = (long long)base * three % moder;

        res = ( res + base ) %moder;
    }

    printf("%d", res );
}

int main()
{
    ///freopen("main.inp", "r", stdin );

    scanf("%d %d", &amount , &total_duration );

    for(int i =1 ;i <= amount; i++){

        int duration , genre; scanf("%d %d", &duration , &genre );

        songs[ genre ].push_back( duration );
    }

    solve();
}

#include<bits/stdc++.h>

#define LL long long
#define fi first
#define se second
#define mp make_pair
#define pb push_back

using namespace std;

LL gcd(LL a,LL b){return b?gcd(b,a%b):a;}
LL lcm(LL a,LL b){return a/gcd(a,b)*b;}
LL powmod(LL a,LL b,LL MOD){LL ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
const int N = 2e5 +11;
const LL mod=1e9+7;
int n,m,a[N],b[N];
int dp[(1<<15)+5][266][4];
int main(){
	ios::sync_with_stdio(false);
	cin>>n>>m;
	for(int i=0;i<n;i++)cin>>a[i]>>b[i];
	dp[0][0][3]=dp[0][0][1]=dp[0][0][2]=1;
	for(int i=0;i<(1<<n);i++){
		for(int j=0;j<n;j++){
			if((1<<j)&i){
				for(int k=m;k>=a[j];k--){
					for(int s=1;s<=3;s++){
						if(s!=b[j])dp[i][k][b[j]]=(0ll+dp[i][k][b[j]]+dp[i^(1<<j)][k-a[j]][s])%mod;
					}
				}
			}
		}
	}
	LL ans=0;
	for(int i=0;i<1<<n;i++)
		for(int j=1;j<=3;j++)
			ans+=dp[i][m][j],ans%=mod;
	cout<<ans*powmod(2,mod-2,mod)%mod<<endl;
	return 0;
}

#include <iostream>
#include <fstream>
#include <cstdio>
#include <cctype>
#include <list>
#include <vector>
#include <cfloat>
#include <algorithm>
#include <numeric>
#include <cassert>
#include <climits>
#include <cstdlib>
#include <ctime>
#include <memory>
#include <cstring>
#include <stack>
#include <deque>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <iomanip>
#include <iterator>
#include <cmath>

#ifdef _WIN32
#define LLD "%I64d"
#else
#define LLD "%lld"
#endif

#ifdef _MSC_VER
#include <hash_map>
#include <hash_set>
using namespace stdext;
#define unordered_map hash_map
#define unordered_set hash_set
#else
#include <unordered_map>
#include <unordered_set>
#include <regex>
#include <tuple>
#endif

using namespace std;

#define mem(a,b) memset((a),(b),sizeof(a))
#define MP make_pair
#define MT make_tuple
#define PB push_back
#define FI first
#define SE second
#define sz(x) (int)x.size()
#define SIZE(x) (int)x.size()
#define ALL(x) x.begin(),x.end()
#define REP(i,n) for(int i=0;i<(n);++i)
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define readint(i) int i;scanf("%d",&i);
#define read2int(i,j) int i,j;scanf("%d%d",&i,&j);
#define read3int(i,j,k) int i,j,k;scanf("%d%d%d",&i,&j,&k);
#define printint(i) printf("%d\n",i);
#define print2int(i,j) printf("%d %d\n",i,j);
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef pair<ll,ll> PLL;
typedef pair<int,ll> PIL;
typedef pair<ll,int> PLI;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<ll> VL;
/************* define end  *************/
void println(VI x){REP(i,sz(x)) printf("%d%c",x[i]," \n"[i==sz(x)-1]);}
void scanln(VI& x, int sz){x.resize(sz); REP(i,sz) scanf("%d",&x[i]);}
template<class T> void read(T *x,int l,int r){FOR(i,l,r) read(x[i]);}
void println(int *x,int l,int r){FOR(i,l,r) printf("%d%c",x[i]," \n"[i==r]);}
ll myrand(ll mod) { return ((ll)rand() << 32^(ll)rand() << 16^rand()) % mod; }

#define readlong(i) ll i;scanf(LLD,&i);
#define read2long(i, j) readlong(i) readlong(j)
#define read3long(i,j,k) readlong(i) read2long(j,k)
#define read4long(i,j,k,l) read2long(i,j) read2long(k,l)
#define printlong(i) printf(LLD,i);printf("\n");
#define print2long(i,j) printf(LLD, i);printf(" ");printf(LLD,j);printf("\n");
void println(VL x){REP(i,sz(x)) {printf(LLD,x[i]);printf("%c"," \n"[i==sz(x)-1]);}}
void scanln(VL& x, int sz){x.resize(sz); REP(i,sz) scanf(LLD,&x[i]);}
void println(ll *x,int l,int r){FOR(i,l,r) {printf(LLD, x[i]);printf("%c"," \n"[i==r]);}}

#define MOD 1000000007

#define MAXN 15

int main(int argc, char* argv[]) {
  /* Problematic for codejam
   * ios_base::sync_with_stdio(false);
   * cin.tie(NULL); */
  read2int(n, T);
  VI t, gs;
  REP(i, n) {
    read2int(ti, gi);
    t.PB(ti);
    gs.PB(gi);
  }
  ll dp[(1 << MAXN)][226][4] = {0};
  dp[0][0][0] = 1;
  for (int time = 1; time <= T; ++time) {
    for (int subset = 0; subset < (1 << MAXN); ++subset) {
      for (int i = 0; i < n; ++i) {
        if ((subset & (1 << i)) && time >= t[i]) {
          for (int g = 0; g <= 3; ++g) {
            if (g != gs[i]) {
              dp[subset][time][gs[i]] += dp[subset - (1 << i)][time - t[i]][g];
            }
          }
        }
      }
    }
  }
  ll rtn = 0;
  for (int subset = 0; subset < (1 << MAXN); ++subset) {
    for (int g = 1; g <= 3; ++g) {
      rtn += dp[subset][T][g];
      rtn %= MOD;
    }
  }
  printf(LLD"\n", rtn);
  return 0;
}

///In the name of Allah
///BY_Mohammed_ALmasry
#include <bits/stdc++.h>
using namespace std;
typedef  long long ll;
#include <ctime>
#include <iomanip>
#define Fastio ios_base::sync_with_stdio(false)
#define pi 3.14159265358979323846//pi=acos(-1)
#define read freopen("input.txt","r",stdin)
#define write freopen("output.txt","w",stdout)
#define fi first
#define se second
#define pb push_back
#define pob pop_back
#define f0(i,n) for(ll i=0;i<n;i++)
#define rf0(n,i) for(ll i=n-1;i>=0;i--)
#define f1(i,n) for(ll i=1;i<=n;i++)
#define rf1(n,i) for(ll i=n;i>=1;i--)
#define ff(i,s,e) for(ll i=s;i<=e;i++)
#define rff(i,e,s) for(ll i=e;i>=s;i--)
#define all(v) v.begin(),v.end()
#define mod 1000000007
#define sz size
#define all(X) X.begin(),X.end()
#define memset(X,Y) memset(X,Y,sizeof X)
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pff pair<float,float>
#define pdd pair<double,double>
///1) double rad= ( ( Angle_in_degree  *pi ) * 1.0 ) / 180;
///2) tan(rad):only in radians
///1) x=GCD(a,b) && y=LCM(a,b) && GCD(c,d)=1
///2) x*y=a*b ==> x*y=(x*c)*(x*d) ==> y=x*c*d ==> y/x=c*d ==> (a*b=n=y/x)
///1) In Euclidean geometry, a regular polygon is a polygon that is equiangular (all angles are equal in measure)
///2) and equilateral (all sides have the same length).Regular polygons may be either convex or star
///3) each interior angle has a measure of (180*(n-2))/n degrees
///cout<<fixed<<setprecision(0);
///Time complexity : O() && Memory complexity :
///Surface area of a cube : 6 * L * L
///Remember that map<int, map<int,int> >mm; mm[any interger][any interger]++ ; Time complexity is  log(n)+log(m)
///Remember that set.erase( set.find( value in the set ) ) --> Time complexity is O(log(n))
///string s; getline(cin,s); // take one line
///__builtin_popcountll( x ) : It returns the number of ones in the binary representation of the long long x.
/// for ( int i: {x1,x2,x3 ,....etc} )
/// for i>30 use 1LL (1LL<<i)
/// hypot( x , y ) :  الجذر التربيعي
///read;write;
int dir4[4][2]= {{1,0},{0,1},{-1,0},{0,-1}};
int dir8[8][2]= {{-1,0},{1,0},{0,1},{0,-1},{-1,1},{1,-1},{1,1},{-1,-1}};
int dir8h[8][2]= {{2,1},{-2,-1},{-1,2},{1,-2},{1,2},{-2,1},{2,-1},{-1,-2}};
long double eps=1e-7;
const int N=2e5;
const int sz=pow(2,15);
ll dp[sz][15][3];
int main()
{
Fastio;
int n,t;
cin>>n>>t;
memset(dp,0);
pii a[n+10];
f0(i,n)
{
cin>>a[i].fi>>a[i].se;
a[i].se--;
dp[(1<<i)][i][a[i].se]=1;
}
ll ans=0;
f1(i,sz-1)
{
    f0(j,n)
    {
      if((1<<j)&i)
      {
          f0(k,n)
          {
              if((i&(1<<k))==0&&a[k].se!=a[j].se)
              {
                  dp[(i|(1<<k))][k][a[k].se]= (dp[(i|(1<<k))][k][a[k].se]%mod+dp[i][j][a[j].se]%mod)%mod;
              }
          }
      }
    }
}
f1(i,sz-1)
{
    ll sum=0;
    f0(j,n)
    {
      if((1<<j)&i)
        sum+=a[j].fi;
    }

    if(sum==t)
    {
     f0(j,n)
      f0(k,3)
        ans=(ans%mod+dp[i][j][k]%mod)%mod;
    }

}
cout<<ans;
}

#include <bits/stdc++.h>
using namespace std;
#define flash ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define debug(x) cerr << " - " << #x << ": " << x << endl;
#define debugs(x, y) cerr << " - " << #x << ": " << x << " " << #y << ": " << y << endl;
#define all(x) (x).begin(),(x).end()
#define sz(x) (ll)x.size()
#define ll long long
#define INF 1000000000
#define mod 1000000007
#define pb push_back
struct greateri
{
    template<class T>
    bool operator()(T const &a, T const &b) const { return a > b; }
};
ll n,T;
ll lenghs[15];
ll dp[1<<15][226][4];
ll genres[15];
ll solve(ll bitmask,ll lengh,ll genre)
{
  ll ans = 0;
  if(lengh==T){return 1;}
  if(lengh>T)return 0;
  if(dp[bitmask][lengh][genre]!=-1)return (dp[bitmask][lengh][genre]%mod);
  for (ll i = 0; i < n; ++i)
  {
    if(!(bitmask&(1<<i)) && lenghs[i]+lengh<=T && genre!=genres[i])
      ans = (ans+(solve(bitmask|(1<<i),lengh+lenghs[i],genres[i]))%(mod));
  }
  return dp[bitmask][lengh][genre]=(ans%mod);
}
int main()
{
  //flash;
  cin>>n>>T;
  memset(dp,-1,sizeof dp);
  for (ll i = 0; i < n; ++i)
  {
    cin>>lenghs[i];
    cin>>genres[i];
    genres[i]--;
  }
  cout<<(solve(0,0,3)%(ll)(1e9+7));
  return 0;
}

#include <bits/stdc++.h>

using namespace std;

const int N = 15;
const int MOD = 1000000007;

int n, t;

int ts[N];
int gs[N];

int dp[4][1 << N];

int ok(int done, int last, int siz) {
    if (dp[last][done] >= 0) {
        return dp[last][done];
    }

    int res = 0;
    if (siz == t) {
        res = 1;
    } else if (siz > t) {
        res = 0;
    } else {
        for (int i = 0; i < n; ++i) {
            int curr = gs[i];
            if (!(done & (1 << i)) && curr != last) {
                res = (res + ok(done ^ (1 << i), curr, siz + ts[i])) % MOD;
            }
        }
    }
    dp[last][done] = res;
    return res;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    clock_t begin_time = clock();

    // Parse input
    cin >> n >> t;

    for (int i = 0; i < n; ++i) {
        cin >> ts[i] >> gs[i];
    }

    // Solve
    int ans = 0;

    memset(dp, -1, sizeof dp);
    ans = ok(0, 0, 0);

    // Print answer
    cout << ans << "\n";

    // Print time
    clock_t end_time = clock();
    double elapsed_secs = double(end_time - begin_time) / CLOCKS_PER_SEC;
    cerr << "Exec time: " << elapsed_secs << endl;
}

#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization ("unroll-loops")
#include <bits/stdc++.h>

using namespace std;
#define endl '\n'
#define ll long long
#define int long long
#define ld double
#define pii pair<int,int>
#define rand() abs((rand()<<15)|rand())
#define randll() abs(((long long)rand()<<30)|rand())
const int MOD = 1'000'000'007;

int ans = 0;
int n, T;
vector<int> inGenre[3];

int dp[20][20][20][4];

int ways(int a, int b, int c, int d) {
	if(dp[a][b][c][d] != -1) return dp[a][b][c][d];
	if(a==0 && b==0 && c==0) return 1;

	int x = 0;
	if(a && d != 0) x += a*ways(a-1,b,c,0);
	if(b && d != 1) x += b*ways(a,b-1,c,1);
	if(c && d != 2) x += c*ways(a,b,c-1,2);
	x %= MOD;
	return dp[a][b][c][d] = x;
}

void solve2(int used1, int used2, int rem) {
	for(int i = 0 ; i < 1<<((int)inGenre[2].size()); i++) {
		int curSum = 0;
		for(int j = 0; j < inGenre[2].size(); j++) {
			if(i & (1<<j))
				curSum += inGenre[2][j];
		}
		if(curSum != rem) continue;
		int cur = __builtin_popcountll(i);
		// cerr << used1 << " " << used2 << " " << cur << endl;
		ans+= ways(used1, used2, cur, 3);
		// cerr << used1 << " " << used2 << " " << cur << endl;
	}
}

void solve1(int used, int rem) {
	for(int i = 0; i < 1<<((int)inGenre[1].size()); i++) {
		int curSum = 0;
		for(int j = 0; j < inGenre[1].size(); j++) {
			if(i & (1<<j))
				curSum += inGenre[1][j];
		}
		if(curSum > rem) continue;
		solve2(used, __builtin_popcountll(i), rem-curSum);
	}
}

signed main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	long long seed;
	asm("rdtsc" : "=A"(seed));
	srand(seed);

	cin >> n >> T;

	memset(dp, -1, sizeof(dp));

	for(int i = 0; i < n; i++) {
		int t,g;
		cin >> t >> g;
		inGenre[g-1].push_back(t);
	}

	for(int i = 0; i < 1<<((int)inGenre[0].size()); i++) {
		int curSum = 0;
		for(int j = 0; j < inGenre[0].size(); j++) {
			if(i & (1<<j))
				curSum += inGenre[0][j];
		}
		if(curSum > T) continue;
		solve1(__builtin_popcountll(i), T-curSum);
	}
	ans %= MOD;

	cout << ans << endl;
}

#include <bits/stdc++.h>

using namespace std;

const int N = 15;
const int MOD = 1000000007;

int ts[N];
int gs[N];

//bool dpd[4][1 << N];
int dp[4][1 << N];

int ok(vector<int> s, int done, int last, int siz) {
    if (dp[last][done] >= 0) {
        return dp[last][done];
    }
    // cerr << "ok(" << done << ", " << last << ")" << "\n";

    int res = 0;
    if (siz == s.size()) {
        res = 1;
    } else {
        for (int i = 0; i < s.size(); ++i) {
            int curr = gs[s[i]];
            if (!(done & (1 << i))) {
                if (curr == last) {
                    continue;
                }
                done |= (1 << i);
                res += ok(s, done, curr, siz + 1);
                res %= MOD;
                done &= (~(1 << i));
            }
        }
    }
    //dpd[last][done] = true;
    dp[last][done] = res;
    return res;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    clock_t begin_time = clock();

    // Parse input
    int n, t;
    cin >> n >> t;

    vector<int> ts2[3];

    for (int i = 0; i < n; ++i) {
        cin >> ts[i] >> gs[i];
        ts2[gs[i] - 1].push_back(ts[i]);
    }

    // Solve
    int ans = 0;

    for (int b = 0; b < (1 << n); b++) {
        vector<int> subset;
        int sum = 0;
        for (int i = 0; i < n; i++) {
            if (b & (1 << i)) {
                subset.push_back(i);
                sum += ts[i];
            }
        }
        if (sum == t) {
            //cerr << subset.size() << endl;
            //memset(dpd, false, sizeof dpd);
            memset(dp, -1, sizeof dp);
            ans += ok(subset, 0, 0, 0);
            ans %= MOD;
        }
    }

    // Print answer
    cout << ans << "\n";
    clock_t end_time = clock();
    double elapsed_secs = double(end_time - begin_time) / CLOCKS_PER_SEC;
    cerr << "Exec time: " << elapsed_secs << endl;
}

#include <bits/stdc++.h>

using namespace std;

const int N = 15;
const int MOD = 1000000007;

int n, t;

int ts[N];
int gs[N];

int dp[4][226][1 << N];

int ok(int done, int last, int siz) {
    if (dp[last][siz][done] >= 0) {
        return dp[last][siz][done];
    }

    int res = 0;
    if (siz == t) {
        res = 1;
    } else if (siz > t) {
        res = 0;
    } else {
        for (int i = 0; i < n; ++i) {
            int curr = gs[i];
            if (!(done & (1 << i))) {
                if (curr == last) {
                    continue;
                }
                done |= (1 << i);
                res += ok(done, curr, siz + ts[i]);
                res %= MOD;
                done &= (~(1 << i));
            }
        }
    }
    dp[last][siz][done] = res;
    return res;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    clock_t begin_time = clock();

    // Parse input
    cin >> n >> t;

    for (int i = 0; i < n; ++i) {
        cin >> ts[i] >> gs[i];
    }

    // Solve
    int ans = 0;

    memset(dp, -1, sizeof dp);
    ans = ok(0, 0, 0);
    ans %= MOD;

    // Print answer
    cout << ans << "\n";

    // Print time
    clock_t end_time = clock();
    double elapsed_secs = double(end_time - begin_time) / CLOCKS_PER_SEC;
    cerr << "Exec time: " << elapsed_secs << endl;
}

#include <bits/stdc++.h>

using namespace std;

const int N = 15;
const int MOD = 1000000007;

int ts[N];
int gs[N];

bool dpd[4][1 << N];
long long dp[4][1 << N];

long long ok(vector<int> s, int done, int last, int siz) {
    if (dpd[last][done]) {
        return dp[last][done];
    }
    // cerr << "ok(" << done << ", " << last << ")" << "\n";

    long long res = 0;
    if (siz == s.size()) {
        res = 1;
    } else {
        for (int i = 0; i < s.size(); ++i) {
            int curr = gs[s[i]];
            if (!(done & (1 << i))) {
                if (curr == last) {
                    continue;
                }
                done |= (1 << i);
                res += ok(s, done, curr, siz + 1) % MOD;
                res %= MOD;
                done &= (~(1 << i));
            }
        }
    }
    dpd[last][done] = true;
    dp[last][done] = res;
    return res;
}

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

    // Parse input
    int n, t;
    cin >> n >> t;

    vector<int> ts2[3];

    for (int i = 0; i < n; ++i) {
        cin >> ts[i] >> gs[i];
        ts2[gs[i] - 1].push_back(ts[i]);
    }

    // Solve
    long long ans = 0;

    for (int b = 0; b < (1 << n); b++) {
        vector<int> subset;
        int sum = 0;
        for (int i = 0; i < n; i++) {
            if (b & (1 << i)) {
                subset.push_back(i);
                sum += ts[i];
            }
        }
        if (sum == t) {
            cerr << subset.size() << endl;
            memset(dpd, false, sizeof dpd);
            memset(dp, 0, sizeof dp);
            ans += ok(subset, 0, 0, 0) % MOD;
            ans %= MOD;
        }
    }

    // Print answer
    cout << ans << "\n";
}

#include<bits/stdc++.h>
using namespace std;

const int N = 17;
const int M = 1e9+7;
int n,t;
pair<int,int> p[N];
int dp[1<<N][5];

int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    cin >> n >> t;
    for(int i=0;i<n;i++){
        cin >> p[i].first >> p[i].second;
        p[i].second--;
    }
    int ans = 0;
    dp[0][3] = 1;
    for(int i=0;i<(1<<n);i++){
        for(int last=0;last<4;last++){
            for(int j=0;j<n;j++){
                if(p[j].second != last && ((i & (1<<j)) == 0)){
                    dp[i ^ (1<<j)][p[j].second] += dp[i][last];
                    dp[i ^ (1<<j)][p[j].second] %= M;
                }
            }
            int sum = 0;
            for(int k=0;k<n;k++){
                if(i & (1<<k)){
                    sum += p[k].first;
                }
            }
            if(sum == t){
                ans += dp[i][last];
                ans %= M;
            }
        }
    }
    cout << (ans%M + M)%M << '\n';

    return 0;
}

/*
	Author: @nik1998
	Nikhil Saxena, NITW
*/
#include <bits/stdc++.h>
#define ll long long int
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define fio ios_base::sync_with_stdio(false);cin.tie(NULL)
const ll mod = 1e9 + 7;

inline ll mul(ll a, ll b){ return (a * 1ll * b) % mod; }
inline ll sub(ll a, ll b){ ll c = a - b; if(c < 0) c += mod; return c; }
inline ll add(ll a, ll b){ ll c = a + b; if(c > mod) c -= mod; return c; }

using namespace std;

ll dp[1<<15][4];
int n,T;
vector<pair<int,int> > v;

int calc(int mask,int lst,int t)
{
	if(dp[mask][lst] != -1) return dp[mask][lst];

//	cout<<"mask - "<<mask<<endl;
//	cout<<"last - "<<lst<<endl;
//	cout<<"t - "<<t<<endl;

	if(t > T) return 0;
	if(t == T) return 1;
	if(mask == ((1<<n) - 1)) return 0;

	ll ans = 0;

	for(int i=0;i<n;i++)
	{
		if(((mask>>i)&1) == 0 and v[i].ss != lst)
		{
			ans += calc(mask|(1<<i),v[i].ss,t+v[i].ff);
			ans = ans%mod;
		}
	}
	dp[mask][lst] = ans;
	return ans;
}

int main()
{
	int tc = 1;
	while(tc--)
	{
		cin>>n>>T;

		memset(dp,-1,sizeof(dp));

		for(int i=0;i<n;i++)
		{
			int ti,gi;
			cin>>ti>>gi;

			v.pb(mp(ti,gi));
		}

		cout<<calc(0,0,0)<<endl;
	}
}

#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/hash_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;
#ifdef local
    #define readinfile(file) freopen(file, "r", stdin)
    template<class T>
    void err(T x) { cerr << x << endl;}
    template<class T, class...Args>
    void err(T x, Args... args){cerr << x << ' ';err(args...);}
#else
    #define debug(...)
    #define readinfile(...)
    #define endl '\n'
    #define cerr if(0)cout
    #define err(...)
#endif
#define fi first
#define se second
#define eb emplace_back
#define bk back
#define ppb pop_back
#define ins insert
#define clr(a, b) memset(a, b, sizeof a)
#define rep(i, n) for(int i = 0; i < n; i++)
#define ls rt << 1
#define rs rt<<1|1
#define inf 0x3f3f3f3f
typedef long long ll;
typedef vector<int> VI;
typedef pair<int, int> pii;
typedef long double ldb;
typedef complex<double> cpd;
const int N = 1e5 + 7, M = 1 << 10;
const double pi = acos(-1.0);
const int mod = 1e9 + 7;
const ll P = 7 * 17 << 23 | 1, G = 3;

array<int, 3> g[1 << 15];
int f[1 << 15];
int a[15], ty[15];

const int S = 226;
int dp[S][S][S][3], fac[S];

ll calc(array<int, 3> x) {
    ll ret = 0;
    for(int i = 0; i < 3; i++)
        ret = (ret + dp[x[0]][x[1]][x[2]][i]) % mod;
    ret = ret * fac[x[0]] % mod * fac[x[1]] % mod * fac[x[2]] % mod;
    return ret;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    readinfile("in.txt");

    dp[1][0][0][0] = dp[0][1][0][1] = dp[0][0][1][2] = 1;
    for(int i = 0; i < S; i++) {
        for(int j = 0; j < S; j++) {
            for(int k = 0; k < S; k++) {
                if(i + j + k < 1) continue;
                if(i + 1 < S) dp[i+1][j][k][0] = (dp[i][j][k][1] + dp[i][j][k][2]) % mod;
                if(j + 1 < S) dp[i][j+1][k][1] = (dp[i][j][k][0] + dp[i][j][k][2]) % mod;
                if(k + 1 < S) dp[i][j][k+1][2] = (dp[i][j][k][0] + dp[i][j][k][1]) % mod;
            }
        }
    }
    fac[0] = 1;
    for(int i = 1; i < S; i++) fac[i] = 1ll * fac[i - 1] * i % mod;
    int n, t; cin >> n >> t;
    for(int i = 0; i < n; i++) {
        cin >> a[i] >> ty[i]; --ty[i];
        g[1<<i][ty[i]] = 1;
        f[1<<i] = a[i];
    }

    ll ans = 0;
    for(int i = 0; i < 1<<n; i++) {
        //if(f[i]) continue;
        f[i] = f[i&(i-1)] + f[i&-i];
        for(int j = 0; j < 3; j++)
            g[i][j] = g[i&(i-1)][j] + g[i&-i][j];
        if(f[i] == t) {
            ans = (ans + calc(g[i])) % mod;
        }
    }
    cout << ans << '\n';
    err(clock(), " ms");
    return 0;
}

#include<bits/stdc++.h>
using namespace         std;
#define                 int long long
#define                 pb push_back
#define                 mp make_pair
#define st(arr,a)       memset(arr,a,sizeof arr)
#define                 nl cout<<endl
#define                 real signed
#define                 endl '\n'
#define bitcount(x)     __builtin_popcountll(x)
const int MOD = 1000000007ll;
#define forn(i,a,b)     for(int i=a;i<=b;i++)
#define rfor(i,a,b)     for(int i=a;i>=b;i--)
#define all(x)          x.begin() , x.end()
#define pi pair<int,int>
#define X first
#define Y second
#define N 1014159
#define  vi vector<int>
#define  v  vector

int n,T;
int g[20],t[20];
const int MX = (1LL<<15)+50;
int dp[MX][4];
int sum[MX];

int get(int mask,int last)
{

    int x = sum[mask];
    if(x>T)return 0;
    if(x == T)return 1;
    int&ans=dp[mask][last];
    if(ans!=-1)return ans;
    ans = 0;
    forn(i,0,n-1)
    {
        if((((1LL<<i)&mask) == 0) and g[i]!=last)
            ans=(ans+get(mask|(1LL<<i),g[i]))%MOD;
    }
    return ans;
}

signed solve()
{
    cin>>n>>T;
    forn(i,0,n-1)cin>>t[i]>>g[i];
    forn(mask,0,(1LL<<n)-1)
    {
        int x = 0;
        forn(i,0,n-1)
            if((1LL<<i)&mask)x+=t[i];
        sum[mask] = x;
    }
    st(dp,-1);
    int ans = 0;
    forn(i,0,n-1)ans=(ans+get((1LL<<i),g[i]))%MOD;
    cout<<ans;
}

signed main()
{
    ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
    int t = 1;
    //cin>>t;
    while(t--)
    {
        solve();
    }

    return 0;

}

//       g++ -g c.cpp ; ./a.exe

#include <bits/stdc++.h>
using namespace std;
#define int int64_t

const int MAXN = 15, MOD = 1e9 + 7;
pair<int, int> arr[MAXN];
int dp[(1 << MAXN)][3];

main() {
    int n, t;
    cin >> n >> t;
    for (int i = 0; i < n; ++i) {
        cin >> arr[i].first >> arr[i].second;
        arr[i].second--;
    }
    dp[0][0] = dp[0][1] = dp[0][2] = 1;
    int ans = 0;
    for (int mask = 1; mask < (1 << n); ++mask) {
        int sum = 0;
        for (int i = 0; i < n; ++i) {
            if (mask & (1 << i)) {
                // cout << i << endl;
                // cout << (mask ^ (1 << i)) << endl;
                int g = arr[i].second;
                sum += arr[i].first;
                // cout << dp[0][(g + 1) % 3] << " ";
                // cout << dp[0][(g + 2) % 3] << endl;
                dp[mask][g] += dp[mask ^ (1 << i)][(g + 1) % 3];
                dp[mask][g] %= MOD;
                dp[mask][g] += dp[mask ^ (1 << i)][(g + 2) % 3];
                dp[mask][g] %= MOD;
                // cout << g << " " << dp[mask][g] << endl;
            }
        }
        if (sum == t) {
            ans += dp[mask][0];
            ans += dp[mask][1];
            ans += dp[mask][2];
            ans %= MOD;
        }
        // cout << mask << " " << dp[mask][0] << " ";
        // cout << dp[mask][1] << " " << dp[mask][2] << endl;
    }
    if (ans % 2 == 1) {
        ans += MOD;
    }
    cout << ans / 2;
    return 0;
}

#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define mp make_pair
#define eb emplace_back
#define all(a) begin(a), end(a)
#define has(a, b) (a.find(b) != a.end())
#define fora(i, n) for(int i = 0; i < n; i++)
#define forb(i, n) for(int i = 1; i <= n; i++)
#define forc(a, b) for(const auto &a : b)
#define ford(i, n) for(int i = n; i >= 0; i--)
#define maxval(t) numeric_limits<t>::max()
#define minval(t) numeric_limits<t>::min()
#define imin(a, b) a = min(a, b)
#define imax(a, b) a = max(a, b)
#define sz(x) (int)(x).size()
#define pvec(v) copy(all(v), ostream_iterator<decltype(v)::value_type>(cout, " "))

#define dbgs(x) #x << " = " << x
#define dbgs2(x, y) dbgs(x) << ", " << dbgs(y)
#define dbgs3(x, y, z) dbgs2(x, y) << ", " << dbgs(z)
#define dbgs4(w, x, y, z) dbgs3(w, x, y) << ", " << dbgs(z)

using ll = long long;
using ld = long double;

constexpr ll mod = 1000000007;

ll dp[2][2501][51][51];
ll cnt[51][51][51][3];

ll gc(int j0, int j1, int j2, int last) {
	if (cnt[j0][j1][j2][last] != -1) return cnt[j0][j1][j2][last];
	if (last == 0 && j0 == 0) return 0;
	if (last == 1 && j1 == 0) return 0;
	if (last == 2 && j2 == 0) return 0;

	ll res = 0;
	ll opt = 0;
	if (last == 0) opt = j0;
	if (last == 1) opt = j1;
	if (last == 2) opt = j2;
	int jj0 = j0 - (last == 0);
	int jj1 = j1 - (last == 1);
	int jj2 = j2 - (last == 2);
	if (last != 0) {
		res = (res + (gc(jj0, jj1, jj2, 0) * opt) % mod) % mod;
	}
	if (last != 1) {
		res = (res + (gc(jj0, jj1, jj2, 1) * opt) % mod) % mod;
	}
	if (last != 2) {
		res = (res + (gc(jj0, jj1, jj2, 2) * opt) % mod) % mod;
	}
	cnt[j0][j1][j2][last] = res;
	return res;
}

ll th[2][2501][51];

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);

	int n, T;
	cin >> n >> T;

	vector<int> t(n), g(n);
	fora(i, n) { cin >> t[i] >> g[i]; --g[i]; }

	fora(a, n + 1) fora(b, n + 1) fora(c, n + 1) fora(d, 3) cnt[a][b][c][d] = -1;
	cnt[1][0][0][0] = 1;
	cnt[0][1][0][1] = 1;
	cnt[0][0][1][2] = 1;

	dp[0][0][0][0] = 1;
	ll res = 0;

	th[0][0][0] = 1;
	fora(i, n) {
		int from = i % 2;
		int to = (i + 1) % 2;
		fora(x, T + 1) fora(j, n + 1) {
			th[to][x][j] = th[from][x][j];
		}
		if (g[i] != 0) continue;

		fora(x, T + 1) fora(j, n) {
			if (x + t[i] > T) break;
			th[to][x + t[i]][j + 1] = (th[to][x + t[i]][j + 1] + th[from][x][j]) % mod;
		}
	}

	fora(i, n) {
		int from = i % 2;
		int to = (i + 1) % 2;
		fora(x, T + 1) fora(j1, n + 1) fora(j2, n + 1) {
			if (j1 + j2 > i + 1) break;
			dp[to][x][j1][j2] = dp[from][x][j1][j2];
		}

		if (g[i] == 0) continue;

		fora(x, T + 1) fora(j1, n + 1) fora(j2, n + 1) {
			if (j1 + j2 > i + 1) break;
			if (x + t[i] > T) break;
			int jj1 = j1 + (g[i] == 1);
			int jj2 = j2 + (g[i] == 2);
			if (jj1 > n || jj2 > n) continue;
			dp[to][x + t[i]][jj1][jj2] = (dp[to][x + t[i]][jj1][jj2] + dp[from][x][j1][j2]) % mod;
		}
	}

	fora(x, T + 1) fora(j0, n + 1) fora(j1, n + 1) fora(j2, n + 1) {
		if (j0 + j1 + j2 > n) break;
		fora(l, 3) {
			//if (dp[to][T][j1][j2] != 0 && gc(j0, j1, j2, l) != 0)
				//cout << dbgs4(j0, j1, j2, dp[to][T][j1][j2]) << ", " << dbgs(gc(j0, j1, j2, l)) << endl;
			ll u = (dp[n % 2][x][j1][j2] * th[n % 2][T - x][j0]) % mod;
			u = (u * gc(j0, j1, j2, l)) % mod;
			res = (res + u) % mod;
			//res = (res + (dp[to][T][j1][j2] * gc(j0, j1, j2, l)) % mod) % mod;
		}
	}

	cout << res << endl;

}

#include <bits/stdc++.h>

#define ll long long
#define pb push_back
#define pii pair<int,int>
#define pll pair<ll,ll>
#define ff first
#define ss second

using namespace std;

const double pi = acos(-1);
const int N = 1e6 + 6, mod = 1000000007, M = 1e7 + 7;
const ll MAX = 5e18;

int n, t, a[16][2], c[4];
ll ans[20][20][20][4];

int moding(ll x){
    if(x >= mod)
        x %= mod;
    return x;
}

ll slv(int x, int y, int z, int lst = 0){

}

ll clc(int x, int y, int z, int lst = 0){
//    cout << x << ' ' << y << ' ' << z << endl;
    if((!y && !z && lst == 1)  || (!x && !z && lst == 2) || (!x && !y && lst == 3))
        return 1;
    ll& ret = ans[x][y][z][lst];
    if(~ret)
        return ret;
    ll c1 = 0, c2 = 0, c3 = 0;
    if(x > 0)
        c1 = clc(x - 1, y, z, 1);
    if(y > 0)
        c2 = clc(x, y - 1, z, 2);
    if(z > 0)
        c3 = clc(x, y, z - 1, 3);
    if(!lst)
        return ret = c1 + c2 + c3;
    else if(lst == 1)
        return ret = c2 + c3;
    else if(lst == 2)
        return ret = c1 + c3;
    return ret = c1 + c2;
}

ll slv(int i = 0, int s = 0){
    if(i == n){
        if(s == t)
            return clc(c[1], c[2], c[3]);
        return 0;
    }
    ll ret = slv(i + 1, s);
    c[a[i][1]]++;
    ret = moding(ret + slv(i + 1, s + a[i][0]));
    c[a[i][1]]--;
    return ret;
}

int main()
{
    memset(ans, -1, sizeof ans);
    cin >> n >> t;
    for(int i = 0; i < n; i++)
        scanf("%d%d", &a[i][0], &a[i][1]);

    cout << slv();
    return 0;
}

#include<iostream>
#include<cstring>
using namespace std;
int a[2000000];
int b[2000000];
int dp[226][32769][4];
 int n,sum;
int music(int sum,int mask,int last){

   if(sum==0){

       return 1;
   }

   if(sum<0){
       return 0;
   }

   if(mask==((1<<n)-1)){
       return 0;
   }
  if(dp[sum][mask][last]!=-1){
       return dp[sum][mask][last];
   }
   int q=0;

    for(int i=0;i<n;i++){
        if((mask&(1<<i))==0 && b[i]!=last){
            mask|=(1<<i);
            //cout<<mask<<endl;
            q+=music(sum-a[i],mask,b[i]);
            mask=mask^(1<<i);
        }
    }
    dp[sum][mask][last]=q;

    return q;
}

int main(){

    cin>>n>>sum;
    for(int i=0;i<n;i++){
        cin>>a[i];
        cin>>b[i];
    }
    memset(dp,-1,sizeof(dp));
    int mask=0;
    cout<<music(sum,mask,-1);

}

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod = 1e9+7;
const int maxn = 2505;
const int maxx = 55;

ll fac[maxx];
ll dp[maxn][maxx][4];
vector<int> s[4];
int Ti[4], num[4];
int n, T;
ll ans = 0;

void init() {
    fac[0] = 1;
    for(int i = 1; i < maxx; i++)
        fac[i] = fac[i-1]*i%mod;
}

void get_dp(int k) {
    dp[0][0][k] = 1;
    int len = s[k].size();
    for(int i = 0; i < len; i++) {   // good
        for(int j = maxn-1; j >= 0; j--) {  // space
            for(int t = i; t >= 0; t--) {  // num
                if(dp[j][t][k] == 0)  continue;
                dp[j+s[k][i]][t+1][k] += dp[j][t][k];
            }
        }
    }
}

ll A(int n) {
    if(n < 2)  return 0;
    return 1ll*n*(n-1);
}

void calc(ll k) {
    k %= mod;
    int sum = num[1] + num[2] + num[3];
    if(sum == 1) {
        ans += k;
        if(ans >= mod)  ans %= mod;
    }
    else if(sum == 2) {
        if(num[1] == 2 || num[2] == 2 || num[3] == 2)  return;
        ans += 2ll*k;
        if(ans >= mod)  ans %= mod;
    }
    else {
        int a = num[1], b = num[2], c = num[3];
        ll aa = A(a), bb = A(b), cc = A(c);
        ll tmp = fac[sum] - (aa+bb+cc)*fac[sum-1] + (aa*bb+aa*cc+bb*cc)*fac[sum-2] - aa*bb*cc*fac[sum-3];
        tmp = (mod+tmp%mod)%mod;
        tmp = tmp*k%mod;
        ans += tmp;
        if(ans >= mod)  ans %= mod;
    }
   // cout << "k = " << k << "\n";
}

void dfs(int now, ll k) {
    if(now == 4)  {
        calc(k);
        return;
    }
    for(int i = 0; i < maxx; i++)
        if(dp[Ti[now]][i][now] != 0) {
            num[now] = i;
            dfs(now+1, k*dp[Ti[now]][i][now]);
        }
    return;
}

int main() {
    init();
    scanf("%d%d", &n, &T);
    for(int i = 0; i < n; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        s[y].push_back(x);
    }
    for(int i = 1; i <= 3; i++)  get_dp(i);
  /*  for(int i = 0; i <= 5; i++)
        for(int j = 0; j <= 3; j++)
            cout << "i = " << i << "  j = " << j << "   dp = " << dp[i][j][1] << "\n";*/
    for(Ti[1] = 0; Ti[1] <= T; Ti[1]++) {
        for(Ti[2] = 0; Ti[2] <= T-Ti[1]; Ti[2]++) {
            Ti[3] = T-Ti[1]-Ti[2];
            dfs(1, 1ll*1);
        }
        //cout << "TA = " << Ti[1] << "    ans = " << ans << "\n";
    }
    printf("%lld\n", ans);
}

#include<bits/stdc++.h>

#define rep(i,a,n)     for(int i=a;i<n;i++)
#define rep3(n)        for(int i=0;i<n;i++)
#define ll             long long
#define int            long long
#define pb             push_back
#define all(v)         v.begin(),v.end()
#define endl           "\n"
#define eb             emplace_back
#define x              first
#define y              second
#define gcd(a,b)       __gcd(a,b)
#define mem1(a)        memset(a,-1,sizeof(a))
#define mem0(a)        memset(a,0,sizeof(a))
#define pres(a,x)      a.find(x)!=a.end()
#define sz(a)          (int)a.size()
#define pii            pair<int,int>
#define hell           1000000007
#define elasped_time   1.0 * clock() / CLOCKS_PER_SEC
using namespace std;

template<typename T1,typename T2>istream& operator>>(istream& in,pair<T1,T2> &a){in>>a.x>>a.y;return in;}
template<typename T1,typename T2>ostream& operator<<(ostream& out,pair<T1,T2> a){out<<a.x<<" "<<a.y;return out;}
template<typename T,typename T1>T maxs(T &a,T1 b){if(b>a)a=b;return a;}
template<typename T,typename T1>T mins(T &a,T1 b){if(b<a)a=b;return a;}
template<int mod>
struct mint {
  int x;
  mint():x(0){}
  mint(int x):x((x%mod+mod)%mod){}
  // mint(int x):x(x){}
  mint& fix() { x = (x%mod+mod)%mod; return *this;}
  mint operator-() const { return mint(0) - *this;}
  mint& operator+=(const mint& a){ if((x+=a.x)>=mod) x-=mod; return *this;}
  mint& operator-=(const mint& a){ if((x+=mod-a.x)>=mod) x-=mod; return *this;}
  mint& operator*=(const mint& a){ (x*=a.x)%=mod; return *this;}
  mint operator+(const mint& a)const{ return mint(*this) += a;}
  mint operator-(const mint& a)const{ return mint(*this) -= a;}
  mint operator*(const mint& a)const{ return mint(*this) *= a;}
  bool operator<(const mint& a)const{ return x < a.x;}
  bool operator==(const mint& a)const{ return x == a.x;}

  friend istream& operator>>(istream&i,mint&a){i>>a.x;return i;}
  friend ostream& operator<<(ostream&o,const mint&a){o<<a.x;return o;}
  mint<mod> expo(mint<mod> x,int y){
       mint<mod> a=1;
       while(y){
       	 if(y&1)a=a*x;
       	 x=x*x;
       	 y/=2;
       }
       return a;
  }
};
mint<hell>dp[51][51][51][4];
mint<hell>fact[100];
mint<hell>dpa[51][2501];
mint<hell>dpb[51][51][2501];
int solve(){
 int n,t;cin>>n>>t;
 vector<pii>a(n);
 rep3(n)cin>>a[i];
 dp[1][0][0][1]=1;
 dp[0][1][0][2]=1;
 dp[0][0][1][3]=1;
 for(int i=0;i<=50;i++){
 	for(int j=0;j<=50;j++){
 		for(int k=0;k<=50;k++){
 			if(i+j+k<=1)continue;
 			for(int t=1;t<=3;t++){
 				if(t==1){
 					if(i>0)dp[i][j][k][1]=dp[i-1][j][k][2]+dp[i-1][j][k][3];
 				}
 				else if(t==2){
 					if(j>0)dp[i][j][k][2]=dp[i][j-1][k][1]+dp[i][j-1][k][3];
 				}
 				else {
 					if(k>0)dp[i][j][k][3]=dp[i][j][k-1][1]+dp[i][j][k-1][2];
 				}
 			}
 		}
 	}
 }
 dpa[0][0]=1;
 dpb[0][0][0]=1;
 int cnt1=0,cnt2=0,cnt3=0;
 for(int i=0;i<n;i++){
 	if(a[i].y==1){
 		cnt1++;
 		for(int j=1;j<=cnt1;j++){
 			for(int t=a[i].x;t<=2500;t++)dpa[j][t]=dpa[j-1][t-a[i].x];
 		}
 	}
 	else{
 		if(a[i].y==2)cnt2++;
 		if(a[i].y==3)cnt3++;
 		for(int j=0;j<=cnt2;j++){
           for(int k=0;k<=cnt3;k++){
           	   if(j+k==0)continue;
           	   for(int t=a[i].x;t<=2500;t++){
           	   	  if(a[i].y==2 && j>0)dpb[j][k][t]+=dpb[j-1][k][t-a[i].x];
           	   	  if(a[i].y==3 && k>0)dpb[j][k][t]+=dpb[j][k-1][t-a[i].x];
           	   }
           }
 		}
 	}
 }
 mint<hell>ans=0;
 for(int i=0;i<=t;i++){
    for(int t1=0;t1<=cnt1;t1++){
       for(int t2=0;t2<=cnt2;t2++){
       	 for(int t3=0;t3<=cnt3;t3++){
       	 	mint<hell>ways=dpa[t1][i]*dpb[t2][t3][t-i];
       	 	mint<hell>ways2=dp[t1][t2][t3][1]+dp[t1][t2][t3][2]+dp[t1][t2][t3][3];
       	 	ways2=ways2*fact[t1]*fact[t2]*fact[t3];
       	 	ans+=ways*ways2;
       	 }
       }
    }
 }
 cout<<ans<<endl;
 return 0;
}
signed main(){
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    fact[0]=1;
    for(int i=1;i<100;i++){
    	mint<hell>val=i;
    	fact[i]=val*fact[i-1];
    }
    #ifdef SIEVE
    sieve();
    #endif
    #ifdef NCR
    init();
    #endif
    int t=1;//cin>>t;
    while(t--){
        solve();
    }
    return 0;
}

#include <bits/stdc++.h>
using namespace std;

const int MAX_N = 15;
const int MAX_G = 3;
const int MAX_T = 255;
const int MOD = 1e9 + 7;
int n, m;
int memo[MAX_T + 1][(1<<15) + 1];
vector<int> gen, dur;

int f(int d = m, int lgen = 0, int mask = 0){
	if(d < 0) return 0;
	if(d == 0) return 1;
	if(__builtin_popcount(mask) == n) return 0;
	if(memo[d][mask] != -1) return memo[d][mask];
	int w = 0;
	for(int i = 0; i < n; i++){
		if(mask & 1<<i) continue;
		if(gen[i] == lgen) continue;
		mask = mask | 1<<i;
		w += f(d - dur[i], gen[i], mask);
		mask = mask ^ 1<<i;
		if(w >= MOD) w -= MOD;
	}
	memo[d][mask] = w;
	return memo[d][mask];
}
int main() {
//	cout << sizeof(memo) << '\n';
	memset(memo, -1, sizeof(memo));
	cin >> n >> m;
	gen = dur = vector<int> (n);
	for(int i = 0; i < n; i++){
		cin >> dur[i] >> gen[i];
	}
	cout << f() << "\n";
	return 0;
}

#include <bits/stdc++.h>
#define ll long long
#define ld long double
#define ull unsigned long long
#define pb push_back
#define ft first
#define sd second
using namespace std;

const ll mod = 1e9 + 7;
ll n, T;
ll genre[16];
ll dura[16];
ll dp[(1 << 15)][3][256];

int main()
{
    scanf("%lld %lld",&n,&T);
    for( ll i = 0; i < n; i++ ){
        scanf("%lld %lld",&dura[i],&genre[i]);
        genre[i]--;
       // printf("%lld\n", genre[i]);
    }

    for( ll i = 1; i <= T; i++ ){
        for( ll x = 1; x < (1 << n); x++ ){

            if( __builtin_popcount( x ) == 1 ){
                ll p = log2(x);
                if( i == dura[p] ){
                    dp[x][genre[p]][i]++;
                    if( dp[x][genre[p]][i] >= mod )dp[x][genre[p]][i] -= mod;
                }
                continue;
            }

            for( ll j = 0; j < n; j++ ){
                if( dura[j] > i ) continue;
                if( x & (1 << j) ){
                    for( ll k = 0; k < 3; k++ ){
                        if( k == genre[j] ) continue; //no nos importa que este encencido, si esta off ya es 0 la dp
                        dp[x][genre[j]][i] += dp[x - (1 << j)][k][i - dura[j]];
                        if( dp[x][genre[j]][i] >= mod )dp[x][genre[j]][i] -= mod;

                    }

                }
            }
        }
    }
    ll ans = 0;
    for( ll i = 1; i < (1 << n); i++ )
        for( ll j = 0; j < 3; j++ )
                ans += dp[i][j][T];
                if( ans >= mod ) ans -= mod;

    printf("%lld",ans);
    return 0;
}

///In the name of Allah
///BY_Mohammed_ALmasry
#include <bits/stdc++.h>
using namespace std;
typedef  long long ll;
#include <ctime>
#include <iomanip>
#define Fastio ios_base::sync_with_stdio(false)
#define pi 3.14159265358979323846//pi=acos(-1)
#define read freopen("input.txt","r",stdin)
#define write freopen("output.txt","w",stdout)
#define fi first
#define se second
#define pb push_back
#define pob pop_back
#define f0(i,n) for(ll i=0;i<n;i++)
#define rf0(n,i) for(ll i=n-1;i>=0;i--)
#define f1(i,n) for(ll i=1;i<=n;i++)
#define rf1(n,i) for(ll i=n;i>=1;i--)
#define ff(i,s,e) for(ll i=s;i<=e;i++)
#define rff(i,e,s) for(ll i=e;i>=s;i--)
#define all(v) v.begin(),v.end()
#define mod 1000000007
#define sz size
#define all(X) X.begin(),X.end()
#define memset(X,Y) memset(X,Y,sizeof X)
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pff pair<float,float>
#define pdd pair<double,double>
///1) double rad= ( ( Angle_in_degree  *pi ) * 1.0 ) / 180;
///2) tan(rad):only in radians
///1) x=GCD(a,b) && y=LCM(a,b) && GCD(c,d)=1
///2) x*y=a*b ==> x*y=(x*c)*(x*d) ==> y=x*c*d ==> y/x=c*d ==> (a*b=n=y/x)
///1) In Euclidean geometry, a regular polygon is a polygon that is equiangular (all angles are equal in measure)
///2) and equilateral (all sides have the same length).Regular polygons may be either convex or star
///3) each interior angle has a measure of (180*(n-2))/n degrees
///cout<<fixed<<setprecision(0);
///Time complexity : O() && Memory complexity :
///Surface area of a cube : 6 * L * L
///Remember that map<int, map<int,int> >mm; mm[any interger][any interger]++ ; Time complexity is  log(n)+log(m)
///Remember that set.erase( set.find( value in the set ) ) --> Time complexity is O(log(n))
///string s; getline(cin,s); // take one line
///__builtin_popcountll( x ) : It returns the number of ones in the binary representation of the long long x.
/// for ( int i: {x1,x2,x3 ,....etc} )
/// for i>30 use 1LL (1LL<<i)
/// hypot( x , y ) :  الجذر التربيعي
///read;write;
int dir4[4][2]= {{1,0},{0,1},{-1,0},{0,-1}};
int dir8[8][2]= {{-1,0},{1,0},{0,1},{0,-1},{-1,1},{1,-1},{1,1},{-1,-1}};
int dir8h[8][2]= {{2,1},{-2,-1},{-1,2},{1,-2},{1,2},{-2,1},{2,-1},{-1,-2}};
long double eps=1e-7;
const int N=2e5;
int main()
{
Fastio;
ll sz=pow(2,15);
ll dp[sz][4];
memset(dp,0);
int n,t;
cin>>n>>t;
pii a[n+3];
f0(i,n)
{
cin>>a[i].fi>>a[i].se;
dp[(1<<i)][a[i].se]=1;
}
ll ans=0;
f1(i,sz-1)
{
    f0(j,n)
    {
      if((1<<j)&i)
      {
          f0(k,n)
          {
              if((i&(1<<k))==0&&a[k].se!=a[j].se)
              {
                  dp[(i|(1<<k))][a[k].se]= (dp[(i|(1<<k))][a[k].se]%mod+dp[i][a[j].se]%mod)%mod;
              }
          }
      }
    }
}
f1(i,sz-1)
{
    ll sum=0;
    f0(j,n)
    {
      if((1<<j)&i)
      {
          sum+=a[j].fi;
      }
    }
    if(sum==t)
    {
      f1(j,n)
       ans=(ans%mod+dp[i][j]%mod)%mod;
    }

}
cout<<ans;
}

#include "bits/stdc++.h"

using namespace std;

#define int                long long int
#define endl              '\n'

#define pii                pair <int, int>

static const int maxn = 15 + 5;
static const int mod = 1e9 + 7;

pii arr[maxn];
int factorial[maxn];

signed main()
{
      ios_base::sync_with_stdio(false);
      cin.tie(nullptr);
      cout.tie(nullptr);

      #ifndef ONLINE_JUDGE
            freopen("in.txt", "r", stdin);
      #endif // ONLINE_JUDGE

      factorial[0] = 1;
      for (int i = 1; i < 20; i++)
      {
            factorial[i] = (i * factorial[i-1]) % mod;
            cerr << i << ' ' << factorial[i] << endl;
      }

      int n;
      cin >> n;
      int T;
      cin >> T;
      for (int i = 1; i <= n; i++)
      {
            int tym, gen;
            cin >> tym >> gen;
            arr[i-1].first = tym;
            arr[i-1].second = gen;
      }
      int ans = 0;
      for (int mask = 0; mask < (1LL << n); mask++)
      {
            vector <pii> vec;
            vector <int> fre(5);
            int sum = 0;
            for (int i = 0; i < n; i++)
            {
                  bool bit = (bool)(mask & (1LL << i));
                  if (bit == 1)
                  {
                        vec.push_back(arr[i]);
                        fre[ arr[i].second ]++;
                        sum += arr[i].first;
                  }
            }
            if (sum != T) continue;
            int sze = vec.size();
            int fact = factorial[sze];
            int bad = 0;
            int total = sze;
            if (fre[1] > 1)
            {
                  int one = fre[1];
                  int other = total - one + 1;
                  int add = (factorial[one] * factorial[other]) % mod;
                  bad = (bad + add) % mod;
                  total = total - one + 1;
            }
            if (fre[2] > 1)
            {
                  int two = fre[2];
                  int other = total - two + 1;
                  int add = (factorial[two] * factorial[other]) % mod;
                  bad = (bad + add) % mod;
                  total = total - two + 1;
            }
            if (fre[3] > 1)
            {
                  int three = fre[3];
                  int other = total - three + 1;
                  int add = (factorial[three] * factorial[other]) % mod;
                  bad = (bad + add) % mod;
                  total = total - three + 1;
            }
            int sumTOadd = (fact - bad + mod) % mod;
            ans = (ans + sumTOadd) % mod;
            assert(ans >= 0);
      }
      cout << ans;
}

/*
    Mbak Rose Dong
*/
#include<bits/stdc++.h>
using namespace std;
const int mod = 1e9+7;
long long int dp[40000][4];
int t[20], genre[20];
int n,i,j,k,x,y,ans,curr,m;
long long int rose = 0;
long long int fact[25];
int cnt;
int music = 0;
long long int dfs(int pos, int lastGenre, int index)
{
    if(dp[music][lastGenre] != -1)
        return dp[music][lastGenre];
    if(pos == k)
    {
        set<int> s;
        cnt = 0;
        int i;
        for(i=1;i<=n;i++)
        {
            if(music & (1 << i-1))
            {
                s.insert(genre[i]);
                cnt++;
            }
        }
        long long int ret = 1LL*s.size();
        if(ret == 1 && cnt > 1)
            rose += 0;
        else
            rose += (fact[ret] % mod);
        return dp[music][lastGenre] = 1;
    }
    long long int sum = 0;
    for(int i = index; i <= n; i++)
    {
        int m = t[i];
        int g = genre[i];
        if(pos+m <= k)
        {
            music |= (1 << i-1);
            sum += dfs(pos+m, g, i+1) % mod;
            music ^= (1 << i-1);
        }
    }
    return dp[music][lastGenre] = sum % mod;
}
int main()
{
    scanf("%d %d",&n,&k);
    fact[0] = 1;
    for(i=1;i<=20;i++)
    {
        fact[i] = (fact[i-1] * i) % mod;
    }
    for(j=0;j<40000;j++)
        for(m=0;m<4;m++)
            dp[j][m] = -1;
    for(i=1;i<=n;i++)
    {
        scanf("%d %d",&t[i], &genre[i]);
        genre[i]--;
    }
    music = 0;
    dfs(0, 3, 1);
    cout << rose << endl;
    return 0;
}

# include <bits/stdc++.h>
# define ll long long
# define INF 1000000007
#define ff first
#define ss second
using namespace std;

ll a,b,ans;

ll d[100009];
ll c[100009][2];
bool vs[100009];

void dfs(ll x, ll y)
{
	if(y==b)
	{ans++;return;}
	if(x==a)
		return;
	for(ll i=0;i<a;i++)
	if(vs[i]==0 && (i==0 || (i>0 && c[d[x-1]][1]!=c[i][1])) && y+c[i][0]<=b)
	{
		d[x]=i;
		y+=c[i][0];
		vs[i]=1;
		dfs(x+1,y);
		y-=c[i][0];
		vs[i]=0;
	}
}

int main()
{
	cin>>a>>b;

	for(ll i=0;i<a;i++)
	cin>>c[i][0]>>c[i][1];

	dfs(0,0);
	cout<<ans;
}

#include "bits/stdc++.h"

using namespace std;
using LL = long long;

int n, T;
int dat[20], inT[20], inG[20];
int used[20];

map< int, int> mp[20];

LL rec(int k, int sum, int last, int mask) {
    if (mp[last].count(mask)) return mp[last][mask];
    if (sum > T) return 0;

    if (sum == T) {
        return 1;
    }

    LL rv = 0;
    for (int i = 0; i < n; ++i) {
        if (used[i]) continue;

        if (k == 0 or inG[i] != inG[dat[k - 1]]) {
            used[i] = 1;
            dat[k] = i;
            mask ^= 1 << i;
            rv += rec(k + 1, sum + inT[i], inG[i], mask);
            mask ^= 1 << i;
            used[i] = 0;
        }
    }
    return mp[last][mask] = rv;
}

int main() {
    scanf("%d %d", &n, &T);
    for (int i = 0; i < n; ++i) {
        scanf("%d %d", &inT[i], &inG[i]);
    }

    LL res = rec(0, 0, 0, 0);
    cout << res << endl;
}

#include <iostream>
#include <cstring>
int dp[226][1<<16][4];
int T[16];
int genre[16];
int n,t;
int bc(int num)
{
 return __builtin_popcountll(num);
}
using namespace std;
int solve(int time ,int mask , int last){

if(time == 0 || mask == (1<<n) - 1)
    return 1;

if(time <= 0)
    return 0;

if(dp[time][mask][last] != -1)
    return dp[time][mask][last];

 int ret =0;
for(int i=0 ; i < n ; i++){
    if(!(mask &(1<<i)) && last != genre[i]){
       ret += solve(time - T[i] , mask | 1<<i ,genre[i]);
    }
}

return dp[time][mask][last] = ret;

}

int main()
{

  memset(dp , -1 ,sizeof(dp));
    cin >> n >> t ;
    for(int i=0 ; i<n ;i++){
        cin >> T[i];
        cin >> genre[i];
    }
    int ans =0;
    for(int i=0 ; i<n ; i++)
      ans += solve(t - T[i],1<<i, genre[i]);

      cout << ans;

    return 0;
}

#include <iostream>
#include <cstring>
int dp[226][1<<16][4];
int T[16];
int genre[16];
int n,t;
int bc(int num)
{
 return __builtin_popcountll(num);
}
using namespace std;
int solve(int time ,int mask , int last){

if(time == 0)
    return 1;

if(time <= 0)
    return 0;

if(dp[time][mask][last] != -1)
    return dp[time][mask][last];

 int ret =0;
for(int i=0 ; i < n ; i++){
    if(!(mask &(1<<i)) && last != genre[i]){
       ret += solve(time - T[i] , mask | 1<<i ,genre[i]);
    }
}

return dp[time][mask][last] = ret;

}

int main()
{

  memset(dp , -1 ,sizeof(dp));
    cin >> n >> t ;
    for(int i=0 ; i<n ;i++){
        cin >> T[i];
        cin >> genre[i];
    }
    int ans =0;
    for(int i=0 ; i<n ; i++)
      ans += solve(t - T[i],1<<i, genre[i]);

      cout << ans;

    return 0;
}

#include <bits/stdc++.h>

using namespace std;

const int N = 15;
const int MOD = 1000000007;

int ts[N];
int gs[N];

bool dpd[4][1 << N];
long long dp[4][1 << N];

long long ok(vector<int> s, int done, int last, int siz) {
    if (dpd[last][done]) {
        return dp[last][done];
    }
    // cerr << "ok(" << done << ", " << last << ")" << "\n";

    long long res = 0;
    if (siz == s.size()) {
        res = 1;
    } else {
        for (int i = 0; i < s.size(); ++i) {
            int curr = gs[s[i]];
            if (!(done & (1 << i))) {
                if (curr == last) {
                    continue;
                }
                done |= (1 << i);
                res += ok(s, done, curr, siz + 1) % MOD;
                done &= (~(1 << i));
            }
        }
    }
    dpd[last][done] = true;
    dp[last][done] = res;
    return res;
}

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

    // Parse input
    int n, t;
    cin >> n >> t;

    vector<int> ts2[3];

    for (int i = 0; i < n; ++i) {
        cin >> ts[i] >> gs[i];
        ts2[gs[i] - 1].push_back(ts[i]);
    }

    // Solve
    long long ans = 0;

    for (int b = 0; b < (1 << n); b++) {
        vector<int> subset;
        int sum = 0;
        for (int i = 0; i < n; i++) {
            if (b & (1 << i)) {
                subset.push_back(i);
                sum += ts[i];
            }
        }
        if (sum == t) {
            cerr << subset.size() << endl;
            memset(dpd, false, sizeof dpd);
            memset(dp, 0, sizeof dp);
            ans += ok(subset, 0, 0, 0) % MOD;
        }
    }

    // Print answer
    cout << ans << "\n";
}

#include <bits/stdc++.h>
#define FOR(i, a, b) for(int i = (a); i <= (b); i++)
#define FORR(i, a, b) for(int i = (a); i >= (b); i--)
#define minimize(a) a % 1000000007;
#define maxn 2005
#define F first
#define S second
using namespace std;
int n, T, a[16], b[4];
long long res, dp[1 << 16][4];

int main()
{
    ios_base::sync_with_stdio(0);
#ifndef ONLINE_JUDGE
    freopen("inp.txt", "r", stdin);
#endif // ONLINE_JUDGE
    cin >> n >> T;
    FOR(i, 0, n-1) cin >> a[i] >> b[i], b[i]--;
    dp[0][3] = 1;
    FOR(i, 0, (1 << n)-1)
        FOR(st, 0, 3)
        {
            FOR(j, 0, n-1)
            {
                if(b[j] != st && ((i & (1 << j)) == 0))
                {
                   dp[i ^ (1 << j)][b[j]] = (dp[i ^ (1 << j)][b[j]] + dp[i][st]) % 1000000007;
                }
            }
            int sum = 0;
            FOR(j, 0, n-1) if(i & (1 << j)) sum += a[j];
            if(sum == T)
            {
                res = (res + dp[i][st]) % 1000000007;
            }
        }
        cout << res;

}

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int, int> pi;
constexpr int inf = 0x3f3f3f3f;
constexpr double EPS = 1e-30;
constexpr double PI = atan(1) * 4;

template <typename T> inline bool chmax(T& x, T y) {return x < y ? x = y, 1 : 0;}
template <typename T> inline bool chmin(T& x, T y) {return x > y ? x = y, 1 : 0;}
inline int LSB(int i) {return (i & -i);}

constexpr int MOD = 1e9+7;

int n, t, cost[20], g[5], dp[(1 << 15) + 5][20];
ll res;

int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    cin >> n >> t;
    for (int i = 0; i < n; i++)
        cin >> cost[i] >> g[i];

    for (int i = 0; i < n; i++){
        dp[(1 << i)][i] = 1;
    }

    for (int i = 0; i < (1 << n); i++){
        for (int j = 0; j < n; j++){ //Next song
            if (i & (1 << j)) continue;
            for (int k = 0; k < n; k++){
                if (i & (1 << k)){ //Previous song
                    if (g[j] == g[k]) continue;
                    dp[i | (1 << j)][j] = (dp[i | (1 << j)][j] + dp[i][k]) % MOD;
                }
            }
        }
    }

    for (int i = 0; i < (1 << n); i++){
        int cur = 0;
        for (int j = 0; j < n; j++){
            if (i & (1 << j)) cur += cost[j];
        }

        if (cur == t){
            for (int j = 0; j < n; j++){
                res = (res + dp[i][j]) % MOD;
            }
        }
    }

    cout << res << endl;
    return 0;
}

/* ****GT_18**** */

#include<bits/stdc++.h>
#define ll          long long
#define pb          push_back
#define    endl        '\n'
#define pii         pair<ll int,ll int>
#define vi          vector<ll int>
#define all(a)      (a).begin(),(a).end()
#define F           first
#define S           second
#define sz(x)       (ll int)x.size()
#define hell        1000000007
#define rep(i,a,b)    for(ll int i=a;i<b;i++)
#define lbnd        lower_bound
#define ubnd        upper_bound
#define bs          binary_search
#define mp          make_pair
using namespace std;

#define N  100005
ll timei,t[100],g[100],dp[20][20][20][5],n,fac[100];
ll sol(ll x)
{
    ll i,j,k,l,m;
    ll a[4];
    a[0]=0;a[1]=0;a[2]=0;a[3]=0;
    k=0;
    // cout<<n<<endl;
    for(i=0;i<n;i++)
    {
        if((x>>i)&1)
        {
            // cout<<k<<endl;
            k+=t[i];
            a[g[i]-1]++;
        }
    }
    // cout<<k<<endl;
    if(k!=timei)
        return 0;
    ll ans=0;
    // cout<<x<<endl;
    // cout<<a[0]<<" "<<a[1]<<" "<<a[2]<<endl;
    ans=(ans+dp[a[0]][a[1]][a[2]][0])%hell;
    ans=(ans+dp[a[0]][a[1]][a[2]][1])%hell;
    ans=(ans+dp[a[0]][a[1]][a[2]][2])%hell;
    ans=(ans*(fac[a[0]]))%hell;
    ans=(ans*(fac[a[1]]))%hell;
    ans=(ans*(fac[a[2]]))%hell;
    return ans;
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int TESTS=1;
//    cin>>TESTS;
    while(TESTS--)
    {
        ll i,j,k,l,m;
        for(i=0;i<20;i++)
        {
            for(j=0;j<20;j++)
            {
                for(k=0;k<20;k++)
                {
                    for(l=0;l<4;l++)
                    {
                        dp[i][j][k][l]=0;
                    }
                }
            }
        }
        fac[0]=1;
        for(i=1;i<100;i++)
        {
            fac[i]=(fac[i-1]*i)%hell;
        }
        dp[1][0][0][0]=1;dp[0][1][0][1]=1;dp[0][0][1][2]=1;
        for(i=0;i<20;i++)
        {
            for(j=0;j<20;j++)
            {
                for(k=0;k<20;k++)
                {
                    if(i!=0)
                        dp[i][j][k][0]=max(dp[i][j][k][0],(dp[i-1][j][k][1]+dp[i-1][j][k][2])%hell);
                    if(j!=0)
                        dp[i][j][k][1]=max(dp[i][j][k][1],(dp[i][j-1][k][0]+dp[i][j-1][k][2])%hell);
                    if(k!=0)
                        dp[i][j][k][2]=max(dp[i][j][k][2],(dp[i][j][k-1][0]+dp[i][j][k-1][1])%hell);
                }
            }
        }
        // cout<<dp[1][1][1][0]<<endl;
        cin>>n>>timei;
        for(i=0;i<n;i++)
        {
            cin>>t[i]>>g[i];
        }
        ll ans=0;
        for(i=0;i<(1<<n);i++)
        {
            ans+=sol(i);
        }
        cout<<ans;
    }
    return 0;
}

#include<bits/stdc++.h>
#include<stdio.h>
using namespace std;
typedef long long int ld;
typedef unsigned long long int lu;
typedef vector< int > vi;
typedef vector < ld > vd;
typedef set <ld> sd;
typedef vector< vi > vvi;
typedef vector< vd > vvd;
typedef pair< int,int > ii;
typedef pair< ld,ld > id;
#define sz(a) ld((a).size())
#define test(t) ll t;cin>>t;while(t--)
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define tr(c,i) for(__typeof((c).begin()) i = (c).begin(); i != (c).end(); i++)
#define present(c,x) ((c).find(x) != (c).end())
#define cpresent(c,x) (find(all(c),x) != (c).end())
#define fastio ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define Vi vector
#define pr pair
#define mpr make_pair
#define fi first
#define se second
#define isnum(a) (a>=48 && a<=57)
#define isS(a) (a>='a' && a<='z')
#define isU(a) (a>='A' && a<='Z')
#define toS(a) (isU(a)?a+32:a)
#define toU(a) (isS(a)?a-32:a)
#define toC(a) a&15

set <ld> s[100005];
ld d[100005];

vector<char> prime (100000+1, true);
void sieve(ld n)
{
	//O(nloglogn) time
	prime[0] = prime[1] = false;
	for (ld i=2; i<=n; ++i)
	{
		if (prime[i])
		{
			s[i].insert(i);
			for (ld j=2*i; j<=n; j+=i)
			{
				prime[j] = false;
				s[j].insert(i);
			}
		}
	}
}
#define forn(i,e) for(int i = 0; i < e; i++)
#define rep(i,a,b) for(i=a;i<b;i++)
#define REP(i,a,b) for(i=a;i<=b;i++)
#define reprev(i,a,b) for(i=a;i>=b;i--)

#define leadzero(a) __builtin_clz(a) //count leading zeros
#define trailzero(a) __builtin_ctz(a) //count trailing zeros
#define bitcount(a) __builtin_popcount(a) // count set bits (add ll)
#define ln cout<<"\n"
#define sp cout<<" "
#define maxe(a) *max_element(a.begin(),a.end())
#define maxi(a) max_element(a.begin(),a.end())-a.begin()
#define mine(a) *min_element(a.begin(),a.end())
#define mini(a) min_element(a.begin(),a.end())-a.begin()
ld gcd(ld a, ld b) { if(b == 0) return a; return gcd(b, a % b); }
ld fastpowMOD(ld a, ld p,ld MOD){ if(p==0) return 1; ld z = fastpowMOD(a,p/2,MOD); z = (z*z)%MOD; if(p%2) z = (z*a)%MOD; return z; }
ld fastpow(ld a, ld p){ if(p==0) return 1; ld z = fastpow(a,p/2); z = (z*z); if(p%2) z = (z*a); return z; }
ld a,b;

ld search1(ld a[], ld f,ld n)
{
	ld left=1;
	ld right=n+1;
	while(right-left>1)
	{
		ld mid = left + (right-left)/2;
		if(a[mid]<f)
		{
			left=mid;
		}
		else right=mid;
	}
	return a[left];
}
ld  p = 1e9+7;

int main(){
	ld n,i,j,T;
	cin >> n >> T;
	ld t[n],g[n];
	rep(i,0,n)
	{
		cin >> t[i] >> g[i];
	}
	ld dp[(1<<n)][n];
	bool bdp[(1<<n)][n];
	memset(dp,0,sizeof(dp));
	memset(bdp,0,sizeof(bdp));
	rep(i,0,n)dp[0][i]=1;
	for(ld mask=0;mask<(1<<n)-1;mask++)
	{
		if(mask==0)
		{
			rep(i,0,n)
			{
				dp[mask|(1<<i)][i] = (dp[mask|(1<<i)][i] + 1)%p;
				bdp[mask|(1<<i)][i]=1;
			}
			continue;
		}
		rep(i,0,n)
		{
			if(mask&(1<<i) && bdp[mask][i])
			{
				rep(j,0,n)
				{
					if(!(mask&(1<<j)) && g[j]!=g[i])
					{
						dp[mask|(1<<j)][j] = (dp[mask|(1<<j)][j] + dp[mask][i])%p;
						bdp[mask|(1<<j)][j]=1;
					}
				}
			}
		}
	}
	ld totsum=0;
	for(ld mask=0;mask<(1<<n);mask++)
	{
		ld cnt = 0;
		rep(i,0,n)
		{
			if(mask&(1<<i))cnt+=t[i];
		}
		if(cnt==T)
		{
			rep(i,0,n)(totsum = totsum + dp[mask][i])%p;
		}
	}
	cout << totsum << endl;
	return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mk make_pair
#define Size(x) ((int)((x).size()))
#define rep(i, l, r) for(int (i) = (l); (i) <= (r); ++(i))
#define per(i, r, l) for(int (i) = (r); (i) >= (l); --(i))
#define chkmax(x, y) (x) = max((x), (y))
#define chkmin(x, y) (x) = min((x), (y))
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> VI;
inline char gc() {
	static char now[1 << 16], *S, *T;
	if (S == T) {T = (S = now) + fread(now, 1, 1 << 16, stdin); if (S == T) return EOF;}
	return *S ++;
}
#define gc getchar
inline int read() {
	int x = 0, f = 1; char c = gc();
	while (c < '0' || c > '9') {(c == '-') ? (f = 0) : 0; c = gc();}
	while (c >= '0' && c <= '9') {x = (x << 3) + (x << 1) + (c ^ 48); c = gc();}
	return f ? x : ((~ x) + 1);
}
const int N = 16;
const int mod = 1e9 + 7;
inline void Add(int &x, const int &y) {
	x += y;
	(x >= mod) ? (x -= mod) : 0;
}
int n, T, t[N], g[N];
int f[66000][230][3], ans;
int main() {
//	freopen("in.txt", "r", stdin);
	n = read(); T = read();
	rep(i, 1, n) {
		t[i] = read();
		g[i] = read() - 1;
		f[1 << (i - 1)][t[i]][g[i]] = 1;
	}
	rep(s, 1, (1 << n) - 1) {
		rep(j, 0, 2) {
			Add(ans, f[s][T][j]);
		}
		for (int i = 1; i <= n; ++ i) {
			if (1 << (i - 1) & s) continue ;
			rep(j, 0, 2) if (j ^ g[i]) {
				rep(k, 0, T - t[i]) {
					if (f[s][k][j]) {
						Add(f[s | (1 << (i - 1))][k + t[i]][j], f[s][k][j]);

					}

				}
			}

		}
	}
	printf("%d\n", ans);
	return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(i=j;i<=k;++i)
#define dow(i,j,k) for(i=j;i>=k;--i)
#define LL long long
#define D double
#define sz(X) (int)(X.size())
#define itr iterator
#define mkp make_pair
#define pr pair
#define fi first
#define se second
const int N=15;
const int mt=300;
const LL md=1000000007;
LL fpw(LL x,LL y){
    LL res=1;while(y){if(y&1)res*=x,res%=md;x*=x;x%=md;y>>=1;}return res%md;
}
LL exgcd(LL& x,LL& y,LL a,LL b){
    if(!b){x=1;y=0;return a;}
    LL res=exgcd(y,x,b,a%b);y-=x*(a/b);return res;
}
LL inv(LL o){
    LL x,y;exgcd(x,y,o,md);
    x=(x%md+md)%md;return x;
}
int n,T,t[N],g[N],a[3][2];
LL f[mt][1<<N][3];
bool vis[mt][1<<N][3];
void sol(int x,int y,int z){
    if(vis[x][y][z])return;
    int i;vis[x][y][z]=1;
    rep(i,1,n)if(((1<<i-1)&y) && x>=t[i] && g[i]==z){
        sol(x-t[i],y-(1<<i-1),(z+1)%3);sol(x-t[i],y-(1<<i-1),(z+2)%3);
        f[x][y][z]=(f[x][y][z]+f[x-t[i]][y-(1<<i-1)][(z+1)%3]+f[x-t[i]][y-(1<<i-1)][(z+2)%3])%md;
    }
}
int main(){
    scanf("%d%d",&n,&T);int i;
    rep(i,1,n)scanf("%d%d",&t[i],&g[i]),--g[i];
    f[0][0][0]=f[0][0][1]=f[0][0][2]=1;vis[0][0][0]=vis[0][0][1]=vis[0][0][2]=1;
    int ed=1<<n;--ed;LL ans=0;
    rep(i,0,ed){
        sol(T,i,0);sol(T,i,1);sol(T,i,2);
        ans=(ans+f[T][i][0]+f[T][i][1]+f[T][i][2])%md;
    }
    cout<<ans*inv(2)%md;
}
/*
1 1
1 1
*/

#include<bits/stdc++.h>
#define ll long long
#define mod 1e9+7
using namespace std;
ll n,m,t,x,k,cas,a[20][20],dp[(1<<15)+2][250][4];
ll call(ll mask,ll T,ll prv)
{
    if(T==k) return 1;
    if(T>k) return 0;
    if(mask==(1<<n)-1) return 0;
    ll &ret = dp[mask][T][prv];
    if(ret!=-1) return ret;
    ret = 0;
    for(ll i=0;i<n;i++)
    {
        if((mask&(1<<i))==0&&prv!=a[i][1])
        {
            ret += call(mask|(1<<i),T+a[i][0],a[i][1]);
        }
    }
    return ret;
}
int main()
{

    memset(dp,-1,sizeof(dp));
    cin>>n>>k;
    for(ll i=0;i<n;i++)
    for(ll j=0;j<2;j++)
        cin>>a[i][j];
    cout<<call(0,0,0)<<"\n";
}

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pb push_back
#define mod 1000000007
vector<pair<ll,ll>> v;
ll dp[256][1<<15];
ll func(ll T,ll check,ll g)
{

    if(T==0)
    return 1;
    if(T<0)
    return 0;

    if(dp[T][check]!=-1)
    return dp[T][check];

    ll sum=0;
    for(ll i=0;i<v.size();i++)
    {

        if(v[i].second!=g&&(check&(1<<i))==0)
        {
            sum=(sum+func(T-v[i].first,(check|(1<<i)),v[i].second))%mod;
        }
    }

    return dp[T][check]=sum;
}

int main()
{
    ll n,T;
    cin>>n>>T;
    memset(dp,-1,sizeof(dp));
    for(ll i=1;i<=n;i++)
    {
        ll x,y;
        cin>>x>>y;
        v.pb({x,y});
    }
    cout<<func(T,0,-1);
}

#include <bits/stdc++.h>
#define x first
#define y second
#define int long long
using namespace std;
typedef long long ll;
const int N = 1e2 + 10;
const int EE = 1e6 + 10;
const int mod = 1e9 + 7;
int n, T;
int d[EE][5], t[N], g[N];

int ans;

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

    cin >> n >> T;
    for (int i = 0; i < n; ++i) cin >> t[i] >> g[i];
    int mass = (1<<n);
    d[0][1] = 1;
    d[0][2] = 1;
    d[0][3] = 1;
    for (int i = 1; i < mass; ++i)
    {
        int sum = 0;
        for (int j = 0; j < n; ++j)
        {
            if (i&(1<<j))
            {
                int f, s;
                if (g[j] == 1) f = 2, s = 3;
                if (g[j] == 2) f = 1, s = 3;
                if (g[j] == 3) f = 2, s = 1;
                d[i][g[j]] =(d[i][g[j]] + d[i^(1<<j)][f] + d[i^(1<<j)][s]) % mod;
                sum +=t[j];
            }
        }
        if (sum == T)
        {
            ans = (ans + d[i][1] + d[i][2] + d[i][3]) % mod;
        }
    }
    cout <<   ans / 2;
    return 0;
}

#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;

using VI  = vector<int>;
using VVI = vector<VI>;
using VB  = vector<bool>;
const int Mod = 1000000007;

int N, T;
VI time, type;
VVI D;

void ReadData();
void Solve();
int GetTotalTime(int mask);

int main()
{
    ReadData();
    Solve();

    return 0;
}

void ReadData()
{
    cin >> N >> T;

    type = time = VI(N);
    for (int i = 0; i < N; ++i)
    {
        cin >> time[i] >> type[i];
        --type[i];
    }
}

void Solve()
{
    D = VVI(1 << N, VI(3));
    for (int i = 0; i < N; ++i)
        D[1 << i][type[i]] = 1;

    for (int mask = 2; mask < (1 << N); ++mask)
        for (int t = 0; t < 3; ++t)
        {
            if (D[mask][t])
                continue;

            for (int i = 0; i < N; ++i)
                if (type[i] == t && (mask & (1 << i)))
                    for (int tp = 0; tp < 3; ++tp)
                        if (t != tp)
                        {
                            D[mask][t] = D[mask][t] + D[mask ^ (1 << i)][tp];
                            D[mask][t] = D[mask][t] >= Mod ? D[mask][t] - Mod : D[mask][t];
                        }
        }

    int res{0};
    for (int mask = 1; mask < (1 << N); ++mask)
        for (int t = 0; t < 3; ++t)
            if (GetTotalTime(mask) == T)
                res = (res + D[mask][t]) % Mod;

    cout << res << '\n';
}

int GetTotalTime(int mask)
{
    int t{0};

    for (int i = 0; i < mask; ++i)
        if (mask & (1 << i))
            t += time[i];

    return t;
}

#include <bits/stdc++.h>

#define pb push_back
#define eb emplace_back
#define fi first
#define se second
#define mp make_pair

const int N = 17, M = 1000000007, inf = 0x3f3f3f3f;

using namespace std;
typedef long long ll;
typedef pair<int, int> ii;
int n, t;
int T[N], g[N];

ll memo[N][N][N];
ll fat[N];

ll dp[N][N];
ll nchoosek(ll a, ll b) {
	static int t = 0;
	if(t == 0) {
		dp[0][0] = 1;
		for(int i = 0; i <= 15; ++i) {
			for(int j = 0; j <= i; ++j) {
				if(i == 0 and j == 0) dp[i][j] = 1;
				else if(j == 0) dp[i][j] = dp[i-1][j];
				else if(j == i) dp[i][j] = dp[i-1][j-1];
				else dp[i][j] = (dp[i-1][j-1] + dp[i-1][j])%M;
			}
		}
	}
	t = 1;
	return dp[a][b];
}
ll f(int k, int c1, int c2) {
	if(k == 0) return c1 == 0 and c2 == 0;

	ll & st = memo[k][c1][c2];
	if(st == -1) {
		st = 0;
		for(int x = 0; x <= c1; ++x) {
			for(int y = 0; y <= c2; ++y) {
				if(x + y > 0) {
					if(x == y) {
						st += (((nchoosek(c1, x) * nchoosek(c2, y)%M) * fat[x]%M) * fat[y] % M) * 2ll * f(k-1, c1 - x, c2 - y)%M;
					}
					else if(abs(x - y) <= 1) {
						st += (((nchoosek(c1, x) * nchoosek(c2, y) % M) * fat[x] %M) * fat[y] %M) * f(k-1, c1 - x, c2 - y) %M;
					}
					st %= M;
				}
			}
		}
	}
	return st;
}

ll solve(int bs) {
	int tot = 0;
	vector<int> id;
	for(int i = 0; i < n; ++i) {
		if((bs >> i)&1) id.pb(i);
	}

	for(int j : id) tot += T[j];
	if(tot != t) return 0;
	int cnt[4];
	memset(cnt, 0, sizeof cnt);
	for(int j : id) cnt[g[j]]++;

	if(cnt[3] == 0) {
		if(cnt[1] == cnt[2]) return 2ll * (fat[cnt[1]] * fat[cnt[2]])%M;
		if(abs(cnt[1] - cnt[2]) == 1) return (fat[cnt[1]] * fat[cnt[2]])%M;
		else return 0;
	} else {
		ll ans = f(cnt[3]+1, cnt[1], cnt[2]);
		ans = (ans + 2ll*f(cnt[3], cnt[1], cnt[2]))%M;
		if(cnt[3] > 1) ans = (ans + f(cnt[3]-1, cnt[1], cnt[2]))%M;
		return ans;
	}
}

int main() {
	memset(memo, -1, sizeof memo);
	ios::sync_with_stdio(0); cin.tie(0);

	fat[0] = 1;
	for(ll i = 1; i <= 15; ++i) fat[i] = (fat[i-1] * i)%M;
	cin >> n >> t;

	for(int i = 0; i < n; ++i) {
		cin >> T[i] >> g[i];
	}

	ll sum = 0;
	for(int i = 1; i < (1 << n); ++i) {
		ll ans = solve(i);
		sum += ans;
		sum %= M;
	}
	cout << sum << endl;
}

#include <bits/stdc++.h>

using namespace std;

const int NMAX = 50;
const int TMAX = 2500;
const int MOD = 1e9 + 7;

int n,m;
int t[NMAX + 5];
int g[NMAX + 5];

int fr[5];

int dp_first2[2][NMAX + 1][NMAX + 1][TMAX + 1];
int dp_last[2][NMAX + 1][TMAX + 1];
int num_ways[NMAX + 1][NMAX + 1][NMAX + 1][3];

vector<pair<int,int> > genre[2];

inline int total_ways(int i,int j,int k) {
    int ans = 0;
    ans = (ans + num_ways[i][j][k][0]) % MOD;
    ans = (ans + num_ways[i][j][k][1]) % MOD;
    ans = (ans + num_ways[i][j][k][2]) % MOD;
    return ans;
}

int main() {

    scanf("%d %d",&n,&m);

    genre[0] = {{0,0}};
    genre[1] = {{0,0}};

    for(int i = 1; i <= n; i++) {
        scanf("%d %d",&t[i],&g[i]);
        genre[g[i] > 2].push_back({t[i],g[i]});
        fr[g[i]]++;
    }

    num_ways[1][0][0][0] = 1;
    num_ways[0][1][0][1] = 1;
    num_ways[0][0][1][2] = 1;

    for(int i = 0; i <= n; i++) {
        for(int j = 0; j <= n; j++) {
            for(int k = 0; k <= n; k++) {
                if(i)num_ways[i][j][k][0] = (num_ways[i][j][k][0] + 1LL * i * (num_ways[i - 1][j][k][1] + num_ways[i - 1][j][k][2])) % MOD;
                if(j)num_ways[i][j][k][1] = (num_ways[i][j][k][1] + 1LL * j * (num_ways[i][j - 1][k][0] + num_ways[i][j - 1][k][2])) % MOD;
                if(k)num_ways[i][j][k][2] = (num_ways[i][j][k][2] + 1LL * k * (num_ways[i][j][k - 1][0] + num_ways[i][j][k - 1][1])) % MOD;
            }
        }
    }
    dp_first2[0][0][0][0] = 1;

    for(int i = 1,l = 1; i < (int)genre[0].size(); i++,l ^= 1) {
        for(int j = 0; j <= i; j++) {
            for(int k = 0; j + k <= i; k++) {
                for(int t = 0; t <= m; t++) {
                    dp_first2[l][j][k][t] = dp_first2[l ^ 1][j][k][t];
                    if(genre[0][i].second == 1) {
                        if(genre[0][i].first <= t && j > 0) {
                            dp_first2[l][j][k][t] = (dp_first2[l][j][k][t] + dp_first2[l ^ 1][j - 1][k][t - genre[0][i].first]) % MOD;
                        }
                    }
                    else {
                        if(genre[0][i].first <= t && k > 0) {
                            dp_first2[l][j][k][t] = (dp_first2[l][j][k][t] + dp_first2[l ^ 1][j][k - 1][t - genre[0][i].first]) % MOD;
                        }
                    }
                }
            }
        }
    }

    dp_last[0][0][0] = 1;

    for(int i = 1,l = 1; i < (int)genre[1].size(); i++,l ^= 1) {
        for(int j = 0; j <= i; j++) {
            for(int t = 0; t <= m; t++) {
                dp_last[l][j][t] = dp_last[l ^ 1][j][t];
                if(j > 0 && genre[1][i].first <= t) {
                    dp_last[l][j][t] = (dp_last[l][j][t] + dp_last[l][j - 1][t - genre[1][i].first]) % MOD;
                }
            }
        }
    }

    int l1 = 1 - ((int)genre[0].size() % 2);
    int l2 = 1 - ((int)genre[1].size() % 2);

    int ans = 0;

    for(int t = 0; t <= m; t++) {
        for(int i = 0; i <= fr[1]; i++) {
            for(int j = 0; j <= fr[2]; j++) {
                for(int k = 0; k <= fr[3]; k++) {
                    ans = (ans + 1LL * (1LL * dp_first2[l1][i][j][t] * dp_last[l2][k][m - t] % MOD) * (total_ways(i,j,k))) % MOD;
                }
            }
        }
    }

    printf("%d\n",ans);

    return 0;
}

#include<cstdio>
#include<algorithm>
#include<cstring>
#define ll long long
using namespace std;
const ll MOD=1e9+7;
int n,T,t[25],g[25];
ll f[25][1<<15];
int calc(int s)
{
	int ans=0;
	for(int i=0;i<n;i++)
	  if((1<<i)&s)
	    ans+=t[i];
	return ans;
}
int main()
{
	scanf("%d%d",&n,&T);
	for(int i=0;i<n;i++)
	{
		scanf("%d%d",&t[i],&g[i]);
		f[i][1<<i]=1;
	}
	for(int i=0;i<(1<<n);i++)
	{
		for(int now=0;now<n;now++)
		{
			if(!f[now][i])continue;
			f[now][i]%=MOD;
			for(int nxt=0;nxt<n;nxt++)
			{
				if((1<<nxt)&i)continue;
				if(g[nxt]==g[now])continue;
				f[nxt][i|(1<<nxt)]+=f[now][i];
			}
		}
	}
	int ans=0;
	for(int i=0;i<(1<<n);i++)
	{
		if(calc(i)==T)
		{
			for(int j=0;j<n;j++)
			  ans+=f[j][i];
		}
	}
	printf("%I64d\n",ans%MOD);
	return 0;
}

///Coder ---->>>> Kael (Joan Marcos Rivera)
///Team ACM : CyberSpace ____ IPVCE FEDERICO ENGELS
///KingOfString
///Copyright

#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
using namespace std;

typedef long long ll;
typedef pair < int , int > par;

#define pb push_back
#define mp make_pair
#define s second
#define f first
#define maxn 33000
#define mod 1000000007
#define less(n) order_of_key(n)
#define en_pos(n) find_by_order(n) /// --- >> iterador --- >> empieza en 0

int dp[226][maxn][5],t[16],g[16];
main() {

    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int n , T;

    cin >> n >> T;

    for(int i=0;i<n;i++)
        cin >> t[i] >> g[i];

    for(int i=0;i<n;i++)
        dp[t[i]][(1ll<<i)][g[i]] = 1;

    for(int i=1;i<(1ll<<n);i++){
        for(int j=0;j<n;j++){
            if(i & (1ll << j)){
                for(int k=0;k<n;k++){
                    if(g[j] != g[k] && !(i & (1ll << k))){
                        for(int tempo=1;tempo<=T;tempo++){
                            if(tempo + t[k] > T)break;
                            dp[tempo+t[k]][i|(1ll<<k)][g[k]] = (dp[tempo][i][g[j]] + dp[tempo+t[k]][i|(1ll<<k)][g[k]]) % mod;
                        }
                    }
                }
            }
        }
    }

    int ans = 0;
    for(int i=1;i<(1ll<<n);i++){
        for(int j=1;j<=3;j++){
            ans = (dp[T][i][j] + ans) % mod;
        }
    }

    cout << ans << '\n';

}

#include<bits/stdc++.h>

using namespace std;

#define endl '\n'

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<int, pii> piii;

const int N = 15;
const int T = 228;
const int MOD = 1e9 + 7;
int t[N], g[N];

int dp[1 << N][3][T];

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

    int n, time;
    cin >> n >> time;
    for(int i = 0; i < n; i++){

        cin >> t[i]>> g[i];
        g[i]--;
        dp[1 << i][g[i]][t[i]] = 1;
    }

    for(int mask = 1; mask < (1 << n); mask++){
        for(int i = 0; i < n; i++){
            if(mask & (1 << i)){
                for(int j = 0; j < n; j++){
                    if((mask & (1 << j)) == 0){
                        if(g[i] != g[j]){
                            int new_mask = mask | (1 << j);
                            for(int ttime = 0; ttime + t[j] <= time; ttime++){
                                dp[new_mask][g[j]][ttime + t[j]] += dp[mask][g[i]][ttime];
                                if(dp[new_mask][g[j]][ttime + t[j]] >= MOD){
                                    dp[new_mask][g[j]][ttime + t[j]] -= MOD;
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    int ans = 0;
    for(int mask = 0; mask < (1 << n); mask++){
        for(int i = 0; i < 3; i++) {
            ans += dp[mask][i][time];
            if(ans >= MOD){
                ans -= MOD;
            }
        }
    }

    cout << ans << endl;

}

#include <bits/stdc++.h>
#define ll long long
#define vpnt(ans) for(ll i = 0; i < ans.size(); i++) cout << ans[i] << (i + 1 < ans.size() ? ' ' : '\n');
#define setbit(x,k) (x |= (1 << k))
#define clearbit(x,k) (x &= ~(1ll << k))
#define checkbit(x,k) (x & (1ll << k))
#define mp make_pair
#define scl(x) scanf("%lld",&x)
#define sci(x) scanf("%d",&x)
#define pb push_back
#define pf push_front
#define ppb pop_back
#define ppf pop_front
#define pii pair<int,int>
#define YES printf("YES\n")
#define Yes printf("Yes\n")
#define yes printf("yes\n")
#define NO printf("NO\n")
#define No printf("No\n")
#define no printf("no\n")
#define nn printf("\n")
#define mod 1000000007
using namespace std;

ll n,t;
vector<int>v[5];
ll dp[5][17][17][17];

ll solve(int g, int time, int g1, int g2, int g3)
{
    if(time == t) return 1;
    if(time>t) return 0;
    if(dp[g][g1][g2][g3]!=-1) return dp[g][g1][g2][g3];
    ll res = 0;
    if(g!=1)
    {
        for(int j = 0; j<v[1].size(); j++)
        {
            if(checkbit(g1,j)) continue;
            int mask = g1;
            setbit(mask,j);
            res += solve(1, time+v[1][j], mask , g2, g3);
        }
    }
    if(g!=2)
    {
        for(int j = 0; j<v[2].size(); j++)
        {
            if(checkbit(g2,j)) continue;
            int mask = g2;
            setbit(mask,j);
            res += solve(2, time+v[2][j], g1 , mask, g3);
        }
    }
    if(g!=3)
    {
        for(int j = 0; j<v[3].size(); j++)
        {
            if(checkbit(g3,j)) continue;
            int mask = g3;
            setbit(mask,j);
            res += solve(3, time+v[3][j], g1 , g2, mask);
        }
    }
    return dp[g][g1][g2][g3] = res % mod;
}

int main()
{
    memset(dp, -1, sizeof(dp));
    cin>>n>>t;
    for(int i=0; i<n; i++)
    {
        int x,y;
        cin>>x>>y;
        v[y].pb(x);
    }
    for(int i=1; i<=3; i++) sort(v[i].begin(), v[i].end());
    cout<<solve(0, 0, 0,0,0); nn;
}

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <algorithm>
#include <iostream>
using namespace std;
#define ll long long

const int maxn=1e5+10;
const ll mod=1e9+7;

ll f[1<<15][3];
int x[20],y[20],time[1<<15];
bool vis[20];
int n,ci,value,Ttime;
ll sum;
int a[20];

void dfs(int i,int k)
{
    int j;
    if (ci==i)
    {
        if (ci==0)
        {
            for (i=0;i<n;i++)
                f[1<<i][y[i]]++;
            return;
        }
        for (i=0;i<n;i++)
            if (!vis[i])
                for (j=0;j<3;j++)
                    if (y[i]!=j)
                        (f[value|(1<<i)][y[i]]+=f[value][j])%=mod;
        return;
    }
    for (j=k;j<=n-ci+i;j++)
        if (!vis[j])
        {
            a[i]=j;
            vis[j]=1;
            value+=(1<<j);
            dfs(i+1,j+1);
            value-=(1<<j);
            vis[j]=0;
        }
}

int main()
{
    int i,j;
    scanf("%d%d",&n,&Ttime);
    for (i=0;i<n;i++)
    {
        scanf("%d%d",&x[i],&y[i]);
        y[i]--;
    }
    for (ci=0;ci<n;ci++)
        dfs(0,0);

    for (i=1;i<(1<<15);i++)
    {
        j=i&(i-1);
        time[i]=time[j]+x[(int)(log(i-j)/log(2))];
        if (time[i]==Ttime)
        {
            for (j=0;j<3;j++)
                (sum+=f[i][j])%=mod;
        }
    }

    printf("%lld",sum);
    return 0;
}
/*
15 15
1 1
1 1
1 1
1 1
1 1
1 2
1 2
1 2
1 2
1 2
1 3
1 3
1 3
1 3
1 3

6 3
1 1
1 1
1 2
1 2
1 3
1 3

*/

#include<bits/stdc++.h>
#define int long long
using namespace std;
int dp[1<<16][5],n,val[16],type[16],res=0,t;
signed main()
{
	cin>>n>>t;
	for(int i=1;i<=n;i++)
	{
		cin>>val[i]>>type[i];
		dp[1<<(i-1)][type[i]]=1;
	}
	for(int i=1;i<(1<<n);i++)
	{
		for(int last=1;last<=3;last++)
		{
			for(int j=1;j<=n;j++)
			{
				if((i&(1<<(j-1)))==0&&last!=type[j])
				{
					dp[i|(1<<(j-1))][type[j]]=dp[i|(1<<(j-1))][type[j]]+dp[i][last];
				}
			}
			int sum=0;
			for(int k=1;k<=n;k++)
			{
				if((1<<(k-1)&i)!=0) sum+=val[k];
			}
			if(sum==t) res+=dp[i][last];
		}
	}
	cout<<res;
}

//bismillahir rahmanir rahim            //Author:Fayed Anik

#include <bits/stdc++.h>

using namespace std;

#define         ll                         long  long
#define         lf                         double
#define         pb(x)                      push_back(x)
#define         ull                        unsigned long long
#define         sfl(a)                     scanf("%lld",&a)
#define         sf(a)                      scanf("%d",&a)
#define         pf(a)                      printf("%d\n",a)
#define         pfl(a)                     printf("%lld\n",a)
#define         pdl(a)                     printf("%llf\n",a)
#define         FOR(x,n)                   for(ll x=1;x<=n;++x)
#define         vii                        vector< ll > v
#define         pi                         3.14159265359
#define         mex                        10000000
#define         pii                        pair< ll , ll >
#define         mem(m,a)                   memset( m, a,sizeof m)
#define         mp(a,b)                    make_pair(a,b)
#define         maxn                       100000
#define         mod                        1000000007
#define         INF                        1e17
#define         f1                         first
#define         f2                         second
#define         all(v)                     v.begin(),v.end()
#define         PI                         acos(-1)
#define         printminusone              printf("-1\n")
#define         bug                        printf("bug")

bool CHECK(ll NN,ll pos) { return (bool) (NN & (1ll<<pos)); }
ll SET(ll NN,ll pos){ return NN=NN | (1ll<<pos); }
ll RESET(ll NN,ll pos){ return NN=NN & ~(1ll<<pos); }

ll N,T;
pii A[20];

ll dp[33368][226][4];

ll solve(ll mask,ll tot,ll type){

	if(tot<0){
		return 0;
	}
	if(tot==0){
		return 1;
	}

	ll &ret=dp[mask][tot][type],tmp;

	if(ret!=-1) return ret;

	ret = 0;
	for(ll i=0;i<N;i++){

		if(!CHECK(mask,i) and A[i+1].f2!=type){
			tmp=SET(mask,i);
			ret = ret+solve(tmp,tot-A[i+1].f1,A[i+1].f2)%mod;
		}
	}

	return dp[mask][tot][type]=ret;
}
int main(){
	sfl(N),sfl(T);
	for(ll i=1;i<=N;i++){
		sf(A[i].f1);
		sf(A[i].f2);
	}
	mem(dp,-1);
	ll ans=solve(0ll,T,0ll);
	pfl(ans);
	return 0;
}

#include<bits/stdc++.h>
#define ll long long
#define mod 1e9+7
using namespace std;
ll n,m,t,x,k,cas,a[20][20],dp[(1<<15)+2];
ll call(ll mask,ll T,ll prv)
{
    if(T==k) return 1;
    if(T>k) return 0;
    if(mask==(1<<n)-1) return 0;
    ll &ret = dp[mask];
    if(ret!=-1) return ret;
    ret = 0;
    for(ll i=0;i<n;i++)
    {
        if((mask&(1<<i))==0&&prv!=a[i][1])
        {
            ret += call(mask|(1<<i),T+a[i][0],a[i][1]);
        }
    }
    return ret;
}
int main()
{

    memset(dp,-1,sizeof(dp));
    cin>>n>>k;
    for(ll i=0;i<n;i++)
    for(ll j=0;j<2;j++)
        cin>>a[i][j];
    cout<<call(0,0,0)<<"\n";
}

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <vector>

using namespace std;

typedef unsigned long long ll;

const int INF = 2147483647;
const int INF2 = 0x3f3f3f3f;
const ll INF64 = 0x3f3f3f3f3f3f3f3f;
const double PI = 3.14159265358979323846;
const int MOD = (int)(1e9) + 7;
const ll TARGET = (1LL << 32) - 1LL;

template <typename T>
inline T read() {
    T X = 0, w = 0;
    char ch = 0;
    while (!isdigit(ch)) {
        w |= ch == '-';
        ch = getchar();
    }
    while (isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
    return w ? -X : X;
}

struct Point {
    int l;
    int r;
    bool operator<(const Point &other) const { return r < other.l; }
};

const int MAXN = 16;
int n, m, k;
int w, h;

int CASE = 1;
pair<int, int> arr[MAXN];
bool vis[MAXN];

ll ans = 0;
int fact[MAXN];

int main() {
#ifdef LOCALLL
    freopen("in", "r", stdin);
    freopen("out", "w", stdout);
#endif
    fact[0] = 1;
    for (int i = 1; i <= MAXN; i++) {
        fact[i] = fact[i - 1] * i;
    }
    scanf("%d %d", &n, &m);
    for (int i = 0; i < n; i++) {
        scanf("%d %d", &arr[i].second, &arr[i].first);
    }
    for (int s = 0; s < (1 << n); s++) {
        vector<pair<int, int>> vec;
        int t = 0;
        for (int i = 0; i < n; i++) {
            if ((s >> i) & 1) {
                vec.push_back(arr[i]);
                t += arr[i].second;
            }
        }
        if (t == m) {
            map<int, int> rep;
            for (auto a : vec) {
                rep[a.first]++;
            }
            int x = __builtin_popcount(s);
            k = fact[x];
            for (auto b : rep) {
                if (b.second == 1) continue;
                if (x - b.second == 0) {
                    k = 0;
                    break;
                }
                k -= fact[b.second] * (x - b.second + 1);
            }
            ans += k % MOD;
            ans %= MOD;
        }
    }
    printf("%lld", ans);
    return 0;
}

#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#define all(x) x.begin(), x.end()
using namespace std;
typedef long long ll;
typedef double db;
const int MOD = 1e9 + 7;
int cnt[3375], f[16];
int convert(int cnt[])
{
	return cnt[0] * 15 * 15 + cnt[1] * 15 + cnt[2];
}
void set_up(int id, int last, int n, int cnd[])
{
	++cnt[convert(cnd)];
	if (id == n)
		return;
	for (int i = 0; i < 3; ++i)
	{
		if (i != last)
		{
			++cnd[i];
			set_up(id + 1, i, n, cnd);
			--cnd[i];
		}
	}
}
bool check(vector<pair<int, int>>& a, int n)
{
	for (int i = 1; i < n; ++i)
		if (a[i].second != a[i - 1].second)
			return true;
	return false;
}
void convert(int a, int cnd[])
{
	for (int i = 2; i >= 0; --i)
	{
		cnd[i] = a % 15;
		a /= 15;
	}
}
int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	int n, t;
	cin >> n >> t;
	vector<pair<int, int>> a(n);
	for (int i = 0; i < n; ++i)
		cin >> a[i].first >> a[i].second;
	if (n == 15 && !check(a, n))
	{
		int ans = 0;
		for (int i = 0; i > n; ++i)
			ans += (a[i].first == t);
		cout << ans;
		return 0;
	}
	fill(cnt, cnt + 3375, 0);
	int cnd[3] = { 0, 0, 0 };
	set_up(0, -1, n + 1, cnd);
	f[0] = 1;
	for (int i = 1; i <= 15; ++i)
		f[i] = 1ll * f[i - 1] * i % MOD;
	vector<vector<int>> dp(3375, vector<int>(t + 1, 0));
	dp[0][0] = 1;
	int ans = 0, tmp;
	for (int i = 0; i < n; ++i)
	{
		for (int j = 3374; j > 0; --j)
		{
			convert(j, cnd);
			if (cnd[a[i].second - 1] == 0)
				continue;
			cnd[a[i].second - 1] -= 1;
			tmp = convert(cnd);
			for (int k = t; k >= a[i].first; --k)
			{
				dp[j][k] += dp[tmp][k - a[i].first];
				dp[j][k] %= MOD;
			}
		}
	}
	for (int i = 0; i < 3375; ++i)
	{
		tmp = 1ll * dp[i][t] * cnt[i] % MOD;
		convert(i, cnd);
		for (int j = 0; j < 3; ++j)
			tmp = 1ll * tmp * f[cnd[j]] % MOD;
		ans = (ll(ans) + tmp) % MOD;
	}
	cout << ans;
	return 0;
}

#include <bits/stdc++.h>
#define INT long long
#define oo 987654321
#define OO 9999999987654321
#define MOD 998244353
#define mod 1000000007
using namespace std;
int n, T, t[20], g[20], dt[226][3][1<<15];
int dp(int x, int y, int z, int s)
{
    if( y == T ) return 1;
    if( x == n ) return 0;
    if( ~dt[y][z][s] ) return dt[y][z][s];
    int &ret = dt[y][z][s] = 0;
    for(int i = 0 ; i < n ; i++ )
    {
        if( (s&(1<<i)) == 0 )
        {
            if( g[i] != z )
                ret += dp(x+1, y+t[i], g[i], s|(1<<i));
        }
    }
    return ret;
}
int main()
{
    ios::sync_with_stdio(false);
    memset(dt, -1, sizeof(dt));
    cin>>n>>T;
    for(int i = 0 ; i < n ; i++ ) cin>>t[i]>>g[i];
    cout<<dp(0, 0, 0, 0);
}

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
#define INF 1e19
#define LBW return
#define AK 0
#define IOI ;
#define int ll
template <typename T> void chmin(T &x,const T &y){if(x>y)x=y;}
template <typename T> void chmax(T &x,const T &y){if(x<y)x=y;}
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
	while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
const int N=2000+10;
const int mod=1e9+7;
int n,t,dp[1<<15][16],sta[1<<15],ok[1<<15],ans;
struct node{int t,g;}a[N];
inline int work(int x){
	int res=0;
	for(int i=0;i<n;i++)if((1<<i)&x)res+=a[i+1].t;
	if(res==t)ok[x]=1;
	else if(res>t)ok[x]=2;
	return res;
}
signed main(){
	n=read(),t=read();
	for(int i=1;i<=n;i++) a[i].t=read(),a[i].g=read();
	for(int i=1;i<(1<<n);i++)sta[i]=work(i);
	for(int i=0;i<n;i++)dp[1<<i][i+1]=1;
	int all=(1<<n)-1;
	for(int st=0;st<=all;st++){
		if(ok[st]==2)continue;
		if(ok[st]==1){
			for(int i=0;i<n;i++)if(st&(1<<i))(ans+=dp[st][i+1])%mod;
			continue;
		}
		for(int i=0;i<n;i++)if((1<<i)&st)
		for(int j=0;j<n;j++)if((!((1<<j)&st))&&a[i+1].g!=a[j+1].g){
			(dp[(1<<j)|st][j+1]+=dp[st][i+1])%mod;
		}

	}
	cout<<ans;
	LBW AK IOI;
}

# include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;

# define F first
# define S second
# define endl '\n'
# define sep ' '
# define pb push_back
# define fast_io ios::sync_with_stdio(0);cin.tie(0); cout.tie(0);

const ll md = 1e9 + 7;
const int xn = 1e2 + 10;
const int xm = 1e5 + 10;
const int SQ = 320;
const int sq = 1e3 + 10;
const ll inf = 1e18 + 10;

ll power(ll a, ll b) {return (!b ? 1 : (b & 1 ? a * power(a * a % md, b / 2) % md : power(a * a % md, b / 2) % md));}
ll zarb(ll a, ll b){return (a * b + 10 * md) % md;}
ll jaam(ll a, ll b){return (a + b + 10 * md) % md;}

ll n, T, a[xn], b[xn], dp[xn][xn][xn][3], sum, ted[3], ans;
vector <int> vec;

void check(int x){
	vec.clear();
	for (int i = 0; i < n; i ++)
		if (x&(1 << i)) vec.push_back(i);
	sum = 0;
	for (int v : vec) sum += a[v];
	if (sum != T) return;
	memset(ted, 0, sizeof ted);
	for (int v : vec) ted[b[v] - 1] ++;
	ans += dp[ted[0]][ted[1]][ted[2]][0];
	ans += dp[ted[0]][ted[1]][ted[2]][1];
	ans += dp[ted[0]][ted[1]][ted[2]][2];
}

int main(){
	//fast_io;

	cin >> n >> T;
	for (int i = 0; i < n; i ++) cin >> a[i] >> b[i];

	dp[1][0][0][0] = 1;
	dp[0][1][0][1] = 1;
	dp[0][0][1][2] = 1;
	for (int i = 0; i <= 15; i ++){
		for (int j = 0; j <= 15; j ++){
			for (int k = 0; k <= 15; k ++){
				if (i + j + k < 2) continue;
				for (int p = 0; p < 3; p ++){
					if (p == 0){
						if (!i) continue;
						dp[i][j][k][p] += i * dp[i - 1][j][k][1];
						dp[i][j][k][p] += i * dp[i - 1][j][k][2];
					}
					else if (p == 1){
						if (!j) continue;
						dp[i][j][k][p] += j * dp[i][j - 1][k][0];
						dp[i][j][k][p] += j * dp[i][j - 1][k][2];
					}
					else{
						if (!k) continue;
						dp[i][j][k][p] += k * dp[i][j][k - 1][0];
						dp[i][j][k][p] += k * dp[i][j][k - 1][1];
					}
				}
			}
		}
	}
	for (int i = 0; i < pow(2, n); i ++) check(i);
	cout << ans << endl;
	return 0;
}

//#define NDEBUG
#define REL
#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES

#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4")

#include <iostream>
#include <vector>
#include <math.h>
#include <queue>
#include <deque>
#include <algorithm>
#include <sstream>
#include <ctime>
#include <string>
#include <iomanip>
#include <climits>
#include <set>
#include <map>
#include <cassert>
#include <fstream>
#include <stack>
#include <cstdio>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <random>

#define pb push_back
#define mp make_pair
#define all(x) x.begin(), x.end()
#define nn "\n"
#define pp " "
#define sze(x) (ll)x.size()

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;

template <typename T>
bool uax(T &a, const T b) {
	if (a < b) {
		a = b;
		return true;
	}
	return false;
}

template <typename T>
bool uin(T &a, const T b) {
	if (a > b) {
		a = b;
		return true;
	}
	return false;
}

template <typename T1, typename T2>
istream &operator>>(istream &in, pair<T1, T2> &p) {
	in >> p.first >> p.second;
	return in;
}

template <typename T1, typename T2>
ostream &operator<<(ostream &out, pair<T1, T2> &p) {
	out << p.first << ' ' << p.second;
	return out;
}

mt19937 rnd(1928);

const int MOD = 1e9 + 7;
const int B = 17;
const int S = (1 << B);

int n, t;
vector<pair<int, int>> p;

int dp[S];
bool gp[S];
vector<vector<int>> c;
vector<int> lb;

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#else
	//freopen("close-vertices.in", "r", stdin);
	//freopen("close-vertices.out", "w", stdout);
#endif
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	fill(dp, dp + S, -1);
	cin >> n >> t;
	p.resize(n);
	for (int i = 0; i < n; i++) {
		cin >> p[i];
		p[i].second--;
	}
	c.resize((1 << n), vector<int>(3, 0));
	lb.resize((1 << n), -1);
	for (int i = 0; i < (1 << n); i++) {
		int sum = 0;
		for (int j = 0; j < n; j++) {
			if (i & (1 << j)) {
				sum += p[j].first;
				c[i][p[j].second]++;
				lb[i] = j;
			}
		}
		if (sum == t) gp[i] = true;
		else gp[i] = false;
	}
	ll ans = 0;
	dp[0] = 1;
	for (int i = 1; i < (1 << n); i++) {
		for (int j = 0; j < n; j++) {
			if (i & (1 << j)) {
				lb[i] = j;
				int pm = i - (1 << lb[i]);
				int ng = p[lb[i]].second;
				int vm = c[pm][0] + c[pm][1] + c[pm][2] + 1 - c[pm][ng] * 2;
				if (dp[pm] != -1) dp[i] = ll(dp[pm]) * ll(vm) % MOD;
				if (dp[i] != -1) break;
			}
		}
		if (gp[i] && dp[i] != -1) {
			ans = ans + ll(dp[i]) % MOD;
		}
	}
	cout << ans;
}

#include <bits/stdc++.h>
#define lowbit(a) ((a)&(-(a)))
using namespace std;

int n, T;
struct node {
	int t;
	int g;
}a[20];
bool vis[20];
int ans = 0;

long long dp[(1 << 16)][4];

int dfs(int sta,int dt, int lg)
{
	if (dt == T)
		return 1;
	if (dp[sta][lg] != -1)return dp[sta][lg];
	int ans = 0;
	for (int i = 1; i <= n; i++)
	{
		if (!vis[i]&&a[i].g!=lg&& dt + a[i].t<=T)
		{
			vis[i] = 1;
			ans+=dfs(sta|(1<<i),dt + a[i].t, a[i].g);
			vis[i] = 0;
		}
	}
	dp[sta][lg] = ans;
	return ans;
}

int main()
{
	cin >> n >> T;
	for (int i = 1; i <= n; i++)
		cin >> a[i].t >> a[i].g;
	memset(dp, -1, sizeof dp);
	dfs(0,0, 0);
	cout << dp[0][0] << endl;
	return 0;
}

#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>

#define MAX 100005
#define MOD 1000000007
#define eps 1e-6

using namespace std;

typedef long long ll;
typedef complex<double> point;

#define pii pair<int, int>
#define pip pair<int ,pii>
#define F first
#define S second
#define X real()
#define Y imag()

int ar[] = {0 ,0 ,1 ,-1};
int ac[] = {1 ,-1 ,0 ,0};

int T,n;
pii tg[20];
int dp[(1 << 16)][18];
int solve(int msk, int last ,int len){
    if(len >= T)
        return len == T ? 1 : 0;
    if(msk == ((1 << n) - 1))
        return 0;
    int &ret = dp[msk][last];
    if(ret + 1)
        return ret;
    int res = 0;
    for(int i = 0; i < n; i++)
        if(!(msk & (1 << i)) && tg[last].S != tg[i].S)
            res += solve(msk | (1 << i), i, len + tg[i].F) % MOD;

    return ret = res % MOD;
}
int main(){
#ifdef Fake_Plastic_Tree
      freopen("input.txt", "r", stdin);
      //freopen("output.txt" ,"w" ,stdout);
#endif //Fake_Plastic_Tree
    ios_base::sync_with_stdio(false);cin.tie(0);
    cout << fixed << setprecision(7);
    cin >> n >> T;
    for(int i = 0; i < n ; i++){
        int t,g; cin >> t >> g;
        tg[i] = pii(t,g);
    }
    memset(dp, -1, sizeof dp);
    cout << solve(0 ,n ,0) << '\n';
    return 0;
}

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define dep(i,a,b) for(int i=(a);i>=(b);--i)
#define pb push_back
typedef long long ll;
const int maxn=(int)2e5+100;
const int mod=(int)1e9+7;
int n,m;
ll ans,dp[(2<<15)+100][4];
struct node{
	int t,g;
}a[20];
int main(){
	cin>>n>>m;
	rep(i,0,n-1) scanf("%d%d",&a[i].t,&a[i].g);
	dp[0][1]=dp[0][2]=dp[0][3]=1;
	rep(mark,0,(1<<n)-1) rep(last,0,3){
		rep(i,0,n-1) if(a[i].g!=last&&((mark&(1<<i))==0))
			dp[mark^(1<<i)][a[i].g]=(dp[mark^(1<<i)][a[i].g]+dp[mark][last])%mod;
		int sum=0;
		rep(i,0,n-1) if(mark&(1<<i)) sum+=a[i].t;
		if(sum==m) ans=(ans+dp[mark][last])%mod;
	}
	printf("%lld\n",ans/2);
}

#include <bits/stdc++.h>
#define int long long

using namespace std;

const int N = 1e5, mod = 1e9 + 7;

int readInt()
{
    bool minus = false;
    int result = 0;
    char ch;
    ch = getchar();
    while (true) {
        if (ch == '-')
            break;
        if (ch >= '0' && ch <= '9')
            break;
        ch = getchar();
    }
    if (ch == '-')
        minus = true;
    else
        result = ch - '0';
    while (true) {
        ch = getchar();
        if (ch < '0' || ch > '9')
            break;
        result = result * 10 + (ch - '0');
    }
    if (minus)
        return -result;
    else
        return result;
}
int t[20], g[20];
int dp[20][20][20][20][4];
int n, T, ans = 0;
void fun(int id, int sum, int num)
{
    if (id > n) {
        if (sum == T) {
            int cnt[4] = { 0, 0, 0, 0 };
            int ln = 0;
            for (int i = 0; i <= 15; i++) {
                if ((num & (1 << i))) {
                    ln ++;
                    cnt[g[i]] ++;
                }
            }

            int t = dp[cnt[1]][cnt[2]][cnt[3]][ln][1] + dp[cnt[1]][cnt[2]][cnt[3]][ln][2] + dp[cnt[1]][cnt[2]][cnt[3]][ln][3];
            t %= mod;
            if(cnt[1] > 1){
                t = (t * cnt[1]) % mod;
            }
            if(cnt[2] > 1){
                t = (t * cnt[2]) % mod;
            }
            if(cnt[3] > 1){
                t = (t * cnt[3]) % mod;
            }
            ans = (ans + t) % mod;
        }
        return;
    }
    fun(id + 1, sum + t[id], (num | (1 << id)));
    fun(id + 1, sum, num);
}
main()
{
    n = readInt(), T = readInt();
    for (int i = 1; i <= n; i++) {
        t[i] = readInt();
        g[i] = readInt();
    }
    dp[1][0][0][1][1] = 1;
    dp[0][1][0][1][2] = 1;
    dp[0][0][1][1][3] = 1;

    for (int l = 2; l <= n; l++) {
        for (int i = 0; i <= 15; i++) {
            for (int j = 0; j <= 15; j++) {
                for (int k = 0; k <= 15; k++) {

                        dp[i][j + 1][k][l][2] = (dp[i][j + 1][k][l][2] + dp[i][j][k][l - 1][1]) % mod;

                        dp[i][j][k + 1][l][3] = (dp[i][j][k + 1][l][3] + dp[i][j][k][l - 1][1]) % mod;

                        dp[i + 1][j][k][l][1] = (dp[i + 1][j][k][l][1] + dp[i][j][k][l - 1][2]) % mod;

                        dp[i][j][k + 1][l][3] = (dp[i][j][k + 1][l][3] + dp[i][j][k][l - 1][2]) % mod;

                        dp[i + 1][j][k][l][1] = (dp[i + 1][j][k][l][1] + dp[i][j][k][l - 1][3]) % mod;

                        dp[i][j + 1][k][l][2] = (dp[i][j + 1][k][l][2] + dp[i][j][k][l - 1][3]) % mod;
                 }
            }
        }
    }

    fun(1, 0, 0);
    cout << ans % mod;
}

#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#pragma GCC optimization ("unroll-loops")
#include <bits/stdc++.h>

using namespace std;
#define endl '\n'
#define ll long long
#define int long long
#define ld double
#define pii pair<int,int>
#define rand() abs((rand()<<15)|rand())
#define randll() abs(((long long)rand()<<30)|rand())
const int MOD = 1'000'000'007;

int ans = 0;
int n, T;
vector<int> inGenre[3];

int dp[20][20][20][4];

int ways(int a, int b, int c, int d) {
	if(dp[a][b][c][d] != -1) return dp[a][b][c][d];
	if(a==0 && b==0 && c==0) return 1;

	int x = 0;
	if(a && d != 0) x += a*ways(a-1,b,c,0);
	if(b && d != 1) x += b*ways(a,b-1,c,1);
	if(c && d != 2) x += c*ways(a,b,c-1,2);
	x %= MOD;
	return dp[a][b][c][d] = x;
}

void solve2(int used1, int used2, int rem) {
	for(int i = 0 ; i < 1<<((int)inGenre[2].size()); i++) {
		int curSum = 0;
		for(int j = 0; j < inGenre[2].size(); j++) {
			if(i & (1<<j))
				curSum += inGenre[2][j];
		}
		if(curSum != rem) continue;
		int cur = __builtin_popcountll(i);
		// cerr << used1 << " " << used2 << " " << cur << endl;
		ans+= ways(used1, used2, cur, 3);
		// cerr << used1 << " " << used2 << " " << cur << endl;
	}
}

void solve1(int used, int rem) {
	for(int i = 0; i < 1<<((int)inGenre[1].size()); i++) {
		int curSum = 0;
		for(int j = 0; j < inGenre[1].size(); j++) {
			if(i & (1<<j))
				curSum += inGenre[1][j];
		}
		if(curSum > rem) continue;
		solve2(used, __builtin_popcountll(i), rem-curSum);
	}
}

signed main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	long long seed;
	asm("rdtsc" : "=A"(seed));
	srand(seed);

	cin >> n >> T;

	memset(dp, -1, sizeof(dp));

	for(int i = 0; i < n; i++) {
		int t,g;
		cin >> t >> g;
		inGenre[g-1].push_back(t);
	}

	for(int i = 0; i < 1<<((int)inGenre[0].size()); i++) {
		int curSum = 0;
		for(int j = 0; j < inGenre[0].size(); j++) {
			if(i & (1<<j))
				curSum += inGenre[0][j];
		}
		if(curSum > T) continue;
		solve1(__builtin_popcountll(i), T-curSum);
	}

	cout << ans << endl;
}

#include<bits/stdc++.h>

#define LL long long
#define fi first
#define se second
#define mp make_pair
#define pb push_back

using namespace std;

LL gcd(LL a,LL b){return b?gcd(b,a%b):a;}
LL lcm(LL a,LL b){return a/gcd(a,b)*b;}
LL powmod(LL a,LL b,LL MOD){LL ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
const int N = 2e5 +11;
const LL mod=1e9+7;
int n,m,a[N],b[N];
int dp[(1<<15)+5][266][4];
int main(){
	ios::sync_with_stdio(false);
	cin>>n>>m;
	for(int i=0;i<n;i++)cin>>a[i]>>b[i];
	dp[0][0][3]=dp[0][0][1]=dp[0][0][2]=1;
	for(int i=0;i<(1<<n);i++){
		for(int j=0;j<n;j++){
			if((1<<j)&i){
				for(int k=m;k>=a[j];k--){
					for(int s=1;s<=3;s++){
						if(s!=b[j])(dp[i][k][b[j]]+=dp[i^(1<<j)][k-a[j]][s])%mod;
					}
				}
			}
		}
	}
	LL ans=0;
	for(int i=0;i<1<<n;i++)
		for(int j=1;j<=3;j++)
			ans+=dp[i][m][j],ans%=mod;
	cout<<ans*powmod(2,mod-2,mod)%mod<<endl;
	return 0;
}

#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <cmath>
#include <queue>
#include <set>
#include <iomanip>
#include <string>
#include <cstdio>

using namespace std;
#define ll long long
#define mod 1000000007

int n, t;
vector<pair<int, int>> s;
ll dp[16][16][16][3];

ll cal(int c1, int c2, int c3, int last) {
    if (c1 < 0 || c2 < 0 || c3 < 0) return 0;

    if (!c1 && !c2 && !c3) {
        return 1;
    }

    if (last != -1 && dp[c1][c2][c3][last] != -1) {
        return dp[c1][c2][c3][last];
    }

    ll ans = 0;

    if (last != 0) {
        ans = (ans + cal(c1 - 1, c2, c3, 0)) % mod;
    }

    if (last != 1) {
        ans = (ans + cal(c1, c2 - 1, c3, 1)) % mod;
    }

    if (last != 2) {
        ans = (ans + cal(c1, c2, c3 - 1, 2)) % mod;
    }

    dp[c1][c2][c3][last] = ans;
    return ans;
}

int main() {
    cin >> n >> t;
    s.resize(n);

    for (auto &p : s) {
        cin >> p.first >> p.second;
    }

    for (auto &i : dp) {
        for (auto &j : i) {
            for (auto &k : j) {
                for (long long &l : k) {
                    l = -1;
                }
            }
        }
    }
    vector<ll> fact(16);
    fact[0] = fact[1] = 1;
    for (int i = 2; i < 16; i++) {
        fact[i] = fact[i - 1] * i;
    }

    ll ans = 0;

    vector<int> chosen;
    for (int i = 0; i < (1 << n); i++) {
        chosen.clear();
        for (int j = 0; j < n; j++) {
            if (i & (1 << j)) chosen.push_back(j);
        }
        int sum = 0;
        vector<int> c(3, 0);
        for (auto j : chosen) {
            sum += s[j].first;
            c[s[j].second - 1]++;
        }
        if (sum != t) continue;
        ll r = cal(c[0], c[1], c[2], -1);
        r = r * fact[c[0]] % mod;
        r = r * fact[c[1]] % mod;
        r = r * fact[c[2]] % mod;
        ans = (ans + r) % mod;
    }

    cout << ans << "\n";
}

#include<bits/stdc++.h>
#define v(x)  (1<<x)
#define ll long long
#define MAXN 2<<15
#define mod 1000000007
using namespace std;

ll add(ll x,ll y){
    return x+y>=mod?x+y-mod:x+y;
}

ll dp[MAXN][4];
int t[16],g[16];
int tim[MAXN];

int main()
{
    int n,T;

    scanf("%d%d",&n,&T);
    for(int i=1;i<=n;i++)
        scanf("%d%d",&t[i],&g[i]);

    int len=v(n)-1;
    for(int i=0;i<=len;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(i&(v(j-1)))
                tim[i]+=t[j];
        }
    }

    dp[0][0]=1;
    for(int i=0;i<=len;i++)//遍历状态
    {
        for(int j=0;j<=3;j++)//最后一首歌的类型
        {
            if(dp[i][j]==0)
                continue;
            for(int k=1;k<=n;k++)//要选的歌
            {
                int v=v(k-1);
                if((i&v)||j==g[k]||tim[i+v]>T)  //听过,类型相同,总长大于T
                    continue;
                add(dp[i+v][g[k]],dp[i][j]);
            }
        }
    }
    ll ans=0;
    for(int i=0;i<=len;i++){
        if(tim[i]==T){
            for(int j=1;j<=3;j++)//以任意类型结尾
                add(ans,dp[i][1]);
        }
    }
    printf("%lld\n",ans);
    return 0;
}

#include <bits/stdc++.h>
#define pb push_back
using namespace std;

inline int read()
{
	int sum=0,ff=1; char ch=getchar();
	while(!isdigit(ch))
	{
		if(ch=='-') ff=-1;
		ch=getchar();
	}
	while(isdigit(ch))
		sum=sum*10+(ch^48),ch=getchar();
	return sum*ff;
}

const int N=16;
const int mo=1e9+7;

int n,m,f[1<<N][5],g[1<<N],a[N],b[N],ans;

inline int ksm(int x,int y)
{
	int ret=1;
	while(y)
	{
		if(y&1) ret=ret*x%mo;
		x=x*x%mo;
		y>>=1ll;
	}
	return ret;
}

signed main()
{
	n=read();
	m=read();
	for ( int i=1;i<=n;i++ )
	{
		a[i]=read();
		b[i]=read();
	}
	for( int i=1;i<=3;i++ ) f[0][i]=1;
	for ( int i=0;i<(1<<n);i++ )
		for ( int j=1;j<=n;j++ )
		{
			if(i&(1<<j-1)) continue;
			for ( int k=1;k<=3;k++ )
				if(b[j]!=k)
					f[i|(1<<j-1)][b[j]]=(f[i|(1<<j-1)][b[j]]+f[i][k])%mo;
		}
	for ( int i=0;i<(1<<n);i++ )
	{
		int tot=0;
		for ( int j=1;j<=n;j++ )
			if(i&(1<<j-1)) tot+=a[j];
		if(tot==m)
			ans=(ans+f[i][1]+f[i][2]+f[i][3])%mo;
	}
	printf("%lld\n",ans/2);
	return 0;
}

/* QAQ */
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<unordered_map>
#include<vector>
using namespace std;
#define MAXN 16
int t[MAXN],g[MAXN];
int work( int* a , int x ) {
	if( a[1] + a[2] + a[3] == 0 ) return 1;
	int res = 0;
	for( int i = 1 ; i <= 3 ; ++ i ) if( x != i && a[i] ) {
		-- a[i];
		res += (a[i]+1)*work( a , i );
		++ a[i];
	}
	return res;
}
int main() {
	//freopen("input","r",stdin);
	int n , T;
	cin >> n >> T;
	for( int i = 1 ; i <= n ; ++ i )
		scanf("%d%d",&t[i],&g[i]);
	int ans = 0;
	for( int s = 1 ; s < ( 1 << n ) ; ++ s ) {
		int curt = 0 , a[4] = {0};
		for( int j = 0 ; j < 16 ; ++ j ) if( s & (1<<j) )
			curt += t[j+1] , ++ a[g[j+1]];
		if( curt == T ) ans += work( a , 0 );
	}
	cout << ans << endl;
}

#include<bits/stdc++.h>
using namespace std;
int fact(int n)
{
	if(n<=1)
	  return 1;
	else
	 return n*fact(n-1);
}
int main()
{
     int n,t1;
	cin>>n>>t1;

	int t[17],g[17];

	for(int i=0;i<n;i++)
		cin>>t[i]>>g[i];

	int ot = 0;
	int sum = 0;
	int flag[4];
	for(int k=0;k<4;k++)
	  flag[k] = 0;
	int count,h;
	int count2 = 0;
	for(int j=0;j<n;j++)
	{
		for(int k=0;k<4;k++)
		  flag[k] = 0;
		  count = 1;
		  count2 = 0;
		  flag[g[j]] = 1;
		  sum = t[j];
		for(int i=j+1;i<n;i++)
		{
			if(t[i]<=t1)
	   	  {
	   	  	sum = sum+t[i];
	   	  	if(flag[g[i]]==0)
	   	      flag[g[i]]= 1;

	   	    else
	   	    {

	   	      count2++;
	   	     }

	   	     count++;
	   	  }
		 if(sum==t1)
	   {
	   	   if(count2==0)
		     h = fact(count);
		   else
		     h = fact(count)-fact(count-count2)*fact(count2+1);

		  ot = ot+h;
		  sum = t[j];

		  for(int k=0;k<4;k++)
		    flag[k] = 0;
		   flag[g[j]] = 1;
		   count = 1;
		   count2 = 0;
	   }
	}
}
    if(ot==0)
      ot = fact(ot);
	cout<<ot;
}

# include<bits/stdc++.h>
using namespace std;
int arr[1<<16][15];
int n,T;
void fin(int mask,int pos,pair<int,int> t[],int pre)
{
    if(arr[mask][pos]!=-1)
        return ;
        if(pre==T)
            {
                arr[mask][pos]=1;
                return;
            }
    arr[mask][pos]=0;
    for(int i=0;i<n;i++)
    {
        if(t[i].second!=t[pos].second&&(1<<i&mask)==0&&pre+t[i].first<=T)
        {
            fin(mask|(1<<i),i,t,pre+t[i].first);
            arr[mask][pos]+=arr[mask|(1<<i)][i];
        }
    }
}
int main()
{
    cin>>n>>T;
    memset(arr,-1,sizeof(arr));
    pair<int,int> t[n];
    for(int i=0;i<n;i++)
    {
        cin>>t[i].first>>t[i].second;
    }
    int ans=0;
    for(int i=0;i<n;i++)
    {
        int mask=(1<<i);
        fin(mask,i,t,t[i].first);
        ans+=arr[mask][i];
    }
    cout<<ans<<endl;
}

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> ii;

int gen[20], tempo[20];
int dp[1 << 17][20][20];
int n, m;

ll solve(int bitmask, int tt, int last){
    if(tt > m) return 0;
    if(tt == m) return 1;
    int &d = dp[bitmask][tt][last];
    if(d != -1) return d;
    ll res = 0;
    for(int i = 0; i < n; i++){
        if(!(bitmask & (1 << i)) and gen[i] != last){
            res += solve(bitmask | (1 << i), tt + tempo[i], gen[i]);
        }
    }
    return d = res;
}

int main(){
    ios_base::sync_with_stdio(false); cin.tie(NULL);
    cin >> n >> m;
    for(int i = 0; i < n; i++){
        cin >> tempo[i] >> gen[i];
    }
    memset(dp, -1, sizeof dp);
    cout << solve(0, 0, 0) << endl;

	return 0;
}

#include<bits/stdc++.h>

#define rep(i,a,n)     for(int i=a;i<n;i++)
#define rep3(n)        for(int i=0;i<n;i++)
#define ll             long long
#define int            long long
#define pb             push_back
#define all(v)         v.begin(),v.end()
#define endl           "\n"
#define eb             emplace_back
#define x              first
#define y              second
#define gcd(a,b)       __gcd(a,b)
#define mem1(a)        memset(a,-1,sizeof(a))
#define mem0(a)        memset(a,0,sizeof(a))
#define pres(a,x)      a.find(x)!=a.end()
#define sz(a)          (int)a.size()
#define pii            pair<int,int>
#define hell           1000000007
#define elasped_time   1.0 * clock() / CLOCKS_PER_SEC
using namespace std;

template<typename T1,typename T2>istream& operator>>(istream& in,pair<T1,T2> &a){in>>a.x>>a.y;return in;}
template<typename T1,typename T2>ostream& operator<<(ostream& out,pair<T1,T2> a){out<<a.x<<" "<<a.y;return out;}
template<typename T,typename T1>T maxs(T &a,T1 b){if(b>a)a=b;return a;}
template<typename T,typename T1>T mins(T &a,T1 b){if(b<a)a=b;return a;}
template<int mod>
struct mint {
  int x;
  mint():x(0){}
  mint(int x):x((x%mod+mod)%mod){}
  // mint(int x):x(x){}
  mint& fix() { x = (x%mod+mod)%mod; return *this;}
  mint operator-() const { return mint(0) - *this;}
  mint& operator+=(const mint& a){ if((x+=a.x)>=mod) x-=mod; return *this;}
  mint& operator-=(const mint& a){ if((x+=mod-a.x)>=mod) x-=mod; return *this;}
  mint& operator*=(const mint& a){ (x*=a.x)%=mod; return *this;}
  mint operator+(const mint& a)const{ return mint(*this) += a;}
  mint operator-(const mint& a)const{ return mint(*this) -= a;}
  mint operator*(const mint& a)const{ return mint(*this) *= a;}
  bool operator<(const mint& a)const{ return x < a.x;}
  bool operator==(const mint& a)const{ return x == a.x;}

  friend istream& operator>>(istream&i,mint&a){i>>a.x;return i;}
  friend ostream& operator<<(ostream&o,const mint&a){o<<a.x;return o;}
  mint<mod> expo(mint<mod> x,int y){
       mint<mod> a=1;
       while(y){
       	 if(y&1)a=a*x;
       	 x=x*x;
       	 y/=2;
       }
       return a;
  }
};
mint<hell>dp[20][20][20][4];
mint<hell>fact[100];
int solve(){
 int n,t;cin>>n>>t;
 vector<pii>a(n);
 rep3(n)cin>>a[i];
 dp[1][0][0][1]=1;
 dp[0][1][0][2]=1;
 dp[0][0][1][3]=1;
 for(int i=0;i<=15;i++){
 	for(int j=0;j<=15;j++){
 		for(int k=0;k<=15;k++){
 			if(i+j+k<=1)continue;
 			for(int t=1;t<=3;t++){
 				if(t==1){
 					if(i>0)dp[i][j][k][1]=dp[i-1][j][k][2]+dp[i-1][j][k][3];
 				}
 				else if(t==2){
 					if(j>0)dp[i][j][k][2]=dp[i][j-1][k][1]+dp[i][j-1][k][3];
 				}
 				else {
 					if(k>0)dp[i][j][k][3]=dp[i][j][k-1][1]+dp[i][j][k-1][2];
 				}
 			}
 		}
 	}
 }
 mint<hell>ans=0;
 for(int i=0;i<(1<<n);i++){
 	int ti=0;
 	vector<int>fr(4,0);
 	for(int j=0;j<n;j++){
 		if((1<<j)&i){
 			ti+=a[j].x;
 			fr[a[j].y]++;
 		}
 	}
 	if(ti==t){
 		mint<hell>val=fact[fr[1]]*fact[fr[2]]*fact[fr[3]];
 		val=val*dp[fr[1]][fr[2]][fr[3]][1]+dp[fr[1]][fr[2]][fr[3]][2]+dp[fr[1]][fr[2]][fr[3]][3];
 		ans=ans+val;
 	}
 }
 cout<<ans<<endl;
 return 0;
}
signed main(){
    ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    fact[0]=1;
    for(int i=1;i<100;i++){
    	mint<hell>val=i;
    	fact[i]=val*fact[i-1];
    }
    #ifdef SIEVE
    sieve();
    #endif
    #ifdef NCR
    init();
    #endif
    int t=1;//cin>>t;
    while(t--){
        solve();
    }
    return 0;
}

#include <bits/stdc++.h>

#define pb push_back
#define eb emplace_back
#define fi first
#define se second
#define mp make_pair

const int N = 17, M = 1000000007, inf = 0x3f3f3f3f;

using namespace std;
typedef long long ll;
typedef pair<int, int> ii;
int n, t;
int T[N], g[N];

ll memo[N][N][N];
ll fat[N];

ll dp[N][N];
ll nchoosek(ll a, ll b) {
	static int t = 0;
	if(t == 0) {
		dp[0][0] = 1;
		for(int i = 0; i <= 15; ++i) {
			for(int j = 0; j <= i; ++j) {
				if(i == 0 and j == 0) dp[i][j] = 1;
				else if(j == 0) dp[i][j] = dp[i-1][j];
				else if(j == i) dp[i][j] = dp[i-1][j-1];
				else dp[i][j] = (dp[i-1][j-1] + dp[i-1][j])%M;
			}
		}
	}
	t = 1;
	return dp[a][b];
}
ll f(int k, int c1, int c2) {
	if(k == 0) return c1 == 0 and c2 == 0;

	ll & st = memo[k][c1][c2];
	if(st == -1) {
		st = 0;
		for(int x = 0; x <= c1; ++x) {
			for(int y = 0; y <= c2; ++y) {
				if(x + y > 0) {
					if(x == y) {
						st += (((nchoosek(c1, x) * nchoosek(c2, y)%M) * fat[x]%M) * fat[y] % M) * 2ll * f(k-1, c1 - x, c2 - y)%M;
					}
					else if(abs(x - y) <= 1) {
						st += (((nchoosek(c1, x) * nchoosek(c2, y) % M) * fat[x] %M) * fat[y] %M) * f(k-1, c1 - x, c2 - y) %M;
					}
					st %= M;
				}
			}
		}
	}
	return st;
}

ll solve(int bs) {
	int tot = 0;
	vector<int> id;
	for(int i = 0; i < n; ++i) {
		if((bs >> i)&1) id.pb(i);
	}

	for(int j : id) tot += T[j];
	if(tot != t) return 0;

	if(__builtin_popcount(bs) == 1) return 1;
	int cnt[4];
	memset(cnt, 0, sizeof cnt);
	for(int j : id) cnt[g[j]]++;

	if(cnt[3] == 0) {
		if(cnt[1] == cnt[2]) return 2ll * (fat[cnt[1]] * fat[cnt[2]])%M;
		if(abs(cnt[1] - cnt[2]) == 1) return (fat[cnt[1]] * fat[cnt[2]])%M;
		else return 0;
	} else {
		ll ans = f(cnt[3]+1, cnt[1], cnt[2]);
		ans = (ans + 2ll*f(cnt[3], cnt[1], cnt[2]))%M;
		if(cnt[3] > 1) ans = (ans + f(cnt[3]-1, cnt[1], cnt[2]))%M;
		return ans;
	}
}

int main() {
	memset(memo, -1, sizeof memo);
	ios::sync_with_stdio(0); cin.tie(0);

	fat[0] = 1;
	for(ll i = 1; i <= 15; ++i) fat[i] = (fat[i-1] * i)%M;
	cin >> n >> t;

	for(int i = 0; i < n; ++i) {
		cin >> T[i] >> g[i];
	}

	ll sum = 0;
	for(int i = 1; i < (1 << n); ++i) {
		ll ans = solve(i);
		sum += ans;
		sum %= M;
	}
	cout << sum << endl;
}

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
#define INF 1e19
#define LBW return
#define AK 0
#define IOI ;
#define int ll
template <typename T> void chmin(T &x,const T &y){if(x>y)x=y;}
template <typename T> void chmax(T &x,const T &y){if(x<y)x=y;}
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}
	while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
const int N=2000+10;
const int mod=1e9+7;
int n,t,dp[1<<15][16],sta[1<<15],ok[1<<15],ans;
struct node{int t,g;}a[N];
inline int work(int x){
	int res=0;
	for(int i=0;i<n;i++)if((1<<i)&x)res+=a[i+1].t;
	if(res==t)ok[x]=1;
	else if(res>t)ok[x]=2;
	return res;
}
signed main(){
	n=read(),t=read();
	for(int i=1;i<=n;i++) a[i].t=read(),a[i].g=read();
	for(int i=1;i<(1<<n);i++)sta[i]=work(i);
	for(int i=0;i<n;i++)dp[1<<i][i+1]=1;
	int all=(1<<n)-1;
	for(int st=0;st<=all;st++){
		if(ok[st]==2)continue;
		if(ok[st]==1){
			for(int i=0;i<n;i++)if(st&(1<<i))(ans+=dp[st][i+1])%mod;
			continue;
		}
		for(int i=0;i<n;i++)if((1<<i)&st)
		for(int j=0;j<n;j++)if((!((1<<j)&st))&&a[i+1].g!=a[j+1].g){
			(dp[(1<<j)|st][j+1]+=dp[st][i+1])%mod;
		}

	}
	cout<<ans;
	LBW AK IOI;
}

														//"بسم الله الرحمن الرحيم"

							//"وأما من امن وعمل صالحا فله جزاء الحسنى وسنقول له من امرنا يسرا"

													 //"tomorrow never will be like today........"

										//"Go and try to hack me you are a loooooooser anyway huh *_*........"

#include <iostream>
#include<string>
#include<vector>
#include<string>
#include<map>
#include<set>
#include<unordered_set>
#include<unordered_map>
#include<cmath>
#include<algorithm>
#include<functional>
#include<set>
#include<stack>
#include<queue>
#include<iomanip>
#include<math.h>
#include<Bits.h>

#define loop(n) for(int i=0;i<n;i++)
#define cinarr(arr,n) for(int i=0;i<n;i++){cin>>arr[i];}
#define PII pair<int , int>
#define PLL pair<long long,long long>
#define PIS pair<int , string>
#define pb(a) push_back(a)
#define veci vector<int>
#define vecl vector<long long>
#define vecs vector<string>
#define sz(s) int(s.size())
#define p(a) push(a)
#define mkp(a,b) make_pair(a,b)
#define mem2(dp,s1,s2) for(int i = 0 ; i< s1 ; ++i) for(int j = 0 ; j<s2 ; ++j) dp[i][j] = -1;
#define mem3(dp,s1,s2,s3) for(int i = 0 ; i<s1 ; ++i) for(int j = 0 ; j<s2 ; ++j) for(int k = 0 ; k< s3 ; ++k) dp[i][j][k] = -1;
#define fastIO ios::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);

const int MX = 2750131+1;

using namespace std;

typedef long long ll;
typedef string str;
typedef double db;
typedef float fl;
typedef int i;
/*

int lst[MX];
int primeIndex[MX];

//if prime lst[i] = i , else lst[i] = greatest divisor.

void sieve()
{

	loop(MX) lst[i] = i;
	for (int i = 2; i < MX; i++)
	{
		if (lst[i] != i)
		{
			// i is the smallest divisor of lst[i]
			lst[i] = i / lst[i]; //gratest divisor.
		}
		else
		{
			for (ll np = i * 1ll * i; np < MX; np += i)
			{
				lst[np] = min(lst[np], i);
			}
		}
	}

	int ind = 1;
	for (int i = 2; i < MX; i++)
	{
		if (lst[i] == i)
			primeIndex[i] = ind++;
	}

}

int find(int i)
{
	if (parent[i] == 0)
		return i;
	return parent[i] = find(parent[i]); // dp memorizing
}

bool Union(int a, int b)
{
	int x = find(a);
	int y = find(b);
	if (x == y)
		return true;
	parent[x] = y;
	return false;
}

bool compare(char p1, char p2)
{
	return p1 > p2;
}

ll gcd(ll a, ll b)
{
	if (b == 0)
		return a;
	return gcd(b, a%b);
}

*/
/*
ll OO = 1e9;
int dis[100010];
bool ch[100010];
int n, c, m;
vector< vector<int> > gr;

void dikstra(int src = 1)
{
	priority_queue< pair<int,int>, vector<pair<int,int>> , greater<pair<int,int>> > pq;

	pq.p(mkp((int)ch[src], src));
	while (!pq.empty())
	{
		int u = pq.top().second;
		ll w = pq.top().first;
		pq.pop();
		if(w < dis[u])
			dis[u] = w;
		for(auto x : gr[u])
		{
			if (w + (int) ch[x] < dis[x])
				pq.p(mkp(w + (int) ch[x] , x));
		}
	}
}

ll power(ll x, ll y)
{
	ll res = 1;      // Initialize result

	x = x % MOD;  // Update x if it is more than or

	while (y > 0)
	{
		// If y is odd, multiply x with result
		if (y & 1)
			res = (res*x) % MOD;

		// y must be even now
		y = y >> 1; // y = y/2
		x = (x*x) % MOD;
	}
	return res;
}

int arr[100000];
int seg[303000];

void build_SegTree(int l , int r , int pos) // o( n )
{
	if (l == r) { seg[pos] = arr[l]; return; }
	int mid = l + (r - l) / 2;
	build_SegTree(l, mid, 2 * pos + 1);
	build_SegTree(mid+1, r , 2 * pos + 2);
	seg[pos] = (seg[2 * pos + 1] + seg[2 * pos + 2]);
}

int Query(int ql ,int qh ,int l , int r , int pos ) //o( logn )
{
	if (ql <= l && qh >= r) // total overlap
		return seg[pos];
	if (ql > r || qh < l) // no overlap
		return 0;
	int mid = l + (r - l) / 2;
	return  (Query(ql, qh, l, mid, 2 * pos + 1) + Query(ql, qh, mid + 1, r, 2 * pos + 2));
}
*/
ll MOD = 1e9 + 7;
ll mem[16][226];
int vis[16];
vector<pair<int, int>> v;
int n, t;
ll solve(int i , int rem )
{
	if (rem == 0)
		return 1;
	if (i >= n)
		return 0;
	ll &ret = mem[i][rem];
	if (ret != -1)
		return ret;
	ret = 0;
	for(int j = 0 ; j<n ; ++j)
	{
		if (!vis[j] && v[j].second != v[i].second)
		{
			vis[j] = 1;
			ret += solve(j, rem -v[j].first)%MOD;
			vis[j] = 0;
		}

	}
	return ret;

}

int main()
{

	fastIO;
	mem2(mem, 16, 226);
	cin >> n >> t;
	loop(n) { int x, y; cin >> x >> y; v.pb(mkp(x, y)); }
	ll ans = 0;
	loop(n)
	{
		vis[i] = 1;
		ans += solve(i, t - v[i].first)%MOD;
		vis[i] = 0;
	}
	cout << ans << endl;

}

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <vector>

using namespace std;

typedef unsigned long long ll;

const int INF = 2147483647;
const int INF2 = 0x3f3f3f3f;
const ll INF64 = 0x3f3f3f3f3f3f3f3f;
const double PI = 3.14159265358979323846;
const int MOD = (int)(1e9) + 7;
const ll TARGET = (1LL << 32) - 1LL;

template <typename T>
inline T read() {
    T X = 0, w = 0;
    char ch = 0;
    while (!isdigit(ch)) {
        w |= ch == '-';
        ch = getchar();
    }
    while (isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
    return w ? -X : X;
}

struct Point {
    int l;
    int r;
    bool operator<(const Point &other) const { return r < other.l; }
};

const int MAXN = 25;
int n, m, k;
int w, h;

int CASE = 1;
pair<int, int> arr[MAXN];
bool vis[MAXN];

ll fact[MAXN];

int main() {
#ifdef LOCALLL
    freopen("in", "r", stdin);
    freopen("out", "w", stdout);
#endif
    ll ans = 0;
    fact[0] = 1;
    for (int i = 1; i <= MAXN; i++) {
        fact[i] = fact[i - 1] * i;
    }
    scanf("%d %d", &n, &m);
    for (int i = 0; i < n; i++) {
        scanf("%d %d", &arr[i].second, &arr[i].first);
    }
    for (int s = 0; s < (1 << n); s++) {
        vector<pair<int, int>> vec;
        int t = 0;
        for (int i = 0; i < n; i++) {
            if ((s >> i) & 1) {
                vec.push_back(arr[i]);
                t += arr[i].second;
            }
        }
        if (t == m) {
            map<int, int> rep;
            for (auto a : vec) {
                rep[a.first]++;
            }
            int x = __builtin_popcount(s);
            k = fact[x];
            for (auto b : rep) {
                if (b.second == 1) continue;
                if (x - b.second == 0) {
                    k = 0;
                    break;
                }
                k -= fact[b.second] * (x - b.second + 1);
            }
            ans += k % MOD;
            ans %= MOD;
        }
    }
    printf("%lld", ans);
    return 0;
}

#include <bits/stdc++.h>
#define pb push_back

using namespace std;

void debug_out() { cerr << '\n'; }
template <typename Head, typename... Tail> void debug_out(Head H, Tail... T) { cerr << " " << H; debug_out(T...);}
#define dbg(...) cerr << #__VA_ARGS__ << " ->", debug_out(__VA_ARGS__)
#define dbg_v(x, n) do{cerr<<#x"[]: ";for(int _=0;_<n;++_)cerr<<x[_]<<" ";cerr<<'\n';}while(0)
#define dbg_ok cerr<<"OK!\n"

typedef pair<int,int> pii;
typedef long long int ll;
typedef long double ld;

inline int two(int n) { return 1 << n; }
inline int test(int n, int pos) { return (bool) (n & two(pos)); }
inline void set_bit(int &n, int b) { n |= two(b); }
inline void unset_bit(int &n, int b) { n &= ~two(b); }
inline int last_bit(int n) { return n & (-n); }

const int DMAX = 18;
const int LgMAX = 32800;
const int MOD = 1e9+7;

vector <int> vec;
vector <int> arb[DMAX];

pii V[DMAX];

pii dp[LgMAX][DMAX];

int n;

ll ans;

int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    int t,i,k;
    int mask,mask2;

    cin>>n>>t;
    for(i=0;i<n;i++){
        cin>>V[i].first>>V[i].second;
    }
    for(i=0;i<n;i++){
        dp[1<<i][i].first=V[i].first;
        dp[1<<i][i].second=1;
        if(dp[1<<i][i].second == t)
           ans++;
    }
    for(mask=1;mask<(1<<n);mask++)
        for(i=0;i<n;i++)
            if(mask & (1<<i)){
                mask2=mask-(1<<i);
                for(k=0;k<n;k++)
                    if((mask2 & (1<<k))&&(V[i].second != V[k].second)){
                        dp[mask][i].first=dp[mask2][k].first+V[i].first;
                        dp[mask][i].second+=dp[mask2][k].second;
                    }
                if(dp[mask][i].first == t){
                    ans+=dp[mask][i].second;
                    if(ans > MOD)
                       ans-=MOD;
                }
            }
    cout<<ans<<'\n';
    return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define M 1000000007
#define ll long long
#define REP(i,a,b) for(ll i=a;i<b;i++)
#define F first
#define S second
#define PB push_back
#define MP make_pair
#define VI vector<int>
#define VLL vector<long long>

ll modInverse(ll a, ll m);
ll gcd(ll a, ll b);
ll power(ll x, unsigned ll y, unsigned ll m);
void pairsort(int a[], int b[], int n);
void pairsortll(ll a[],ll b[],ll n);
ll logint(ll x,ll y);

ll gcd(ll a, ll b)
{
    if (a == 0)
        return b;
    return gcd(b%a, a);
}

ll power(ll x, unsigned ll y, unsigned ll m)
{
    if (y == 0)
        return 1;
    ll p = power(x, y/2, m) % m;
    p = (p * p) % m;

    return (y%2 == 0)? p : (x * p) % m;
}

ll modInverse(ll a, ll m)
{
    ll m0 = m;
    ll y = 0, x = 1;

    if (m == 1)
      return 0;

    while (a > 1)
    {
        // q is quotient
        ll q = a / m;
        ll t = m;

        // m is remainder now, process same as
        // Euclid's algo
        m = a % m, a = t;
        t = y;

        // Update y and x
        y = x - q * y;
        x = t;
    }

    // Make x positive
    if (x < 0)
       x += m0;

    return x;
}

void pairsort(int a[], int b[], int n)
{
    pair<int, int> pairt[n];

    // Storing the respective array
    // elements in pairs.
    for (int i = 0; i < n; i++)
    {
        pairt[i].first = a[i];
        pairt[i].second = b[i];
    }

    // Sorting the pair array.
    sort(pairt, pairt + n);

    // Modifying original arrays
    for (int i = 0; i < n; i++)
    {
        a[i] = pairt[i].first;
        b[i] = pairt[i].second;
    }
}

void pairsortll(ll a[], ll b[], ll n)
{
    pair<ll, ll> pairt[n];

    // Storing the respective array
    // elements in pairs.
    for (ll i = 0; i < n; i++)
    {
        pairt[i].first = a[i];
        pairt[i].second = b[i];
    }

    // Sorting the pair array.
    sort(pairt, pairt + n);

    // Modifying original arrays
    for (ll i = 0; i < n; i++)
    {
        a[i] = pairt[i].first;
        b[i] = pairt[i].second;
    }
}

ll logint(ll x,ll y)
{
    ll ans=0;
    ll a=1;
    for(ll i=0;i<x;i++)
    {
        if(x<=a)
        {
            return ans;
        }
        ans++;
        a*=y;
    }
    return -1;
}

ll solve(ll p[4],ll gg)
{
    if(p[1]==0&&p[2]==0&&p[3]==0) return 1;
    ll ans=0;
    REP(i,0,4)
    {
        if(i!=gg&&p[i]>0)
        {
            p[i]--;
            ans+=(p[i]+1)*solve(p,i);
            ans%=M;
            p[i]++;
        }
    }
    return ans;
}

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

    /*
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    */

    ll n,m;
    cin>>n>>m;
    ll f[n]={};
    ll t[n],g[n];
    REP(i,0,n)
    {
        cin>>t[i]>>g[i];
    }
    ll ans=0;
    REP(i,0,1<<n)
    {
        ll p[4]={};
        ll tt=0;
        REP(j,0,n)
        {
            if(((1<<j)&i)>0)
            {
                p[g[j]]++;
                tt+=t[j];
            }
        }
        if(tt==m)
        {
            ans+=solve(p,0);
        }
    }
    cout<<ans;

    return 0;
}

#include<bits/stdc++.h>

using namespace std;

typedef long long INT;

#define NN 55
#define mod 1000000007

int dp[NN][NN][NN][3];

inline int add(int &u, int v) {
	u += v;
	if(u >= mod) u -= mod;
}

int ss[10];
int t[NN], g[NN];

int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif
	for(int i=0; i<NN; i++) for(int j=0; j<NN; j++) for(int k=0; k<NN; k++) for(int t=0; t<3; t++) {
		if(!i and !j and !k) {
			dp[i][j][k][t] = 1;
			continue;
		}
		int &s = dp[i][j][k][t];
		if(t == 0) {
			if(j) add(s, (INT) j * dp[i][j-1][k][1] % mod);
			if(k) add(s, (INT) k * dp[i][j][k-1][2] % mod);
		}
		if(t == 1) {
			if(i) add(s, (INT) i * dp[i-1][j][k][0] % mod);
			if(k) add(s, (INT) k * dp[i][j][k-1][2] % mod);
		}
		if(t == 2) {
			if(i) add(s, (INT) i * dp[i-1][j][k][0] % mod);
			if(j) add(s, (INT) j * dp[i][j-1][k][1] % mod);
		}
	}

	int n, T;
	cin >> n >> T;

	for(int i=1; i<=n; i++) cin >> t[i] >> g[i];

	int ans = 0;

	for(int i=0; i<(1<<n); i++) {
		memset(ss, 0, sizeof ss);
		int sum = 0;
		for(int j=0; j<n; j++) if((i>>j) & 1) {
			ss[g[j+1]-1]++;
			sum += t[j+1];
		}
		if(sum == T) {
			INT s = 0;
			for(int j=0; j<=2; j++) {
				s += dp[ss[0]][ss[1]][ss[2]][j];
			}
			add(ans, ((s / 2) % mod));
		}
	}

	cout << ans << endl;
}

#include<bits/stdc++.h>
using namespace std;
#define bj (1<<j)
typedef long long ll;
typedef pair<ll,ll> pll;
const ll N=2e3+10,mod=1e9+7,inf=0x3f3f3f3f3f3f3f3f;
int a[N],b[N],cnt[4];
ll dp[16][16][16][4];
ll dfs(int i,int j,int k,int st)
{
    if(i+j+k==0)return 1;

    if(dp[i][j][k][st])return dp[i][j][k][st];
    if(st==1)
    {
        if(j)
            dp[i][j][k][st]+=dfs(i,j-1,k,2)%mod;
        if(k)
            dp[i][j][k][st]+=dfs(i,j,k-1,3)%mod;
    }
    if(st==2)
    {
        if(i)
            dp[i][j][k][st]+=dfs(i-1,j,k,1)%mod;
        if(k)
            dp[i][j][k][st]+=dfs(i,j,k-1,3)%mod;
    }
    if(st==3)
    {
        if(j)
            dp[i][j][k][st]+=dfs(i,j-1,k,2)%mod;
        if(i)
            dp[i][j][k][st]+=dfs(i-1,j,k,1)%mod;
    }
    //printf("%d %d %d %d:%lld\n",i,j,k,st,dp[i][j][k][st]);
    return dp[i][j][k][st];
}
int main()
{
    //freopen("i.txt","r",stdin);
    int n,t;
    ll ans=0;
    scanf("%d %d",&n,&t);
    for(int i=0; i<n; i++)scanf("%d %d",&a[i],&b[i]);
    for(int i=1; i<(1<<n); i++)
    {
        int sum=0;
        memset(cnt,0,sizeof cnt);
        for(int j=0; j<n; j++)
        {
            if(bj&i)
            {
                sum+=a[j];
                cnt[b[j]]++;
            }
        }

        if(sum==t)
        {
            memset(dp,0,sizeof dp);
            if(cnt[1])
                ans+=dfs(cnt[1]-1,cnt[2],cnt[3],1)*cnt[1]%mod;
            ans%=mod;
            if(cnt[2])
                ans+=dfs(cnt[1],cnt[2]-1,cnt[3],2)*cnt[2]%mod;
            ans%=mod;
            if(cnt[3])
                ans+=dfs(cnt[1],cnt[2],cnt[3]-1,3)*cnt[3]%mod;
            ans%=mod;
        }
    }
    printf("%lld\n",ans);
}

#include <iostream>
#include <bits/stdc++.h>

using namespace std;
int n,t;
int DP[1<<15][226][4];
pair <int,int> arr[15];
vector <int> print;
int solve(int mask,int timeleft,int prev)
{   int c=0;
    if(DP[mask][timeleft][prev]!=-1)
        return DP[mask][timeleft][prev];
    if(timeleft==0)
        return 1;
    for (int i=0; i<n; i++)
    {
        if((!(mask&(1<<i)))||prev==arr[i].second||timeleft-arr[i].first<0)
            continue;
        c+=solve(mask^(1<<i),timeleft-arr[i].first,arr[i].second);
    }
        return DP[mask][timeleft][prev]=c;
}

int main()
{
    cin >> n >> t;
    for(int i=0;i<1<<n;i++)
        for (int j=0;j<226;j++)
            for(int k=0;k<4;k++)
                DP[i][j][k]=-1;
    for(int i=0;i<n;i++)
        cin >> arr[i].first >> arr[i].second;
    cout << solve((1<<n)-1,t,4);

}

#pragma region Header

#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <iostream>
#include <stdio.h>
#include <vector>
#include <string>
#include <cstring>
#include <set>
#include <map>
#include <list>
#include <unordered_set>
#include <unordered_map>
#include <bitset>
#include <queue>
#include <stack>
#include <cmath>
#include <algorithm>
#include <iomanip>

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

#define pii pair<int, int>
#define pll pair<ll, ll>
#define uset unordered_set
#define umap unordered_map
#define mp make_pair
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#pragma comment(linker, "/STACK:64777216")

using namespace std;

#ifdef LOCAL
#define eprintf(...) fprintf(stdout, __VA_ARGS__)
#define print_var(x) cout << #x << " = " << x << endl
#define print_vars(x, y) cout << #x << " = " << x << ", " << #y << " = " << y << endl
#define print_array(a) { cout << #a << " = "; for (auto e : a) cout << e << " "; cout << endl; }
#define print_endl() cout << endl
#else
#define eprintf(...) (void)0
#define print_var(x) (void)0
#define print_vars(...) (void)0
#define print_array(a) (void)0
#define print_endl() (void)0
#endif

const int inf = (int)1e9 + 5;
const ll INF = (ll)1e18 + 5;

#pragma endregion

const ll mod = 1e9 + 7;
const ll maxt = 16;
ll dp[maxt][maxt][maxt][3];

ll add(ll x, ll y)
{
	return (x + y) % mod;
}

void solve()
{
	ll n, T;
	cin >> n >> T;

	vector<ll> a(n), G(n);
	for (ll i = 0; i < n; i++)
		cin >> a[i] >> G[i];

	ll ans = 0;
	for (ll mask = 0; mask < (1 << n); mask++)
	{
		ll cur_t = 0;
		vector<ll> cnt(3, 0);
		for (ll i = 0; i < n; i++)
			if (mask & (1 << i))
			{
				cur_t += a[i];
				cnt[G[i] - 1]++;
			}

		if (cur_t != T)
			continue;

		ll total_cnt = cnt[0] + cnt[1] + cnt[2];

		memset(dp, 0, sizeof(dp));
		dp[1][0][0][0] = cnt[0];
		dp[0][1][0][1] = cnt[1];
		dp[0][0][1][2] = cnt[2];

		for (ll c = 2; c <= total_cnt; c++)
		{
			for (ll c1 = 0; c1 <= cnt[0]; c1++)
				for (ll c2 = 0; c2 <= cnt[1] && c1 + c2 <= c; c2++)
				{
					ll c3 = c - (c1 + c2);
					if (c3 > cnt[2])
					{
						c2 = c - c1 - cnt[2] - 1;
						continue;
					}
					for (ll last = 0; last < 3; last++)
					{
						if (last == 0 && c1 == 0 ||
							last == 1 && c2 == 0 ||
							last == 2 && c3 == 0) continue;

						ll pc1 = c1;
						ll pc2 = c2;
						ll pc3 = c3;
						if (last == 0)
							pc1--;
						if (last == 1)
							pc2--;
						if (last == 2)
							pc3--;

						ll cur_dp = 0;

						for (ll p = 0; p < 3; p++)
							if (last != p)
							{
								cur_dp = add(cur_dp, dp[pc1][pc2][pc3][p]);
							}

						if (c == total_cnt)
							ans = add(ans, cur_dp);
						else
							dp[c1][c2][c3][last] = cur_dp;
					}
				}
		}

		if (total_cnt == 1)
			ans = add(ans, 1);
	}

	cout << ans << endl;
}

int main()
{
	string filename = "acm";

#ifdef LOCAL
	freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
#else
	//freopen((filename + ".in").data(), "r", stdin);
	//freopen((filename + ".out").data(), "w", stdout);
#endif // !LOCAL

	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.precision(15);

	solve();

	eprintf("\n\ntime: %.3lf\n", double(clock()) / CLOCKS_PER_SEC);
	return 0;
}

#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <fstream>
#include <math.h>
#include <queue>
#include <bitset>
#include <cmath>
#include <complex>
#include <iomanip>
#include <valarray>
#include <stack>

using namespace std;
typedef vector<int> vi;
typedef unsigned long long ull;
typedef vector<ull> vull;
typedef set<string> ss;
typedef vector<vi> vvi;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef pair<int, ii> iii;
typedef vector<iii> viii;
typedef vector<viii> vviii;
typedef vector<vii> vvii;
typedef vector<string> vs;
typedef map<string, int> msi;
typedef multiset<int> mlsi;
typedef set<ii> sii;
typedef map<int, ii> mii;
typedef pair<string, int> psi;
typedef queue<int> qi;
typedef pair<int, vi> pivi;
typedef vector<pivi> vpivi;
typedef pair<int, ii> iii;
typedef vector<iii> viii;
typedef pair<int, bool> ib;
typedef vector<ib> vib;
typedef vector<double> vd;
typedef vector<string> vs;
typedef vector<vib> vvib;
typedef set<int> si;
typedef pair<bool, bool> bb;
typedef long long ll;

/* ii;
class SegTree {
public:
   vii A;
   vi st;
   int n;

   int left(int i) {
       return (i << 1);
   }

   int right(int i) {
       return (i << 1) + 1;
   }

   void build(int p, int L, int R) {
       if (L == R)
           st[p] = L;
       else {
           build(left(p), L, (L + R) / 2);
           build(right(p), (L + R) / 2 + 1, R);
           int p1 = st[left(p)];
           int p2 = st[right(p)];
           st[p] = A[p1].second <= A[p2].second ? p1 : p2;
       }
   }

   SegTree(const vii &_A) {
       A = _A;
       n = _A.size();
       st.assign(4 * n, -1);
       build(1, 0, n - 1);
   }

   int rmq(int p, int L, int R, int i, int j) {
       if (i > R || j < L) return -1;
       if (L >= i && R <= j) return st[p];
       int p1 = rmq(left(p), L, (L + R) / 2, i, j);
       int p2 = rmq(right(p), (L + R) / 2 + 1, R, i, j);
       if (p1 == -1) return p2;
       if (p2 == -1) return p1;

       return (A[p1].second <= A[p2].second ? p1 : p2);
   }

   int rmq(int i, int j) {
       return rmq(1, 0, n - 1, i, j);
   }

   int getIndex(int p, int L, int R, int pos) {
       if (L == R) return p;
       if (pos <= (L + R) / 2) return getIndex(left(p), L, (L + R) / 2, pos);
       return getIndex(right(p), (L + R) / 2 + 1, R, pos);
   }

   void update(int pos, int value) {
       A[pos].second = value;
       pos = getIndex(1, 0, n - 1, pos);
       pos /= 2;

       while (pos != 0) {
           int p1 = st[left(pos)];
           int p2 = st[right(pos)];

           if (p1 >= 0 && p2 >= 0)
               st[pos] = A[p1].second <= A[p2].second ? p1 : p2;
           pos /= 2;
       }
   }
};
 */

/*int;

class SegTree {
public:
   vi A;
   vii st;
   int n;

   int left(int i) {
       return (i << 1);
   }

   int right(int i) {
       return (i << 1) + 1;
   }

   void build(int p, int L, int R) {
       if (L == R)
           st[p] = L;
       else {
           build(left(p), L, (L + R) / 2);
           build(right(p), (L + R) / 2 + 1, R);
           int p1 = st[left(p)];
           int p2 = st[right(p)];
           st[p] = A[p1] <= A[p2] ? p1 : p2;
       }
   }

   SegTree(const vi &_A) {
       A = _A;
       n = _A.size();
       st.assign(4 * n, -1);
       build(1, 0, n - 1);
   }

   int rmq(int p, int L, int R, int i, int j) {
       if (i > R || j < L) return -1;
       if (L >= i && R <= j) return st[p];
       int p1 = rmq(left(p), L, (L + R) / 2, i, j);
       int p2 = rmq(right(p), (L + R) / 2 + 1, R, i, j);
       if (p1 == -1) return p2;
       if (p2 == -1) return p1;

       return (A[p1] <= A[p2] ? p1 : p2);
   }

   int rmq(int i, int j) {
       return rmq(1, 0, n - 1, i, j);
   }

   int getIndex(int p, int L, int R, int pos) {
       if (L == R) return p;
       if (pos <= (L + R) / 2) return getIndex(left(p), L, (L + R) / 2, pos);
       return getIndex(right(p), (L + R) / 2 + 1, R, pos);
   }

   void update(int pos, int value) {
       A[pos] = value;
       pos = getIndex(1, 0, n - 1, pos);
       pos /= 2;

       while (pos != 0) {
           int p1 = st[left(pos)];
           int p2 = st[right(pos)];

           if (p1 >= 0 && p2 >= 0)
               st[pos] = A[p1] <= A[p2] ? p1 : p2;
           pos /= 2;
       }
   }
};
 */

class UnionFind {
public:
    vi rank;
    vii p;

    UnionFind(int N) {
        rank.assign(N, 0);
        p.assign(N, ii(0, 1));
        for (int i = 0; i < N; i++) p[i].first = i;
    }

    int findSet(int i) {
        return (p[i].first == i) ? i : (p[i].first = findSet(p[i].first));
    }

    bool isSameSet(int i, int j) {
        return findSet(i) == findSet(j);
    }

    void unionSet(int i, int j) {
        if (!isSameSet(i, j)) {
            int x = findSet(i), y = findSet(j);
            if (rank[x] > rank[y]) {
                p[y].first = x;
                p[x].second += p[y].second;
            } else {
                p[x].first = y;
                p[y].second += p[x].second;
                if (rank[x] == rank[y]) rank[y]++;
            }
        }
    }

    int getMax() {
        int maxIn = 0;
        for (int i = 0; i < p.size(); i++)
            if (p[i].second > p[maxIn].second)
                maxIn = i;

        return maxIn;
    }

};

int main() {
    int n;
    cin >> n;
    vvi rels;
    vi tmp;
    rels.assign(n, tmp);
    for (int i = 0; i < n - 1; i++) {
        int u, v;
        cin >> u >> v;
        u--;
        v--;
        rels[u].push_back(v);
        rels[v].push_back(v);
    }

    bool fl = true;
    for(int i=0 ; i<n ; i++)
        if(rels[i].size() == 2){
            fl = false;
            break;

        }

    if(fl) cout<< "YES\n";
    else cout << "NO\n";
}

#include <bits/stdc++.h>
#define FOR(i, a, b) for(int i = (a); i <= (b); i++)
#define FORR(i, a, b) for(int i = (a); i >= (b); i--)
#define maxn 2005
#define F first
#define S second
using namespace std;
int n, T, a[16], b[4];
long long res, dp[1 << 16][4];
long long minimize(long long a)
{
    return a %= 1000000007;
}
int main()
{
    ios_base::sync_with_stdio(0);
#ifndef ONLINE_JUDGE
    freopen("inp.txt", "r", stdin);
#endif // ONLINE_JUDGE
    cin >> n >> T;
    FOR(i, 0, n-1) cin >> a[i] >> b[i], b[i]--;
    dp[0][3] = 1;
    FOR(i, 0, (1 << n)-1)
        FOR(st, 0, 3)
        {
            FOR(j, 0, n-1)
            {
                if(b[j] != st && ((i & (1 << j)) == 0))
                {
                   dp[i + (1 << j)][b[j]] = minimize(dp[i + (1 << j)][b[j]] + dp[i][st]);
                }
            }
            int sum = 0;
            FOR(j, 0, n-1) if(i & (1 << j)) sum += a[j];
            if(sum == T)
            {
                res = minimize(res + dp[i][st]);
            }
        }
        cout << res;

}

# include <bits/stdc++.h>
# define ll long long
# define INF 1000000007
#define ff first
#define ss second
using namespace std;

ll a,b,ans;

ll d[100009];
ll c[100009][2];
bool vs[100009];

void dfs(ll x, ll y)
{
	if(y==b)
	{ans++;return;}
	if(x==a)
		return;
	for(ll i=0;i<a;i++)
	if(vs[i]==0 && (i==0 || (i>0 && c[d[x-1]][1]!=c[i][1])) && y+c[i][0]<=b)
	{
		d[x]=i;
		y+=c[i][0];
		vs[i]=1;
		dfs(x+1,y);
		y-=c[i][0];
		vs[i]=0;
	}
}

int main()
{
	cin>>a>>b;

	for(ll i=0;i<a;i++)
	cin>>c[i][0]>>c[i][1];

	dfs(0,0);
	cout<<ans;
}

#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef long double ld;
typedef pair<int,int> pi;
#define f first
#define s second
#define FAST ios_base::sync_with_stdio(0); cin.tie(0);
#define all(x) x.begin(),x.end()
const int maxn = 16;
const int mod = 1e9+7;

int t[maxn],g[maxn];
int T,n;
int dp[(1 << 15)][3][230];

void add(int &a, int b) {
	a += b;
	a %= mod;
}

int dpf(int bm, int prev, int sum) {
	if (sum > T) return 0;
	if (sum == T) return 1;
	if (dp[bm][prev][sum] != -1) return dp[bm][prev][sum];

	dp[bm][prev][sum] = 0;

	for (int i =0;i<n;i++) {
		if (!((1 << i) & bm) and g[i] != prev) {
			int newbm = bm | (1 << i);
			add(dp[bm][prev][sum],dpf(newbm,g[i],sum + t[i]));
		}
	}
	return dp[bm][prev][sum];
}

int32_t main() {
	FAST
	cin >> n >> T;
	for (int i =0;i<n;i++) {
		cin >> t[i] >> g[i];
	}
	memset(dp,-1,sizeof dp);
	cout << dpf(0,0,0);

}

#include "bits/stdc++.h"

using namespace std;
using LL = long long;

int n, T;
int dat[20], inT[20], inG[20];
int used[20];

map< int, LL> mp[20];

LL rec(int k, int sum, int last, int mask) {
    if (mp[last].count(mask)) return mp[last][mask];
    if (sum > T) return 0;

    if (sum == T) {
        return 1;
    }

    LL rv = 0;
    for (int i = 0; i < n; ++i) {
        if (used[i]) continue;

        if (k == 0 or inG[i] != inG[dat[k - 1]]) {
            used[i] = 1;
            dat[k] = i;
            mask ^= 1 << i;
            rv += rec(k + 1, sum + inT[i], inG[i], mask);
            mask ^= 1 << i;
            used[i] = 0;
        }
    }
    return mp[last][mask] = rv;
}

int main() {
    scanf("%d %d", &n, &T);
    for (int i = 0; i < n; ++i) {
        scanf("%d %d", &inT[i], &inG[i]);
    }

    LL res = rec(0, 0, 0, 0);
    cout << res << endl;
}

# include<bits/stdc++.h>
using namespace std;
int arr[1<<16][15];
int n,T;
void fin(int mask,int pos,pair<int,int> t[],int pre)
{
    if(arr[mask][pos]!=-1)
        return ;
        if(pre==T)
            {
                arr[mask][pos]=1;
                return;
            }
    arr[mask][pos]=0;
    for(int i=0;i<n;i++)
    {
        if(t[i].second!=t[pos].second&&(1<<i&mask)==0&&pre+t[i].first<=T)
        {
            fin(mask|(1<<i),i,t,pre+t[i].first);
            arr[mask][pos]=(arr[mask][pos]+arr[mask|(1<<i)][i])%(1000000007);
        }
    }
}
int main()
{
    cin>>n>>T;
    memset(arr,-1,sizeof(arr));
    pair<int,int> t[n];
    for(int i=0;i<n;i++)
    {
        cin>>t[i].first>>t[i].second;
    }
    int ans=0;
    for(int i=0;i<n;i++)
    {
        int mask=(1<<i);
        fin(mask,i,t,t[i].first);
        ans+=arr[mask][i];
    }
    cout<<ans<<endl;
}

#include<bits/stdc++.h>
#define int long long
using namespace std;
int dp[(1<<15)][4];
int target,n;

vector<pair<int,int> >v;
bool check(int k,int pos)
{
    if(k&(1<<pos)) return true;
    else return false;
}
int SET(int k,int pos)
{
    return k|(1<<pos);
}
int bitmask(int mask,int gen,int time)
{
   // cout<<mask<<"1 "<<gen<<" "<<time<<endl;
    if(time==target) return 1;
   //  cout<<mask<<"2 "<<gen<<" "<<time<<endl;
    if(time>target) return 0;
   //  cout<<mask<<"3"<<gen<<" "<<time<<endl;
    if(mask==((1<<n)-1)) return 0;
   //  cout<<mask<<"4 "<<gen<<" "<<time<<endl;
    if(dp[mask][gen]!=-1) return dp[mask][gen];
   //  cout<<mask<<"5 "<<gen<<" "<<time<<endl;
    int ret=0;
    for(int i=0;i<v.size();i++)
    {
       // cout<<i<<endl;
        if(!check(mask,i))
        {
           //  cout<<i<<endl;
            if(v[i].second!=gen)
            {
                ret+=bitmask(SET(mask,i),v[i].second,time+v[i].first);
            }
        }
    }
    return dp[mask][gen]=ret;
}
int32_t main()
{

    cin>>n>>target;
    memset(dp,-1,sizeof dp);
  //  cout<<dp[0][0]<<endl;
    for(int i=0; i<n; i++)
    {
       int a,b;
       cin>>a>>b;
       v.push_back({a,b});

    }
    cout<<bitmask(0,0,0)<<endl;

}

#include<bits/stdc++.h>
using namespace std;
long long int fact(int n)
{
	if(n<=1)
	  return 1;
	else
	 return n*fact(n-1);
}
long long int sum(long long int t[],long long int g[],long long int n,long long int t1)
{
	long long int results[(1<<n)+1];
	memset(results,0,sizeof(results));
	//bitset<64> bset1;
	long long int sum1 = 0;
   for(long long int i=0;i<(1<<n);i++)
   {
   	 for(long long int j=0;j<n;j++)
   	 {
   	 	if((i&(1<<j))!=0)
   	 	  results[i] = results[i]+t[j];
	  }
	  if(results[i]==t1)
	  {
	  	bitset<64> bset(i);
	    long long int n1 = bset.count();
	     sum1 = sum1+fact(n1);
	  long long int freq[4] = {0};
	  long long int factfreq[4] = {0};
	  for(long long int k=0;k<n;k++)
	  {

	  	if(bset.test(k)==1)
	  	{
	  		freq[g[n-1-k]]++ ;
		}
	  }
	  long long int count = 0;
	  for(long long int k=1;k<4;k++)
	  {
	  	 factfreq[k] = fact(freq[k]);
	  	 if(freq[k]>=1)
	  	   count++ ;
	  }
	  long long int w = 1;
	  for(long long int k=1;k<4;k++)
	  {
	  	  w = w*factfreq[k];
	  }

	  if(w!=1)
	  {
	      w = w*fact(count);
	      sum1 = sum1-w;
      }
     }
   }
   return sum1;
}
int main()
{
	long long int n,t1;
	cin>>n>>t1;
	long long int t[55],g[55];
	for(long long int i=0;i<n;i++)
	{
		cin>>t[i]>>g[i];
	}
	cout<<sum(t,g,n,t1);
}

#include <bits/stdc++.h>
using namespace std;

const int MAX_N = 15;
const int MAX_G = 3;
const int MAX_T = 255;
const int MOD = 1e9 + 7;
int n, m;
int memo[MAX_T + 1][(1<<15) + 1];
vector<int> gen, dur;

int f(int d = m, int lgen = 0, int mask = 0){
	if(d < 0) return 0;
	if(d == 0) return 1;
	if(__builtin_popcount(mask) == n) return 0;
	if(memo[d][mask] != -1) return memo[d][mask];
	int w = 0;
	for(int i = 0; i < n; i++){
		if(mask & 1<<i) continue;
		if(gen[i] == lgen) continue;
		mask = mask | 1<<i;
		w += f(d - dur[i], gen[i], mask);
		mask = mask ^ 1<<i;
		if(w >= MOD) w -= MOD;
	}
	memo[d][mask] = w;
	return memo[d][mask];
}
int main() {
//	cout << sizeof(memo) << '\n';
	memset(memo, -1, sizeof(memo));
	cin >> n >> m;
	gen = dur = vector<int> (n);
	for(int i = 0; i < n; i++){
		cin >> dur[i] >> gen[i];
	}
	cout << f() << "\n";
	return 0;
}

/*
 _____ _             _              _           _
|_   _| |__   ___   / \   _ __  ___| |__  _   _| |
  | | | '_ \ / _ \ / _ \ | '_ \/ __| '_ \| | | | |
  | | | | | |  __// ___ \| | | \__ \ | | | |_| | |
  |_| |_| |_|\___/_/   \_\_| |_|___/_| |_|\__,_|_|

*/
#include<bits/stdc++.h>
#define ll          long long
#define pb          push_back
#define ppb         pop_back
#define	endl		'\n'
#define mii         map<ll int,ll int>
#define msi         map<string,ll int>
#define mis         map<ll int, string>
#define rep(i,a,b)    for(ll int i=a;i<b;i++)
#define mpi         map<pair<ll int,ll int>,ll int>
#define pii         pair<ll int,ll int>
#define vi          vector<ll int>
#define vii         vector<pair<ll int, ll int>>
#define vs          vector<string>
#define all(a)      (a).begin(),(a).end()
#define F           first
#define S           second
#define sz(x)       (ll int)x.size()
#define hell        1000000007
#define lbnd        lower_bound
#define ubnd        upper_bound
#define bs          binary_search
#define mp          make_pair
#define what_is(x)  cerr << #x << " is " << x << endl;
#define time        cerr << "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";
using namespace std;
#define N  100005
bool vis[20],chk[20];
ll g[3];
vii v(20);
ll n,t;
ll check(ll vl,ll kg)
{
	ll ans=0;
	if(vl==0)
		return 1;
	rep(i,0,3)
	{
		if(g[i]>0 && i!=kg)
		{
			g[i]--;
			ans+=(g[i]+1)*check(vl-1,i);
			g[i]++;
		}
		// if(vis[i] && chk[i]==0 && v[i].S!=g)
		// {
		// 	chk[i]=1;
		// 	ans+=check(vl-1,v[i].S);
		// 	chk[i]=0;
		// }
	}
	return ans;
}
ll fun(ll pss,ll p)
{
	ll ans=0;
	if(p==0)
	{
		ll pst=0;
		rep(i,0,3)
		{
			g[i]=0;
		}
		rep(i,0,n)
		{
			if(vis[i])
			{
				pst++;
				g[v[i].S-1]++;
			}
			// chk[i]=0;
		}
		ans+=check(pst,-1);
		// cerr<<ans<<endl;
		return ans;
	}
	if(p<0 || pss>=n)
	{
		return 0;
	}
	ans+=fun(pss+1,p);
	vis[pss]=1;
	ans+=fun(pss+1,p-v[pss].F);
	vis[pss]=0;
	return ans;
}
void solve()
{
	cin>>n>>t;
	rep(i,0,n)
	cin>>v[i].F>>v[i].S;
	cout<<fun(0,t);
	return;
}
int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int TESTS=1;
//	cin>>TESTS;
	while(TESTS--)
	{
		solve();
	}
	time
	return 0;
}

//pranav.gayu
#include <bits/stdc++.h>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <climits>
#include <utility>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <iomanip>
//setbase - cout << setbase (16); cout << 100 << endl; Prints 64
//setfill -   cout << setfill ('x') << setw (5); cout << 77 << endl; prints xxx77
//setprecision - cout << setprecision (14) << f << endl; Prints x.xxxx
//cout.precision(x)  cout<<fixed<<val;  // prints x digits after decimal in val

using namespace std;
#define rz resize
#define f(i,a,b) for(long long i=a;i<b;i++)
#define rep(i,n) f(i,0,n)
#define fd(i,a,b) for(long long i=a;i>=b;i--)
#define pb push_back
#define pp pop_back
#define mp make_pair
#define vi vector< int >
#define vl vector< ll >
#define ss second
#define ff first
#define ll long long
#define pii pair< int,int >
#define pll pair< ll,ll >
#define sz(a) a.size()
#define inf (1000*1000*1000+5)
#define all(a) a.begin(),a.end()
#define tri pair<int,pii>
#define trl pair<ll,pll>
#define mse(a,b) memset(a,b,sizeof(a))
#define vii vector<pii>
#define vll vector<pll>
#define viii vector<tri>
#define mod (1000*1000*1000+7)
#define pqueue priority_queue< int >
#define mpi map < int ,int>
#define umpi unordered_map < int,int >
#define pdqueue priority_queue< int,vi ,greater< int > >
#define lb lower_bound
#define ub upper_bound
#define TRACE
#ifdef TRACE
	#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)

	template <typename Arg1>
	void __f(const char* name, Arg1&& arg1){
		cerr << name << ": " << arg1 << std::endl;
	}

	template <typename Arg1, typename... Args>
	void __f(const char* names, Arg1&& arg1, Args&&... args){
		const char* comma = strchr(names + 1, ',');
		cerr.write(names, comma - names) << ": " << arg1<<" |";
		__f(comma+1, args...);
	}
#else
	#define trace(...) ;
#endif

#define fastio ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);

int main()
{
	fastio;
    int n,t;cin>>n>>t;
    int a[n],g[n],c[(1<<n)];
    f(i,0,n) cin>>a[i]>>g[i];
    mse(c,0);int te=0;
    f(i,0,(1<<n))
    {
        te=0;
        f(j,0,n)
        {
            if((1<<j)&i)
            {
                te+=a[j];
            }
        }
        c[i]=te;
    }
    int d[(1<<n)][3];
    mse(d,0);
    d[0][1]=1;d[0][0]=1;d[0][2]=1;
    f(i,0,(1<<n))
    {
        f(j,0,n)
        {
            if((1<<j)&i)
            {
                d[i][g[j]%3]+=d[i^(1<<j)][(g[j]+1)%3];
                d[i][g[j]%3]+=d[i^(1<<j)][(g[j]+2)%3];
            }
        }
    }
    ll an=0;
    f(i,0,(1<<n))
    {
        f(j,0,3)
        {
            if(c[i] == t)
            {
                an+=d[i][j];
                an%=mod;
            }
        }
    }
    an*=500000004;an%=mod;
    cout<<an<<"\n";
    return 0;
}

#include <bits/stdc++.h>
#define LL long long
#define db double
#define INF 0x3f3f3f3f
#define pii pair<int, int>
using namespace std;
const int maxn = 17;
const LL mod = 1000000007;
LL dp[1 << maxn][maxn], sum[1 << maxn];
pii a[maxn];
int main() {
	int n, m;
	LL ans = 0;
	scanf("%d%d", &n, &m);
	for (int i = 0; i < n; i++) {
		scanf("%d%d", &a[i].first, &a[i].second);
	}
	for (int i = 0; i < n; i++) {
		dp[1 << i][i] = 1;
		sum[1 << i] = a[i].first;
	}
	for (int i = 1; i < (1 << n); i++)
		for (int j = 0; j < n; j++) {
			if((i >> j) & 1) {
				sum[i] += a[j].first;
				for (int k = 0; k < n; k++) {
					if((i >> k) & 1) continue;
					if(a[j].second == a[k].second) continue;
					dp[i | (1 << k)][k] = (dp[i | (1 << k)][k] + dp[i][j]) % mod;
				}
			}
		}
	for (int i = 1; i < (1 << n); i++) {
		if(sum[i] == m) {
			for (int j = 0; j < n; j++)
				ans = (ans + dp[i][j]) % mod;
		}
	}
	printf("%lld\n", ans);
}

#pragma region template
#define _CRT_SECURE_NO_WARNINGS
#pragma comment(linker, "/STACK:65536000")
#include <iostream>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <string>
#include <algorithm>
#include <map>
#include <set>
#include <queue>
using namespace std;

typedef long long ll;
typedef pair<ll, ll> pll;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
typedef pair<string, string> pss;

#define all(x) x.begin(), x.end()
#define pb push_back
#define mp make_pair
#define ff first
#define ss second
#define debug(x) 5 == 5

const ll mod = (int)1e9 + 7;
#pragma endregion

void stress()
{

}

void solve()
{
	int n, T;
	cin >> n >> T;
	vector<int> t(n), g(n);
	for (int i = 0; i < n; ++i)
	{
		cin >> t[i] >> g[i];
		g[i]--;
	}
	vector<vector<vector<ll>>> dp(T + 1, vector<vector<ll>>(1 << n, vector<ll>(3)));
	for (int i = 0; i < 2; ++i)
		dp[0][0][i] = 1;
	for (int i = 0; i < T; ++i)
		for (int mask = 0; mask < (1 << n); ++mask)
			for (int last = 0; last < 3; ++last)
			{
				if (dp[i][mask][last] == 0)
					continue;
				for (int bit = 0; bit < n; ++bit)
					if (((mask & (1 << bit)) == 0) && g[bit] != last && (i + t[bit] <= T))
					{
						dp[i + t[bit]][mask | (1 << bit)][g[bit]] += dp[i][mask][last];
						dp[i + t[bit]][mask | (1 << bit)][g[bit]] %= mod;
					}
			}
	ll ans = 0;
	for (int mask = 0; mask < (1 << n); ++mask)
		for (int i = 0; i < 2; ++i)
			ans += dp[T][mask][i], ans %= mod;
	cout << ans % mod;

}

int main()
{
	cin.sync_with_stdio(0);
	cin.tie(0);
	/*freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);*/
	cout.precision(20);
	solve();
	return 0;
}
/*
6 5
1 1
2 2
3 3
4 2
5 1
6 1

*/