#![doc = " # Bundled libraries"]
#![doc = ""]
#![doc = " ## `kyopro_lib` (private)"]
#![doc = ""]
#![doc = " ### Modules"]
#![doc = ""]
#![doc = " - `::__kyopro_lib::segtree` → `$crate::segtree`"]
#[allow(unused_imports)]
use itertools::Itertools;
use proconio::input;
#[allow(unused_imports)]
use proconio::marker::*;
fn main() {
    input! { n : usize , q : usize , a : [u64 ; n] , tlr : [(u8 , Usize1 , usize) ; q] , }
    let mut st = LazySegTree::build_from_iter(
        a.iter().map(|a| (0, 0, 1 - a, *a)),
        (0, 0, 0, 0),
        |a, b| {
            (
                a.0 + b.0 + a.3 * b.2,
                a.1 + b.1 + a.2 * b.3,
                a.2 + b.2,
                a.3 + b.3,
            )
        },
        |a, b| a ^ b,
        |a, b, _| {
            if *b {
                (a.1, a.0, a.3, a.2)
            } else {
                *a
            }
        },
    );
    for (t, l, r) in tlr {
        if t == 1 {
            st.update_range(l..r, true);
        } else {
            println!("{}", st.query(l..r).0);
        }
    }
}
use self::segtree::LazySegTree;
pub mod segtree {
    use std::ops::Range;
    use std::ops::RangeBounds;
    fn bound_to_range<R: RangeBounds<usize>>(r1: R, r2: Range<usize>) -> Range<usize> {
        use std::ops::Bound;
        let s = match r1.start_bound() {
            Bound::Included(&s) => s,
            Bound::Excluded(&s) => s + 1,
            Bound::Unbounded => r2.start,
        };
        let e = match r1.end_bound() {
            Bound::Included(&e) => e + 1,
            Bound::Excluded(&e) => e,
            Bound::Unbounded => r2.end,
        };
        std::cmp::max(s, r2.start)..std::cmp::min(e, r2.end)
    }
    fn is_overlap(r1: &Range<usize>, r2: &Range<usize>) -> bool {
        !(r2.end <= r1.start || r1.end <= r2.start)
    }
    fn is_include(r1: &Range<usize>, r2: &Range<usize>) -> bool {
        r1.start <= r2.start && r2.end <= r1.end
    }
    pub struct SegTree<T, F> {
        n: usize,
        id: T,
        dat: Vec<T>,
        f: F,
    }
    impl<T, F> SegTree<T, F>
    where
        T: Clone,
        F: Fn(&T, &T) -> T,
    {
        pub fn new(n: usize, id: T, f: F) -> Self {
            let n = n.next_power_of_two();
            Self {
                n: n,
                id: id.clone(),
                dat: vec![id; n * 2 - 1],
                f: f,
            }
        }
        pub fn build_from_slice(dat: &[T], id: T, f: F) -> Self {
            let n = dat.len().next_power_of_two();
            let mut v = Vec::with_capacity(2 * n - 1);
            v.resize(n - 1, id.clone());
            v.extend_from_slice(dat);
            v.resize(2 * n - 1, id.clone());
            let mut st = Self {
                n: n,
                id: id,
                dat: v,
                f: f,
            };
            for i in (0..n - 1).rev() {
                st.update_at(i);
            }
            st
        }
        pub fn build_from_iter<I: Iterator<Item = T>>(iter: I, id: T, f: F) -> Self {
            use itertools::Itertools;
            Self::build_from_slice(&iter.collect_vec(), id, f)
        }
        #[inline]
        pub fn len(&self) -> usize {
            self.n
        }
        #[inline]
        pub fn get_element(&self, i: usize) -> &T {
            &self.dat[self.n + i - 1]
        }
        #[inline]
        pub fn as_slice(&self) -> &[T] {
            &self.dat[self.n - 1..]
        }
        pub fn update(&mut self, i: usize, dat: T) {
            let i = self.n + i - 1;
            self.dat[i] = dat;
            self.update_to_bottom_up(i);
        }
        pub fn update_by<F2: Fn(&mut T)>(&mut self, i: usize, f: F2) {
            let i = self.n + i - 1;
            f(&mut self.dat[i]);
            self.update_to_bottom_up(i);
        }
        #[inline]
        fn update_at(&mut self, i: usize) {
            self.dat[i] = (self.f)(&self.dat[i * 2 + 1], &self.dat[i * 2 + 2]);
        }
        #[inline]
        fn update_to_bottom_up(&mut self, mut i: usize) {
            while i != 0 {
                i = (i - 1) / 2;
                self.update_at(i);
            }
        }
        pub fn query<R: RangeBounds<usize>>(&self, r: R) -> T {
            self.query_impl(0, &bound_to_range(r, 0..self.n), 0..self.n)
        }
        fn query_impl(&self, k: usize, r: &Range<usize>, a: Range<usize>) -> T {
            if !is_overlap(r, &a) {
                self.id.clone()
            } else if is_include(r, &a) {
                self.dat[k].clone()
            } else {
                let m = (a.start + a.end) / 2;
                (self.f)(
                    &self.query_impl(k * 2 + 1, r, a.start..m),
                    &self.query_impl(k * 2 + 2, r, m..a.end),
                )
            }
        }
    }
    pub struct LazySegTree<T, U, F, G, H> {
        n: usize,
        id: T,
        dat: Vec<T>,
        lazy: Vec<Option<U>>,
        f: F,
        g: G,
        h: H,
    }
    impl<T, U, F, G, H> LazySegTree<T, U, F, G, H>
    where
        T: Clone,
        U: Clone,
        F: Fn(&T, &T) -> T,
        G: Fn(&U, &U) -> U,
        H: Fn(&T, &U, usize) -> T,
    {
        pub fn new(n: usize, id: T, f: F, g: G, h: H) -> Self {
            let n = n.next_power_of_two();
            Self {
                n: n,
                id: id.clone(),
                dat: vec![id; 2 * n - 1],
                lazy: vec![None; 2 * n - 1],
                f: f,
                g: g,
                h: h,
            }
        }
        pub fn build_from_slice(dat: &[T], id: T, f: F, g: G, h: H) -> Self {
            let mut lst = Self::new(dat.len(), id, f, g, h);
            for i in 0..dat.len() {
                lst.dat[lst.n - 1 + i] = dat[i].clone();
            }
            for i in (0..lst.n - 1).rev() {
                lst.dat[i] = (lst.f)(&lst.dat[i * 2 + 1], &lst.dat[i * 2 + 2]);
            }
            lst
        }
        pub fn build_from_iter<I: Iterator<Item = T>>(iter: I, id: T, f: F, g: G, h: H) -> Self {
            use itertools::Itertools;
            Self::build_from_slice(&iter.collect_vec(), id, f, g, h)
        }
        pub fn len(&self) -> usize {
            self.n
        }
        fn marge_effect(&mut self, k: usize, x: &U) {
            if let Some(y) = self.lazy[k].take() {
                self.lazy[k] = Some((self.g)(&y, x));
            } else {
                self.lazy[k] = Some(x.clone());
            }
        }
        fn eval(&mut self, k: usize, l: usize) {
            if let Some(x) = self.lazy[k].take() {
                self.dat[k] = (self.h)(&self.dat[k], &x, l);
                if k < self.n - 1 {
                    self.marge_effect(k * 2 + 1, &x);
                    self.marge_effect(k * 2 + 2, &x);
                }
            }
        }
        pub fn update_range<R: RangeBounds<usize>>(&mut self, r: R, x: U) {
            self.update_range_impl(&bound_to_range(r, 0..self.n), 0, 0..self.n, &x)
        }
        fn update_range_impl(&mut self, r: &Range<usize>, k: usize, a: Range<usize>, x: &U) {
            if !is_overlap(r, &a) {
                self.eval(k, a.end - a.start);
                return;
            }
            if is_include(r, &a) {
                self.marge_effect(k, x);
                self.eval(k, a.end - a.start);
                return;
            }
            let m = (a.start + a.end) / 2;
            self.eval(k, a.end - a.start);
            self.update_range_impl(r, k * 2 + 1, a.start..m, x);
            self.update_range_impl(r, k * 2 + 2, m..a.end, x);
            self.dat[k] = (self.f)(&self.dat[k * 2 + 1], &self.dat[k * 2 + 2]);
        }
        pub fn query<R: RangeBounds<usize>>(&mut self, r: R) -> T {
            self.query_impl(&bound_to_range(r, 0..self.n), 0, 0..self.n)
        }
        fn query_impl(&mut self, r: &Range<usize>, k: usize, a: Range<usize>) -> T {
            if !is_overlap(r, &a) {
                self.id.clone()
            } else if is_include(r, &a) {
                self.eval(k, a.end - a.start);
                self.dat[k].clone()
            } else {
                let m = (a.start + a.end) / 2;
                self.eval(k, a.end - a.start);
                let x = self.query_impl(r, k * 2 + 1, a.start..m);
                let y = self.query_impl(r, k * 2 + 2, m..a.end);
                (self.f)(&x, &y)
            }
        }
    }
}


Measured memory_bytes: 34800