#include <iostream>
#include <cstring>
using namespace std;
const int MAXN = 1000;
long long C[MAXN][MAXN]; //组合数
long long s[MAXN][MAXN]; //各字母可以出现的种数和个数
long long dp[MAXN]; //各长度的字符串满足要求的数量
//组合数打表
void init()
{
C[1][0] = C[1][1] = 1;
for (int i = 2; i < MAXN; i++)
{
C[i][0] = 1;
for (int j = 1; j <= i; j++)
C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
}
}
int main()
{
init();
int N, M;
while (cin >> N >> M)
{
for (int i = 1; i <= N; i++)
{
cin >> s[i][0]; //s[i][0]表示该字母可以出现的种数
for (int j = 1; j <= s[i][0]; j++)
cin >> s[i][j];
}
memset(dp, 0, sizeof(dp));
for (int i = 1; i <= s[1][0]; i++) //第1个字符
{
if (s[1][i] <= M)
dp[s[1][i]] = C[M][s[1][i]];
}
for (int i = 2; i <= N; i++) //第2~N个字符
{
if (s[i][0])
for (int j = M; j >= 0; j--)
if (dp[j])
for (int k = 1; k <= s[i][0] && j + s[i][k] <= M; k++)
if (s[i][k])
dp[j + s[i][k]] += dp[j] * C[M - j][s[i][k]];
}
cout << dp[M] << endl;
}
return 0;
}