#include<bits/stdc++.h>
using namespace std;

void solution()
{
  int h, w; cin >> h >> w;
  long long output = 1;
  int values[h + w][3] = {};
  for(int i = 0; i < h; i++)
  {
    string s; cin >> s;
    for(int j = 0; j < w; j++)
    {
      if(s[j] == '.')
      {values[i + j][0]++;}
      else if(s[j] == 'R')
      {values[i + j][1]++;}
      else
      {values[i + j][2]++;}
    }
  }
  for(int i = 0; i < h + w; i++)
  {
    if(values[i][0] && values[i][1] == 0 && values[i][2] == 0)
    {output *= 2;}
    else if(values[i][1] && values[i][2])
    {output *= 0;}
    output %= 998244353;
  }
  cout << output << endl;
  return;
}
int main()
{
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  int count, counter = 0;
  count = 1;
  while(counter++ < count)
  {solution();}
  return 0;
}

#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef long double db;
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
template <typename T>
using ordered_multiset = tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>;
template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
#define pll pair<ll,ll>
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define ub(v,val) upper_bound(v.begin(),v.end(),val)
#define np(str) next_permutation(str.begin(),str.end())
#define lb(v,val) lower_bound(v.begin(),v.end(),val)
#define sortv(vec) sort(vec.begin(),vec.end())
#define rev(p) reverse(p.begin(),p.end());
#define v vector
#define len length()
#define repc(i,s,e) for(ll i=s;i<e;i++)
#define fi first
#define se second
#define mset(a,val) memset(a,val,sizeof(a));
#define mt make_tuple
#define repr(i,n) for(i=n-1;i>=0;i--)
#define rep(i,n) for(i=0;i<n;i++)
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define at(s,pos) *(s.find_by_order(pos))
#define set_ind(s,val) s.order_of_key(val)
long long int M = 1e9 + 7 ;
long long int inf = 9 * 1e18;
const double PI = acos(-1);
//CLOCK
ll begtime = clock();
#define time() cout << "\n\nTime elapsed: " << (clock() - begtime)*1000/CLOCKS_PER_SEC << " ms\n\n";
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
//CLOCK ENDED
ll n, m;
// modular exponentiation
ll binpow(ll val, ll deg)
{
	if (deg < 0)
		return 0;
	if (!deg)
		return 1 % M;
	if (deg & 1)
		return binpow(val, deg - 1) * val % M;
	ll res = binpow(val, deg >> 1);
	return (res * res) % M;
}
//binomial
ll modinv(ll n) {
	return binpow(n, M - 2);
}

ll dp[3005][3005], ways[3005][3005];

int main() {
	// your code goes here
	IOS;
#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	ll i, j, t, k, x, y, z, N;

	//dp[i][j] denotes ith index tak aur j groups

	//ways[i][j] sum%i==j


	mset(dp, 0);
	mset(ways, 0);

	dp[0][0] = 1;

	ll sum = 0;

	ways[1][0] = 1;
	cin >> n;
	ll a[n];
	rep(i, n) cin >> a[i];

	rep(i, n) {
		sum += a[i];
		repr(j, n) {
			ll rem = sum % (j + 1);
			(dp[i + 1][j + 1] += ways[j + 1][rem]) %= M;
			(ways[j + 2][sum % (j + 2)] += dp[i + 1][j + 1]) %= M;
		}
	}
	// rep(i, n + 1) {
	// 	rep(j, n + 1) {
	// 		debug(i, j, dp[i][j]);
	// 	}
	// }
	ll ans = 0;
	for (i = 1; i <= n; i++) (ans += dp[n][i]) %= M;
	cout << ans;

	return 0;



}














