#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
#define pb push_back
#define fr(i,n) for(int i=0;i<n;i++)
#define Fr(i,n) for(int i=0;i++<n;)
#define ifr(i,n) for(int i=n-1;i>=0;i--)
#define iFr(i,n) for(int i=n;i>0;i--)

struct modint{
    using i64=int_fast64_t;
    i64 a;
    static constexpr i64 MOD=1e9+7;
    constexpr modint():a(){}
    constexpr modint(i64 a_):a(a_%MOD){
        if(a<0) a+=MOD;
    }
    constexpr modint inv()const noexcept{
        i64 n=1,m=MOD-2,A=a;
        while(m){
            if(m&1)(n*=A)%=MOD;
            (A*=A)%=MOD;
            m>>=1;
        }
        modint y;
        y.a=n;
        return y;
    }
    constexpr bool operator==(const modint& x)const noexcept{
        return a==x.a;
    }
    constexpr bool operator!=(const modint& x)const noexcept{
        return a!=x.a;
    }
    constexpr modint operator+(const modint& x)const noexcept{
        modint y;
        y.a=a+x.a;
        if(y.a>=MOD) y.a-=MOD;
        return y;
    }
    constexpr modint operator-(const modint& x)const noexcept{
        modint y;
        y.a=a-x.a;
        if(y.a<0) y.a+=MOD;
        return y;
    }
    constexpr modint operator*(const modint& x)const noexcept{
        modint y;
        y.a=(a*x.a)%MOD;
        return y;
    }
    constexpr modint operator/(const modint& x)const noexcept{
        modint y;
        y.a=(a*x.inv().a)%MOD;
        return y;
    }
    constexpr modint& operator+=(const modint& x)noexcept{
        a+=x.a;
        if(a>=MOD) a-=MOD;
        return *this;
    }
    constexpr modint& operator-=(const modint& x)noexcept{
        a-=x.a;
        if(a<0) a+=MOD;
        return *this;
    }
    constexpr modint& operator*=(const modint& x)noexcept{
        (a*=x.a)%=MOD;
        return *this;
    }
    constexpr modint& operator/=(const modint& x)noexcept{
        (a*=x.inv().a)%=MOD;
        return *this;
    }
};
istream& operator>>(istream &in,modint& x)noexcept{
    static int_fast64_t a_;
    in>>a_;
    modint y(a_);
    x=y;
    return in;
}
ostream& operator<<(ostream &out,const modint& x)noexcept{
    out<<x.a;
    return out;
}
constexpr modint pwr(int_fast64_t a,int_fast64_t b)noexcept{
    modint _;
    int_fast64_t n=1,A=a;
    while(b){
        if(b&1) (n*=A)%=modint::MOD;
        (A*=A)%=modint::MOD;
        b>>=1;
    }
    _.a=n;
    return _;
}

template <int n> struct COMB{
    int_fast64_t fc[n],ifc[n],Bn[n];
    constexpr COMB():fc(),ifc(),Bn(){
        fc[0]=1;
        for(int i=1;i<n;++i){
            fc[i]=fc[i-1]*i%modint::MOD;
            Bn[i]=(Bn[i-1]*i+1)%modint::MOD;
        }
        int_fast64_t N=1,A=fc[n-1],b=modint::MOD-2;
        while(b){
            if(b&1) (N*=A)%=modint::MOD;
            (A*=A)%=modint::MOD;
            b>>=1;
        }
        ifc[n-1]=N;
        for(int i=n-1;i>=1;--i) ifc[i-1]=ifc[i]*i%modint::MOD;
    };
    modint operator()(int N,int R)const{
        if(N<0||R<0||N<R) return 0;
        return fc[N]*ifc[R]%modint::MOD*ifc[N-R];
    }
    modint operator[](int N)const{
        modint _;
        _.a=fc[N];
        return _;
    }
    modint operator()(int N)const{
        modint _;
        _.a=ifc[N];
        return _;
    }
};
constexpr COMB<1010> comb;

modint dp[1010][2][1010]={},dpc[1010]={},kari{};
int main(){
    ll n,num=1;
    bool f[1010];
    string s;
    cin>>n>>s;
    if(n==1&&s=="-"){
        cout<<(modint::MOD+1)/2<<" "<<0<<" "<<(modint::MOD+1)/2<<endl;
        return 0;
    }
    int q=0,r=n;
    n=-1;
    if(s[q]=='-') q++;
    if(s[q]=='-'){q++;n++;num++;}
    if(s[q]=='-'){cout<<"0 0 0"<<endl;return 0;}
    for(int i=q;i<r;i++){
        if(s[i]=='X'){
            if(num==0){cout<<"0 0 0"<<endl;return 0;}
            if(n>=0) f[n]=num-1;
            n++;num=0;
        }
        else{
            if(num>1){cout<<"0 0 0"<<endl;return 0;}
            num++;
        }
    }
    if(num==2) f[n++]=1;
    dpc[0]=1;
    fr(i,n){
        if(f[i]){
            fr(j,2){
                fr(k,2*n+2){
                    kari=modint(k*k+3*k+2).inv();
                    dp[i+1][j][0]+=dp[i][j][k]*kari;
                    dp[i+1][j][1]+=dp[i][j][k]*(modint(0)-kari);
                }
            }
            dp[i+1][1][0]+=dpc[i];
            dp[i+1][1][1]-=dpc[i];
        }
        else{
            fr(j,2){
                fr(k,2*n+2){
                    kari=modint(k+1).inv();
                    dp[i+1][j][0]+=dp[i][j][k]*kari;
                    dp[i+1][j][1]-=dp[i][j][k]*kari;
                    dp[i+1][j][k+2]+=dp[i][j][k]/(k*k+3*k+2);
                }
            }
            dp[i+1][1][1]+=dpc[i];
            dp[i+1][1][0]-=dpc[i];
            dpc[i+1]+=dpc[i];
        }
    }
    modint ans[3]={};
    fr(j,2){
        fr(k,2*n+2){
            ans[j]+=dp[n][j][k]*comb[k];
            ans[j+1]-=dp[n][j][k]*(comb[k]+comb.Bn[k]);
        }
    }
    kari=modint(2).inv();
    ans[0]+=dpc[n]*kari;
    ans[2]-=dpc[n]*kari;
    cout<<ans[0]<<" "<<ans[1]<<" "<<ans[2]<<endl;
}

Measured memory_bytes: 16256