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>
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, -1, 0, 1};
using namespace std;
char str[5001];
class Point {
 public:
  int Left;
  int Right;
  int Up;
  int Down;
};
Point f1[5001], f2[5001];
int ans1, ans2, n, m;
int dfs(int p, int tot) {
  int tmp;
  if (str[p] == 'D')
    tmp = f2[p].Down;
  else if (str[p] == 'U')
    tmp = f2[p].Up;
  else if (str[p] == 'L')
    tmp = f2[p].Left;
  else
    tmp = f2[p].Right;
  if (f2[p].Left != -1) f2[f2[p].Left].Right = f2[p].Right;
  if (f2[p].Right != -1) f2[f2[p].Right].Left = f2[p].Left;
  if (f2[p].Up != -1) f2[f2[p].Up].Down = f2[p].Down;
  if (f2[p].Down != -1) f2[f2[p].Down].Up = f2[p].Up;
  if (ans1 == tot) ans2++;
  if (ans1 < tot) {
    ans1 = tot;
    ans2 = 1;
  }
  if (tmp != -1) dfs(tmp, tot + 1);
  return 0;
}
int work() {
  scanf("%d%d", &n, &m);
  getchar();
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) str[i * m + j] = getchar();
    getchar();
  }
  memset(f1, -1, sizeof(f1));
  memset(f2, -1, sizeof(f2));
  int k;
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < m; ++j) {
      int p = i * m + j;
      if (str[p] == '.') continue;
      {
        k = i + 1;
        while (str[k * m + j] == '.' && k < n) k++;
        if (k < n) {
          f1[p].Down = k * m + j;
          f1[k * m + j].Up = p;
        }
      }
      {
        k = i - 1;
        while (str[k * m + j] == '.' && k >= 0) k--;
        if (k >= 0) {
          f1[p].Up = k * m + j;
          f1[k * m + j].Down = p;
        }
      }
      {
        k = j - 1;
        while (str[i * m + k] == '.' && k >= 0) k--;
        if (k >= 0) {
          f1[p].Left = i * m + k;
          f1[i * m + k].Right = p;
        }
      }
      {
        k = j + 1;
        while (str[i * m + k] == '.' && k < m) k++;
        if (k < m) {
          f1[p].Right = i * m + k;
          f1[i * m + k].Left = p;
        }
      }
    }
  ans1 = ans2 = 0;
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < m; ++j)
      if (str[i * m + j] != '.') {
        for (int k = 0; k < 5001; ++k) f2[k] = f1[k];
        dfs(i * m + j, 1);
      }
  printf("%d %d\n", ans1, ans2);
  return 0;
}
int main() {
  work();
  return 0;
}
