#include <bits/stdc++.h>
using namespace std;
inline bool setmin(int &x, int y) { return (y < x) ? x = y, 1 : 0; }
inline bool setmax(int &x, int y) { return (y > x) ? x = y, 1 : 0; }
inline bool setmin(long long &x, long long y) { return (y < x) ? x = y, 1 : 0; }
inline bool setmax(long long &x, long long y) { return (y > x) ? x = y, 1 : 0; }
const int N = 50;
const int inf = (int)1e9 + 1;
const long long big = (long long)1e18 + 1;
const int P = 239;
const int P1 = 31;
const int P2 = 57;
const int MOD = (int)1e9 + 7;
const int MOD1 = (int)1e9 + 9;
const int MOD2 = 998244353;
const double eps = 1e-9;
const double pi = atan2(0, -1);
const int ABC = 26;
namespace FFT {
const int MaxN = 8192;
const int MaxTN = 16384;
const int M = 1000000007;
const long double PI = acos(-1.0);
inline int modpow(int a, const int &n) {
  int res = 1;
  for (int i = n; i; i >>= 1) {
    if (i & 1) res = (long long)res * a % M;
    a = (long long)a * a % M;
  }
  return res;
}
struct complex {
  long double r, i;
  complex() {}
  complex(const long double &_r, const long double &_i) : r(_r), i(_i) {}
  inline complex conj() const { return complex(r, -i); }
  friend inline complex operator+(const complex &lhs, const complex &rhs) {
    return complex(lhs.r + rhs.r, lhs.i + rhs.i);
  }
  friend inline complex operator-(const complex &lhs, const complex &rhs) {
    return complex(lhs.r - rhs.r, lhs.i - rhs.i);
  }
  friend inline complex operator*(const complex &lhs, const complex &rhs) {
    complex res;
    res.r = lhs.r * rhs.r - lhs.i * rhs.i;
    res.i = lhs.r * rhs.i + lhs.i * rhs.r;
    return res;
  }
};
int tn, tl;
int bitRev[MaxTN];
complex root[MaxTN];
inline void fft_init(int n) {
  tn = 1, tl = 0;
  while (tn < n) tn <<= 1, ++tl;
  for (int i = 1; i < tn; ++i) {
    int l = bitRev[i >> 1] >> 1;
    int r = (i & 1) << tl - 1;
    bitRev[i] = l | r;
  }
  int bn = tn >> 1;
  for (int i = 0; i < bn; ++i)
    root[bn + i] = complex(cos(2 * PI / tn * i), sin(2 * PI / tn * i));
  for (int i = bn - 1; i > 0; --i) root[i] = root[i << 1];
}
inline void fft(complex *a, int type) {
  if (type == 1) reverse(a + 1, a + tn);
  for (int i = 0; i < tn; ++i) {
    int r = bitRev[i];
    if (i < r) swap(a[i], a[r]);
  }
  for (int k = 1; k < tn; k <<= 1) {
    complex *g = root + k;
    for (int s = 0; s < tn; s += k << 1) {
      complex *w = g;
      for (int i = s; i < s + k; ++i, ++w) {
        complex o = a[i], e = *w * a[i + k];
        a[i] = o + e;
        a[i + k] = o - e;
      }
    }
  }
}
inline void polycopy(complex *da, int *a, int n) {
  for (int i = 0; i <= n; ++i) da[i] = complex(a[i] & 32767, a[i] >> 15);
  for (int i = n + 1; i < tn; ++i) da[i] = complex(0, 0);
}
inline void polymul(int *a, int *b, int *c, int n) {
  static complex da[MaxTN];
  static complex db[MaxTN];
  polycopy(da, a, n);
  polycopy(db, b, n);
  fft(da, 0);
  fft(db, 0);
  static complex dc[MaxTN];
  static complex dd[MaxTN];
  for (int i = 0; i < tn; ++i) {
    int j = (tn - i) & (tn - 1);
    complex ta = (da[i] + da[j].conj()) * complex(0.5, 0);
    complex tb = (da[i] - da[j].conj()) * complex(0, -0.5);
    complex tc = (db[i] + db[j].conj()) * complex(0.5, 0);
    complex td = (db[i] - db[j].conj()) * complex(0, -0.5);
    dc[i] = ta * tc + ta * td * complex(0, 1);
    dd[i] = tb * tc + tb * td * complex(0, 1);
  }
  fft(dc, 1);
  fft(dd, 1);
  for (int i = 0; i <= n; ++i) {
    int ta = (long long)(dc[i].r / tn + 0.5) % M;
    int tb = (long long)(dc[i].i / tn + 0.5) % M;
    int tc = (long long)(dd[i].r / tn + 0.5) % M;
    int td = (long long)(dd[i].i / tn + 0.5) % M;
    c[i] = (ta + ((long long)(tb + tc) << 15) + ((long long)td << 30)) % M;
    c[i] = (c[i] + M) % M;
  }
}
}  // namespace FFT
inline void add(int &x, int y) {
  x += y;
  if (x >= MOD) {
    x -= MOD;
  }
}
int dp[2][N + 1][2500 + 1];
vector<vector<int> > calcDP(vector<int> a, int T) {
  int n = (int)a.size(), p = 0;
  for (int j = 0; j < n + 1; j++) {
    fill(dp[p][j], dp[p][j] + T + 1, 0);
  }
  dp[p][0][0] = 1;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n + 1; j++) {
      fill(dp[p ^ 1][j], dp[p ^ 1][j] + T + 1, 0);
    }
    for (int j = 0; j < n + 1; j++) {
      for (int k = 0; k < T + 1; k++) {
        if (dp[p][j][k] == 0) {
          continue;
        }
        add(dp[p ^ 1][j][k], dp[p][j][k]);
        if (k + a[i] <= T) {
          add(dp[p ^ 1][j + 1][k + a[i]], dp[p][j][k]);
        }
      }
    }
    p ^= 1;
  }
  vector<vector<int> > res(n + 1, vector<int>(T + 1));
  for (int j = 0; j < n + 1; j++) {
    for (int k = 0; k < T + 1; k++) {
      res[j][k] = dp[p][j][k];
    }
  }
  return res;
}
int dp1[N + 1][N + 1][N + 1][3];
void calc() {
  dp1[1][0][0][0] = 1;
  dp1[0][1][0][1] = 1;
  dp1[0][0][1][2] = 1;
  for (int i = 0; i < N + 1; i++) {
    for (int j = 0; j < N + 1; j++) {
      for (int k = 0; k < N + 1; k++) {
        for (int l = 0; l < 3; l++) {
          if (dp1[i][j][k][l] == 0) {
            continue;
          }
          if (i + 1 <= N && l != 0) {
            add(dp1[i + 1][j][k][0], dp1[i][j][k][l]);
          }
          if (j + 1 <= N && l != 1) {
            add(dp1[i][j + 1][k][1], dp1[i][j][k][l]);
          }
          if (k + 1 <= N && l != 2) {
            add(dp1[i][j][k + 1][2], dp1[i][j][k][l]);
          }
        }
      }
    }
  }
}
int fact[N + 1];
void init_fact() {
  fact[0] = 1;
  for (int i = 1; i < N + 1; i++) {
    fact[i] = 1LL * fact[i - 1] * i % MOD;
  }
}
int cnt23[N + 1][N + 1][8192 + 12];
int tmpA[8192 + 12], tmpB[8192 + 12];
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.precision(20);
  cout << fixed;
  init_fact();
  int n, T;
  cin >> n >> T;
  vector<int> t[3];
  for (int i = 0; i < n; i++) {
    int a, b;
    cin >> a >> b;
    t[b - 1].push_back(a);
  }
  vector<vector<vector<int> > > vals;
  for (int i = 0; i < 3; i++) {
    vals.push_back(calcDP(t[i], T));
  }
  FFT::fft_init(8192);
  for (int i = 0; i < (int)t[1].size() + 1; i++) {
    for (int j = 0; j < (int)t[2].size() + 1; j++) {
      for (int k = 0; k < T + 1; k++) {
        tmpA[k] = vals[1][i][k];
        tmpB[k] = vals[2][j][k];
      }
      FFT::polymul(tmpA, tmpB, cnt23[i][j], 8192);
    }
  }
  calc();
  int ans = 0;
  for (int c1 = 0; c1 < (int)t[0].size() + 1; c1++) {
    for (int c2 = 0; c2 < (int)t[1].size() + 1; c2++) {
      for (int c3 = 0; c3 < (int)t[2].size() + 1; c3++) {
        for (int sum1 = 0; sum1 < T + 1; sum1++) {
          int sum23 = T - sum1;
          long long val1 = 1LL * vals[0][c1][sum1] * cnt23[c2][c3][sum23] %
                           MOD * fact[c1] % MOD * fact[c2] % MOD * fact[c3] %
                           MOD;
          int val2 = 0;
          for (int l = 0; l < 3; l++) {
            add(val2, dp1[c1][c2][c3][l]);
          }
          add(ans, val1 * val2 % MOD);
        }
      }
    }
  }
  cout << ans << "\n";
  return 0;
}
