#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const long long LINF = 0x3f3f3f3f3f3f3f3f;
const long double pi = acos(-1);
const int MOD = 1e9 + 7;
const int MAXN = 1000005;
vector<int> g[MAXN];
int qtosgruposta[MAXN];
vector<pair<int, int> > info[MAXN];
int n, m;
long long int fat[MAXN];
int main() {
  scanf("%d%d", &n, &m);
  fat[0] = 1;
  for (long long int i = 1; i < MAXN; i++) {
    fat[i] = (fat[i - 1] * i) % MOD;
  }
  for (int i = 0; i < n; i++) {
    int a;
    map<int, int> tmp;
    scanf("%d", &a);
    for (int i = 0; i < a; i++) {
      int b;
      scanf("%d", &b);
      if (!tmp.count(b)) {
        qtosgruposta[b]++;
      }
      tmp[b]++;
      g[i].push_back(b);
    }
    for (auto p : tmp) {
      info[p.first].push_back(make_pair(i, p.second));
    }
  }
  long long int resp = 1;
  sort(info + 1, info + m + 1);
  for (int i = 1; i <= m; i++) {
    vector<pair<int, int> > tmp = info[i];
    bool acabou = false;
    for (int j = i; j <= m; j++) {
      if (info[j] != tmp) {
        acabou = true;
        resp = (resp * fat[j - i]) % MOD;
        i = j - 1;
        break;
      }
    }
    if (!acabou) {
      resp = (resp * (fat[m + 1 - i])) % MOD;
      break;
    }
  }
  cout << resp << "\n";
  return 0;
}
