#include <bits/stdc++.h>
using namespace std;
const int inf = 1e9 + 1;
struct node {
  int mn, cnt, add;
};
struct query {
  int l, r, vl;
};
struct segtree {
  int size;
  vector<node> tree;
  node pull(node t1, node t2) {
    node rt;
    rt.mn = min(t1.mn, t2.mn);
    rt.cnt = (t1.mn == rt.mn ? t1.cnt : 0) + (t2.mn == rt.mn ? t2.cnt : 0);
    rt.add = 0;
    return rt;
  }
  void build(int t, int l, int r) {
    if (l + 1 == r) {
      tree[t] = {0, 1, 0};
      return;
    }
    int md = r + l >> 1;
    build(t * 2 + 1, l, md);
    build(t * 2 + 2, md, r);
    tree[t] = pull(tree[t * 2 + 1], tree[t * 2 + 2]);
  }
  segtree(int size) : size(size) {
    tree.resize(4 * size);
    build(0, 0, size);
  }
  void push(int t, int l, int r) {
    if (!tree[t].add) return;
    tree[t].mn += tree[t].add;
    if (l + 1 != r) {
      tree[t * 2 + 1].add += tree[t].add;
      tree[t * 2 + 2].add += tree[t].add;
    }
    tree[t].add = 0;
  }
  void upd(int t, int l, int r, int x, int y, int vl) {
    push(t, l, r);
    if (l >= x && r <= y) {
      tree[t].add += vl;
      push(t, l, r);
      return;
    }
    if (l >= y || r <= x) return;
    int md = r + l >> 1;
    upd(t * 2 + 1, l, md, x, y, vl);
    upd(t * 2 + 2, md, r, x, y, vl);
    tree[t] = pull(tree[t * 2 + 1], tree[t * 2 + 2]);
  }
  void upd(int l, int r, int vl) { upd(0, 0, size, l, r + 1, vl); }
  node get(int t, int l, int r, int x, int y) {
    push(t, l, r);
    if (l >= x && r <= y) return tree[t];
    if (l >= y || r <= x) return {inf, 0, 0};
    int md = r + l >> 1;
    node lc = get(t * 2 + 1, l, md, x, y);
    node rc = get(t * 2 + 2, md, r, x, y);
    return pull(lc, rc);
  }
  int get(int l, int r) {
    node rt = get(0, 0, size, l, r + 1);
    return (!rt.mn ? rt.cnt : 0);
  }
};
int n, m, root;
vector<vector<int>> g;
vector<int> ord, beg, lst;
vector<string> pole;
vector<pair<int, int>> ed;
vector<bool> used;
void dfs(int v) {
  used[v] = true;
  beg[v] = (int)ord.size();
  ord.push_back(v);
  for (int u : g[v]) {
    if (!used[u]) {
      dfs(u);
    }
  }
  lst[v] = (int)ord.size() - 1;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cin >> n >> m;
  g.resize(n * m + 1);
  beg.resize(n * m + 1);
  lst.resize(n * m + 1);
  used.resize(n * m + 1);
  pole.resize(n);
  root = n * m;
  for (int i = 0; i < n; ++i) cin >> pole[i];
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      if (pole[i][j] == 'U') {
        if (i > 0)
          ed.emplace_back((i - 1) * m + j, (i + 1) * m + j);
        else
          ed.emplace_back(root, (i + 1) * m + j);
        if (i + 2 < n)
          ed.emplace_back(i * m + j, (i + 2) * m + j);
        else
          ed.emplace_back(i * m + j, root);
      }
      if (pole[i][j] == 'L') {
        if (j > 0)
          ed.emplace_back(i * m + (j - 1), i * m + (j + 1));
        else
          ed.emplace_back(root, i * m + (j + 1));
        if (j + 2 < m)
          ed.emplace_back(i * m + j, i * m + (j + 2));
        else
          ed.emplace_back(i * m + j, root);
      }
    }
  }
  for (auto &e : ed) {
    g[e.first].push_back(e.second);
    g[e.second].push_back(e.first);
  }
  dfs(root);
  vector<vector<query>> q(n * m + 2);
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      int no = i * m + j, ne;
      if (pole[i][j] == 'U')
        ne = (i + 1) * m + j;
      else if (pole[i][j] == 'L')
        ne = i * m + (j + 1);
      else
        continue;
      if ((i + j) & 1) swap(no, ne);
      q[beg[no]].push_back({beg[ne], lst[ne], 1});
      q[lst[no] + 1].push_back({beg[ne], lst[ne], -1});
    }
  }
  segtree st(n * m + 2);
  long long out = 0;
  for (int i = 0; i <= n * m; ++i) {
    for (auto &e : q[i]) {
      st.upd(e.l, e.r, e.vl);
    }
    out += (n * m + 1) - st.get(0, n * m);
  }
  cout << out;
}
