既然要交换AB,那就在线段树中把两种矩阵都存下来好了
然后swap( c[ rt ][ 0 ],c[ rt ][ 1 ] )。
int n,q;
char s[MAXN];
struct M
{
    ll m[2][2];
    M(){mem(m,0);}
}A,B;
M mul(M a, M b)
{
	M ans;
	for (int i = 0; i < 2; i++)
		for (int j = 0; j < 2; j++)
			for (int k = 0; k < 2; k++)
				ans.m[i][j] = (ans.m[i][j] + a.m[i][k] * b.m[k][j] % mod) % mod;
	return ans;
}
struct Segment_Tree
{
    #define lson rt<<1,l,mid
    #define rson rt<<1|1,mid+1,r
    M c[MAXN<<2][2];
    int lazy[MAXN<<2];
    inline int ls(int p) {return p<<1;}
    inline int rs(int p) {return p<<1|1;}
    void push_up(int p) 
    {
        c[p][0]=mul(c[ls(p)][0],c[rs(p)][0]);
        c[p][1]=mul(c[ls(p)][1],c[rs(p)][1]);
    }
    void push_down(int p)
    {
        swap(c[ls(p)][0],c[ls(p)][1]);
        swap(c[rs(p)][0],c[rs(p)][1]);
        lazy[ls(p)]^=lazy[p];
        lazy[rs(p)]^=lazy[p];
        lazy[p]=0;
    }
    void build(int rt,int l,int r)
    {
        lazy[rt]=0;
        if(l==r)
        {
            if(s[l]=='A') c[rt][0]=A,c[rt][1]=B;
            else c[rt][0]=B,c[rt][1]=A;
            return;
        }
        int mid = (l+r)>>1;
        build(lson);build(rson);
        push_up(rt);
    }
    void Query(int ql,int qr,int rt,int l,int r,M & ans)
    {
        if(ql<=l && r<=qr)
        {
            ans=mul(ans,c[rt][0]);
            return;
        }
        if(lazy[rt]) push_down(rt);
        int mid=(l+r)>>1;
        if(ql<=mid) Query(ql,qr,lson,ans);
        if(qr>mid) Query(ql,qr,rson,ans);
        return ;
    }
    void update(int ql,int qr,int rt,int l,int r)//区间更新
    {
        if(ql<=l && qr>=r) {lazy[rt]^=1;swap(c[rt][0],c[rt][1]);return;}
        if(lazy[rt]) push_down(rt);
        int mid=(l+r)>>1;
        if(ql<=mid) update(ql,qr,lson);
        if(qr>mid) update(ql,qr,rson);
        push_up(rt);
    }
}tree;

int main()
{
    rd(n),rd(q);
    scanf("%s",s+1);
    A.m[0][0] = A.m[1][0] = A.m[1][1] = B.m[0][0] = B.m[0][1] = B.m[1][1] = 1;
    tree.build(1,1,n);
    while(q--)
    {
        int op;rd(op);
        if(op==1)
        {
            int l,r;rd(l),rd(r);
            tree.update(l,r,1,1,n);
        }
        else
        {
            int l,r,a,b;
            rd(l),rd(r),rd(a),rd(b);
            M ans,base;
            ans.m[0][0]=ans.m[1][1]=1;
            base.m[0][0]=a,base.m[0][1]=b;
            tree.Query(l,r,1,1,n,ans);
            base=mul(base,ans);
            printf("%lld %lld\n",base.m[0][0],base.m[0][1]);
        }
    }
    //stop;
    return 0;
}