#include<bits/stdc++.h>
#define REP(i,n) for(int i=0,i##_len=(n);i<i##_len;++i)
#define rep(i,a,b) for(int i=int(a);i<int(b);++i)
#define All(x) (x).begin(),(x).end()
using namespace std;
typedef long long ll;
constexpr ll mod=1e9+7;
class mint {
 private:
  ll _num,_mod=mod;
  mint set(ll num){ 
      _num = num ;
      if(_num<0){
          if(_num>=-mod)_num=mod+_num;
          else _num=mod-(-_num)%mod;
      }
      else if(_num>=mod) _num%=mod;
      return *this;
  }
  
 public:
  mint(){ _num = 0; }
  mint(ll num){
      _num = num;
      if(_num<0){
          if(_num>=-mod)_num=mod+_num;
          else _num=mod-(-_num)%mod;
      }
      else if(_num>=mod) _num%=mod;
  }
  mint(ll num,ll M){
      _mod=M;
      _num=num;
      if(_num<0){
          if(_num>=-mod)_num=mod+_num;
          else _num=mod-(-_num)%mod;
      }
      else if(_num>=mod) _num%=mod;
  }
  mint(const mint &cp){_num=cp._num;_mod=cp._mod;}
  ll imod(){
    ll n=_mod-2;
    ll ans = 1,x=_num;
    while(n != 0){
        if(n&1) ans = ans*x%mod;
        x = x*x %mod;
        n = n >> 1;
    }
    return ans;
  }
  mint operator+ (const mint &x){ return mint(_num + x._num , _mod); }
  mint operator- (const mint &x){ return mint(_num - x._num , _mod);}
  mint operator* (const mint &x){ return mint(_num * x._num , _mod); }
  mint operator/ (mint x){ return mint(_num * x.imod() , _mod);}
  
  mint operator+=(const mint &x){ return set(_num + x._num); }
  mint operator-=(const mint &x){ return set(_num - x._num); }
  mint operator*=(const mint &x){ return set(_num * x._num); }
  mint operator/=(mint x){ return set(_num * x.imod());}

  mint operator= (const ll x){ return set(x); }
  mint operator+ (const ll x){return *this + mint(x,_mod); }
  mint operator- (const ll x){ return *this - mint(x,_mod); }
  mint operator* (const ll x){ return *this * mint(x,_mod); }
  mint operator/ (const ll x){ return *this/mint(x);}

  mint operator+=(const ll x){ *this = *this + x;return *this; }
  mint operator-=(const ll x){ *this = *this - x;return *this; }
  mint operator*=(const ll x){ *this = *this * x;return *this;}
  mint operator/=(const ll x){ *this = *this / x;return *this;}

  bool operator==(const mint &x)const{return _num==x._num;}
  bool operator!=(const mint &x)const{return _num!=x._num;}

  friend mint operator+(ll x,const mint &m){return mint(m._num + x , m._mod);}
  friend mint operator-(ll x,const mint &m){return mint( x - m._num , m._mod);}
  friend mint operator*(ll x,const mint &m){return mint(m._num * (x % m._mod) , m._mod);}
  friend mint operator/(ll x,mint m){return mint(m.imod() * (x % m._mod) , m._mod);}

  explicit operator ll() { return _num; }
  explicit operator int() { return (int)_num; }
  
  friend ostream& operator<<(ostream &os, const mint &x){ os << x._num; return os; }
  friend istream& operator>>(istream &is, mint &x){ll val; is>>val; x.set(val); return is;}
};
typedef tuple<vector<mint>,vector<mint>,mint> T;
T sekibun(T &v,int state){
    vector<mint> p,q;
    mint c;
    tie(p,q,c)=v;
    if(state==0){
        p.push_back(0);
        q.push_back(0);
        for(int i=p.size()-1;i>0;--i){
            p[i]=p[i-1]/mint(i);
        }
        for(int i=q.size()-1;i>0;--i){
            q[i]=q[i-1]/mint(i);
        }
        p[0]=c;
        q[0]=0;
        c=mod-c;
    }
    else if(state==1){
        p.push_back(0);
        q.push_back(0);
        mint r=0;
        for(int i=p.size()-1;i>0;--i){
            p[i]=mod-p[i-1]/mint(i);
            r+=p[i-1]/mint(i);
        }
        p[0]=r;
        r=0;
        for(int i=q.size()-1;i>0;--i){
            q[i]=mod-q[i-1]/mint(i);
            r+=q[i-1]/mint(i);
        }
        q[0]=r-c;
    }
    else{
        p.push_back(0);
        q.push_back(0);
        mint r=0;
        REP(i,p.size()){
            r+=p[i]/mint(i+1);
            p[i]=0;
        }
        p[0]=r+c;
        r=0;
        REP(i,q.size()){
            r+=q[i]/mint(i+1);
            q[i]=0;
        }
        q[0]=r-c;
        c=0;
    }
    return tie(p,q,c);
}
T operator+(T a,T b){
    vector<mint> p(max(get<0>(a).size(),get<0>(b).size()))
                ,q(max(get<1>(a).size(),get<1>(b).size()));
    mint c=0;
    REP(i,get<0>(a).size()) p[i]+=get<0>(a)[i];
    REP(i,get<0>(b).size()) p[i]+=get<0>(b)[i];
    REP(i,get<1>(a).size()) q[i]+=get<1>(a)[i];
    REP(i,get<1>(b).size()) q[i]+=get<1>(b)[i];
    c=get<2>(a)+get<2>(b);
    return tie(p,q,c);
}

mint pre[1010][2];
void calc(){
    pre[0][0]=1;
    pre[0][1]=-1;
    rep(i,0,1005){
        pre[i+1][0]=pre[i][0]*mint(i+1);
        pre[i+1][1]=pre[i][1]*mint(i+1)-1;
    }
}
typedef tuple<mint,mint,mint> F;

F int_e(T f){
    F res; vector<mint> p=get<0>(f),q=get<1>(f);
    rep(i,0,p.size())get<0>(res)+=p[i]*pre[i][0],get<1>(res)+=p[i]*pre[i][1];
    rep(i,0,q.size())get<1>(res)+=q[i]*pre[i][0],get<2>(res)+=q[i]*pre[i][1];
    get<0>(res)+=get<2>(f)/2; get<2>(res)-=get<2>(f)/2; return res;
}
void t_add(F &a,F b){get<0>(a)+=get<0>(b),get<1>(a)+=get<1>(b),get<2>(a)+=get<2>(b);}
void t_dec(F &a,F b){get<0>(a)-=get<0>(b),get<1>(a)-=get<1>(b),get<2>(a)-=get<2>(b);}
int main(){
    int N;cin>>N;
    string S;cin>>S;calc();
    typedef vector<T> vt;
    typedef vector<vt> vvt;
    typedef vector<vvt> vvvt;
    vector<vvvt> dp(N+1,vvvt(2,vvt(2,vt(2))));
    dp[0][0][1][1]=T({0},{0},1);
    dp[0][1][1][1]=T({1},{0},-1);
    rep(i,1,N+1){
        if(S[i-1]=='X'){
            dp[i][0][1][0]=sekibun(dp[i-1][0][0][1],1)+sekibun(dp[i-1][1][0][1],1)
                          +sekibun(dp[i-1][0][1][1],1)+sekibun(dp[i-1][1][1][1],1)
                          +sekibun(dp[i-1][1][1][0],0)+sekibun(dp[i-1][1][1][1],0);
        }
        else{
            dp[i][0][0][1]=sekibun(dp[i-1][1][1][0],0)+sekibun(dp[i-1][1][1][1],0);
            REP(j,2) REP(k,2) dp[i][0][0][1]=dp[i][0][0][1]+sekibun(dp[i-1][j][1][k],1);
            dp[i][1][1][1]=sekibun(dp[i-1][0][1][0],0)+sekibun(dp[i-1][0][1][1],0);
        }
    }
    F ans;
    REP(i,2){
        t_add(ans,int_e(dp[N][i][1][0]));
        T S=sekibun(dp[N][i][0][1],2);
        t_add(ans,F(get<0>(S)[0],get<1>(S)[0],get<2>(S)));
        t_dec(ans,int_e(dp[N][i][0][1]));
        S=sekibun(dp[N][i][1][1],2);
        t_add(ans,F(get<0>(S)[0],get<1>(S)[0],get<2>(S)));
    }
    mint p,q,r;
    tie(p,q,r)=ans;
    cout<<p<<" "<<q<<" "<<r<<endl;
}


Measured memory_bytes: 34432