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;
int N, M;
char S[5005][5005];
char T[5005][5005];
vector<vector<short> > tree1;
int leaf1;
vector<vector<short> > tree2;
int leaf2;
void update(vector<short> &tree, int leaf, int x, short v) {
  x += leaf;
  tree[x] = v;
  while (x >>= 1) tree[x] = tree[x << 1] + tree[(x << 1) | 1];
}
short get(vector<short> &tree, int leaf, int x, int y) {
  if (x > y) return 0;
  short ret = 0;
  x += leaf;
  y += leaf;
  while (x <= y) {
    if ((x & 1)) ret += tree[x];
    if (!(y & 1)) ret += tree[y];
    x = (x + 1) >> 1;
    y = (y - 1) >> 1;
  }
  return ret;
}
int leftmost(vector<short> &tree, int leaf, int x) {
  int p = 1;
  short v = get(tree, leaf, 1, x) + 1;
  while (p < leaf) {
    if (v <= tree[p + p]) {
      p = p + p;
    } else {
      v -= tree[p + p];
      p = p + p + 1;
    }
  }
  return p - leaf;
}
int rightmost(vector<short> &tree, int leaf, int y) {
  int p = 1;
  int v = get(tree, leaf, 1, y);
  while (p < leaf) {
    if (v <= tree[p + p]) {
      p = p + p;
    } else {
      v -= tree[p + p];
      p = p + p + 1;
    }
  }
  return p - leaf;
}
int chk[5005][5005];
int score(int x, int y) {
  for (int i = 1; i <= N; i++) {
    for (int j = 1; j <= M; j++) {
      update(tree1[i], leaf1, j, (S[i][j] != '.'));
      update(tree2[j], leaf2, i, (S[i][j] != '.'));
      T[i][j] = S[i][j];
    }
  }
  int ret = 0;
  while ((1 <= x && x <= N && 1 <= y && y <= M) && T[x][y] != '.') {
    char c = T[x][y];
    T[x][y] = '.';
    ++ret;
    chk[x][y] += 1;
    update(tree1[x], leaf1, y, 0);
    update(tree2[y], leaf2, x, 0);
    if (c == 'U') {
      x = rightmost(tree2[y], leaf2, x);
    } else if (c == 'D') {
      x = leftmost(tree2[y], leaf2, x);
    } else if (c == 'L') {
      y = rightmost(tree1[x], leaf1, y);
    } else if (c == 'R') {
      y = leftmost(tree1[x], leaf1, y);
    }
  }
  return ret;
}
int main() {
  scanf("%d%d", &N, &M);
  for (int i = 1; i <= N; i++) scanf("%s", S[i] + 1);
  for (leaf1 = 1; leaf1 <= M; leaf1 <<= 1)
    ;
  for (leaf2 = 1; leaf2 <= N; leaf2 <<= 1)
    ;
  tree1.resize(N + 1);
  for (int i = 1; i <= N; i++) tree1[i].resize(leaf1 + leaf1);
  tree2.resize(M + 1);
  for (int i = 1; i <= M; i++) tree2[i].resize(leaf2 + leaf2);
  int ans1 = 0, ans2 = 0;
  for (int i = 1; i <= N; i++) {
    for (int j = 1; j <= M; j++)
      if (chk[i][j] <= 100) {
        int s = score(i, j);
        if (s > ans1) {
          ans1 = s;
          ans2 = 1;
        } else if (s == ans1) {
          ans2++;
        }
      }
  }
  printf("%d %d\n", ans1, ans2);
  return 0;
}
