#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
int R,C,dp[110][70][70],stk[70],top,cur[110],num[110];
char s[110][20];
bool fit(int x,int k)
{
if(cur[k]&x) return 0;
return 1;
}
int main()
{
int i,j,k,t;
while(scanf("%d%d",&R,&C)==2)
{
top=0;
int total=1<<C,x,cnt;
for(i=0;i<total;i++)
if( !( i&(i<<2)||i&(i<<1) ) ) //不存在相邻的1直接距离小于3的,即合法
stk[++top]=i;
for(i=1;i<=R;i++)
{
scanf("%s",s[i]+1);
cur[i]=0;
for(j=1;j<=C;j++)
{
if(s[i][j]==‘H‘) cur[i]+=(1<<(j-1));
}
}
memset(dp,-1,sizeof(dp));
for(i=1;i<=top;i++)
{
cnt=0;
x=stk[i];
while(x)
{
cnt++; //整型数x的转换为二进制后1的个数
x&=(x-1);
}
num[i]=cnt;
if( fit(stk[i],1) )
dp[1][1][i]=num[i];
}
for(i=2;i<=R;i++)
{
for(t=1;t<=top;t++)
{
if(!fit(stk[t],i)) continue;
for(j=1;j<=top;j++)
{
if(stk[t]&stk[j]) continue;
for(k=1;k<=top;k++)
{
if(stk[t]&stk[k]) continue;
if(dp[i-1][j][k]==-1) continue;
dp[i][k][t]=max(dp[i][k][t],dp[i-1][j][k]+num[t]);
}
}
}
}
int ans=0;
for(i=1;i<=top;i++)
for(j=1;j<=top;j++)
ans=max(ans,dp[R][i][j]);
printf("%d\n",ans);
}
return 0;
}
炮兵阵地(状态压缩dp)