template<typename T> inlinevoidread(T &x){ x = 0; T k = 1; char in = getchar(); while (!isdigit(in)) { if (in == '-') k = -1; in = getchar(); } while (isdigit(in)) x = x * 10 + in - '0', in = getchar(); x *= k; }
constint M = 1<<11; constint N = 105;
int n, m, maxn, ans; int mp[N], f[3][M][M]; vector<int> d, v;// 可行状态的对应的炮兵个数 char in[15];
// 计算每种情况的炮兵个数 inlineintcount(int x){ int re = 0; for (int i = 0; i <= 30; ++i) if (x & (1 << i)) re++; return re; }
intmain(){ read(n), read(m); maxn = (1 << m) - 1; for (int i = 0; i < n; ++i) { scanf("%s", in); //处理地图 for (int j = 0; j < m; ++j) if (in[j] == 'H') mp[i] |= 1 << j; } // 预处理可行状态 for (int i = 0; i <= maxn; ++i) if ((i & (i >> 1)) == 0 && (i & (i >> 2)) == 0) d.push_back(i), v.push_back(count(i)); // 单独处理一二行 for (int i = 0; i < d.size(); ++i) if ((d[i] & mp[0]) == 0)// 一贯的保证可行 f[0][d[i]][0] = v[i]; for (int i = 0; i < d.size(); ++i) if ((d[i] & mp[1]) == 0) for (int j = 0; j < d.size(); ++j) if ((d[j] & d[i]) == 0) f[1][d[i]][d[j]] = max(f[1][d[i]][d[j]], f[0][d[j]][0] + v[i]); // 愉快的dp for (int i = 2; i < n; ++i)// 行数 for (int j = 0; j < d.size(); ++j)// 该行 if ((d[j] & mp[i]) == 0) for (int k = 0; k < d.size(); ++k)// 上一行 if ((d[k] & d[j]) == 0) for (int l = 0; l < d.size(); ++l)// 上二行 if ((d[l] & d[k]) == 0 && (d[l] & d[j]) == 0) f[i%3][d[j]][d[k]] = max(f[i%3][d[j]][d[k]], f[(i-1)%3][d[k]][d[l]] + v[j]);// 重点 // 统计最后一行的最大值 for (int i = 0; i < d.size(); ++i) for (int j = 0; j < d.size(); ++j) ans = max(ans, f[(n-1)%3][d[i]][d[j]]); printf("%d\n", ans); }