#include #include #include #include using namespace std ; using ull = unsigned long long ; const int MAX = 32 ; char b[MAX][MAX] ; int row[MAX] ; int closed ; int cnts[16] ; int w, h ; const int BLOCKED = 15 ; const int STORE = 14 ; const int NEWHALL = 13 ; ull packstate() { ull r = closed ; for (int i=0; i<16; i++) cnts[i] = -1 ; int halln = 0 ; for (int i=1; i<=w; i++) { if (row[i] < STORE) { if (cnts[row[i]] < 0) cnts[row[i]] = halln++ ; row[i] = cnts[row[i]] ; } r = (r << 4) + row[i] ; } return r ; } void unpackstate(ull s) { for (int i=0; i<16; i++) cnts[i] = 0 ; for (int i=w; i>0; i--) { int v = s & 15 ; row[i] = v ; cnts[v]++ ; s >>= 4 ; } closed = s ; } int incscore(int cs, int rs, int nv, int left, int up) { if (nv == STORE) return (left < STORE && b[cs][rs-1] == '.') + (up < STORE && b[cs-1][rs] == '.') ; if (nv < STORE && b[cs][rs] == '.') return (left == STORE) + (up == STORE) ; return 0 ; } void rewriterow(int ov, int nv) { for (int i=1; i<=w; i++) if (row[i] == ov) row[i] = nv ; } int main(int argc, char *argv[]) { cin >> h >> w ; memset(b, '#', sizeof(b)) ; for (int i=0; i> s ; for (int j=0; j states, nstates ; ull initstate = packstate() ; states[initstate] = 0 ; int esccount = 0 ; for (int cs=1; cs<=h+1; cs++) { for (int rs=1; rs<=w; rs++) { int ri = rs ; int is = b[cs][rs] ; if (is == 'U' || is == 'D') esccount++ ; nstates.clear() ; for (auto it: states) { for (int nv=NEWHALL; nv<=BLOCKED; nv++) { if ((is == '#') != (nv == BLOCKED)) continue ; if ((is == 'U' || is == 'D') && nv != NEWHALL) continue ; unpackstate(it.first) ; int closing = 0 ; if (row[ri] < STORE && cnts[row[ri]] == 1 && nv != NEWHALL) closing = 1 ; if (closing && cnts[1] > 0) continue ; if (closed && closing) continue ; if (esccount < 2 && closing) continue ; closed |= closing ; int score = it.second + incscore(cs, rs, nv, row[ri-1], row[ri]) ; if (nv == NEWHALL) { if (row[ri] < STORE && row[ri-1] < STORE) { if (row[ri] != row[ri-1]) rewriterow(row[ri-1], row[ri]) ; } else if (row[ri] < STORE) { // leave it be } else if (row[ri-1] < STORE) { row[ri] = row[ri-1] ; } else { row[ri] = NEWHALL ; } } else { row[ri] = nv ; } ull ns = packstate() ; if (nstates.find(ns) == nstates.end()) nstates[ns] = score ; else nstates[ns] = max(score, nstates[ns]) ; } } swap(states, nstates) ; } } int r = 0 ; for (auto it: states) r = max(r, it.second) ; cout << r << endl ; }