#include<bits/stdc++.h>
#define lc (u<<1)
#define rc (u<<1|1)
const int N=5e5+10;
struct tag{
int xxor;
};
struct info{
int l,r;
bool ok;
};
struct tree{
info val;
tag t;
}tr[N*4];
info operator ^ (const info&u,const int&x){
info res;
res.l=u.l^x;
res.r=u.r^x;
res.ok=u.ok;
return res;
}
info operator + (const info&l,const info&r){
info res;
res.l=l.l;
res.r=r.r;
if(!l.ok||!r.ok) res.ok=false;
else{
if(l.r==r.l) res.ok=false;
else res.ok=true;
}
return res;
}
int n,q;
std::string str;
void settag(int u,tag t){
tr[u].val=tr[u].val^t.xxor;
}
void push_up(int u){
tr[u].val=tr[lc].val+tr[rc].val;
}
void push_down(int u){
if(tr[u].t.xxor){
settag(lc,tr[u].t);
settag(rc,tr[u].t);
tr[u].t.xxor=0;
}
}
void build(int u,int l,int r){
if(l==r){
if(str[l]=='0')tr[u].val={0,0,true};
else tr[u].val={1,1,true};
return;
}
int mid=(l+r)>>1;
build(lc,l,mid);
build(rc,mid+1,r);
push_up(u);
}
void modify(int u,int l,int r,int ql,int qr){
if(l==ql&&r==qr){
settag(u,(tag){1});
return;
}
push_down(u);
int mid=(l+r)>>1;
if(qr<=mid) modify(lc,l,mid,ql,qr);
else if(ql>mid) modify(rc,mid+1,r,ql,qr);
else{
modify(lc,l,mid,ql,mid);
modify(rc,mid+1,r,mid+1,qr);
}
push_up(u);
}
bool query(int u,int l,int r,int ql,int qr){
if(l==ql&&r==qr) return tr[u].val.ok;
push_down(u);
int mid=(l+r)>>1;
if(qr<=mid) return query(lc,l,mid,ql,qr);
if(ql>mid) return query(rc,mid+1,r,ql,qr);
return query(lc,l,mid,ql,mid)&&query(rc,mid+1,r,mid+1,qr)&&tr[lc].val.r!=tr[rc].val.l;
}
signed main(){
std::cin>>n>>q;
std::cin>>str;
str=' '+str;
build(1,1,n);
while(q--){
int tp,l,r;
std::cin>>tp>>l>>r;
if(tp==1) modify(1,1,n,l,r);
else{
if(query(1,1,n,l,r))std::cout<<"Yes"<<'\n';
else std::cout<<"No"<<'\n';
}
}
}