#include <bits/stdc++.h>
#pragma GCC optimize("O2")
using namespace std;
const int N = 52;
const long long mod = 1e9 + 7;
const long long mod2 = 998244353;
const long long inf = 8e18;
const int LOG = 22;
long long pw(long long a, long long b, long long M) {
  return (!b ? 1
             : (b & 1 ? (a * pw(a * a % M, b / 2, M)) % M
                      : pw(a * a % M, b / 2, M)));
}
int dp[3][N][N][N * N], f[3][N][N * N];
int w[N][N][N * N], Dp[N][N][N][2], ways[N][N][N * N];
long long first[N], I[N];
vector<int> vec[3];
long long E(long long r, long long n) {
  if (r > n || r < 0) return 0;
  return first[n] * I[r] % mod * I[n - r] % mod;
}
bool cmp(int i, int j) { return (int)vec[i].size() < (int)vec[j].size(); }
int main() {
  int n, Ti;
  I[0] = first[0] = 1;
  for (int i = 1; i < N; i++)
    first[i] = first[i - 1] * i % mod, I[i] = pw(first[i], mod - 2, mod);
  scanf("%d%d", &n, &Ti);
  for (int i = 1; i <= n; i++) {
    int t, g;
    scanf("%d%d", &t, &g);
    g--;
    vec[g].push_back(t);
  }
  vector<int> C = {0, 1, 2};
  sort((C).begin(), (C).end(), cmp);
  for (int typ = 0; typ < 3; typ++) {
    dp[typ][0][0][0] = 1;
    if ((int)vec[typ].size() == 0) {
      f[typ][0][0] = 1;
      continue;
    }
    for (int i = 1; i <= (int)vec[typ].size(); i++) {
      for (int j = 0; j <= i; j++) {
        for (int T = 0; T < N * N; T++) {
          dp[typ][i][j][T] = dp[typ][i - 1][j][T];
          if (j && T >= vec[typ][i - 1])
            dp[typ][i][j][T] = (dp[typ][i][j][T] +
                                dp[typ][i - 1][j - 1][T - vec[typ][i - 1]]) %
                               mod;
          if (i == (int)vec[typ].size()) {
            f[typ][j][T] = dp[typ][i][j][T];
          }
        }
      }
    }
  }
  for (int i = 0; i <= (int)vec[C[0]].size(); i++) {
    for (int j = 0; j <= (int)vec[C[1]].size(); j++) {
      for (int T1 = 0; T1 <= 50 * i; T1++) {
        for (int T2 = 0; T2 <= 50 * j; T2++) {
          w[i][j][T1 + T2] =
              (w[i][j][T1 + T2] + (1ll * f[C[0]][i][T1] * first[i] % mod) *
                                      (1ll * f[C[1]][j][T2] * first[j] % mod) %
                                      mod) %
              mod;
        }
      }
    }
  }
  for (int i = 0; i <= n; i++) {
    for (int j = 0; j <= n; j++) {
      if (i == 0) {
        if (j) Dp[i][j][j - 1][1] = 1;
      } else if (j == 0) {
        Dp[i][j][i - 1][0] = 1;
      }
      for (int x = 0; x <= n; x++) {
        Dp[i + 1][j][x][0] = (Dp[i + 1][j][x][0] + Dp[i][j][x][1]) % mod;
        Dp[i][j + 1][x][1] = (Dp[i][j + 1][x][1] + Dp[i][j][x][0]) % mod;
        Dp[i + 1][j][x + 1][0] =
            (Dp[i + 1][j][x + 1][0] + Dp[i][j][x][0]) % mod;
        Dp[i][j + 1][x + 1][1] =
            (Dp[i][j + 1][x + 1][1] + Dp[i][j][x][1]) % mod;
      }
    }
  }
  Dp[0][0][0][0] = 1;
  for (int i = 0; i <= (int)vec[C[0]].size(); i++) {
    for (int j = 0; j <= (int)vec[C[1]].size(); j++) {
      for (int T = 0; T < N * N; T++) {
        for (int x = 0; x <= n; x++) {
          ways[i + j][x][T] =
              (ways[i + j][x][T] +
               (1ll * w[i][j][T] *
                ((1ll * Dp[i][j][x][0] + Dp[i][j][x][1]) % mod))) %
              mod;
        }
      }
    }
  }
  long long tot = 0;
  for (int i = 0; i <= n - (int)vec[C[2]].size(); i++) {
    for (int x = 0; x <= i; x++) {
      for (int T2 = 0; T2 < N * N; T2++) {
        for (int j = 0; j <= (int)vec[C[2]].size(); j++) {
          tot = (tot + 1ll * ways[i][x][T2] * E(j - x, i + 1 - x) % mod *
                           first[j] % mod * 1ll * f[C[2]][j][Ti - T2]) %
                mod;
        }
      }
    }
  }
  printf("%lld\n", tot);
  return 0;
}
