#include <bits/stdc++.h>
using namespace std;
long long MOD = 1000000007;
long long fact[1000005];
int blobId[1000005], lastFreeBlobId = 1;
set<int> blob[1000005];
queue<int> freeBlob;
void calculateFacts() {
  fact[0] = 1;
  for (__typeof(1) i = 1; i < 1000005; i += 1)
    fact[i] = (fact[i - 1] * i) % MOD;
}
int getFreeBlobId() {
  if (freeBlob.empty()) return lastFreeBlobId++;
  int k = freeBlob.front();
  freeBlob.pop();
  return k;
}
void eraseBlob(int id) {
  if (!blob[id].empty()) cerr << "Error! blob is not empty." << endl;
  freeBlob.push(id);
}
void createBlobFromBlobSet(int id, set<int>& miniBlob) {
  if (miniBlob.empty()) return;
  for (__typeof(miniBlob.begin()) it = miniBlob.begin(); it != miniBlob.end();
       ++it) {
    blob[id].erase(*it);
  }
  if (blob[id].empty()) eraseBlob(id);
  id = getFreeBlobId();
  for (__typeof(miniBlob.begin()) it = miniBlob.begin(); it != miniBlob.end();
       ++it) {
    blob[id].insert(*it);
    blobId[*it] = id;
  }
  miniBlob.clear();
}
int main() {
  calculateFacts();
  int n, m, g, t;
  cin >> n >> m;
  map<int, int> rep;
  map<int, set<int> > repBlob, repMiniBlob;
  for (__typeof(1) i = 1; i <= m; i += 1) blob[0].insert(i);
  for (__typeof(0) i = 0; i < n; i += 1) {
    cin >> g;
    for (__typeof(0) j = 0; j < g; j += 1) {
      cin >> t;
      rep[t]++;
    }
    for (__typeof(rep.begin()) it = rep.begin(); it != rep.end(); ++it)
      repBlob[it->second].insert(it->first);
    rep.clear();
    for (__typeof(repBlob.begin()) it = repBlob.begin(); it != repBlob.end();
         ++it) {
      for (__typeof(it->second.begin()) j = it->second.begin();
           j != it->second.end(); ++j) {
        repMiniBlob[blobId[*j]].insert(*j);
      }
      for (__typeof(repMiniBlob.begin()) j = repMiniBlob.begin();
           j != repMiniBlob.end(); ++j)
        createBlobFromBlobSet(j->first, j->second);
      repMiniBlob.clear();
    }
    repBlob.clear();
  }
  long long ans = 1;
  for (__typeof(0) i = 0; i < lastFreeBlobId; i += 1)
    ans = (ans * fact[blob[i].size()]) % MOD;
  cout << ans << endl;
}
