#include <iostream>
#include <cstdio>
#include <string>
#include <map>
#include <vector>
#include <cstring>
using namespace std;
//英语 看博友分析 抄博友程序 二分图匹配 背
char da[2500][15];
//map<string, int> mp;
int mp[2500];
char ve[2500][15];
vector<int> g[2500];
int link[2500];
int vis[2500];
int n,m;
int js;
int toi(char* a)
{
int sum=0;
for(int i=0;i<n;i++)
{
sum=sum*2+a[i]-'0';
}
return sum;
}
bool check(char* a, char* b)
{
int sum=0;
for(int i=0;i<n;i++)
{
if(a[i]!=b[i])
{
sum++;
}
if(sum>=2)
{
return false;
}
}
return true;
}
bool dfs(int x)
{
for(int i=0;i<g[x].size();i++)
{
int y=g[x][i];
if(vis[y]==0)
{
vis[y]=1;
if(link[y]==-1 || dfs(link[y]))
{
link[y]=x;
return true;
}
}
}
return false;
}
int main()
{
while(1)
{
//cin>>n>>m;
scanf("%d%d",&n,&m);
if(n==0 && m==0)
{
break;
}
memset(ve,0,sizeof(ve));
//mp.clear();
memset(mp,0,sizeof(mp));
for(int i=0;i<2500;i++)
{
g[i].clear();
}
memset(link,-1,sizeof(link));
js=0;
for(int i=0;i<m;i++)
{
char s[15];
scanf("%s",s);
int pos=-1;
for(int j=0;j<n;j++)
{
if(s[j]=='*')
{
pos=j;
break;
}
}
if(pos!=-1)
{
s[pos]='1';
if(mp[toi(s)]==0)
{
//cout<<"hi2 "<<s<<endl;
strcpy(ve[js++],s);
mp[toi(s)]++;
}
s[pos]='0';
if(mp[toi(s)]==0)
{
//cout<<"hi3 "<<s<<endl;
strcpy(ve[js++],s);
mp[toi(s)]++;
}
}else
{
if(mp[toi(s)]==0)
{
//cout<<"hi1 "<<s<<endl;
strcpy(ve[js++],s);
mp[toi(s)]++;
}
}
}
for(int i=0;i<js;i++)
{
for(int j=i+1;j<js;j++)
{
if(check(ve[i],ve[j]))
{
g[i].push_back(j);
g[j].push_back(i);
}
}
}
int ans=0;
for(int i=0;i<js;i++)
{
memset(vis,0,sizeof(vis));
if(dfs(i))
{
ans++;
}
}
//cout<<js<<endl;
cout<<js-ans/2<<endl;
}
return 0;
}