#include<bits/stdc++.h>
typedef long long ll;
typedef unsigned long long ull;
#define il inline
using namespace std;
const int MAXN=2*1e5+5;
int tree[MAXN<<2],lazy[MAXN<<2],a[MAXN],n,m;
int lc(int rt){return rt<<1;}
int rc(int rt){return rt<<1|1;}
void push_up(int rt){tree[rt]=tree[lc(rt)]+tree[rc(rt)];}
void push_down(int rt,int len){
if(lazy[rt]){
lazy[lc(rt)]^=1;
lazy[rc(rt)]^=1;
tree[lc(rt)]=(len-(len>>1))-tree[lc(rt)];
tree[rc(rt)]=(len>>1)-tree[rc(rt)];
tree[rt]=0;
}
}
void build(int rt,int l,int r){
if(l==r){
tree[l]=a[l];
return;
}
int m=(l+r)>>1;
build(rt,l,m);
build(rt,m+1,r);
push_up(rt);
}
void upd(int L,int R,int l,int r,int rt){
push_down(rt,r-l+1);
if(L<=l&&R>=r){
lazy[rt]^=1;
tree[rt]=r-l+1-tree[rt];
return;
}
int mid=(l+r)>>1;
if(L<=mid) upd(L,R,l,mid,lc(rt));
if(R>mid) upd(L,R,mid+1,r,rc(rt));
push_up(rt);
}
int query(int L,int R,int l,int r,int rt){
if(L<=l&&R>=r){
return tree[rt];
}
push_down(rt,r-l+1);
int mid=(l+r)>>1;
ll ans=0;
if(L<=mid) ans+=query(L,R,l,mid,lc(rt));
if(R>mid) ans+=query(L,R,mid+1,r,rc(rt));
return ans;
}
int main(){
cin>>n>>m;
string s;
cin>>s;
for(int i=1;i<=n;i++){
a[i]=s[i]-'0';
}
build(1,1,n);
for(int i=1;i<=m;i++){
int opt,x,y;
cin>>opt>>x>>y;
switch(opt){
case 0:{
upd(x,y,1,n,1);
break;
}
case 1:{
cout<<query(x,y,1,n,1)<<endl;
break;
}
}
}
return 0;
}