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;
class Tree {
 private:
  int *buff;
  int sz;
  void nxt(int val, int &l, int &h, int &curr) {
    int mdl = (h - l) / 2;
    if (val <= mdl + l) {
      h = mdl + l;
      curr = curr * 2;
    } else {
      l = mdl + l + 1;
      curr = curr * 2 + 1;
    }
  }
  void del(int val, int l, int h, int curr) {
    while (true) {
      buff[curr]--;
      if (h - l > 0) {
        nxt(val, l, h, curr);
      } else {
        break;
      }
    }
  }
  void add(int val, int l, int h, int curr) {
    while (true) {
      buff[curr]++;
      if (h - l > 0) {
        nxt(val, l, h, curr);
      } else {
        break;
      }
    }
  }
  int findNext(int val, int l, int h, int curr) {
    if (buff[curr] == 0 || val > h) {
      return 1000000000;
    }
    if (buff[curr] == 1 && val < l && l == h) {
      return l;
    }
    int al = l, ah = h, ac = curr;
    int bl = l, bh = h, bc = curr;
    nxt(l, al, ah, ac);
    nxt(h, bl, bh, bc);
    return min(findNext(val, al, ah, ac), findNext(val, bl, bh, bc));
  }
  int findPrev(int val, int l, int h, int curr) {
    if (buff[curr] == 0 || val < l) {
      return -1000000000;
    }
    if (buff[curr] == 1 && val > l && l == h) {
      return l;
    }
    int al = l, ah = h, ac = curr;
    int bl = l, bh = h, bc = curr;
    nxt(l, al, ah, ac);
    nxt(h, bl, bh, bc);
    return max(findPrev(val, al, ah, ac), findPrev(val, bl, bh, bc));
  }

 public:
  void add(int val) { add(val, 0, sz, 1); }
  void del(int val) { del(val, 0, sz, 1); }
  int findNext(int val) { return findNext(val, 0, sz, 1); }
  int findPrev(int val) { return findPrev(val, 0, sz, 1); }
  Tree(int sz) {
    this->sz = sz;
    int tmp = 1;
    int kl = 1;
    while (tmp < sz) {
      tmp *= 2;
      kl++;
    }
    this->buff = new int[sz * kl + 1];
    memset(this->buff, 0, sizeof(int) * (sz * kl + 1));
  }
};
int n, m;
char **input;
Tree *h[5000];
Tree *v[5000];
int findRes(int x, int y) {
  if (x < 0 || x >= n || y < 0 || y >= m) {
    return 0;
  }
  h[x]->del(y);
  v[y]->del(x);
  int res = 1;
  if (input[x][y] == 'D') {
    res += findRes(v[y]->findNext(x), y);
  } else if (input[x][y] == 'U') {
    res += findRes(v[y]->findPrev(x), y);
  } else if (input[x][y] == 'L') {
    res += findRes(x, h[x]->findPrev(y));
  } else if (input[x][y] == 'R') {
    res += findRes(x, h[x]->findNext(y));
  }
  h[x]->add(y);
  v[y]->add(x);
  return res;
}
int main() {
  scanf("%d%d", &n, &m);
  input = new char *[n];
  for (int i = 0; i < n; i++) {
    input[i] = new char[m];
    for (int j = 0; j < m; j++) {
      char c = '=';
      while (!(c == '.' || c == 'D' || c == 'L' || c == 'R' || c == 'U')) {
        scanf("%c", &c);
      }
      input[i][j] = c;
    }
  }
  for (int i = 0; i < n; i++) {
    h[i] = new Tree(m + 1);
  }
  for (int i = 0; i < m; i++) {
    v[i] = new Tree(n + 1);
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (input[i][j] != '.') {
        h[i]->add(j);
        v[j]->add(i);
      }
    }
  }
  int best = 0;
  int count = 0;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      int newr = findRes(i, j);
      if (newr == best) {
        count++;
      } else if (newr > best) {
        count = 1;
        best = newr;
      }
    }
  }
  printf("%d %d\n", best, count);
  return 0;
}
