10 10
.L.....R..
.........U
..D....D..
.R......L.
....L.....
.........D
......U...
D....R....
...U......
........L.
 5 5
DD..D
.....
LU...
U...U
.UL.U
 1 1
U
 5 5
UD..L
RRD..
..RDD
UUL..
DDLRR
 19 23
U..U..R........L...D...
.D.....UL.U.U........DR
..D.U..D....L......R...
D.......RL.L....D.....R
U..D.....U...U.L..D...U
...........L...........
U....U....D.U......LRR.
......RL...U...L.......
DLU..U......UU.U.U.D...
...........D....U......
U...DL......LL.....R...
...U..DD..........LD...
.R.........D.....UU...U
....D......R..........D
.L..........R.....L....
.R........L.LL....R....
..R...D........R....D..
.LR.R..LDU.DDRL......U.
...LL.....D.....DD.....
 11 29
URRUUDDLURLRDDLLRLDUDR.UDLLD.
LRRUDLUDLDULUDL.DURDRR.RRLLRR
D.DUDDURLRDDULDUDDUDDURRDLD.L
.RULURURRDLRRRLUUUU.RDLDLRRRL
.RLDDU.UUULUURURRLLUU.RLDRDUD
LRL.URRRDDURUURUDRRDLDDULRDRL
RLULDU.LRDUDRLDLRDDDDRUUDRDLL
DLUDURRDDUDLLDLLUURLDRUURRLUL
L.RRURRDDRRURRRDDUDRRDULR.LUR
LDLRULURRUULRDUUULLU.LLU.LLLL
DUURDULDDUDLRUUDRUULURLD.RL.U
 2 2
RD
UL
 1 10
LLLLLRRRRR
 3 3
...
...
..R
 17 13
...LD.UR.RUU.
LDLULDUDRRDRL
DD.RRLRUR.UD.
RU...D...LD..
.UR.R...URUUD
.RURD.RLR.D.R
.UUU.RU...UR.
UUUU.R.......
RL.LRU.UD.DUD
LD.DRURRLRDRL
.DR..UULUDDR.
LRLURRUUDDLUR
.LRDDLLR.L.DU
DRUDLLD.LRRU.
..DL.UDL.DUL.
U.DL..D..U.RD
RR.R...RL.L..

2 2
 4 1
 1 1
 8 3
 9 1
 94 1
 4 4
 5 2
 1 1
 24 2

#include <bits/stdc++.h>
using namespace std;
const int maxn = 5001;
struct data {
  int u, d, l, r;
};
int n, m;
string a[maxn];
data g[maxn];
int get(int x, int y) { return x * m + y; }
void init() {
  memset(g, 255, sizeof(g));
  cin >> n >> m;
  for (int i = 0; i < n; i++) cin >> a[i];
  for (int i = 0; i < n; i++) {
    int l = -1;
    for (int j = 0; j < m; j++)
      if (a[i][j] != '.') {
        g[get(i, j)].l = l;
        l = get(i, j);
      }
    int r = -1;
    for (int j = m - 1; j >= 0; j--)
      if (a[i][j] != '.') {
        g[get(i, j)].r = r;
        r = get(i, j);
      }
  }
  for (int j = 0; j < m; j++) {
    int u = -1;
    for (int i = 0; i < n; i++)
      if (a[i][j] != '.') {
        g[get(i, j)].u = u;
        u = get(i, j);
      }
    int d = -1;
    for (int i = n - 1; i >= 0; i--)
      if (a[i][j] != '.') {
        g[get(i, j)].d = d;
        d = get(i, j);
      }
  }
}
void del(int now) {
  if (g[now].u != -1) g[g[now].u].d = g[now].d;
  if (g[now].d != -1) g[g[now].d].u = g[now].u;
  if (g[now].l != -1) g[g[now].l].r = g[now].r;
  if (g[now].r != -1) g[g[now].r].l = g[now].l;
}
void recover(int now) {
  if (g[now].u != -1) g[g[now].u].d = now;
  if (g[now].d != -1) g[g[now].d].u = now;
  if (g[now].l != -1) g[g[now].l].r = now;
  if (g[now].r != -1) g[g[now].r].l = now;
}
int dfs(int now) {
  int ret = 1;
  int x = now / m, y = now % m;
  if (a[x][y] == 'D') {
    int tmp = g[now].d;
    if (tmp != -1) {
      del(now);
      ret += dfs(tmp);
      recover(now);
    }
  } else if (a[x][y] == 'U') {
    int tmp = g[now].u;
    if (tmp != -1) {
      del(now);
      ret += dfs(tmp);
      recover(now);
    }
  } else if (a[x][y] == 'L') {
    int tmp = g[now].l;
    if (tmp != -1) {
      del(now);
      ret += dfs(tmp);
      recover(now);
    }
  } else {
    int tmp = g[now].r;
    if (tmp != -1) {
      del(now);
      ret += dfs(tmp);
      recover(now);
    }
  }
  return ret;
}
void solve() {
  int ans = 0, anstot = 0;
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++)
      if (a[i][j] != '.') {
        int tmp = dfs(get(i, j));
        if (tmp > ans) {
          ans = tmp;
          anstot = 1;
        } else if (tmp == ans)
          ++anstot;
      }
  cout << ans << ' ' << anstot << endl;
}
int main() {
  init();
  solve();
  return 0;
}
