#include <bits/stdc++.h>
using namespace std;
const int MAX = 100 + 10;
const int Mod = (int)1e9 + 7;
int n, m;
int g[MAX][MAX], can[MAX][MAX];
vector<int> p[MAX][MAX];
int get(vector<int> &before, int kind, int have) {
  int j;
  int now = 0, cc = have;
  for (; now < (int)before.size(); now++) {
    if (now + 1 == (int)before.size()) break;
    int a = before[now];
    int b = before[now + 1];
    if (g[a][b] != kind || (kind == 2 && can[b][a])) return 0;
    vector<int> &nL = p[a][b];
    for ((j) = (0); (j) != ((int)nL.size()); ++(j)) {
      if (cc < (int)before.size()) {
        if (nL[j] == before[cc])
          cc++;
        else
          return 0;
      } else {
        while (j < (int)nL.size()) {
          before.push_back(nL[j++]);
          if ((int)before.size() > 2 * n + 1) return 0;
        }
        cc = before.size();
        break;
      }
    }
  }
  return 1;
}
int isCan(int a, int b) {
  int i;
  vector<int> &L = p[a][b];
  int len = L.size();
  for ((i) = (0); (i) <= (len - 2); ++(i))
    if (L[i] == a && L[i + 1] == b) return 1;
  return 0;
}
int go_Before[MAX][MAX], go_After[MAX][MAX];
int f_Before[MAX][MAX], f_After[MAX][MAX];
int ans[MAX];
void work(int u, int kind, int go[MAX][MAX]) {
  int v;
  for ((v) = (1); (v) <= (n); ++(v)) go[u][v] = -1;
  for ((v) = (1); (v) <= (n); ++(v))
    if (g[u][v] == kind && (kind != 2 || g[u][v] == 2)) {
      vector<int> after;
      after.push_back(u);
      after.push_back(v);
      if (!get(after, kind, 1)) continue;
      int Len = after.size();
      go[u][after[Len - 1]] = Len - 1;
    }
}
void add(int &a, int b) {
  a += b;
  if (a >= Mod) a -= Mod;
}
void Dp(int go[MAX][MAX], int f[MAX][MAX]) {
  int i, j, k;
  for ((j) = (1); (j) <= (n); ++(j)) f[j][0] = 1;
  for ((i) = (0); (i) <= (2 * n); ++(i))
    for ((j) = (1); (j) <= (n); ++(j))
      for ((k) = (1); (k) <= (n); ++(k))
        if (go[k][j] != -1 && i + go[k][j] <= 2 * n)
          add(f[k][i + go[k][j]], f[j][i]);
}
void check(int a, int b) {
  int i, j;
  vector<int> &L = p[a][b];
  int len = L.size();
  for ((i) = (0); (i) <= (len - 2); ++(i))
    if (L[i] == a && L[i + 1] == b) {
      vector<int> before, after;
      for (j = i; j >= 0; --j) before.push_back(L[j]);
      for (j = i + 1; j < len; ++j) after.push_back(L[j]);
      if (get(before, 2, before.size()) && get(after, 1, after.size())) {
        reverse(before.begin(), before.end());
        int A = before[0];
        int B = after[after.size() - 1];
        int Len = before.size() + after.size() - 1;
        int l1, l2;
        for ((l1) = (0); (l1) <= (2 * n); ++(l1))
          for ((l2) = (0); (l2) <= (2 * n); ++(l2))
            if (l1 + l2 + Len <= 2 * n)
              add(ans[l1 + l2 + Len],
                  (long long)f_Before[A][l1] * f_After[B][l2] % Mod);
      } else
        return;
    }
  return;
}
int main() {
  int i, j;
  scanf("%d%d", &n, &m);
  for ((i) = (1); (i) <= (m); ++(i)) {
    int a, b;
    scanf("%d%d", &a, &b);
    g[a][b] = 1;
    g[b][a] = 2;
    int k, first;
    scanf("%d", &k);
    while (k--) {
      scanf("%d", &first);
      p[a][b].push_back(first);
    }
    p[b][a] = p[a][b];
    reverse(p[b][a].begin(), p[b][a].end());
  }
  for ((i) = (1); (i) <= (n); ++(i))
    for ((j) = (1); (j) <= (n); ++(j))
      if (g[i][j] == 1 && isCan(i, j)) can[i][j] = 1;
  for ((i) = (1); (i) <= (n); ++(i)) work(i, 1, go_After);
  for ((i) = (1); (i) <= (n); ++(i)) work(i, 2, go_Before);
  work(1, 2, go_Before);
  Dp(go_After, f_After);
  Dp(go_Before, f_Before);
  for ((i) = (1); (i) <= (n); ++(i))
    for ((j) = (1); (j) <= (n); ++(j))
      if (can[i][j] == 1) check(i, j);
  for ((i) = (1); (i) <= (2 * n); ++(i)) cout << ans[i] << endl;
  return 0;
}
