/*
1y,有点意外
对应匈牙利算法看,不同的是右边的点可匹配多个
*/
#include<cstdio>
#include<cstring>
const int MAXN=1005;
struct Node{
int v,next;
}nodes[MAXN*MAXN];
int n,m;
int G[MAXN];
int alloc,N;
bool vi[MAXN];
int link[MAXN][MAXN];
void add(int a,int b){
alloc++;
nodes[alloc].v=b,nodes[alloc].next=G[a];
G[a]=alloc;
}
bool find(int u){
for(int son=G[u];son!=-1;son=nodes[son].next){
int v=nodes[son].v;
//v对应多个匹配
if(vi[v])continue;
vi[v]=1;
if(link[v][0]<N){
link[v][++link[v][0]]=u;
return true;
}
for(int i=1;i<=link[v][0];i++)
if(find(link[v][i])){
link[v][i]=u;
return true;
}
}
return false;
}
bool chk(){
int ans=0;
for(int i=0;i<m;i++)link[i][0]=0;
for(int i=0;i<n;i++){
memset(vi,0,sizeof(vi));
if(!find(i))return false;
}
return true;
}
int main(){
char str[20],ch;
while(scanf("%d%d",&n,&m),n){
memset(G,-1,sizeof(G));
alloc=0;
for(int i=0;i<n;i++){
scanf("%s",str);
while(1){
while(ch=getchar(),ch==' ');
int tmp=ch-'0';
while(ch=getchar(),ch<='9'&&ch>='0')tmp=10*tmp+ch-'0';
add(i,tmp);
if(ch=='\n'||ch==EOF)break;
}
}
int low=0,high=n+1;
while(high-low>1){
int mid=(high+low)>>1;
N=mid;
if(chk())high=mid;
else low=mid;
}
printf("%d\n",high);
}
return 0;
}