The only difference between easy and hard versions is constraints.Polycarp loves to listen to music, so he never leaves the player, even on the way home from the university. Polycarp overcomes the distance from the university to the house in exactly $$$T$$$ minutes.In the player, Polycarp stores $$$n$$$ songs, each of which is characterized by two parameters: $$$t_i$$$ and $$$g_i$$$, where $$$t_i$$$ is the length of the song in minutes ($$$1 \le t_i \le 15$$$), $$$g_i$$$ is its genre ($$$1 \le g_i \le 3$$$).Polycarp wants to create such a playlist so that he can listen to music all the time on the way from the university to his home, and at the time of his arrival home, the playlist is over. Polycarp never interrupts songs and always listens to them from beginning to end. Thus, if he started listening to the $$$i$$$-th song, he would spend exactly $$$t_i$$$ minutes on its listening. Polycarp also does not like when two songs of the same genre play in a row (i.e. successively/adjacently) or when the songs in his playlist are repeated.Help Polycarpus count the number of different sequences of songs (their order matters), the total duration is exactly $$$T$$$, such that there are no two consecutive songs of the same genre in them and all the songs in the playlist are different.

The first line of the input contains two integers $$$n$$$ and $$$T$$$ ($$$1 \le n \le 15, 1 \le T \le 225$$$) — the number of songs in the player and the required total duration, respectively. Next, the $$$n$$$ lines contain descriptions of songs: the $$$i$$$-th line contains two integers $$$t_i$$$ and $$$g_i$$$ ($$$1 \le t_i \le 15, 1 \le g_i \le 3$$$) — the duration of the $$$i$$$-th song and its genre, respectively.

Output one integer — the number of different sequences of songs, the total length of exactly $$$T$$$, such that there are no two consecutive songs of the same genre in them and all the songs in the playlist are different. Since the answer may be huge, output it modulo $$$10^9 + 7$$$ (that is, the remainder when dividing the quantity by $$$10^9 + 7$$$).

NoteIn the first example, Polycarp can make any of the $$$6$$$ possible playlist by rearranging the available songs: $$$[1, 2, 3]$$$, $$$[1, 3, 2]$$$, $$$[2, 1, 3]$$$, $$$[2, 3, 1]$$$, $$$[3, 1, 2]$$$ and $$$[3, 2, 1]$$$ (indices of the songs are given).In the second example, the first and second songs cannot go in succession (since they have the same genre). Thus, Polycarp can create a playlist in one of $$$2$$$ possible ways: $$$[1, 3, 2]$$$ and $$$[2, 3, 1]$$$ (indices of the songs are given).In the third example, Polycarp can make the following playlists: $$$[1, 2, 3]$$$, $$$[1, 3, 2]$$$, $$$[2, 1, 3]$$$, $$$[2, 3, 1]$$$, $$$[3, 1, 2]$$$, $$$[3, 2, 1]$$$, $$$[1, 4]$$$, $$$[4, 1]$$$, $$$[2, 3, 4]$$$ and $$$[4, 3, 2]$$$ (indices of the songs are given).

#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 <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;
}

/* ****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;
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<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>
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 <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
}

#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';
}

#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 <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;

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<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 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;
}

#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;
}

#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<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";
}

#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;
}

#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;
}

/*

*/

#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;
}

///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;

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 <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<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;

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;
}

#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>
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;
}

/*
    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>
#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;
}

/*
	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>
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 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>
#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;
}

#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;
}

/* ---------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;
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;
}

#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>
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<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 <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>
#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;
#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;
}

/*
🧡 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>
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 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>

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;
}

#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>
#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';

}

#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;

#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>
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 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 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;

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;
#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>
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>
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 <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>

#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;
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>
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<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;
}

#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<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<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 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;
#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 <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;
}

// 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;
#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<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<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 <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;
}

#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>

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<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;

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>

#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>

#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

*/