#include <iostream>
#include <string>
#include <string.h>
#include <unordered_map>
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<MAX; i++)
      row[i] = BLOCKED ;
   for (int i=0; i<h; i++) {
      string s ;
      cin >> s ;
      for (int j=0; j<w; j++)
         b[i+1][j+1] = s[j] ;
   }
   if (h < w) {
      for (int i=0; i<MAX; i++)
         for (int j=i+1; j<MAX; j++)
            swap(b[i][j], b[j][i]) ;
      swap(w, h) ;
   }
   unordered_map<ull, int> 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 ;
}
