#include <bits/stdc++.h>
using namespace std;
struct FastReader {
  FastReader &operator,(int &x) {
    scanf("%d", &x);
    return *this;
  }
  FastReader &operator,(signed long long &x) {
    scanf(
        "%"
        "ll"
        "d",
        &x);
    return *this;
  }
  FastReader &operator,(double &x) {
    scanf("%lf", &x);
    return *this;
  }
  FastReader &operator,(long double &x) {
    scanf("%Lf", &x);
    return *this;
  }
  FastReader &operator,(char &x) {
    do x = getchar();
    while (x == ' ' || x == '\n');
    return *this;
  }
  FastReader &operator,(char *x) {
    scanf("%s", x);
    return *this;
  }
  FastReader &operator,(string &x) {
    cin >> x;
    return *this;
  }
} in;
struct FastWriter {
  FastWriter &operator,(const int x) {
    printf("%d", x);
    return *this;
  }
  FastWriter &operator,(const signed long long x) {
    printf(
        "%"
        "ll"
        "d",
        x);
    return *this;
  }
  FastWriter &operator,(const double x) {
    printf(
        "%."
        "8"
        "lf",
        x);
    return *this;
  }
  FastWriter &operator,(const long double x) {
    printf(
        "%."
        "12"
        "Lf",
        x);
    return *this;
  }
  FastWriter &operator,(const char x) {
    putchar(x);
    return *this;
  }
  FastWriter &operator,(const char *x) {
    printf("%s", x);
    return *this;
  }
  FastWriter &operator,(const string &x) { return operator,(x.c_str()); }
  FastWriter &operator-() {
    fflush(stdout);
    return *this;
  }
} out;
inline void quit() { exit(EXIT_SUCCESS); }
template <class T>
inline T sqr(T x) {
  return x * x;
}
template <class T>
inline T gcd(T a, T b) {
  T c;
  while (a) c = a, a = b % a, b = c;
  return b;
}
template <class T>
inline T lcm(T a, T b) {
  return (a / gcd(a, b)) * b;
}
template <class T>
inline T mod_pow(T a, T n, T m) {
  T b = 1;
  while (n) {
    if (n & 1) b = (b * a) % m;
    a = (a * a) % m, n >>= 1;
  }
  return b;
}
static const int N = 1e6 + 1;
static const signed long long M = (signed long long)1e9 + 7;
int n, m;
vector<int> a[N];
int main() {
  in, n, m;
  for (int i = 0; i < n; i++) {
    int k;
    in, k;
    for (int j = 0; j < k; j++) {
      int g;
      in, g;
      g--;
      a[g].push_back(i);
    }
  }
  sort(a, a + m);
  signed long long ans = 1, t = 1;
  for (int i = 1; i < m; i++) {
    if (a[i] == a[i - 1])
      ans = ans * ++t % M;
    else
      t = 1;
  }
  out, ans;
  quit();
}
