#include <iostream>
using namespace std;
#define ll long long
#define maxn 10000007
ll tree[maxn],lazy[maxn];
int n,m;
string s;
inline void push_up(int node,int left_node,int right_node)
{
tree[node]=tree[left_node]+tree[right_node];
return;
}
inline void push_down(int node,int left_node,int right_node,int start,int mid,int end)
{
lazy[left_node]+=lazy[node];
lazy[right_node]+=lazy[node];
if(lazy[node]%2!=0)tree[left_node]=(mid-start+1)-tree[left_node];
if(lazy[node]%2!=0)tree[right_node]=(end-mid)-tree[right_node];
lazy[node]=0;
return;
}
void build_tree(int node,int start,int end)
{
if(start==end)
{
tree[node]=s[start]=='1'?1:0;
return;
}
else
{
int mid=(start+end)>>1;
int left_node=2*node+1;
int right_node=2*node+2;
build_tree(left_node,start,mid);
build_tree(right_node,mid+1,end);
push_up(node,left_node,right_node);
}
}
void update_tree(int node,int l,int r,int start,int end)
{
if(l>end||r<start)return;
if(l<=start&&r>=end)
{
tree[node]=(end-start+1)-tree[node];
lazy[node]+=1;
return;
}
else
{
int left_node=2*node+1;
int right_node=2*node+2;
int mid=(start+end)>>1;
push_down(node,left_node,right_node,start,mid,end);
update_tree(left_node,l,r,start,mid);
update_tree(right_node,l,r,mid+1,end);
push_up(node,left_node,right_node);
return;
}
}
ll query(int node,int l,int r,int start,int end)
{
if(start>=l&&end<=r)return tree[node];
if(start>r||end<l)return 0;
else
{
int mid=(start+end)>>1;
int left_node=2*node+1;
int right_node=2*node+2;
push_down(node,left_node,right_node,start,mid,end);
return query(left_node,l,r,start,mid)+query(right_node,l,r,mid+1,end);
}
}
int main()
{
cin>>n>>m;
cin>>s;
int ch,l,r;
build_tree(0,0,n-1);
for(int i=1;i<=m;i++)
{
cin>>ch>>l>>r;
if(ch==0)
{
update_tree(0,l,r,0,n-1);
}
else if(ch==1)
{
cout<<query(0,l,r,0,n-1)<<endl;
}
}
return 0;
}