#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
#define inf 0x7fffffff
//#define ll long long
#define int long long
//#define double long double
#define re register int
#define void inline void
#define eps 1e-8
//#define mod 1e9+7
#define ls(p) p<<1
#define rs(p) p<<1|1
#define pi acos(-1.0)
#define pb push_back
#define P pair < int , int > 
using namespace std;
const int mod=998244353;
const int M=5e6;
const int N=2*1e5+5;//?????????? 4e8
int n,m;
char s[505][505];
int ans,flag;
int op,ret;
int power(int a,int b)
{
	int sum=1;
	while(b)
	{
		if(b&1)  sum=sum*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	return sum;
}
void solve()
{
	cin>>n>>m;
	for(re i=1;i<=n;i++)  scanf("%s",s[i]+1);
//	for(re i=1;i<=n;i++)  for(re j=1;j<=m;j++)  if(s[i][j]=='.')  op=1;
//	if(!op)  ans++;
	for(re i=1;i<=n;i++)
	{
		int x=i,y=1;
		int red=0,blue=0,cnt=0;
		while(x>=1&&y<=m)
		{
			if(s[x][y]=='.')  cnt++;
			if(s[x][y]=='R')  red=1;
			if(s[x][y]=='B')  blue=1;
			x--,y++;
		}
		if(red==1&&blue==1)  flag=1;
		else if((red==1&&blue==0)||(red==0&&blue==1))
		{
			
//			if(cnt)  ans=(ans+1)%mod;
		}  
		else
		{
			if(cnt)  ret++;
		}
	}
	for(re i=1;i<=m;i++)
	{
		if(i==1)  continue;
		int x=n,y=i;
		int red=0,blue=0,cnt=0;
		while(x>=1&&y<=m)
		{
			if(s[x][y]=='.')  cnt++;
			if(s[x][y]=='R')  red=1;
			if(s[x][y]=='B')  blue=1;
			x--,y++;
		}
		if(red==1&&blue==1)  flag=1;
		else if((red==1&&blue==0)||(red==0&&blue==1))
		{
//			if(cnt)  ans=(ans+1)%mod;
		}
		else
		{
			if(cnt)  ret++;
		}
	}
	ans=(ans+power(2,ret))%mod;
	if(flag)  ans=0;
	cout<<ans<<endl;
}
signed main()
{
    int T=1;
//    cin>>T;
    for(int index=1;index<=T;index++)
    {
        solve();
//        puts("");
    }
    return 0;
}
/*

#((((#

*/ 
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
template<class T> using vc = vector<T>;
template<class T> using vvc = vc<vc<T>>;
template<class T> using vvvc = vc<vvc<T>>;
template<class T> using vvvvc = vvc<vvc<T>>;
template<class T> using PQ = priority_queue<T>;
template<class T> using invPQ = priority_queue<T, vector<T>, greater<T>>;
using IP = pair<int, int>;
using LP = pair<ll, ll>;
#define all(x) begin(x), end(x)
#define rep(i, n) for (int i = 0; (i) < (int)(n); i++)
#define rep3(i, m, n) for (int i = (m); (i) < (int)(n); i++)
#define repr(i, n) for (int i = (n) - 1; (i) >= 0; i--)
#define rep3r(i, m, n) for (int i = (n) - 1; (i) >= (int)(m); i--)
template<class T> inline bool chmax(T & a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T & a, T b) { if (a > b) { a = b; return 1; } return 0; }
constexpr int INF = 1070000000;

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);

    int R, C;
    cin >> R >> C;
    vvc<int> A(R, vc<int>(C-1)), B(R-1, vc<int>(C));
    rep (i, R) rep (j, C-1) cin >> A[i][j];
    rep (i, R-1) rep (j, C) cin >> B[i][j];

    invPQ<tuple<int, int, int, int>> que;
    que.push({0, 0, 0, 1});
    vvvc<int> dist(R, vvc<int>(C, vc<int>(2, INF)));
    dist[0][0][1] = 0;
    while (!que.empty()) {
        while (!que.empty()) {
            int d, r, c, t;
            tie(d, r, c, t) = que.top();
            que.pop();
            if (d > dist[r][c][t]) continue;
            if (c < C-1) if (chmin(dist[r][c+1][1], d + A[r][c])) que.push({ dist[r][c+1][1], r, c+1, 1 });
            if (c > 0) if (chmin(dist[r][c-1][1], d + A[r][c-1])) que.push({ dist[r][c-1][1], r, c-1, 1 });
            if (r < R-1) if (chmin(dist[r+1][c][1], d + B[r][c])) que.push({ dist[r+1][c][1], r+1, c, 1 });
            if (r > 0) if (chmin(dist[r-1][c][0], d + t + 1)) que.push({ dist[r-1][c][0], r-1, c , 0 });
        }
    }

    cout << dist[R-1][C-1][1] << endl;
}