// generated at caterpillow.github.io/byot
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
struct Lazy {
// set, then reverse, then flip
int set;
bool rev;
bool flip;
void operator+=(const Lazy& oth) {
if (oth.set != -1) rev = flip = 0, set = oth.set;
rev ^= oth.rev;
flip ^= oth.flip;
}
};
const Lazy lid = {-1, false, false};
// You can implement your own monoid here for custom operations.
struct Value {
int ans, tot0, tot1, pfx0, pfx1, sfx0, sfx1;
static Value make(int x, int len = 1) {
if (x) return {len, 0, len, 0, len, 0, len};
else return {len, len, 0, len, 0, len, 0};
}
void upd(Lazy lazy, int sz) {
if (lazy.set != -1) {
*this = make(lazy.set, tot0 + tot1);
}
if (lazy.rev) {
swap(pfx0, sfx0);
swap(pfx1, sfx1);
}
if (lazy.flip) {
swap(tot0, tot1);
swap(pfx0, pfx1);
swap(sfx0, sfx1);
}
}
Value operator+(const Value& oth) const {
Value res {};
res.ans = max({ans, oth.ans, sfx0 + oth.pfx0, sfx1 + oth.pfx1});
res.tot0 = tot0 + oth.tot0;
res.tot1 = tot1 + oth.tot1;
if (tot1 == 0) res.pfx0 = tot0 + oth.pfx0;
else res.pfx0 = pfx0;
if (tot0 == 0) res.pfx1 = tot1 + oth.pfx1;
else res.pfx1 = pfx1;
if (oth.tot1 == 0) res.sfx0 = sfx0 + oth.tot0;
else res.sfx0 = oth.sfx0;
if (oth.tot0 == 0) res.sfx1 = sfx1 + oth.tot1;
else res.sfx1 = oth.sfx1;
return res;
}
};
const Value vid = {0, 0, 0, 0, 0, 0, 0};
// end custom code
// generated at caterpillow.github.io/byot
mt19937 mt(chrono::steady_clock::now().time_since_epoch().count());
using ptr = struct Node*;
struct Node {
Value val;
Value agg;
Lazy lazy;
int sz;
int pri;
ptr l, r;
Node() {
pri = mt();
val = vid;
agg = vid;
lazy = lid;
sz = 1;
l = r = nullptr;
}
Node(Value val) : val(val), agg(val) {
pri = mt();
lazy = lid;
sz = 1;
l = r = nullptr;
}
~Node() {
delete l;
delete r;
}
};
int sz(ptr n) { return n ? n->sz : 0; };
Value agg(ptr n) { return n ? n->agg : vid; }
void push(ptr n) {
n->val.upd(n->lazy, 1);
n->agg.upd(n->lazy, sz(n));
if (n->lazy.rev) swap(n->l, n->r);
if (n->l) n->l->lazy += n->lazy;
if (n->r) n->r->lazy += n->lazy;
n->lazy = lid;
}
ptr pull(ptr n) {
if (!n) return nullptr;
if (n->l) push(n->l);
if (n->r) push(n->r);
n->sz = sz(n->l) + 1 + sz(n->r);
n->agg = agg(n->l) + n->val + agg(n->r);
return n;
}
ptr merge(ptr l, ptr r) {
if (!l || !r) return l ? l : r;
push(l), push(r);
if (l->pri > r->pri) return l->r = merge(l->r, r), pull(l);
else return r->l = merge(l, r->l), pull(r);
}
// [-inf, i) and [i, inf]
pair<ptr, ptr> spliti(ptr n, int i) {
if (!n) return {nullptr, nullptr};
push(n);
if (i <= sz(n->l)) {
auto [l, r] = spliti(n->l, i);
n->l = r;
return {l, pull(n)};
} else {
auto [l, r] = spliti(n->r, i - 1 - sz(n->l));
n->r = l;
return {pull(n), r};
}
}
// you CANNOT use the normal range update for range reverses
void reversei(ptr& n, int lo, int hi) {
auto [lm, r] = spliti(n, hi);
auto [l, m] = spliti(lm, lo);
Lazy upd = lid;
upd.rev = true;
if (m) m->lazy += upd;
n = merge(merge(l, m), r);
}
void updi(ptr n, int lo, int hi, Lazy lazy) {
if (!n) return;
push(n);
if (lo >= n->sz || hi <= 0) return;
if (lo <= 0 && n->sz <= hi) {
n->lazy += lazy;
push(n);
return;
}
if (lo <= sz(n->l) && sz(n->l) < hi) n->val.upd(lazy, 1);
updi(n->l, lo, hi, lazy);
updi(n->r, lo - 1 - sz(n->l), hi - 1 - sz(n->l), lazy);
pull(n);
}
Value queryi(ptr n, int lo, int hi) {
if (!n || lo >= sz(n) || hi <= 0) return vid;
push(n);
if (lo <= 0 && sz(n) <= hi) return n->agg;
return queryi(n->l, lo, hi) + (lo <= sz(n->l) && sz(n->l) < hi ? n->val : vid) + queryi(n->r, lo - 1 - sz(n->l), hi - 1 - sz(n->l));
}
void heapify(ptr n) {
if (!n) return;
ptr mx = n;
if (n->l && n->l->pri > mx->pri) mx = n->l;
if (n->r && n->r->pri > mx->pri) mx = n->r;
if (mx != n) swap(n->pri, mx->pri), heapify(mx);
}
ptr build(vector<ptr>& ns, int l = 0, int r = -69) {
if (r == -69) r = (int) ns.size() - 1;
if (l > r) return nullptr;
if (l == r) return ns[l];
int m = (l + r) / 2;
ns[m]->l = build(ns, l, m - 1);
ns[m]->r = build(ns, m + 1, r);
heapify(ns[m]);
return pull(ns[m]);
}
/*
- include range reverse by index (and lazy prop, size, split by index and merge)
- include build (and heapify)
- include range aggregates
- include range updates by index
- include range queries by index
*/
main() {
cin.tie(0)->sync_with_stdio(0);
int n, q; cin >> n >> q;
vector<ptr> ns(n);
for (int i = 0; i < n; i++) {
char x; cin >> x;
ns[i] = new Node(Value::make(x - '0'));
}
ptr treap = build(ns);
for (int i = 0; i < q; i++) {
int t, l, r; cin >> t >> l >> r;
l--;
if (t == 1) {
updi(treap, l, r, {-1, false, true});
}
if (t == 2) {
reversei(treap, l, r);
}
if (t == 3) {
Value res = queryi(treap, l, r);
updi(treap, l, l + res.tot0, {0, false, false});
updi(treap, r - res.tot1, r, {1, false, false});
}
push(treap);
cout << agg(treap).ans << '\n';
}
delete treap;
}
Ly8gZ2VuZXJhdGVkIGF0IGNhdGVycGlsbG93LmdpdGh1Yi5pby9ieW90CgojaW5jbHVkZSA8Yml0cy9zdGRjKysuaD4KCnVzaW5nIG5hbWVzcGFjZSBzdGQ7CnVzaW5nIGxsID0gbG9uZyBsb25nOwoKc3RydWN0IExhenkgewogICAgLy8gc2V0LCB0aGVuIHJldmVyc2UsIHRoZW4gZmxpcAogICAgaW50IHNldDsKICAgIGJvb2wgcmV2OwogICAgYm9vbCBmbGlwOwoKICAgIHZvaWQgb3BlcmF0b3IrPShjb25zdCBMYXp5JiBvdGgpIHsKICAgICAgICBpZiAob3RoLnNldCAhPSAtMSkgcmV2ID0gZmxpcCA9IDAsIHNldCA9IG90aC5zZXQ7CiAgICAgICAgcmV2IF49IG90aC5yZXY7CiAgICAgICAgZmxpcCBePSBvdGguZmxpcDsKICAgIH0KfTsKCmNvbnN0IExhenkgbGlkID0gey0xLCBmYWxzZSwgZmFsc2V9OwoKLy8gWW91IGNhbiBpbXBsZW1lbnQgeW91ciBvd24gbW9ub2lkIGhlcmUgZm9yIGN1c3RvbSBvcGVyYXRpb25zLgpzdHJ1Y3QgVmFsdWUgewogICAgaW50IGFucywgdG90MCwgdG90MSwgcGZ4MCwgcGZ4MSwgc2Z4MCwgc2Z4MTsKCiAgICBzdGF0aWMgVmFsdWUgbWFrZShpbnQgeCwgaW50IGxlbiA9IDEpIHsKICAgICAgICBpZiAoeCkgcmV0dXJuIHtsZW4sIDAsIGxlbiwgMCwgbGVuLCAwLCBsZW59OwogICAgICAgIGVsc2UgcmV0dXJuIHtsZW4sIGxlbiwgMCwgbGVuLCAwLCBsZW4sIDB9OwogICAgfSAKCiAgICB2b2lkIHVwZChMYXp5IGxhenksIGludCBzeikgewogICAgICAgIGlmIChsYXp5LnNldCAhPSAtMSkgewogICAgICAgICAgICAqdGhpcyA9IG1ha2UobGF6eS5zZXQsIHRvdDAgKyB0b3QxKTsKICAgICAgICB9CiAgICAgICAgaWYgKGxhenkucmV2KSB7CiAgICAgICAgICAgIHN3YXAocGZ4MCwgc2Z4MCk7CiAgICAgICAgICAgIHN3YXAocGZ4MSwgc2Z4MSk7CiAgICAgICAgfQogICAgICAgIGlmIChsYXp5LmZsaXApIHsKICAgICAgICAgICAgc3dhcCh0b3QwLCB0b3QxKTsKICAgICAgICAgICAgc3dhcChwZngwLCBwZngxKTsKICAgICAgICAgICAgc3dhcChzZngwLCBzZngxKTsKICAgICAgICB9CiAgICB9CgogICAgVmFsdWUgb3BlcmF0b3IrKGNvbnN0IFZhbHVlJiBvdGgpIGNvbnN0IHsKICAgICAgICBWYWx1ZSByZXMge307CiAgICAgICAgcmVzLmFucyA9IG1heCh7YW5zLCBvdGguYW5zLCBzZngwICsgb3RoLnBmeDAsIHNmeDEgKyBvdGgucGZ4MX0pOwogICAgICAgIHJlcy50b3QwID0gdG90MCArIG90aC50b3QwOwogICAgICAgIHJlcy50b3QxID0gdG90MSArIG90aC50b3QxOwogICAgICAgIGlmICh0b3QxID09IDApIHJlcy5wZngwID0gdG90MCArIG90aC5wZngwOwogICAgICAgIGVsc2UgcmVzLnBmeDAgPSBwZngwOwogICAgICAgIGlmICh0b3QwID09IDApIHJlcy5wZngxID0gdG90MSArIG90aC5wZngxOwogICAgICAgIGVsc2UgcmVzLnBmeDEgPSBwZngxOwogICAgICAgIGlmIChvdGgudG90MSA9PSAwKSByZXMuc2Z4MCA9IHNmeDAgKyBvdGgudG90MDsKICAgICAgICBlbHNlIHJlcy5zZngwID0gb3RoLnNmeDA7CiAgICAgICAgaWYgKG90aC50b3QwID09IDApIHJlcy5zZngxID0gc2Z4MSArIG90aC50b3QxOwogICAgICAgIGVsc2UgcmVzLnNmeDEgPSBvdGguc2Z4MTsKICAgICAgICByZXR1cm4gcmVzOwogICAgfQp9OwoKY29uc3QgVmFsdWUgdmlkID0gezAsIDAsIDAsIDAsIDAsIDAsIDB9OwoKLy8gZW5kIGN1c3RvbSBjb2RlCgovLyBnZW5lcmF0ZWQgYXQgY2F0ZXJwaWxsb3cuZ2l0aHViLmlvL2J5b3QKCm10MTk5MzcgbXQoY2hyb25vOjpzdGVhZHlfY2xvY2s6Om5vdygpLnRpbWVfc2luY2VfZXBvY2goKS5jb3VudCgpKTsKdXNpbmcgcHRyID0gc3RydWN0IE5vZGUqOwoKc3RydWN0IE5vZGUgewogICAgVmFsdWUgdmFsOwogICAgVmFsdWUgYWdnOwogICAgTGF6eSBsYXp5OwoKICAgIGludCBzejsKICAgIGludCBwcmk7CiAgICBwdHIgbCwgcjsKCiAgICBOb2RlKCkgewogICAgICAgIHByaSA9IG10KCk7CiAgICAgICAgdmFsID0gdmlkOwogICAgICAgIGFnZyA9IHZpZDsKICAgICAgICBsYXp5ID0gbGlkOwogICAgICAgIHN6ID0gMTsKICAgICAgICBsID0gciA9IG51bGxwdHI7CiAgICB9CgogICAgTm9kZShWYWx1ZSB2YWwpIDogdmFsKHZhbCksIGFnZyh2YWwpIHsKICAgICAgICBwcmkgPSBtdCgpOwogICAgICAgIGxhenkgPSBsaWQ7CiAgICAgICAgc3ogPSAxOwogICAgICAgIGwgPSByID0gbnVsbHB0cjsKICAgIH0KCiAgICB+Tm9kZSgpIHsKICAgICAgICBkZWxldGUgbDsKICAgICAgICBkZWxldGUgcjsKICAgIH0KfTsKCmludCBzeihwdHIgbikgeyByZXR1cm4gbiA/IG4tPnN6IDogMDsgfTsKVmFsdWUgYWdnKHB0ciBuKSB7IHJldHVybiBuID8gbi0+YWdnIDogdmlkOyB9Cgp2b2lkIHB1c2gocHRyIG4pIHsKICAgIG4tPnZhbC51cGQobi0+bGF6eSwgMSk7CiAgICBuLT5hZ2cudXBkKG4tPmxhenksIHN6KG4pKTsKICAgIGlmIChuLT5sYXp5LnJldikgc3dhcChuLT5sLCBuLT5yKTsKICAgIGlmIChuLT5sKSBuLT5sLT5sYXp5ICs9IG4tPmxhenk7CiAgICBpZiAobi0+cikgbi0+ci0+bGF6eSArPSBuLT5sYXp5OwogICAgbi0+bGF6eSA9IGxpZDsKfQoKcHRyIHB1bGwocHRyIG4pIHsKICAgIGlmICghbikgcmV0dXJuIG51bGxwdHI7CiAgICBpZiAobi0+bCkgcHVzaChuLT5sKTsKICAgIGlmIChuLT5yKSBwdXNoKG4tPnIpOwogICAgbi0+c3ogPSBzeihuLT5sKSArIDEgKyBzeihuLT5yKTsKICAgIG4tPmFnZyA9IGFnZyhuLT5sKSArIG4tPnZhbCArIGFnZyhuLT5yKTsKICAgIHJldHVybiBuOwp9CgpwdHIgbWVyZ2UocHRyIGwsIHB0ciByKSB7CiAgICBpZiAoIWwgfHwgIXIpIHJldHVybiBsID8gbCA6IHI7CiAgICBwdXNoKGwpLCBwdXNoKHIpOwogICAgaWYgKGwtPnByaSA+IHItPnByaSkgcmV0dXJuIGwtPnIgPSBtZXJnZShsLT5yLCByKSwgcHVsbChsKTsKICAgIGVsc2UgcmV0dXJuIHItPmwgPSBtZXJnZShsLCByLT5sKSwgcHVsbChyKTsKfQoKLy8gWy1pbmYsIGkpIGFuZCBbaSwgaW5mXQpwYWlyPHB0ciwgcHRyPiBzcGxpdGkocHRyIG4sIGludCBpKSB7CiAgICBpZiAoIW4pIHJldHVybiB7bnVsbHB0ciwgbnVsbHB0cn07CiAgICBwdXNoKG4pOwogICAgaWYgKGkgPD0gc3oobi0+bCkpIHsKICAgICAgICBhdXRvIFtsLCByXSA9IHNwbGl0aShuLT5sLCBpKTsKICAgICAgICBuLT5sID0gcjsKICAgICAgICByZXR1cm4ge2wsIHB1bGwobil9OwogICAgfSBlbHNlIHsKICAgICAgICBhdXRvIFtsLCByXSA9IHNwbGl0aShuLT5yLCBpIC0gMSAtIHN6KG4tPmwpKTsKICAgICAgICBuLT5yID0gbDsKICAgICAgICByZXR1cm4ge3B1bGwobiksIHJ9OwogICAgfQp9CgovLyB5b3UgQ0FOTk9UIHVzZSB0aGUgbm9ybWFsIHJhbmdlIHVwZGF0ZSBmb3IgcmFuZ2UgcmV2ZXJzZXMKdm9pZCByZXZlcnNlaShwdHImIG4sIGludCBsbywgaW50IGhpKSB7CiAgICBhdXRvIFtsbSwgcl0gPSBzcGxpdGkobiwgaGkpOwogICAgYXV0byBbbCwgbV0gPSBzcGxpdGkobG0sIGxvKTsKICAgIExhenkgdXBkID0gbGlkOwogICAgdXBkLnJldiA9IHRydWU7CiAgICBpZiAobSkgbS0+bGF6eSArPSB1cGQ7CiAgICBuID0gbWVyZ2UobWVyZ2UobCwgbSksIHIpOwp9Cgp2b2lkIHVwZGkocHRyIG4sIGludCBsbywgaW50IGhpLCBMYXp5IGxhenkpIHsKICAgIGlmICghbikgcmV0dXJuOwogICAgcHVzaChuKTsKICAgIGlmIChsbyA+PSBuLT5zeiB8fCBoaSA8PSAwKSByZXR1cm47CiAgICBpZiAobG8gPD0gMCAmJiBuLT5zeiA8PSBoaSkgewogICAgICAgIG4tPmxhenkgKz0gbGF6eTsKICAgICAgICBwdXNoKG4pOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGlmIChsbyA8PSBzeihuLT5sKSAmJiBzeihuLT5sKSA8IGhpKSBuLT52YWwudXBkKGxhenksIDEpOwogICAgdXBkaShuLT5sLCBsbywgaGksIGxhenkpOwogICAgdXBkaShuLT5yLCBsbyAtIDEgLSBzeihuLT5sKSwgaGkgLSAxIC0gc3oobi0+bCksIGxhenkpOwogICAgcHVsbChuKTsKfQoKVmFsdWUgcXVlcnlpKHB0ciBuLCBpbnQgbG8sIGludCBoaSkgewogICAgaWYgKCFuIHx8IGxvID49IHN6KG4pIHx8IGhpIDw9IDApIHJldHVybiB2aWQ7CiAgICBwdXNoKG4pOwogICAgaWYgKGxvIDw9IDAgJiYgc3oobikgPD0gaGkpIHJldHVybiBuLT5hZ2c7CiAgICByZXR1cm4gcXVlcnlpKG4tPmwsIGxvLCBoaSkgKyAobG8gPD0gc3oobi0+bCkgJiYgc3oobi0+bCkgPCBoaSA/IG4tPnZhbCA6IHZpZCkgKyBxdWVyeWkobi0+ciwgbG8gLSAxIC0gc3oobi0+bCksIGhpIC0gMSAtIHN6KG4tPmwpKTsKfQoKdm9pZCBoZWFwaWZ5KHB0ciBuKSB7CiAgICBpZiAoIW4pIHJldHVybjsKICAgIHB0ciBteCA9IG47CiAgICBpZiAobi0+bCAmJiBuLT5sLT5wcmkgPiBteC0+cHJpKSBteCA9IG4tPmw7CiAgICBpZiAobi0+ciAmJiBuLT5yLT5wcmkgPiBteC0+cHJpKSBteCA9IG4tPnI7CiAgICBpZiAobXggIT0gbikgc3dhcChuLT5wcmksIG14LT5wcmkpLCBoZWFwaWZ5KG14KTsKfQoKcHRyIGJ1aWxkKHZlY3RvcjxwdHI+JiBucywgaW50IGwgPSAwLCBpbnQgciA9IC02OSkgewogICAgaWYgKHIgPT0gLTY5KSByID0gKGludCkgbnMuc2l6ZSgpIC0gMTsKICAgIGlmIChsID4gcikgcmV0dXJuIG51bGxwdHI7CiAgICBpZiAobCA9PSByKSByZXR1cm4gbnNbbF07CiAgICBpbnQgbSA9IChsICsgcikgLyAyOwogICAgbnNbbV0tPmwgPSBidWlsZChucywgbCwgbSAtIDEpOwogICAgbnNbbV0tPnIgPSBidWlsZChucywgbSArIDEsIHIpOwogICAgaGVhcGlmeShuc1ttXSk7CiAgICByZXR1cm4gcHVsbChuc1ttXSk7Cn0KCi8qCgotIGluY2x1ZGUgcmFuZ2UgcmV2ZXJzZSBieSBpbmRleCAoYW5kIGxhenkgcHJvcCwgc2l6ZSwgc3BsaXQgYnkgaW5kZXggYW5kIG1lcmdlKQotIGluY2x1ZGUgYnVpbGQgKGFuZCBoZWFwaWZ5KQotIGluY2x1ZGUgcmFuZ2UgYWdncmVnYXRlcwotIGluY2x1ZGUgcmFuZ2UgdXBkYXRlcyBieSBpbmRleAotIGluY2x1ZGUgcmFuZ2UgcXVlcmllcyBieSBpbmRleAoKKi8KCm1haW4oKSB7CiAgICBjaW4udGllKDApLT5zeW5jX3dpdGhfc3RkaW8oMCk7CiAgICAKICAgIGludCBuLCBxOyBjaW4gPj4gbiA+PiBxOwoKICAgIHZlY3RvcjxwdHI+IG5zKG4pOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgICAgICBjaGFyIHg7IGNpbiA+PiB4OwogICAgICAgIG5zW2ldID0gbmV3IE5vZGUoVmFsdWU6Om1ha2UoeCAtICcwJykpOwogICAgfQogICAgcHRyIHRyZWFwID0gYnVpbGQobnMpOwoKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcTsgaSsrKSB7CiAgICAgICAgaW50IHQsIGwsIHI7IGNpbiA+PiB0ID4+IGwgPj4gcjsKICAgICAgICBsLS07CiAgICAgICAgaWYgKHQgPT0gMSkgewogICAgICAgICAgICB1cGRpKHRyZWFwLCBsLCByLCB7LTEsIGZhbHNlLCB0cnVlfSk7CiAgICAgICAgfQogICAgICAgIGlmICh0ID09IDIpIHsKICAgICAgICAgICAgcmV2ZXJzZWkodHJlYXAsIGwsIHIpOwogICAgICAgIH0KICAgICAgICBpZiAodCA9PSAzKSB7CiAgICAgICAgICAgIFZhbHVlIHJlcyA9IHF1ZXJ5aSh0cmVhcCwgbCwgcik7CiAgICAgICAgICAgIHVwZGkodHJlYXAsIGwsIGwgKyByZXMudG90MCwgezAsIGZhbHNlLCBmYWxzZX0pOwogICAgICAgICAgICB1cGRpKHRyZWFwLCByIC0gcmVzLnRvdDEsIHIsIHsxLCBmYWxzZSwgZmFsc2V9KTsKICAgICAgICB9CiAgICAgICAgcHVzaCh0cmVhcCk7IAogICAgICAgIGNvdXQgPDwgYWdnKHRyZWFwKS5hbnMgPDwgJ1xuJzsKICAgIH0KICAgIGRlbGV0ZSB0cmVhcDsKfQo=