Hakone Ekiden is one of the Japanese New Year's traditions. In Hakone Ekiden, 10 runners from each team aim for the goal while connecting the sashes at each relay station. In the TV broadcast, the ranking change from the previous relay station is displayed along with the passing order of each team at the relay station. So, look at it and tell us how many possible passage orders for each team at the previous relay station. The number of possible transit orders can be very large, so answer by the remainder divided by 1,000,000,007.



Input

The input is given in the form:

> n
> c1
> c2
> ...
> cn
>

The number n (1 ≤ n ≤ 200) representing the number of teams is on the first line, and the ranking changes from the previous relay station in order from the first place on the following n lines. If it is'`U`', the ranking is up, if it is'`-`', the ranking is not changed) is written.

Output

Please output in one line by dividing the number of passages that could have been the previous relay station by 1,000,000,007.

Examples

Input

3
-
U
D


Output

1


Input

5
U
U
-
D
D


Output

5


Input

8
U
D
D
D
D
D
D
D


Output

1


Input

10
U
D
U
D
U
D
U
D
U
D


Output

608


Input

2
D
U


Output

0
#include<bits/stdc++.h>
using namespace std;
#define ALL(x) x.begin(),x.end()
#define rep(i,n) for(int i=0;i<(n);i++)
#define debug(v) cout<<#v<<":";for(auto x:v){cout<<x<<' ';}cout<<endl;
#define mod 1000000007
using ll=long long;
const int INF=1000000000;
const ll LINF=1001002003004005006ll;
int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};
// ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
template<class T>bool chmax(T &a,const T &b){if(a<b){a=b;return true;}return false;}
template<class T>bool chmin(T &a,const T &b){if(b<a){a=b;return true;}return false;}

struct IOSetup{
    IOSetup(){
        cin.tie(0);
        ios::sync_with_stdio(0);
        cout<<fixed<<setprecision(12);
    }
} iosetup;

template<typename T1,typename T2>
ostream &operator<<(ostream &os,const pair<T1,T2>&p){
    os<<p.first<<" "<<p.second;
    return os;
}

template<typename T>
ostream &operator<<(ostream &os,const vector<T>&v){
    for(int i=0;i<(int)v.size();i++) os<<v[i]<<(i+1==v.size()?"":" ");
    return os;
}

template<ll Mod>
struct ModInt{
    long long x;
    ModInt():x(0){}
    ModInt(long long y):x(y>=0?y%Mod:(Mod-(-y)%Mod)%Mod){}
    ModInt &operator+=(const ModInt &p){
        if((x+=p.x)>=Mod) x-=Mod;
        return *this;
    }
    ModInt &operator-=(const ModInt &p){
        if((x+=Mod-p.x)>=Mod)x-=Mod;
        return *this;
    }
    ModInt &operator*=(const ModInt &p){
        x=(int)(1ll*x*p.x%Mod);
        return *this;
    }
    ModInt &operator/=(const ModInt &p){
        (*this)*=p.inverse();
        return *this;
    }
    ModInt operator-()const{return ModInt(x);}
    ModInt operator+(const ModInt &p)const{return ModInt(*this)+=p;}
    ModInt operator-(const ModInt &p)const{return ModInt(*this)-=p;}
    ModInt operator*(const ModInt &p)const{return ModInt(*this)*=p;}
    ModInt operator/(const ModInt &p)const{return ModInt(*this)/=p;}
    ModInt operator==(const ModInt &p)const{return x==p.x;}
    ModInt operator!=(const ModInt &p)const{return x!=p.x;}
    ModInt inverse()const{
        int a=x,b=Mod,u=1,v=0,t;
        while(b>0){
            t=a/b;
            swap(a-=t*b,b);swap(u-=t*v,v);
        }
        return ModInt(u);
    }
    ModInt pow(long long n)const{
        ModInt ret(1),mul(x);
        while(n>0){
            if(n&1) ret*=mul;
            mul*=mul;n>>=1;
        }
        return ret;
    }
    friend ostream &operator<<(ostream &os,const ModInt &p){return os<<p.x;}
    friend istream &operator>>(istream &is,ModInt &a){long long t;is>>t;a=ModInt<Mod>(t);return (is);}
    static int get_mod(){return Mod;}
};
using mint=ModInt<mod>;
 
template<int MAX>
struct comcalc{
    vector<mint> fact,finv,inv;
    comcalc():fact(MAX),finv(MAX),inv(MAX){
        fact[0]=mint(1),fact[1]=mint(1),finv[0]=mint(1),finv[1]=mint(1),inv[1]=mint(1);
        for(int i=2;i<MAX;i++){
            fact[i]=fact[i-1]*mint(i);
            inv[i]=mint(0)-inv[mod%i]*(mint(mod/i));
            finv[i]=finv[i-1]*inv[i];
        }
    }
    mint com(int n,int k){
        if(n<k) return mint(0);
        if(n<0 or k<0) return mint(0);
        return fact[n]*(finv[k]*finv[n-k]);
    }
    mint fac(int n){
        return fact[n];
    }
    // 重複組み合わせ:n種類の物から重複を許し，k個選ぶ
    mint nHk(int n,int k){
        return com(n+k-1,k);
    }
    // 玉n区別，箱k区別，各箱1個以上O(k)
    mint F12_dis_dis_one(int n,int k){
        mint ret=1;
        for(int i=0;i<=k;i++){
            mint add=com(k,i)*(mint(i).pow(n));
            if((k-i)%2) ret-=add;
            else        ret+=add;
        }
        return ret;
    }
};
mint pow_mod(mint x,ll n){
    return x.pow(n);
}
mint inv_mod(mint x){
    return x.inverse();
}
// O(n)
mint fact_mod(ll n){
    mint ret=1;
    for(int i=2;i<=n;i++) ret*=mint(i);
    return ret;
}
// O(r)
mint comb_mod(ll n,ll r){
    if(r>n-r) r=n-r;
    if(r==0) return 1;
    mint a=1,b=mint(fact_mod(r)).inverse();
    for(int i=0;i<r;i++)a*=mint(n-i);
    return a*b;
}
 
const int MAX=4010000;
using cominit=comcalc<MAX>;

void hakone(){
    int n;cin>>n;
    vector<char> s;
    rep(i,n){
        char c;cin>>c;
        if(c!='-')s.push_back(c);
    }
    n=(int)s.size();
    
    mint dp[n+1][n+1];
    rep(i,n+1)rep(j,n+1)dp[i][j]=0;
    dp[0][0]=1;

    rep(i,n){
        rep(j,n){
            mint src=dp[i][j];
            // 空きと保留中の個数は一致．それはそう
            if(s[i]=='U'){
                // iを空き場所へ入れる
                // iを保留する
                dp[i+1][j]+=src*j;
                if(j+1<=n)dp[i+1][j+1]+=src;
            }else{
                // 保留したものを今見てる場所に入れ，iを保留
                // 保留したものを今見てる場所に入れ，iを空きへ入れる
                dp[i+1][j]+=src*j;
                if(j) dp[i+1][j-1]+=src*j*j;
            }
        }
    }
    cout<<dp[n][0]<<endl;
}

signed main(){
    hakone();
    return 0;
}

