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>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#define rep(i, a, b) for(int i=(a); i<(b); i++)
#define repi(i, a, b) for(int i=(a); i>(b); i--)
#define db(x) (cerr << #x << ": " << (x) << '\n')
#define sync ios_base::sync_with_stdio(false), cin.tie(NULL)
#define tests(t) int t; cin >> t; while(t--)
#define iceil(n, x) (((n) + (x) - 1) / (x))
#define ll long long
#define gcd __gcd
#define pb push_back
#define pf push_front
#define pob pop_back
#define pof pop_front
#define sz size()
#define all(v) (v).begin(), (v).end()
#define uni(v) sort(all(v)); (v).erase(unique(all(v)), (v).end());
#define pii pair<int, int>
#define vi vector<int>
#define vpii vector<pii>
#define vvi vector<vi>
#define fi first
#define se second
#define umap unordered_map
#define uset unordered_set
#define pqueue priority_queue
#define si(a) scanf("%d", &a)
#define sll(a) scanf("%lld", &a)
#define bitcount(x) __builtin_popcount(x)
#define cps CLOCKS_PER_SEC
#define PI acos(-1.0)
#define EPS 1e-9
#define mod 1000000007
#define MOD 1000000007
#define N 15
using namespace std;

#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
    cerr << name << " : " << arg1 << '\n';
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
    const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}

template<typename T>
using minpq = priority_queue<T, vector<T>, greater<T>>;

template<typename T>
using maxpq = priority_queue<T>;

//All indexing is 0-based
using namespace __gnu_pbds;
typedef tree<int, null_type, less<int>, rb_tree_tag,
             tree_order_statistics_node_update> ordered_set;
//methods: find_by_order(k); & order_of_key(k);
//To make it an ordered_multiset, use pairs of (value, time_of_insertion)
//to distinguish values which are similar.

template<class key, class value, class cmp = std::less<key>>
using ordered_map = tree<key, value, cmp, rb_tree_tag, tree_order_statistics_node_update>;
//ordered_map<int, int> my_map;

//Returns no. of values x for which ceil(n / x) == y (y must be > 1).
inline ll CC(ll n, ll y) { return iceil(n, y-1) - iceil(n, y); }

//Returns no. of values x for which floor(n / x) == y
inline ll FF(ll n, ll y) { return n / y - n / (y+1); }

//a and b are assumed to be taken modulo p
inline int add(int a, int b, int p = mod){ int c = a + b; if(c >= p) c -= p; return c; }
inline int sub(int a, int b, int p = mod){ int c = a - b; if(c < 0) c += p; return c; }
inline int mul(int a, int b, int p = mod){ return (a * 1ll * b) % p; }

// #define int ll
#define trace(...) 42

int n, m;
vector<string> grid;
#define U fi.fi
#define L fi.se
#define D se.fi
#define R se.se
vector<vector<pair<pii, pii>>> where, wtemp;

int solve(int i, int j) {
    static int cnt; cnt++; if(cnt > 100) exit(0);
    if(i == -1 || j == -1) return 0;
    if(grid[i][j] == '.') return 0;
    trace(1, i, j);
    
    int u, d, l, r;
    tie(u, l) = wtemp[i][j].fi;
    tie(d, r) = wtemp[i][j].se;

    if(u != -1) wtemp[u][j].D = d;
    if(d != -1) wtemp[d][j].U = u;
    if(l != -1) wtemp[i][l].R = r;
    if(r != -1) wtemp[i][r].L = l;

    if(grid[i][j] == 'U') {
        trace('U');
        int k = wtemp[i][j].U; 
        wtemp[i][j].U = -1;
        return 1 + solve(k, j);
    }
    else if(grid[i][j] == 'L') {
        trace('L');
        int k = wtemp[i][j].L;
        wtemp[i][j].L = -1;
        return 1 + solve(i, k);
    }
    else if(grid[i][j] == 'D') {
        trace('D');
        int k = wtemp[i][j].D;
        wtemp[i][j].D = -1;
        return 1 + solve(k, j);
    }
    else if(grid[i][j] == 'R') {
        trace('R');
        int k = wtemp[i][j].R;
        wtemp[i][j].R = -1;
        return 1 + solve(i, k);
    }
}

void solve() {
    int ans = 0, cnt = 1;
    rep(i, 0, n) {
        rep(j, 0, m) {
            if(grid[i][j] != '.') {
                trace(0, i, j);
                // rtemp = rows, ctemp = columns;
                wtemp = where;
                int kk = solve(i, j);
                if(kk > ans) ans = kk, cnt = 0;
                if(kk == ans) cnt++;
                trace(i, j, kk);
            }
        }
    }
    cout << ans << ' ' << cnt << '\n';
}

void prep() {
    // rows.resize(n);
    // columns.resize(m);
    where.resize(n, vector<pair<pii, pii>>(m, {{-1, -1}, {-1, -1}}));
    rep(i, 0, n) {
        rep(j, 1, m) {
            if(grid[i][j-1] != '.') where[i][j].L = j-1;
            else                    where[i][j].L = where[i][j-1].L;
        }
    }

    rep(i, 0, n) {
        repi(j, m-2, -1) {
            if(grid[i][j+1] != '.') where[i][j].R = j+1;
            else                    where[i][j].R = where[i][j+1].R;
        }
    }

    rep(j, 0, m) {
        rep(i, 1, n) {
            if(grid[i-1][j] != '.') where[i][j].U = i-1;
            else                    where[i][j].U = where[i-1][j].U;
        }
    }

    rep(j, 0, m) {
        repi(i, n-2, -1) {
            if(grid[i+1][j] != '.') where[i][j].D = i+1;
            else                    where[i][j].D = where[i+1][j].D;
        }
    }
}

main()
{   
    #ifndef ONLINE_JUDGE
        freopen("/home/tarun/Desktop/input.txt", "r", stdin);
     // freopen("/home/tarun/Desktop/output.txt", "w", stdout);
    #endif
    sync;
    clock_t clk = clock();
    cerr << "I will return...\n";

    cin >> n >> m;
    rep(i, 0, n) {
        string s; cin >> s;
        grid.pb(s);
    }

    prep();
    solve();

    // rep(i, 0, n) {
    //     rep(j, 0, m) {
    //         cerr << "{" << where[i][j].L << ' ' << where[i][j].R << ' '
    //              << where[i][j].U << ' ' << where[i][j].D << "}\n";
    //     }
    // }
    
    cerr << "...don't you ever hang your head.\n";
    cerr << "Time (in ms): " << double(clock() - clk) * 1000.0 / cps << '\n';
}

//Compile using:
//g++ -o filename.exe --std=c++11 filename.cpp
//Use -D CP for defining a macro CP in the local environment





