description: You are given n dominoes. Each domino has a left and a right cell. Each cell can be colored either black or white. Some cells are already colored, while some aren't yet.
  
  The coloring is said to be valid if and only if it is possible to rearrange the dominoes in some order such that for each 1 ≤ i ≤ n the color of the right cell of the i-th domino is different from the color of the left cell of the ((i mod n)+1)-st domino. 
  
  Note that you can't rotate the dominoes, so the left cell always remains the left cell, and the right cell always remains the right cell.
  
  Count the number of valid ways to color the yet uncolored cells of dominoes. Two ways are considered different if there is a cell that is colored white in one way and black in the other. In particular, colorings BW WB and WB BW different (and both invalid).
  
  As this number can be very big, output it modulo 998 244 353.
  
  Input
  
  The first line of the input contains a single integer n (1 ≤ n ≤ 10^5) — the number of dominoes.
  
  The next n lines describe dominoes. Each line contains two characters which represent the left and the right cell. Character B means that the corresponding cell is black, character W means that the corresponding cell is white, and ? means that the cell is yet to be colored. 
  
  Output
  
  Print a single integer — the answer to the problem.
  
  Examples
  
  Input
  
  
  1
  ?W
  
  
  Output
  
  
  1
  
  
  Input
  
  
  2
  ??
  W?
  
  
  Output
  
  
  2
  
  
  Input
  
  
  4
  BB
  ??
  W?
  ??
  
  
  Output
  
  
  10
  
  Note
  
  In the first test case, there is only one domino, and we need the color of its right cell to be different from the color of its left cell. There is only one way to achieve this.
  
  In the second test case, there are only 2 such colorings:
  
  BB WW and WB WB.
solution: import java.io.*;
  import java.util.*;
  
  public class Main {
  
  	/**
  	 * @param args
  	 */
  	public static void main(String[] args) {
  		FastScanner fs=new FastScanner();
  		PrintWriter out = new PrintWriter(System.out);
  
  		/******  CODE STARTS HERE  *****/
  		//--------------------------------------------------------------------------------------------------------
  		
  			int n=fs.nextInt();
  			int f1=0, f2=0;
  			char[][] s = new char[n][2];
  			for(int i=0; i<n; i++)s[i]=fs.next().toCharArray();
  			
  			int cw=0, cb=0, emp=2, wl=0, bl=0, wr=0, br=0;
  			long cc = 1;
  			for(int i=0; i<n; i++) {
  				if(s[i][0]=='?' && s[i][1]=='?') {
  					cc = (cc*2)%998244353;
  					continue;
  				}
  				emp = 1;
  				
  				if(s[i][0] == s[i][1] && s[i][0]!='?')f1=1;
  				if(s[i][0]=='W') {
  					cw++;
  					wl=1;
  				}
  				else if(s[i][0]=='B') {
  					bl=1;
  					cb++;
  				}
  				if(s[i][1]=='W') {
  					cw++;
  					wr=1;
  				}
  				else if(s[i][1]=='B') {
  					cb++;
  					br=1;
  				}
  			}
  			if(n+n-cw-cb < 0 || cb>n || cw>n) {
  				System.out.println(0);
  				return;
  			}
  			
  			if((wl==1&&wr==1) || (bl==1&&br==1))f2=1;
  			
  			if(n+n-cw-cb == 0) {
  				if(f1==1 || f2==0)
  				System.out.println(1);
  				else System.out.println(0);
  				return;
  			}
  			
  			long ans = nCrModPFermat(n+n-cw-cb, n-cw, 998244353);
  
  //			System.out.println(ans);
  			
  			if(f1==1) {
  				System.out.println(ans);
  			}else if(f2==1) {
  				System.out.println((ans-cc)%998244353);
  			}else {
  				System.out.println(((ans-cc)%998244353+emp)%998244353);
  			}
  		out.close();
  	}
  	
  	
  	/* Iterative Function to calculate
      (x^y)%p in O(log y) */
      static long power(long x, int y, int p)
      {
   
          // Initialize result
          long res = 1;
   
          // Update x if it is more than or
          // equal to p
          x = x % p;
   
          while (y > 0) {
   
              // If y is odd, multiply x
              // with result
              if (y % 2 == 1)
                  res = (res * x) % p;
   
              // y must be even now
              y = y >> 1; // y = y/2
              x = (x * x) % p;
          }
   
          return res;
      }
   
      // Returns n^(-1) mod p
      static long modInverse(long n, int p)
      {
          return power(n, p - 2, p);
      }
   
      // Returns nCr % p using Fermat's
      // little theorem.
      static long nCrModPFermat(int n, int r,
                               int p)
      {
   
            if (n<r)
                return 0;
        // Base case
          if (r == 0)
              return 1;
   
          // Fill factorial array so that we
          // can find all factorial of r, n
          // and n-r
          long[] fac = new long[n + 1];
          fac[0] = 1;
   
          for (int i = 1; i <= n; i++)
              fac[i] = fac[i - 1] * i % p;
   
          return (fac[n] * modInverse(fac[r], p)
                  % p * modInverse(fac[n - r], p)
                  % p)
              % p;
      }
  	
  	
  	
  	
  	
  	
  	// A Lucas Theorem based solution to compute nCr % p
  
  	static class Lucas_Theorem_nCr_mod_P{
  	// Returns nCr % p. In this Lucas Theorem based program,
  	// this function is only called for n < p and r < p.
  		static int nCrModpDP(int n, int r, int p)
  		{
  			// The array C is going to store last row of
  			// pascal triangle at the end. And last entry
  			// of last row is nCr
  			int[] C=new int[r+1];
  		
  			C[0] = 1; // Top row of Pascal Triangle
  		
  			// One by constructs remaining rows of Pascal
  			// Triangle from top to bottom
  			for (int i = 1; i <= n; i++)
  			{
  				// Fill entries of current row using previous
  				// row values
  				for (int j = Math.min(i, r); j > 0; j--)
  		
  					// nCj = (n-1)Cj + (n-1)C(j-1);
  					C[j] = (C[j] + C[j-1])%p;
  			}
  			return C[r];
  		}
  		
  		// Lucas Theorem based function that returns nCr % p
  		// This function works like decimal to binary conversion
  		// recursive function. First we compute last digits of
  		// n and r in base p, then recur for remaining digits
  		static int nCrModpLucas(int n, int r, int p)
  		{
  		// Base case
  		if (r==0)
  			return 1;
  		
  		// Compute last digits of n and r in base p
  		int ni = n%p;
  		int ri = r%p;
  		
  		// Compute result for last digits computed above, and
  		// for remaining digits. Multiply the two results and
  		// compute the result of multiplication in modulo p.
  		return (nCrModpLucas(n/p, r/p, p) * // Last digits of n and r
  				nCrModpDP(ni, ri, p)) % p; // Remaining digits
  		}
  		
  		// Driver program
  		public static void main(String[] args)
  		{
  			int n = 33, r = 8, p = (int)1e9+7;
  			System.out.println("Value of nCr % p is "+nCrModpLucas(n, r, p));
  		}
  		}
  		// This code is contributed by Rahul_Trivedi
  
      
  	//******  CODE ENDS HERE  *****
  	//----------------------------------------------------------------------------------------------------------------
  	
  	static void sort(int[] a) {
  		ArrayList<Integer> l=new ArrayList<>();
  		for (int i:a) l.add(i);
  		Collections.sort(l);
  		for (int i=0; i<a.length; i++) a[i]=l.get(i);
  	}
  	
  	
  	//----------- FastScanner class for faster input---------------------------
  	static class FastScanner {
  		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
  		StringTokenizer st=new StringTokenizer("");
  		String next() {
  			while (!st.hasMoreTokens())
  				try {
  					st=new StringTokenizer(br.readLine());
  				} catch (IOException e) {
  					e.printStackTrace();
  				}
  			return st.nextToken();
  		}
  		
  		int nextInt() {
  			return Integer.parseInt(next());
  		}
  		int[] readArray(int n) {
  			int[] a=new int[n];
  			for (int i=0; i<n; i++) a[i]=nextInt();
  			return a;
  		}
  		long nextLong() {
  			return Long.parseLong(next());
  		}
  	}
  }