#pragma warning (disable : 4996)
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
using namespace std;
const int maxn = 1e6 + 10;
char s[110][11];
int dp[110][80][80];///第i行,第i行取的状态是j,第i - 1行取得状态是k
int tot[maxn];
int num[maxn];
int op[110];//预处理,存储该行的山坡状态
//~9 = -10(因为负数是补码存储的)
//~9 = ~[00001001]原 = [11110110]补 = [11110101]反 = [10001010]原 = -10
//要求一个负数的二进制表示方式,可以先求出它的原码(即负数的绝对值的二进制位),然后每位取反得出它的反码,反码再加1得出补码
//所以实际补码就是源码的最后一个1及以后的位数不变,前面的全取反
//所以lowbit(i) 就是i最后一个1及以后的二进制的值
inline int lowbit(int x) {
return (x & (-x));
}
int main() {
int n, m, cnt = 0, ans = 0;
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; ++i) scanf("%s", s[i]);
for (int i = 0; i < (1 << m); ++i) if (((i & (i >> 1)) == 0) && ((i & (i >> 2)) == 0)) tot[cnt++] = i;
//cout << cnt; m = 10, cnt = 60//最多有60种状态满足条件
for (int i = 1; i < (1 << m); ++i) num[i] = num[i - lowbit(i)] + 1;//预处理出当前状态有几个1
//lowbit(i) 即2 ^ i的二进制下末尾0的个数 //lowbit(3) = 1, lowbit(2) = 2;
//通过动态计算统计每种状态包含1的个数
for (int i = 1; i <= n; ++i) {
for (int j = 0; j < m; ++j) op[i] |= ((s[i][j] == 'H') << j);
for (int j = 0; j < cnt; ++j) {///枚举第i层的状态
if (tot[j] & op[i]) continue;
for (int k = 0; k < cnt; ++k) {///枚举第i - 1的状态
if (tot[j] & tot[k]) continue;
if (i >= 2 && (op[i - 1] & tot[k])) continue;
int val = num[tot[j]];
for (int z = 0; z < cnt; ++z) {///枚举第i - 2的状态
if ((tot[z] & tot[j]) || (tot[z] & tot[k])) continue;
if (op[i - 2] & tot[z]) continue;
dp[i][j][k] = max(dp[i][j][k], dp[i - 1][k][z] + val);
}
ans = max(ans, dp[i][j][k]);
}
}
}
printf("%d\n", ans);
}