#include <bits/stdc++.h>
using namespace std;
template<typename T>
void out(T x) { cout << x << endl; exit(0); }
#define watch(x) cout << (#x) << " is " << (x) << endl
using ll = long long;
const ll mod = 1e9+7;
const int maxn = 1e5 + 5;
using matrix = vector<vector<ll>>;
void add(ll& x, ll y) {
if (x>=mod) x%=mod;
if (y>=mod) y%=mod;
x += y;
if (x>=mod) x%=mod;
}
void mul(ll& x, ll y) {
if (x>=mod) x%=mod;
if (y>=mod) y%=mod;
long long tmp = 1ll*x*y;
tmp %= mod;
x = tmp;
}
ll addr(ll x, ll y) {
if (x>=mod) x%=mod;
if (y>=mod) y%=mod;
x += y;
if (x>=mod) x%=mod;
return x;
}
ll mulr(ll x, ll y) {
if (x>=mod) x%=mod;
if (y>=mod) y%=mod;
long long tmp = 1ll*x*y;
tmp %= mod;
return tmp;
}
matrix mul(matrix a, matrix b) {
int n = a.size();
assert(n>0);
int m = a[0].size();
assert(m == int(b.size()));
int p = b[0].size();
matrix res(n, vector<ll>(p));
for (int i=0; i<n; i++) {
for (int j=0; j<p; j++) {
for (int k=0; k<m; k++) {
ll cur = mulr(a[i][k], b[k][j]);
add(res[i][j], cur);
}
}
}
return res;
}
matrix matpw(matrix mat, int k) {
int n = mat.size();
assert(mat.size() && mat.size()==mat[0].size()); //nxn
matrix res(n,vector<ll>(n));
for (int i=0; i<n; i++) {
res[i][i]=1;
}
while (k>0) {
if (k%2) {
res=mul(res,mat);
}
mat=mul(mat,mat);
k=k/2;
}
return res;
}
matrix id2() {
vector<vector<ll>> mat(2,vector<ll>(2));
mat[0][0]=mat[1][1]=1;
return mat;
}
matrix matA() {
vector<vector<ll>> mat(2,vector<ll>(2,1));
mat[1][0]=0;
// 1 1
// 0 1
return mat;
}
matrix matB() {
vector<vector<ll>> mat(2,vector<ll>(2,1));
mat[0][1]=0;
// 1 0
// 1 1
return mat;
}
int n, q;
string s;
using node = matrix;
node t[4*maxn];
bool o[4*maxn];
node merge(node a, node b) {
return mul(b, a);
}
void build(int v, int tl, int tr) {
if (tl==tr) {
t[v] = s[tl] == 'A' ? matA() : matB();
} else {
int tm=(tl+tr)/2;
build(2*v,tl,tm);
build(2*v+1,tm+1,tr);
t[v] = merge(t[2*v], t[2*v+1]);
}
}
void push(int v) {
if (!o[v]) return;
swap(t[2*v][0], t[2*v][1]);
swap(t[2*v][0][0], t[2*v][0][1]);
swap(t[2*v][1][0], t[2*v][1][1]);
swap(t[2*v+1][0], t[2*v+1][1]);
swap(t[2*v+1][0][0], t[2*v+1][0][1]);
swap(t[2*v+1][1][0], t[2*v+1][1][1]);
o[2*v]=!o[2*v];
o[2*v+1]=!o[2*v+1];
o[v]=false;
}
void flip(int v, int tl, int tr, int l, int r) {
if (r<tl || l>tr) {
return;
}
if (l<=tl && tr<=r) {
// before
// p q
// r s
// after
// s r
// q p
swap(t[v][0], t[v][1]);
swap(t[v][0][0], t[v][0][1]);
swap(t[v][1][0], t[v][1][1]);
o[v] = !o[v];
return;
}
int tm=(tl+tr)/2;
push(v);
flip(2*v,tl,tm,l,r);
flip(2*v+1,tm+1,tr,l,r);
t[v]=merge(t[2*v],t[2*v+1]);
}
matrix qry(int v, int tl, int tr, int l, int r) {
if (l>tr || r<tl) {
return id2();
}
if (l<=tl && tr<=r) {
return t[v];
}
int tm=(tl+tr)/2;
push(v);
return mul(qry(2*v+1,tm+1,tr,l,r), qry(2*v,tl,tm,l,r));
}
int main() {
ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin>>n>>q;
cin>>s;
s="."+s;
build(1,1,n);
while (q--) {
int typ;
cin>>typ;
if (typ==2) {
int l,r; ll a,b;
cin>>l>>r>>a>>b;
matrix M = qry(1,1,n,l,r);
ll resa = addr(mulr(M[0][0],a), mulr(M[0][1],b));
ll resb = addr(mulr(M[1][0],a), mulr(M[1][1],b));
cout<<resa<<" "<<resb<<"\n";
}
if (typ==1) {
int l,r;
cin>>l>>r;
flip(1,1,n,l,r);
}
}
return 0;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CiAKdGVtcGxhdGU8dHlwZW5hbWUgVD4Kdm9pZCBvdXQoVCB4KSB7IGNvdXQgPDwgeCA8PCBlbmRsOyBleGl0KDApOyB9CiNkZWZpbmUgd2F0Y2goeCkgY291dCA8PCAoI3gpIDw8ICIgaXMgIiA8PCAoeCkgPDwgZW5kbAogCiAKIAogCiAKdXNpbmcgbGwgPSBsb25nIGxvbmc7CmNvbnN0IGxsIG1vZCA9IDFlOSs3Owpjb25zdCBpbnQgbWF4biA9IDFlNSArIDU7CiAKIAp1c2luZyBtYXRyaXggPSB2ZWN0b3I8dmVjdG9yPGxsPj47CiAKdm9pZCBhZGQobGwmIHgsIGxsIHkpIHsKICAgIGlmICh4Pj1tb2QpIHglPW1vZDsKICAgIGlmICh5Pj1tb2QpIHklPW1vZDsKICAgIHggKz0geTsKICAgIGlmICh4Pj1tb2QpIHglPW1vZDsKfQogCnZvaWQgbXVsKGxsJiB4LCBsbCB5KSB7CiAgICBpZiAoeD49bW9kKSB4JT1tb2Q7CiAgICBpZiAoeT49bW9kKSB5JT1tb2Q7CiAgICBsb25nIGxvbmcgdG1wID0gMWxsKngqeTsKICAgIHRtcCAlPSBtb2Q7CiAgICB4ID0gdG1wOwp9CiAKbGwgYWRkcihsbCB4LCBsbCB5KSB7CiAgICBpZiAoeD49bW9kKSB4JT1tb2Q7CiAgICBpZiAoeT49bW9kKSB5JT1tb2Q7CiAgICB4ICs9IHk7CiAgICBpZiAoeD49bW9kKSB4JT1tb2Q7CiAgICByZXR1cm4geDsKfQogCmxsIG11bHIobGwgeCwgbGwgeSkgewogICAgaWYgKHg+PW1vZCkgeCU9bW9kOwogICAgaWYgKHk+PW1vZCkgeSU9bW9kOwogICAgbG9uZyBsb25nIHRtcCA9IDFsbCp4Knk7CiAgICB0bXAgJT0gbW9kOwogICAgcmV0dXJuIHRtcDsKfQogCiAKIAptYXRyaXggbXVsKG1hdHJpeCBhLCBtYXRyaXggYikgewogICAgaW50IG4gPSBhLnNpemUoKTsKICAgIGFzc2VydChuPjApOwogICAgaW50IG0gPSBhWzBdLnNpemUoKTsKICAgIGFzc2VydChtID09IGludChiLnNpemUoKSkpOwogICAgaW50IHAgPSBiWzBdLnNpemUoKTsKICAgIG1hdHJpeCByZXMobiwgdmVjdG9yPGxsPihwKSk7CiAgICBmb3IgKGludCBpPTA7IGk8bjsgaSsrKSB7Cglmb3IgKGludCBqPTA7IGo8cDsgaisrKSB7CgkgICAgZm9yIChpbnQgaz0wOyBrPG07IGsrKykgewoJCWxsIGN1ciA9IG11bHIoYVtpXVtrXSwgYltrXVtqXSk7CgkJYWRkKHJlc1tpXVtqXSwgY3VyKTsKCSAgICB9Cgl9CiAgICB9CiAgICByZXR1cm4gcmVzOyAgICAKfQogCiAKbWF0cml4IG1hdHB3KG1hdHJpeCBtYXQsIGludCBrKSB7CiAgICBpbnQgbiA9IG1hdC5zaXplKCk7CiAgICBhc3NlcnQobWF0LnNpemUoKSAmJiBtYXQuc2l6ZSgpPT1tYXRbMF0uc2l6ZSgpKTsgLy9ueG4KICAgIG1hdHJpeCByZXMobix2ZWN0b3I8bGw+KG4pKTsKICAgIGZvciAoaW50IGk9MDsgaTxuOyBpKyspIHsKCXJlc1tpXVtpXT0xOwogICAgfQogCiAKICAgIHdoaWxlIChrPjApIHsKCWlmIChrJTIpIHsKCSAgICByZXM9bXVsKHJlcyxtYXQpOwoJfQoJbWF0PW11bChtYXQsbWF0KTsKCWs9ay8yOwogICAgfQogCiAgICByZXR1cm4gcmVzOwp9CiAKIAptYXRyaXggaWQyKCkgewogICAgdmVjdG9yPHZlY3RvcjxsbD4+IG1hdCgyLHZlY3RvcjxsbD4oMikpOwogICAgbWF0WzBdWzBdPW1hdFsxXVsxXT0xOwogICAgcmV0dXJuIG1hdDsKfQogCm1hdHJpeCBtYXRBKCkgewogICAgdmVjdG9yPHZlY3RvcjxsbD4+IG1hdCgyLHZlY3RvcjxsbD4oMiwxKSk7CiAgICBtYXRbMV1bMF09MDsKICAgIC8vIDEgMQogICAgLy8gMCAxCiAgICByZXR1cm4gbWF0Owp9CiAKbWF0cml4IG1hdEIoKSB7CiAgICB2ZWN0b3I8dmVjdG9yPGxsPj4gbWF0KDIsdmVjdG9yPGxsPigyLDEpKTsKICAgIG1hdFswXVsxXT0wOwogICAgLy8gMSAwCiAgICAvLyAxIDEKICAgIHJldHVybiBtYXQ7Cn0KIAogCmludCBuLCBxOwpzdHJpbmcgczsKIAp1c2luZyBub2RlID0gbWF0cml4OwogCm5vZGUgdFs0Km1heG5dOwpib29sIG9bNCptYXhuXTsKIApub2RlIG1lcmdlKG5vZGUgYSwgbm9kZSBiKSB7CiAgICByZXR1cm4gbXVsKGIsIGEpOwp9CiAKdm9pZCBidWlsZChpbnQgdiwgaW50IHRsLCBpbnQgdHIpIHsKICAgIGlmICh0bD09dHIpIHsKCXRbdl0gPSBzW3RsXSA9PSAnQScgPyBtYXRBKCkgOiBtYXRCKCk7CiAgICB9IGVsc2UgewoJaW50IHRtPSh0bCt0cikvMjsKCWJ1aWxkKDIqdix0bCx0bSk7CglidWlsZCgyKnYrMSx0bSsxLHRyKTsKCXRbdl0gPSBtZXJnZSh0WzIqdl0sIHRbMip2KzFdKTsKICAgIH0KfQogCnZvaWQgcHVzaChpbnQgdikgewogICAgaWYgKCFvW3ZdKSByZXR1cm47CiAgICAKICAgIHN3YXAodFsyKnZdWzBdLCB0WzIqdl1bMV0pOwogICAgc3dhcCh0WzIqdl1bMF1bMF0sIHRbMip2XVswXVsxXSk7CiAgICBzd2FwKHRbMip2XVsxXVswXSwgdFsyKnZdWzFdWzFdKTsKIAogICAgc3dhcCh0WzIqdisxXVswXSwgdFsyKnYrMV1bMV0pOwogICAgc3dhcCh0WzIqdisxXVswXVswXSwgdFsyKnYrMV1bMF1bMV0pOwogICAgc3dhcCh0WzIqdisxXVsxXVswXSwgdFsyKnYrMV1bMV1bMV0pOwogICAgb1syKnZdPSFvWzIqdl07CiAgICBvWzIqdisxXT0hb1syKnYrMV07CiAgICBvW3ZdPWZhbHNlOwp9CiAKIAp2b2lkIGZsaXAoaW50IHYsIGludCB0bCwgaW50IHRyLCBpbnQgbCwgaW50ICByKSB7CiAgICBpZiAocjx0bCB8fCBsPnRyKSB7CglyZXR1cm47CiAgICB9CiAgICBpZiAobDw9dGwgJiYgdHI8PXIpIHsKCS8vIGJlZm9yZQoJLy8gcCBxCgkvLyByIHMKIAoJLy8gYWZ0ZXIKCS8vIHMgcgoJLy8gcSBwCgkKCXN3YXAodFt2XVswXSwgdFt2XVsxXSk7Cglzd2FwKHRbdl1bMF1bMF0sIHRbdl1bMF1bMV0pOwoJc3dhcCh0W3ZdWzFdWzBdLCB0W3ZdWzFdWzFdKTsKCW9bdl0gPSAhb1t2XTsKCXJldHVybjsKICAgIH0KICAgIGludCB0bT0odGwrdHIpLzI7CiAgICBwdXNoKHYpOwogICAgZmxpcCgyKnYsdGwsdG0sbCxyKTsKICAgIGZsaXAoMip2KzEsdG0rMSx0cixsLHIpOwogICAgdFt2XT1tZXJnZSh0WzIqdl0sdFsyKnYrMV0pOwp9CiAKbWF0cml4IHFyeShpbnQgdiwgaW50IHRsLCBpbnQgdHIsIGludCBsLCBpbnQgcikgewogICAgaWYgKGw+dHIgfHwgcjx0bCkgewoJcmV0dXJuIGlkMigpOwogICAgfQogICAgaWYgKGw8PXRsICYmIHRyPD1yKSB7CglyZXR1cm4gdFt2XTsKICAgIH0KICAgIGludCB0bT0odGwrdHIpLzI7CiAgICBwdXNoKHYpOwogICAgcmV0dXJuIG11bChxcnkoMip2KzEsdG0rMSx0cixsLHIpLCBxcnkoMip2LHRsLHRtLGwscikpOwp9CiAKIAogCiAKaW50IG1haW4oKSB7CiAgICBpb3NfYmFzZTo6c3luY193aXRoX3N0ZGlvKGZhbHNlKTsgY2luLnRpZSgwKTsgIGNvdXQudGllKDApOwogCiAgICBjaW4+Pm4+PnE7CiAgICBjaW4+PnM7CiAgICBzPSIuIitzOwogICAgYnVpbGQoMSwxLG4pOwogCiAgICB3aGlsZSAocS0tKSB7CglpbnQgdHlwOwoJY2luPj50eXA7CglpZiAodHlwPT0yKSB7CgkgICAgaW50IGwscjsgbGwgYSxiOwoJICAgIGNpbj4+bD4+cj4+YT4+YjsKCSAgICBtYXRyaXggTSA9IHFyeSgxLDEsbixsLHIpOwoJICAgIGxsIHJlc2EgPSBhZGRyKG11bHIoTVswXVswXSxhKSwgbXVscihNWzBdWzFdLGIpKTsKCSAgICBsbCByZXNiID0gYWRkcihtdWxyKE1bMV1bMF0sYSksIG11bHIoTVsxXVsxXSxiKSk7CgkgICAgY291dDw8cmVzYTw8IiAiPDxyZXNiPDwiXG4iOwoJfQoJaWYgKHR5cD09MSkgewoJICAgIGludCBsLHI7CgkgICAgY2luPj5sPj5yOwoJICAgIGZsaXAoMSwxLG4sbCxyKTsKCX0KICAgIH0KICAgIAogICAgCiAgICByZXR1cm4gMDsKfQ==