#include #include #include using namespace std; using namespace atcoder; using ll = long long; using mint = modint998244353; //using mint = modint1000000007; #define rep(i, n) for (int i = 0; i < (int)(n); i++) #define repu(i, s, t) for (int i = (int)(s); i < (int)(t); i++) #define repd(i, s, t) for (int i = (int)(s)-1; i >= (int)(t); i--) #define all(v) v.begin(), v.end() template bool chmax(T &a, const T b) { if(a >= b) return false; a = b; return true; } template bool chmin(T &a, const T b) { if(a <= b) return false; a = b; return true; } template istream& operator>>(istream &in, vector &a) { for(T &x: a) in >> x; return in; } template ostream& operator<<(ostream &out, const vector &a) { for(const T &x: a) out << x << ' '; return out; } const int di[] = {1, 0, -1, 0, 1, 1, -1, -1, 0}; const int dj[] = {0, 1, 0, -1, -1, 1, 1, -1, 0}; struct S { bool zero_ex, one_ex; vector> val; S() : zero_ex(false), one_ex(false), val(2, vector(3)) {} S(bool x) : zero_ex(!x), one_ex(x), val(2, vector(3)) { val[int(x)] = {1, 1, 1}; } }; S op(S l, S r) { S res; rep(i, 2) rep(j, 3) res.val[i][j] = l.val[i][j] + l.val[i][0] * r.val[0][j] + l.val[i][1] * r.val[1][j]; if(!l.zero_ex) res.val[0] = r.val[0]; if(!l.one_ex) res.val[1] = r.val[1]; if(r.zero_ex) rep(i, 2) res.val[i][0] -= l.val[i][0]; if(r.one_ex) rep(i, 2) res.val[i][1] -= l.val[i][1]; res.zero_ex = l.zero_ex || r.zero_ex; res.one_ex = l.one_ex || r.one_ex; return res; } S e() { return S(); } using F = bool; S mapping(F l, S r) { if(l) return e(); return r; } F composition(F l, F r) { return l || r; } F id() { return false; } int main() { int n, q; string s; cin >> n >> q >> s; lazy_segtree lst(n); rep(i, n) lst.set(i, S(s[i]-'0')); while(q--) { int t, l, r; cin >> t >> l >> r; l--; if(t == 1) { lst.apply(l, r, true); } else { cout << lst.prod(l, r).val[1][2].val() << '\n'; } } return 0; }