#include using namespace std; #define rep(i,a,b) for(int i=a;i> G; vector itr, level; Maxflow(int V) : V(V) { G.assign(V, vector()); } void add_edge(int from, int to, int cap) { G[from].push_back(edge(to, cap, (int)G[to].size())); G[to].push_back(edge(from, 0, (int)G[from].size() - 1)); } void bfs(int s) { level.assign(V, -1); queue q; level[s] = 0; q.push(s); while (!q.empty()) { int v = q.front(); q.pop(); for (auto &e : G[v]) { if (e.cap > 0 and level[e.to] < 0) { level[e.to] = level[v] + 1; q.push(e.to); } } } } int dfs(int v, int t, int f) { if (v == t) return f; for (int& i = itr[v]; i < (int)G[v].size(); ++i) { edge& e = G[v][i]; if (e.cap > 0 and level[v] < level[e.to]) { int d = dfs(e.to, t, min(f, e.cap)); if (d > 0) { e.cap -= d; G[e.to][e.rev].cap += d; return d; } } } return 0; } int run(int s, int t) { int ret = 0, f; while (bfs(s), level[t] >= 0) { itr.assign(V, 0); while ((f = dfs(s, t, INF)) > 0) ret += f; } return ret; } }; //----------------------------------------------------------------- int N, M; string S[50]; int idx[50][50]; int dx[2] = { 1, 0 }; int dy[2] = { 0, 1 }; //----------------------------------------------------------------- int main() { cin >> N >> M; rep(i, 0, N) cin >> S[i]; int b = 0, w = 0; rep(y, 0, N) rep(x, 0, M) { if (S[y][x] == 'w') idx[y][x] = w, w++; else if (S[y][x] == 'b') idx[y][x] = b, b++; } Maxflow mf(1 + w + b + 1); rep(i, 0, w) mf.add_edge(0, i + 1, 1); rep(y, 0, N) rep(x, 0, M) if(S[y][x] != '.') rep(i, 0, 2) { int yy = y + dy[i]; int xx = x + dx[i]; if (yy < 0 || N <= yy) continue; if (xx < 0 || M <= xx) continue; if (S[yy][xx] == '.') continue; int bb = (S[y][x] == 'b' ? idx[y][x] : idx[yy][xx]); int ww = (S[y][x] == 'b' ? idx[yy][xx] : idx[y][x]); mf.add_edge(ww + 1, bb + 1 + w, 1); } rep(i, 0, b) mf.add_edge(1 + w + i, 1 + w + b, 1); int m = mf.run(0, 1 + w + b); int ans = 0; ans += m * 100; ans += min(b - m, w - m) * 10; ans += abs(b - w); cout << ans << endl; }