//最大独立集=总点数-最大匹配/2
//注意判重,判断x1、x2是否连通时,x1^x2为2的指数则连通
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int n, m, sum, ans;
int match[1025], p[1025], p2[11], num[1025];
bool visited[1025], visit[1025];
char str[15];
void init(){
int i, j, x, t, tmp;
memset(match, -1, sizeof(match));
memset(visit, 0, sizeof(visit));
ans=0;sum=0;
for(j=0; j<m; j++){
scanf("%s", str);
tmp=0;x=0;
for(i=0; i<n; i++){
if(str[i]!='*'){
if(str[i]=='1')
tmp+=p2[n-i-1];
}
else x=p2[n-i-1];
}
if(x){
if(!visit[tmp]){
num[sum++]=tmp;
visit[tmp]=1;
}
if(!visit[tmp+x]){
num[sum++]=tmp+x;
visit[tmp+x]=1;
}
}
else if(!visit[tmp]){
num[sum++]=tmp;
visit[tmp]=1;
}
}
}
bool find(int x){
int i;
for(i=0; i<sum; i++){
if(p[num[i]^x]&&!visited[num[i]]){
visited[num[i]]=1;
if(match[num[i]]==-1||find(match[num[i]])){
match[num[i]]=x;
return 1;
}
}
}
return 0;
}
int main(){
//freopen("1.txt", "r", stdin);
int i;
memset(p, 0, sizeof(p));
p[1]=1;p2[0]=1;
for(i=1; i<=10; i++){
p2[i]=p2[i-1]*2;
p[p2[i]]=1;
}
while(scanf("%d%d", &n, &m)&&n){
init();
for(i=0; i<sum; i++){
memset(visited, 0, sizeof(visited));
if(find(num[i]))
ans++;
}
printf("%d\n", sum-ans/2);
}
return 0;
}