Problem: Everybody knows that we have been living in the Matrix for a long time. And in the new seventh Matrix the world is ruled by beavers.

So let's take beaver Neo. Neo has so-called "deja vu" outbursts when he gets visions of events in some places he's been at or is going to be at. Let's examine the phenomenon in more detail.

We can say that Neo's city is represented by a directed graph, consisting of n shops and m streets that connect the shops. No two streets connect the same pair of shops (besides, there can't be one street from A to B and one street from B to A). No street connects a shop with itself. As Neo passes some streets, he gets visions. No matter how many times he passes street k, every time he will get the same visions in the same order. A vision is a sequence of shops.

We know that Neo is going to get really shocked if he passes the way from some shop a to some shop b, possible coinciding with a, such that the list of visited shops in the real life and in the visions coincide.

Suggest beaver Neo such path of non-zero length. Or maybe you can even count the number of such paths modulo 1000000007 (109 + 7)?..

Input

The first line contains integers n and m — the number of shops and the number of streets, correspondingly, 1 ≤ n ≤ 50, <image>. Next m lines contain the descriptions of the streets in the following format: xi yi ki v1 v2 ... vk, where xi and yi (1 ≤ xi, yi ≤ n, xi ≠ yi) are indices of shops connected by a street, ki (0 ≤ ki ≤ n) is the number of visions on the way from xi to yi; v1, v2, ..., vk (1 ≤ vi ≤ n) describe the visions: the numbers of the shops Neo saw. Note that the order of the visions matters.

It is guaranteed that the total number of visions on all streets doesn't exceed 105.

  * to get 50 points, you need to find any (not necessarily simple) path of length at most 2·n, that meets the attributes described above (subproblem E1); 
  * to get 50 more points, you need to count for each length from 1 to 2·n the number of paths that have the attribute described above (subproblem E2). 

Output

Subproblem E1. In the first line print an integer k (1 ≤ k ≤ 2·n) — the numbers of shops on Neo's path. In the next line print k integers — the number of shops in the order Neo passes them. If the graph doesn't have such paths or the length of the shortest path includes more than 2·n shops, print on a single line 0.

Subproblem E2. Print 2·n lines. The i-th line must contain a single integer — the number of required paths of length i modulo 1000000007 (109 + 7).

Examples

Input

6 6
1 2 2 1 2
2 3 1 3
3 4 2 4 5
4 5 0
5 3 1 3
6 1 1 6


Output

4
6 1 2 3


Input

6 6
1 2 2 1 2
2 3 1 3
3 4 2 4 5
4 5 0
5 3 1 3
6 1 1 6


Output

1
2
1
1
2
1
1
2
1
1
2
1

Note

The input in both samples are the same. The first sample contains the answer to the first subproblem, the second sample contains the answer to the second subproblem.

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
const long long INF = 100000000000000000;
vector<int> TopSort(vector<vector<int>>& g) {
  int n = g.size();
  vector<int> in(n + 2);
  for (int f = 0; f < g.size(); f++) {
    for (int s : g[f]) {
      in[s]++;
    }
  }
  queue<int> zd;
  for (int i = 0; i < n; i++) {
    if (in[i] == 0) {
      zd.push(i);
    }
  }
  vector<int> ans;
  while (!zd.empty()) {
    int f = zd.front();
    zd.pop();
    ans.push_back(f);
    for (int s : g[f]) {
      in[s]--;
      if (in[s] == 0) {
        zd.push(s);
      }
    }
  }
  return ans;
}
vector<int> TopSortDfs(vector<vector<int>>& g, int start) {
  int n = g.size();
  vector<int> ans;
  vector<bool> visit(n, false);
  function<void(int)> dfs = [&](int f) {
    visit[f] = true;
    for (int s : g[f]) {
      if (!visit[s]) {
        dfs(s);
      }
    }
    ans.push_back(f);
  };
  dfs(start);
  reverse(ans.begin(), ans.end());
  return ans;
}
void Dkst(vector<vector<pair<int, int>>>& g, vector<long long>& dist,
          vector<int>& parent, int n, int start) {
  dist = vector<long long>(n, INF);
  dist[start] = 0;
  set<pair<long long, long long>> q;
  q.insert(make_pair(dist[start], start));
  while (!q.empty()) {
    long long v = q.begin()->second;
    q.erase(q.begin());
    for (int j = 0; j < g[v].size(); ++j) {
      long long to = g[v][j].first, len = g[v][j].second;
      if (dist[v] + len < dist[to]) {
        q.erase(make_pair(dist[to], to));
        dist[to] = dist[v] + len;
        parent[to] = v;
        q.insert(make_pair(dist[to], to));
      }
    }
  }
}
struct People {
  int sx;
  int sy;
  int ex;
  int ey;
};
void Bfs(vector<vector<int>>& g, vector<bool>& used, vector<int>& dist,
         vector<int>& parent, int n, int start) {
  queue<int> q;
  q.push(start);
  used[start] = 1;
  q.push(start);
  dist[start] = 0;
  while (!q.empty()) {
    int v = q.front();
    q.pop();
    for (int i = 0; i < g[v].size(); i++) {
      int to = g[v][i];
      if (!used[to]) {
        q.push(to);
        used[to] = 1;
        parent[to] = v;
        dist[to] = dist[v] + 1;
      }
    }
  }
}
bool vp = 0;
bool nz = 0;
int evp = 0;
int enz = 0;
void Dfs(vector<vector<int>>& g, vector<vector<vector<int>>>& vid,
         vector<stack<int>>& parent, vector<int>& obr, int f, int k) {
  if (vp) {
    return;
  }
  if (k < 2 * g.size() + 1) {
    if (obr.size() == k + 1) {
      vp = true;
      evp = f;
      return;
    }
    for (int i = 0; i < g[f].size(); i++) {
      int s = g[f][i];
      if (obr.size() == k + 1) {
        vp = true;
        evp = f;
        return;
      }
      if (obr[k + 1] == s) {
        parent[s].push(f);
        int ho = vid[f][s].size();
        obr.insert(obr.end(), vid[f][s].begin(), vid[f][s].end());
        if (obr.size() == k + 2) {
          vp = true;
          evp = s;
          return;
        }
        Dfs(g, vid, parent, obr, s, k + 1);
        if (vp) {
          return;
        }
        parent[s].pop();
        obr.erase(obr.begin() + ho, obr.end());
      }
    }
  }
};
void ODFS(vector<vector<int>>& p, vector<vector<vector<int>>>& vid,
          vector<stack<int>>& parent, vector<int>& obr, int f, int k) {
  if (nz) {
    return;
  }
  if (obr.size() < 2 * p.size() + 1) {
    if (k > 0) {
      for (int i = 0; i < p[f].size(); i++) {
        int s = p[f][i];
        if (obr[k - 1] == s) {
          parent[f].push(s);
          int ho = vid[s][f].size();
          obr.insert(obr.begin(), vid[s][f].begin(), vid[s][f].end());
          k += ho;
          if (1 == k) {
            nz = true;
            enz = s;
            return;
          }
          ODFS(p, vid, parent, obr, s, k - 1);
          if (nz) {
            return;
          }
          parent[f].pop();
          obr.erase(obr.end() - ho, obr.end());
          k -= ho;
        }
      }
    } else {
      nz = true;
    }
  }
};
int main() {
  int n, m;
  cin >> n >> m;
  vector<int> ans;
  vector<vector<vector<int>>> vid(n + 1, vector<vector<int>>(n + 1));
  vector<vector<vector<int>>> vid2;
  vid2 = vid;
  vector<vector<int>> g(n);
  vector<vector<int>> p(n);
  vector<int> sum(n + 1, 1);
  vector<stack<int>> parent(n + 2);
  vector<stack<int>> parent2(n + 2);
  vector<int> obr;
  vector<bool> visit(n + 2, 0);
  vector<bool> visit2(n + 2, 0);
  for (int i = 0; i < m; i++) {
    int f, s;
    cin >> f >> s;
    f--;
    s--;
    vector<int> obr;
    g[f].push_back(s);
    p[s].push_back(f);
    int k;
    cin >> k;
    for (int d = 0; d < k; d++) {
      int pb;
      cin >> pb;
      pb--;
      vid[f][s].push_back(pb);
    }
  }
  for (int i = 0; i < n; i++) {
    for (size_t d = 0; d < g[i].size(); d++) {
      int ind = -1;
      int s = g[i][d];
      bool pr = false;
      bool ja = 0;
      if (vid[i][s].size() > 1) {
        for (size_t c = 0; c < vid[i][s].size(); c++) {
          if (vid[i][s][c] == i && vid[i][s][c + 1] == s) {
            ind = c;
            pr = true;
            obr.insert(obr.begin(), vid[i][s].begin(), vid[i][s].end());
            break;
          }
        }
        vp = 0;
        nz = 0;
        if (pr) {
          parent[s].push(i);
          Dfs(g, vid, parent, obr, s, ind + 1);
          if (obr.size() > 0) {
            ODFS(p, vid, parent2, obr, i, ind);
          } else {
            nz = 0;
          }
          if (vp && nz) {
            int op = enz;
            int ok = evp;
            enz = i;
          } else {
            vp = 0;
            nz = 0;
          }
        }
      }
      if (vp && nz) {
        break;
      }
      obr.clear();
    }
    if (vp && nz) {
      vector<int> a1;
      vector<int> a2;
      int per = evp;
      int per2 = enz;
      a1.push_back(per2);
      a2.push_back(per);
      while (parent2[per2].size() > 0) {
        int sp = per2;
        per2 = parent2[sp].top();
        parent2[sp].pop();
        a1.push_back(per2);
      }
      while (parent[per].size() > 0) {
        int sp = per;
        per = parent[sp].top();
        parent[sp].pop();
        a2.push_back(per);
      }
      ans.insert(ans.begin(), a1.begin(), a1.end());
      ans.insert(ans.begin(), a2.begin(), a2.end() - 1);
      break;
    }
  }
  cout << ans.size() << endl;
  for (int i = ans.size() - 1; i >= 0; i--) {
    cout << ans[i] + 1 << " ";
  }
}