#include<cstdio>
#include<algorithm>
#define MAX 300050
int N, P, M = 0;
long long tree[MAX<<2], lazy[MAX<<2];
int a[MAX];
void build(int start, int end, int node)
{
lazy[node] = 0;
if (start == end)
{
tree[node] = a[start];
return;
}
int mid = (start + end) / 2, left = node * 2 + 1, right = left + 1;
build(start, mid, left);
build(mid + 1, end, right);
tree[node] = tree[left] + tree[right];
}
void down(int node, int start, int end)
{
if (lazy[node])
{
int mid = (start + end) / 2;
lazy[node * 2 + 1] ^= 1;
lazy[node * 2 + 2] ^= 1;
if (lazy[node * 2 + 1])
tree[node * 2 + 1] = (mid - start + 1) - tree[node * 2 + 1];
if (lazy[node * 2 + 2])
tree[node * 2 + 2] = (end - mid) - tree[node * 2 + 2];
lazy[node] = 0;
}
}
void updata(int start, int end, int node, int left, int right)
{
if (start >= left && end <= right)
{
lazy[node] ^= 1;
tree[node] = end - start + 1 - tree[node];
return;
}
down(node, start, end);
int mid = (start + end) / 2, l = node * 2 + 1, r = l + 1;
if (mid >= left)
updata(start, mid, l, left, right);
if (right > mid)
updata(mid + 1, end, r, left, right);
tree[node] = tree[l] + tree[r];
}
long long search(int start, int end, int node, int left, int right)
{
if (start == end)
return tree[node];
if (start >= left && end <= right)
return tree[node];
down(node, start, end);
int mid = (start + end) / 2, l = node * 2 + 1, r = l + 1;
long long ans = 0;
if (left <= mid)
ans += search(start, mid, l, left, right);
if (mid < right)
ans += search(mid + 1, end, r, left, right);
return ans;
}
void print()
{
for (int i = 0; i < 20; i++)
printf("%d %d\n", tree[i], lazy[i]);
printf("\n\n");
}
int main(void)
{
int t, x, y, k;
for (int i = 0; i < MAX<<2; i++)
tree[i] = lazy[i] = 0;
scanf("%d%d", &N, &P);
for (int i = 0; i < N; i++)
scanf("%1d", &a[i]);
build(0, N - 1, 0);
for (int i = 0; i < P; i++)
{
scanf("%d%d%d", &t, &x, &y);
if (t == 0)
updata(0, N - 1, 0, --x, --y);
else
printf("%lld\n", search(0, N - 1, 0, --x, --y));
}
return 0;
}