#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <sstream>
#include <complex>
#include <ctime>
#include <cassert>
#include <functional>

using namespace std;

typedef long long ll;
typedef vector<int> VI;
typedef pair<int,int> PII;

#define REP(i,s,t) for(int i=(s);i<(t);i++)
#define FILL(x,v) memset(x,v,sizeof(x))

const int INF = (int)1E9;

int R, C, ans;
char G[101][101];
int dir[4][2] = {-1,0,1,0,0,1,0,-1};
bool vu[101][101], vd[101][101];
void dfs(int x, int y, bool v[101][101]) {
  v[x][y] = true;
  REP(d,0,4) {
    int nx = x + dir[d][0], ny = y + dir[d][1];
    if (nx < 0 || nx >= R || ny < 0 || ny >= C || v[nx][ny] || G[nx][ny] == '#') continue;
    dfs(nx, ny, v);
  }
}
void enumerate(int i, int j, vector<PII> &shops) {
	if (i == R) {
		for (auto &p: shops) G[p.first][p.second] = '#';
		REP(i,0,R) REP(j,0,C) vu[i][j] = vd[i][j] = false;
		REP(i,0,R) REP(j,0,C) {
			if (G[i][j] == 'U') dfs(i, j, vu);
			if (G[i][j] == 'D') dfs(i, j, vd);
		}
		int sol = 0;
		for (auto &p: shops) {
			REP(d,0,4) {
				int ni = p.first + dir[d][0], nj = p.second + dir[d][1];
				if (ni < 0 || ni >= R || nj < 0 || nj >= C || G[ni][nj] != '.' || !vu[ni][nj] || !vd[ni][nj]) continue;
				sol++;
			}
		}
		ans = max(ans, sol);
		for (auto &p: shops) G[p.first][p.second] = '.';
		return;
	}
	if (G[i][j] == '.') {
		shops.push_back(PII(i, j));
		if (j == C - 1) enumerate(i + 1, 0, shops);
		else enumerate(i, j + 1, shops);
		shops.pop_back();
	}
	if (j == C - 1) enumerate(i + 1, 0, shops);
	else enumerate(i, j + 1, shops);
}
int main() {
	cin >> R >> C;
	REP(i,0,R) cin >> G[i];
	vector<PII> shops;
	enumerate(0, 0, shops);
	cout << ans << endl;
  return 0;
}
