using System;
using System.Collections.Generic;//list用
using System.Text.RegularExpressions;//正規表現用
using System.Text;//StringBuilder用
using System.Collections;//ハッシュテーブル用
using System.Linq;


class Program
{
    Hashtable ht = new Hashtable();
    static List<char> s = new List<char>();
    static decimal result;
    static int N;
    StringBuilder strresult= new StringBuilder("");//Append(str ○○)関数で文字を追加していく



    static void Main()
    {
        Modular mo = new Modular(1);//素数で割った余りを出せで使う★使い方：Modular型で宣言すると、その時点でのその素数で割った余りを保持する変数になる（powべき乗、Fac累乗、nCr組み合わせも関数として存在）カッコ内が初期値
        //Node no = new Node<>();//UnionFind★Find関数で根っこの値を返す（根っこの値が一緒なら同グループ）、Unite関数で二つの木をくっつける
        //Permutation pe = new Permutation<>();//配列＆リストを並べ替えた場合の全ケースを出力★All関数でリスト形式で返す。
        //Treap tr = new Treap<>();//平衡二分木★Insert()関数で挿入、FindIndex()関数で該当する大きさの物が入るべき配列番号を返す。
        // delegate int CFunc();//下関数に使うデリゲータ。コイツと同じ引数と戻り値で関数作って、下の評価式の部分に関数名を入れる。
        //PriorityQueue pr = new PriorityQueue<>(評価式);//優先度付キュー★Enqueue()で格納、Dequeue()で取りだし。引数は評価式（大と小のどちらが優先か）。
        Read1();
        Read2(2*N);
      int count=0;
      int[] LR=new int[2*N];
      bool flag=false;
if(s[0]=='W' || s[2*N-1]=='W'){Console.WriteLine("0");return;}
for(int i=0;i<2*N;i++){
  if(i>0){
  if(flag){if(s[i]==s[i-1]){flag=false;}}else{
  if(s[i]==s[i-1]){flag=true;}
  }}
      if(flag==false){count++;}else{LR[i]=1;}
}         
      if(s[2*N-1]==0){Console.WriteLine("0");return;}
      if(count==N){
       Modular c = new Modular(1);
        int d=0;
        for(int i=0;i<2*N;i++){
        if(LR[i]==0){d++;}else{c*=d;d--;}
        }
        
        
Modular a = new Modular(1);
        for(int j=1;j<=N;j++){a*=j;}
        mo*=a*c;
        result=(decimal)mo;
        Console.WriteLine(result.ToString());
      }
      else{
      Console.WriteLine("0");
      }
    }


    static void Read1()
    {
        string tmp = Console.ReadLine();
        N = int.Parse(tmp);
    }

    static void Read2(int kosuu)
    {
        string tmp = Console.ReadLine();
        for (int i = 0; i < kosuu; i++) { s.Add(tmp[i]); }
    }


    static long Gcd(long a, long b)
    {
        var v = new[] { a, b };
        while (v[1] != 0) { v = new[] { v[1], v[0] % v[1] }; }
        return v[0];
    }

    static long Lcm(long a, long b)
    {
        return a / Gcd(a, b) * b;
    }


}

class Modular
{
    private const int M = 1000000007;//素数
    private long value;
    public Modular(long value) { this.value = value; }
    public static implicit operator Modular(long a)
    {
        var m = a % M;
        return new Modular((m < 0) ? m + M : m);
    }
    public static Modular operator +(Modular a, Modular b)
    {
        return a.value + b.value;
    }
    public static Modular operator -(Modular a, Modular b)
    {
        return a.value - b.value;
    }
    public static Modular operator *(Modular a, Modular b)
    {
        return a.value * b.value;
    }
    private static Modular Pow(Modular a, int n)
    {
        switch (n)
        {
            case 0:
                return 1;
            case 1:
                return a;
            default:
                var p = Pow(a, n / 2);
                return p * p * Pow(a, n % 2);
        }
    }
    public static Modular operator /(Modular a, Modular b)
    {
        return a * Pow(b, M - 2);
    }
    private static readonly List<int> facs = new List<int> { 1 };
    private static Modular Fac(int n)
    {
        for (int i = facs.Count; i <= n; ++i)
        {
            facs.Add((int)(Math.BigMul(facs.Last(), i) % M));
        }
        return facs[n];
    }
    public static Modular Ncr(int n, int r)
    {
        return (n < r) ? 0
        : (n == r) ? 1
        : Fac(n) / (Fac(r) * Fac(n - r));
    }
    public static explicit operator int(Modular a)
    {
        return (int)a.value;
    }
}

Measured memory_bytes: 18192