#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 2e5+10;
int n,m;
string st;
struct node{
int l,r;
bool num,tag;
}a[4*N];
int ls(int x){
return (x<<1);
}
int rs(int x){
return (x<<1)+1;
}
void push_up(int x){
a[x].num = a[ls(x)].num+a[rs(x)].num;
}
void change(int x){
if(a[x].tag ==0)a[x].tag = 1;
else a[x].tag = 0;
}
void push_down(int x){
if(a[x].tag){
a[ls(x)].num = (a[ls(x)].r-a[ls(x)].l+1)-a[ls(x)].num;
a[rs(x)].num = (a[rs(x)].r-a[rs(x)].l+1)-a[rs(x)].num;
change(ls(x));
change(rs(x));
a[x].tag = 0;
}
}
void build(int x,int l,int r){
a[x].l = l,a[x].r = r;
if(l==r){
a[x].num = st[l-1]-'0';
return;
}
int mid = (l+r)>>1;
build(ls(x),l,mid);
build(rs(x),mid+1,r);
push_up(x);
}
void update(int x,int l,int r){
if(l<=a[x].l&&a[x].r<=r){
a[x].num = (a[x].r-a[x].l+1)-a[x].num;
change(x);
return;
}
push_down(x);
int mid = (a[x].l+a[x].r)>>1;
if(l<=mid)update(ls(x),l,r);
if(mid<r)update(rs(x),l,r);
push_up(x);
}
ll query(int x,int l,int r){
if(l<=a[x].l&&a[x].r<=r)return a[x].num;
int mid = (a[x].l+a[x].r)>>1;
push_down(x);
ll res = 0;
if(l<=mid)res+=query(ls(x),l,r);
if(mid<r)res+=query(rs(x),l,r);
return res;
}
void solve(){
int op,l,r;
cin>>op>>l>>r;
if(op==0)update(1,l,r);
if(op==1)cout<<query(1,l,r)<<endl;
}
int main(){
cin>>n>>m;
cin>>st;
build(1,1,n);
while(m--)solve();
return 0;
}