#include<iostream>#include<cstdio>#include<string>#include<cstring>#include<algorithm>usingnamespace std;constint N =110, M =1<<10;int n, m;int g[N];
vector<int> state;int f[2][M][M];//滚动数组优化空间//判断不能有三个相邻的1boolcheck(int x){for(int i =0; i < m -1; i++){if((x >> i &1)&&(x >>(i +1)&1|| x >>(i +2)&1)){returnfalse;}}returntrue;}//统计每一个状态所放的炮的数量intcount(int x){int res =0;for(int i =0; i < m; i++){
res += x >> i &1;}return res;}intmain(){
cin >> n >> m;for(int i =1; i <= n; i++){for(int j =0; j < m; j++){char c;
cin >> c;if(c =='H') g[i]+=1<< j;}}//预处理合法状态for(int i =0; i <1<< m; i++){if(check(i)){
state.push_back(i);}}for(int i =1; i <= n; i++){for(int j =0; j < state.size(); j++){//第i行if((state[j]& g[i])==0){//不能放在山丘上for(int k =0; k < state.size(); k++){//第i-1行if((state[k]& g[i -1])==0){for(int u =0; u < state.size(); u++){//第i-2行if((state[u]& g[i -2])==0){int a = state[j];int b = state[k];int c = state[u];if((a & b)==0&&(a & c)==0&&(b & c)==0){
f[i &1][j][k]=max(f[i &1][j][k], f[(i -1)&1][k][u]+count(a));}}}}}}}}int res =0;for(int i =0; i <= state.size(); i++){for(int j =0; j < state.size(); j++){
res =max(res, f[n &1][i][j]);}}
cout << res << endl;return0;}