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

import java.io.*;
import java.util.StringTokenizer;


public class Main {
    static final int NULL = -1;
    static int n, m;
    static char[] grid[];
    static Node[][] links;

    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        n = sc.nextInt();
        m = sc.nextInt();
        grid = new char[n][];
        for (int i = 0; i < n; i++)
            grid[i] = sc.next().toCharArray();
        preprocessNext();
        int max = 0, cnt = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (grid[i][j] == '.') continue;
                for (int x = 0; x < n; x++)
                    for (int y = 0; y < m; y++)
                        if (links[x][y] != null) links[x][y].reset();
                int c = move(links, i, j);
                if (c == max) cnt++;
                else if (c > max) {
                    cnt = 1;
                    max = c;
                }
            }
        }
        out.println(max + " " + cnt);
        out.flush();
        out.close();
    }

    static int move(Node[][] links, int starti, int startj) {
        int ans = 0;
        Node cur = links[starti][startj];
        while (cur != null) {
            ans++;
            cur.delete();
            cur = cur.setNext();
        }
        return ans;
    }


    static void preprocessNext() {
        int[][][] next = new int[4][n][m];
        for (int i = 0; i < n; i++) {
            int last = NULL;
            for (int j = m - 1; j >= 0; j--) {
                if (grid[i][j] == '.') continue;
                next[1][i][j] = last;
                last = j;
            }
            last = NULL;
            for (int j = 0; j < m; j++) {
                if (grid[i][j] == '.') continue;
                next[0][i][j] = last;
                last = j;
            }
        }
        for (int j = 0; j < m; j++) {
            int last = NULL;
            for (int i = 0; i < n; i++) {
                if (grid[i][j] == '.') continue;
                next[2][i][j] = last;
                last = i;
            }
            last = NULL;
            for (int i = n - 1; i >= 0; i--) {
                if (grid[i][j] == '.')
                    continue;
                next[3][i][j] = last;
                last = i;
            }
        }
        links = constructLinks(next);
    }

    static Node[][] constructLinks(int[][][] next) {
        Node[][] ans = new Node[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (grid[i][j] == '.') continue;
                ans[i][j] = new Node(i, j);
            }
        }
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (grid[i][j] == '.') continue;
                if (next[0][i][j] != NULL)
                    ans[i][j].oleft = ans[i][next[0][i][j]];
                if (next[1][i][j] != NULL)
                    ans[i][j].oright = ans[i][next[1][i][j]];
                if (next[2][i][j] != NULL)
                    ans[i][j].oup = ans[next[2][i][j]][j];
                if (next[3][i][j] != NULL)
                    ans[i][j].odown = ans[next[3][i][j]][j];
            }
        }

        return ans;
    }

    static class Node {
        Node oleft, oright, oup, odown;
        Node left, right, up, down;
        int i, j;
        char dir;

        public Node(int i, int j) {
            this.i = i;
            this.j = j;
            this.dir = grid[i][j];
        }

        void delete() {
            if (left != null) left.right = right;
            if (right != null) right.left = left;
            if (down != null) down.up = up;
            if (up != null) up.down = down;

        }

        Node setNext() {
            if (dir == 'R') return right;
            if (dir == 'L') return left;
            if (dir == 'U') return up;
            return down;
        }

        void reset() {
            left = oleft;
            right = oright;
            up = oup;
            down = odown;
        }
    }

    static class Scanner {
        StringTokenizer st;
        BufferedReader br;

        public Scanner(InputStream system) {
            br = new BufferedReader(new InputStreamReader(system));
        }

        public String next() throws IOException {
            while (st == null || !st.hasMoreTokens()) st = new StringTokenizer(br.readLine());
            return st.nextToken();
        }

        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }


    }

}