/*
炮兵阵地
*/
const int N=200;
int no[N],can[100+10],num[100+10],n,m;
int f[N][1000][1000];//10^8
char s[20];int maxn,cnt;
inline int lowbit(int x)
{
return x&(-x);
}
int main()
{
//freopen("exam.txt","r",stdin);
n=re(),m=re();
maxn=(1<<m)-1;
//chu("%d %d %d\n",m,(1<<m)-1,maxn);
_f(i,1,n)
{
scanf("%s",s);
_f(j,0,m-1)
{
if(s[j]=='H')
{
no[i]+=(1<<j);
}
}
}
//chu("max:%d\n",maxn);
_f(i,0,maxn)
{
if(!((i<<2)&i))
{
if(!((i<<1)&i))
{
can[++cnt]=i;
for(int o=i;o;o-=lowbit(o))++num[cnt];
}
}
}
//chu("cnt:%d\n",cnt);
_f(x,0,n)
{
_f(i,1,cnt)
{
_f(j,1,cnt)
{
f[x][can[i]][can[j]]=-inf;
//chu("change:%d %d %d\n",x,can[i],can[j]);
}
}
}
f[0][0][0]=0;
// return 0;
_f(x,1,n)
{
_f(i,1,cnt)
{
int ii=can[i];
if(ii&no[x])continue;
_f(j,1,cnt)
{
int jj=can[j];
if(jj&no[x-1])continue;
if(ii&jj)continue;
_f(k,1,cnt)
{
int kk=can[k];
if(kk&ii)continue;
//if(no[x-2]&kk)continue;
f[x][ii][jj]=max(f[x-1][jj][kk]+num[i],f[x][ii][jj]);
// chu("f[%d %d %d]:%d\n",x,ii,jj,f[x][ii][jj]);
}
}
}
}
int ans=0;
_f(i,1,cnt)
{
_f(j,1,cnt)
{
ans=max(ans,f[n][can[i]][can[j]]);
}
}
chu("%d",ans);
return 0;
}
/*
这里要注意,状态压缩一般需要初始化,f[0][0]=1或者0,具体要看意义
如果是可能性,则为1,最值是0
还有几个位运算基本操作,比如二进制1的个数,二进制数空几个是0
及其注意:三维数组memset超级慢!!!千万别用
*/
/*
特殊棋盘方格
非常整体思维的一道状压
*/
const int N=20;
inline int lowbit(int x)
{
return (x)&(-x);
}
ll f[(1<<N)+10];ll no[N+10];
int n,m;
int main()
{
//freopen("exam.txt","r",stdin);
n=re(),m=re();
_f(i,1,m)
{
int x=re(),y=re();
no[x]+=(1<<(y-1));
}
f[0]=1;
ll can=(1<<(n))-1;
// chu("%lld\n",can);
_f(i,1,can)
{
int cnt=0;
for(int k=i;k;k-=lowbit(k))cnt++;
for(int k=i;k;k-=lowbit(k))
{
int j=lowbit(k);//在cnt行j状态列放棋子
if(j&no[cnt])continue;
//那其他列就要放其他棋子
int jj=j^i;//j放了其他就不用放了
f[i]+=f[jj];
// chu("f[%d]:%lld\n",i,f[i]);
}
}
chu("%lld",f[can]);
return 0;
}
/*
f[j]表示到j状态的方案数
no[i]=j不合法地形
for(1-(1<<n)-1)循环状态
for(j:1-i)cnt统计这个状态1的个数,就是统计到了第几行
int n,m;scanf("%d%d",&n,&m);
for(int i = 1;i <= m;i++){
int x,y;scanf("%d%d",&x,&y);
a[x] += 1<<(y-1);
}
f[0] = 1;
int maxs = 1<<n;
for(int s = 1;s < maxs;s++){
int cnt = 0;
for(int i = s;i;i-=lowbit(i))cnt++;
for(int i = s;i;i-=lowbit(i)){
if(!(a[cnt] & lowbit(i))){
int ss = s^lowbit(i);
f[s] += f[ss];
}
}
}
printf("%lld\n",f[maxs - 1]);
return 0;
*/