#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
const long long mod = 1e9 + 7;
inline long long gcd(long long a, long long b) {
  return !b ? a : gcd(b, a % b);
}
inline long long q_pow(long long a, long long x) {
  long long ans = 1, tmp = a;
  while (x) {
    if (x & 1) (ans *= tmp) %= mod;
    (tmp *= tmp) %= mod;
    x >>= 1;
  }
  return ans;
}
template <typename T>
inline void re(T &N) {
  int f = 1;
  char c;
  while ((c = getchar()) < '0' || c > '9')
    if (c == '-') f = -1;
  N = c - '0';
  while ((c = getchar()) >= '0' && c <= '9') N = N * 10 + c - '0';
  N *= f;
}
int m, n, t = 1, st, en;
struct SegT {
  struct node {
    int cnt, len;
  } e[N << 2];
  inline void push_up(int p, int l, int r) {
    if (e[p].cnt)
      e[p].len = r - l + 1;
    else
      e[p].len = e[((p) << 1)].len + e[((p) << 1 | 1)].len;
  }
  void update(int p, int l, int r, int L, int R, int k) {
    if (L <= l && r <= R) {
      e[p].cnt += k;
      push_up(p, l, r);
      return;
    }
    int mid = (l + r) >> 1;
    if (L <= mid) update(((p) << 1), l, mid, L, R, k);
    if (mid < R) update(((p) << 1 | 1), mid + 1, r, L, R, k);
    push_up(p, l, r);
  }
  inline int query() { return e[1].len; }
} tr;
struct edge {
  int to, nxt;
} e[N << 1];
int head[N], r[N];
inline void add(int x, int y) {
  e[++t] = {y, head[x]};
  head[x] = t;
  r[y]++;
}
int in[N], out[N], dfstime;
void dfs(int x) {
  in[x] = ++dfstime;
  for (int i = head[x]; i; i = e[i].nxt) {
    int to = e[i].to;
    dfs(to);
  }
  out[x] = dfstime;
}
struct Sqr {
  int d, u, l, r;
} Sq[N];
int Sqc;
struct Seg {
  int d, u, x, ty;
  bool operator<(const Seg &s) const { return x < s.x; }
} Se[N << 1];
int Sec;
inline int id(int x, int y) { return (x - 1) * n + y; }
char str[N];
int main() {
  re(m);
  re(n);
  for (int i = 1; i <= m; i++) scanf("%s", str + (i - 1) * n + 1);
  for (int i = 1; i <= m; i++)
    for (int j = 1; j <= n; j++) {
      if (i - 2 >= 1 && str[id(i - 2, j)] == 'U') add(id(i, j), id(i - 2, j));
      if (i + 2 <= m && str[id(i + 2, j)] == 'D') add(id(i, j), id(i + 2, j));
      if (j - 2 >= 1 && str[id(i, j - 2)] == 'L') add(id(i, j), id(i, j - 2));
      if (j + 2 <= n && str[id(i, j + 2)] == 'R') add(id(i, j), id(i, j + 2));
    }
  for (int i = 1; i <= m; i++)
    for (int j = 1; j <= n; j++)
      if (!r[id(i, j)]) dfs(id(i, j));
  for (int i = 1; i <= m; i++)
    for (int j = 1; j <= n; j++) {
      if (str[id(i, j)] == 'U' && str[id(i + 1, j)] == 'D') {
        Sq[++Sqc] = {in[id(i, j)], out[id(i, j)], in[id(i + 1, j)],
                     out[id(i + 1, j)]};
        Sq[++Sqc] = {in[id(i + 1, j)], out[id(i + 1, j)], in[id(i, j)],
                     out[id(i, j)]};
      }
      if (str[id(i, j)] == 'L' && str[id(i, j + 1)] == 'R') {
        Sq[++Sqc] = {in[id(i, j)], out[id(i, j)], in[id(i, j + 1)],
                     out[id(i, j + 1)]};
        Sq[++Sqc] = {in[id(i, j + 1)], out[id(i, j + 1)], in[id(i, j)],
                     out[id(i, j)]};
      }
    }
  for (int i = 1; i <= Sqc; i++) {
    Se[++Sec] = {Sq[i].d, Sq[i].u, Sq[i].l, 1};
    Se[++Sec] = {Sq[i].d, Sq[i].u, Sq[i].r + 1, -1};
  }
  sort(Se + 1, Se + Sec + 1);
  long long ans = 0;
  int la = -1;
  for (int i = 1; i <= Sec; i++) {
    tr.update(1, 1, m * n, Se[i].d, Se[i].u, Se[i].ty);
    if (i < Sec && Se[i + 1].x != Se[i].x) {
      if (!(~la)) la = Se[i].x - 1;
      ans += 1ll * (Se[i].x - la) * tr.query();
      la = Se[i].x;
    }
  }
  printf("%lld\n", ans / 2);
}
