#include<cstdio>
#include<string.h>
#include<queue>
using namespace std;
const int N=1e3+10;
int n,m,cnt,ans;
queue<int> q;
int vis[N],du[N],a[N],edge_vis[N][N],head[N],dep[N];
struct Node{
int nxt,to;
}edge[N*N];
void add(int x,int y){
edge[++cnt]={head[x],y},head[x]=cnt;
return ;
}
void tuo(){
for(int i=1;i<=n;i++) if(!du[i]) q.push(i),dep[i]=1;
while(!q.empty()){
int t=q.front();
q.pop();
for(int i=head[t];i;i=edge[i].nxt){
int to=edge[t].to;
dep[to]=dep[t]+1;
ans=max(ans,dep[to]);
if(--du[to]==0) q.push(to);
}
}
printf("%d",ans);
}
void solve(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int x;scanf("%d",&x);
memset(vis,0,sizeof vis);
for(int j=1;j<=x;j++){
scanf("%d",&a[j]);
vis[a[j]]=1;
}
for(int j=a[1];j<=a[x];j++)
if(!vis[j])
for(int p=1;p<=x;p++){
int ap=a[p];
if(!edge_vis[j][ap])
du[ap]++,add(j,ap),edge_vis[j][ap]=1;
}
}
tuo();
return ;
}
int main(){
solve();
return 0;
}