1 #include<cstdio>
2 #include<iostream>
3 #include<cmath>
4 #include<vector>
5 #include<cstring>
6 #include<algorithm>
7 #define maxn 100005
8 #define maxm 300005
9 using namespace std;
10 char ch;
11 bool ok;
12 void read(int &x){
13 for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch==‘-‘) ok=1;
14 for (x=0;isdigit(ch);x=x*10+ch-‘0‘,ch=getchar());
15 if (ok) x=-x;
16 }
17 int n,m,x,a,b,siz,ans;
18 struct Edge{
19 int u,v;
20 }edge[maxm];
21 int idx,dfn[maxn],low[maxn],top,stack[maxn],cnt;
22 unsigned int bnm[maxn];
23 vector<int> belong[maxn],scc[maxn];
24 int list[maxn],head,tail,que[maxn],f[maxn];
25 struct Graph{
26 int tot,now[maxn<<1],son[maxm],pre[maxm];
27 void put(int a,int b){pre[++tot]=now[a],now[a]=tot,son[tot]=b;}
28 void add(int a,int b){put(a,b),put(b,a);}
29 void dfs(int u,int fa){
30 dfn[u]=low[u]=++idx,stack[++top]=u;
31 for (int p=now[u],v=son[p];p;p=pre[p],v=son[p])
32 if (!dfn[v]) dfs(v,u),low[u]=min(low[u],low[v]);
33 else if (v!=fa) low[u]=min(low[u],dfn[v]);
34 if (dfn[u]==low[u]){
35 top--;
36 if (fa) bnm[u]++,bnm[fa]++,edge[++siz]=(Edge){fa,u};
37 }
38 if (low[u]==dfn[fa]){
39 int v; ++cnt;
40 belong[fa].push_back(cnt),scc[cnt].push_back(fa);
41 do{v=stack[top--],belong[v].push_back(cnt),scc[cnt].push_back(v);}while (v!=u);
42 }
43 }
44 void calc1(int u,int fa){
45 int t=0,idx=u-n,len=scc[idx].size(),siz=0;
46 for (int i=0;i<len;i++) list[++siz]=scc[idx][i];
47 for (int i=0;i<len;i++) list[++siz]=scc[idx][i];
48 head=1,tail=0;
49 for (int i=1;i<=siz;i++){
50 while (head<=tail&&i-que[head]>(len>>1)) head++;
51 if (head<=tail) ans=max(ans,f[list[que[head]]]+f[list[i]]+i-que[head]);
52 while (head<=tail&&f[list[que[tail]]]-que[tail]<f[list[i]]-i) tail--;
53 que[++tail]=i;
54 if (list[i]==fa&&!t) t=i-1;
55 }
56 for (int i=0;i<len;i++){
57 int d=abs(i-t); if (d>(len>>1)) d=len-d;
58 f[u]=max(f[u],f[scc[idx][i]]+d);
59 }
60 }
61 void calc2(int u,int fa){
62 int ans1=0,ans2=0;
63 for (int p=now[u],v=son[p];p;p=pre[p],v=son[p])
64 if (v!=fa){
65 ans2=max(ans2,f[v]+(v<=n));
66 if (ans1<ans2) swap(ans1,ans2);
67 }
68 ans=max(ans,ans1+ans2),f[u]=ans1;
69 }
70 void tree_dp(int u,int fa){
71 for (int p=now[u],v=son[p];p;p=pre[p],v=son[p]) if (v!=fa) tree_dp(v,u);
72 if (u>n) calc1(u,fa); else calc2(u,fa);
73 }
74 }G1,G2;
75 int main(){
76 read(n),read(m);
77 for (int i=1;i<=m;i++){
78 read(x),read(a);
79 for (x--;x;x--) read(b),G1.add(a,b),a=b;
80 }
81 for (int i=1;i<=n;i++) if (!dfn[i]) G1.dfs(i,0);
82 for (int i=1;i<=siz;i++) G2.add(edge[i].u,edge[i].v);
83 for (int i=1;i<=n;i++) if (bnm[i]+belong[i].size()>=2)
84 for (unsigned int j=0;j<belong[i].size();j++) G2.add(i,n+belong[i][j]);
85 int root=cnt?n+1:1;
86 G2.tree_dp(root,0);
87 printf("%d\n",ans);
88 return 0;
89 }