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

template <typename A, typename B>
string to_string(pair<A, B> p);
 
template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p);
 
template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p);
 
string to_string(const string& s) {
  return '"' + s + '"';
}
 
string to_string(const char* s) {
  return to_string((string) s);
}
 
string to_string(bool b) {
  return (b ? "true" : "false");
}
 
string to_string(vector<bool> v) {
  bool first = true;
  string res = "{";
  for (int i = 0; i < static_cast<int>(v.size()); i++) {
    if (!first) {
      res += ", ";
    }
    first = false;
    res += to_string(v[i]);
  }
  res += "}";
  return res;
}
 
template <size_t N>
string to_string(bitset<N> v) {
  string res = "";
  for (size_t i = 0; i < N; i++) {
    res += static_cast<char>('0' + v[i]);
  }
  return res;
}
 
template <typename A>
string to_string(A v) {
  bool first = true;
  string res = "{";
  for (const auto &x : v) {
    if (!first) {
      res += ", ";
    }
    first = false;
    res += to_string(x);
  }
  res += "}";
  return res;
}
 
template <typename A, typename B>
string to_string(pair<A, B> p) {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}
 
template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p) {
  return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")";
}
 
template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p) {
  return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")";
}
 
void debug_out() { cerr << endl; }
 
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  cerr << " " << to_string(H);
  debug_out(T...);
}
#ifdef LOCAL
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif

#define fi first
#define se second
#define pb push_back
#define mod(n,k) ( ( ((n) % (k)) + (k) ) % (k))
#define forn(i,a,b) for(int i = a; i < b; i++)
#define forr(i,a,b) for(int i = a; i >= b; i--)
#define all(x) (x).begin(), (x).end()

typedef long long ll;
typedef long double ld;
typedef pair<int,int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;

const ll mod = 1e9+7;
int sum(int a, int b){return (a+b) % mod;}
int sub(int a, int b){return (a + mod - b) % mod;}
int mul(int a, int b){return (1ll * a * b) % mod;}
int power(int a,int b){
	int res = 1;
	while(b){
		if(b&1)res = mul(res,a);
		b >>= 1;
		a = mul(a,a);
	}
	return res;
}

const int maxn = 400000+10;
vi graph[maxn];
int N,M,seen[maxn];

int dfs(int u,int p,int &ciclo){
	int res = 1;
	seen[u] = 1;
	int cnt = 0;
	for(auto &v : graph[u]){
		if(v == u)ciclo = 1;
		if(v == p){
			cnt++;
			continue;
		}
		if(!seen[v]){
			res += dfs(v,u,ciclo);
		}else{
			ciclo = 1;
		}
	}
	if(cnt > 1){
		ciclo = 1;
	}
	return res;
}
int main(){
	ios_base::sync_with_stdio(0); cin.tie(0);
	cin >> N;
	forn(i,0,N){
		int u,v; cin >> u >> v; u--; v--;
		graph[u].pb(v);
		graph[v].pb(u);
	}
	int res = 0;
	forn(i,0,maxn){
		if(seen[i])continue;
		int ciclo = 0;
		int cnt = dfs(i,-1,ciclo);
		if(ciclo) res += cnt;
		else res += cnt-1;
		
	}
	cout << res << '\n';
	return 0;
}
/*
__builtin_mul_overflow(x,y,&x)
-fsplit-stack
*/

#include <bits/stdc++.h>

#define debug(var)  do{std::cout << #var << " :";std::cout << std::endl;view(var);}while(0)
template<typename T> void view(T e){ std::cout << e << std::endl;}
template<typename T> void view(const std::vector<T>& v){ int c = v.size(); std::cout << "{"; for(const auto& e : v){ std::cout << e; if (--c) std::cout << ", "; } std::cout << "}" << std::endl; }
template<typename T, typename U> void view(const std::pair<T, U>& v){ std::cout << v.first << ", " << v.second << std::endl; }
template<typename T> void view(const std::set<T>& v){ int c = v.size(); std::cout << "{"; for(const auto& e : v){ std::cout << e; if (--c) std::cout << ", "; } std::cout << "}" << std::endl; }
template<typename T, typename U> void view(const std::map<T, U>& v){ std::cout << "{" << std::endl; for(const std::pair<T, U>& e : v){ std::cout << e.first << ", " << e.second << std::endl; } std::cout << "}" << std::endl; }
template<typename T> void view(const std::vector<std::vector<T> >& vv){ std::cout << "{" << std::endl; for(const auto& v : vv){ view(v); } std::cout << "}" << std::endl; }

using namespace std;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
typedef long long ll;
typedef pair<int, int> pii;
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; }
const long long INF = 1LL << 60;
// const long long MOD = 1000000007;
const double PI = acos(-1);

const long long MOD = 998244353;

int H, W;
vector<string> field;

bool is_valid_move(int h, int w) {
    if (h < 0 || h >= H || w < 0 || w >= W) return false;
    return true;
}

int main() {
    cin >> H >> W;
    field.resize(H);
    rep(i, H) cin >> field[i];

    ll res = 1;

    bool flag = false;
    
    for (int h = 1; h < H; h++) {
        int tmp = h;
        int w = 0;
        int p;
        if (field[h][w] == '.') p = 0;
        else if (field[h][w] == 'R') p = 1;
        else p = 2;

        while (is_valid_move(tmp - 1, w + 1)) {
            tmp--; w++;
            if (field[tmp][w] == 'B') {
                if (p == 1) {
                    res = 0;
                    flag = true;
                    break;
                }
                p = 2;
            }

            if (field[tmp][w] == 'R') {
                if (p == 2) {
                    res = 0;
                    flag = true;
                    break;
                }
                p = 1;
            }
        }

        if (flag) break;

        if (p == 0) {
            res *= 2;
            res %= MOD;
        }
    }

    for (int w = 1; w < W - 1; w++) {
        int tmp = w;
        int h = H - 1;
        int p;
        if (field[h][w] == '.') p = 0;
        else if (field[h][w] == 'R') p = 1;
        else p = 2;

        while (is_valid_move(h - 1, tmp + 1)) {
            tmp++; h--;
            if (field[h][tmp] == 'B') {
                if (p == 1) {
                    res = 0;
                    flag = true;
                    break;
                }
                p = 2;
            }

            if (field[h][tmp] == 'R') {
                if (p == 2) {
                    res = 0;
                    flag = true;
                    break;
                }
                p = 1;
            }
        }

        if (flag) break;

        if (p == 0) {
            res *= 2;
            res %= MOD;
        }
    }

    if (field[0][0] == '.') {
        res *= 2;
        res %= MOD;
    }

    if (field[H - 1][W - 1] == '.') {
        res *= 2;
        res %= MOD;
    }

    cout << res << endl;
}