pub trait Zero: PartialEq + Sized {
    fn zero() -> Self;
    #[inline]
    fn is_zero(&self) -> bool {
        self == &Self::zero()
    }
}
pub trait One: PartialEq + Sized {
    fn one() -> Self;
    #[inline]
    fn is_one(&self) -> bool {
        self == &Self::one()
    }
}
macro_rules !zero_one_impls {($({$Trait :ident $method :ident $($t :ty ) *,$e :expr } ) *) =>{$($(impl $Trait for $t {#[inline ] fn $method () ->Self {$e } } ) *) *} ;}
zero_one_impls !({Zero zero u8 u16 u32 u64 usize i8 i16 i32 i64 isize u128 i128 ,0 } {Zero zero f32 f64 ,0. } {One one u8 u16 u32 u64 usize i8 i16 i32 i64 isize u128 i128 ,1 } {One one f32 f64 ,1. } ) ;
pub trait IterScan: Sized {
    type Output;
    fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output>;
}
pub trait MarkedIterScan: Sized {
    type Output;
    fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output>;
}
#[derive(Clone, Debug)]
pub struct Scanner<'a> {
    iter: std::str::SplitAsciiWhitespace<'a>,
}
mod scanner_impls {
    use super::*;
    impl<'a> Scanner<'a> {
        #[inline]
        pub fn new(s: &'a str) -> Self {
            let iter = s.split_ascii_whitespace();
            Self { iter }
        }
        #[inline]
        pub fn scan<T: IterScan>(&mut self) -> <T as IterScan>::Output {
            <T as IterScan>::scan(&mut self.iter).expect("scan error")
        }
        #[inline]
        pub fn mscan<T: MarkedIterScan>(&mut self, marker: T) -> <T as MarkedIterScan>::Output {
            marker.mscan(&mut self.iter).expect("scan error")
        }
        #[inline]
        pub fn scan_vec<T: IterScan>(&mut self, size: usize) -> Vec<<T as IterScan>::Output> {
            (0..size)
                .map(|_| <T as IterScan>::scan(&mut self.iter).expect("scan error"))
                .collect()
        }
        #[inline]
        pub fn iter<'b, T: IterScan>(&'b mut self) -> ScannerIter<'a, 'b, T> {
            ScannerIter {
                inner: self,
                _marker: std::marker::PhantomData,
            }
        }
    }
    macro_rules !iter_scan_impls {($($t :ty ) *) =>{$(impl IterScan for $t {type Output =Self ;#[inline ] fn scan <'a ,I :Iterator <Item =&'a str >>(iter :&mut I ) ->Option <Self >{iter .next () ?.parse ::<$t >() .ok () } } ) *} ;}
    iter_scan_impls !(char u8 u16 u32 u64 usize i8 i16 i32 i64 isize f32 f64 u128 i128 String ) ;
    macro_rules !iter_scan_tuple_impl {($($T :ident ) *) =>{impl <$($T :IterScan ) ,*>IterScan for ($($T ,) *) {type Output =($(<$T as IterScan >::Output ,) *) ;#[inline ] fn scan <'a ,It :Iterator <Item =&'a str >>(_iter :&mut It ) ->Option <Self ::Output >{Some (($(<$T as IterScan >::scan (_iter ) ?,) *) ) } } } ;}
    iter_scan_tuple_impl!();
    iter_scan_tuple_impl!(A);
    iter_scan_tuple_impl !(A B ) ;
    iter_scan_tuple_impl !(A B C ) ;
    iter_scan_tuple_impl !(A B C D ) ;
    iter_scan_tuple_impl !(A B C D E ) ;
    iter_scan_tuple_impl !(A B C D E F ) ;
    iter_scan_tuple_impl !(A B C D E F G ) ;
    iter_scan_tuple_impl !(A B C D E F G H ) ;
    iter_scan_tuple_impl !(A B C D E F G H I ) ;
    iter_scan_tuple_impl !(A B C D E F G H I J ) ;
    iter_scan_tuple_impl !(A B C D E F G H I J K ) ;
    pub struct ScannerIter<'a, 'b, T> {
        inner: &'b mut Scanner<'a>,
        _marker: std::marker::PhantomData<fn() -> T>,
    }
    impl<'a, 'b, T: IterScan> Iterator for ScannerIter<'a, 'b, T> {
        type Item = <T as IterScan>::Output;
        #[inline]
        fn next(&mut self) -> Option<Self::Item> {
            <T as IterScan>::scan(&mut self.inner.iter)
        }
    }
}
pub mod marker {
    use super::*;
    use std::{iter::FromIterator, marker::PhantomData};
    #[derive(Debug, Copy, Clone)]
    pub struct Usize1;
    impl IterScan for Usize1 {
        type Output = usize;
        #[inline]
        fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> {
            Some(<usize as IterScan>::scan(iter)?.checked_sub(1)?)
        }
    }
    #[derive(Debug, Copy, Clone)]
    pub struct Chars;
    impl IterScan for Chars {
        type Output = Vec<char>;
        #[inline]
        fn scan<'a, I: Iterator<Item = &'a str>>(iter: &mut I) -> Option<Self::Output> {
            Some(iter.next()?.chars().collect())
        }
    }
    #[derive(Debug, Copy, Clone)]
    pub struct CharsWithBase(pub char);
    impl MarkedIterScan for CharsWithBase {
        type Output = Vec<usize>;
        #[inline]
        fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output> {
            Some(
                iter.next()?
                    .chars()
                    .map(|c| (c as u8 - self.0 as u8) as usize)
                    .collect(),
            )
        }
    }
    #[derive(Debug, Copy, Clone)]
    pub struct Collect<T: IterScan, B: FromIterator<<T as IterScan>::Output>> {
        size: usize,
        _marker: PhantomData<fn() -> (T, B)>,
    }
    impl<T: IterScan, B: FromIterator<<T as IterScan>::Output>> Collect<T, B> {
        pub fn new(size: usize) -> Self {
            Self {
                size,
                _marker: PhantomData,
            }
        }
    }
    impl<T: IterScan, B: FromIterator<<T as IterScan>::Output>> MarkedIterScan for Collect<T, B> {
        type Output = B;
        #[inline]
        fn mscan<'a, I: Iterator<Item = &'a str>>(self, iter: &mut I) -> Option<Self::Output> {
            Some(
                (0..self.size)
                    .map(|_| <T as IterScan>::scan(iter).expect("scan error"))
                    .collect::<B>(),
            )
        }
    }
}
#[macro_export]
macro_rules !min {($e :expr ) =>{$e } ;($e :expr ,$($es :expr ) ,+) =>{std ::cmp ::min ($e ,min !($($es ) ,+) ) } ;}
#[macro_export]
macro_rules !chmin {($dst :expr ,$($src :expr ) ,+) =>{{let x =std ::cmp ::min ($dst ,min !($($src ) ,+) ) ;$dst =x ;} } ;}
#[macro_export]
macro_rules !max {($e :expr ) =>{$e } ;($e :expr ,$($es :expr ) ,+) =>{std ::cmp ::max ($e ,max !($($es ) ,+) ) } ;}
#[macro_export]
macro_rules !chmax {($dst :expr ,$($src :expr ) ,+) =>{{let x =std ::cmp ::max ($dst ,max !($($src ) ,+) ) ;$dst =x ;} } ;}
/// binary operaion: $T \circ T \to T$
pub trait Magma {
    /// type of operands: $T$
    type T: Clone + PartialEq;
    /// binary operaion: $\circ$
    fn operate(&self, x: &Self::T, y: &Self::T) -> Self::T;
    #[inline]
    fn reverse_operate(&self, x: &Self::T, y: &Self::T) -> Self::T {
        self.operate(y, x)
    }
}
/// $\forall a,\forall b,\forall c \in T, (a \circ b) \circ c = a \circ (b \circ c)$
pub trait Associative {}
/// associative binary operation
pub trait SemiGroup: Magma + Associative {}
impl<S: Magma + Associative> SemiGroup for S {}
/// $\exists e \in T, \forall a \in T, e \circ a = a \circ e = e$
pub trait Unital: Magma {
    /// identity element: $e$
    fn unit(&self) -> Self::T;
}
/// associative binary operation and an identity element
pub trait Monoid: SemiGroup + Unital {
    /// binary exponentiation: $x^n = x\circ\ddots\circ x$
    fn pow(&self, x: Self::T, n: usize) -> Self::T {
        let mut n = n;
        let mut res = self.unit();
        let mut base = x;
        while n > 0 {
            if n & 1 == 1 {
                res = self.operate(&res, &base);
            }
            base = self.operate(&base, &base);
            n = n >> 1;
        }
        res
    }
}
impl<M: SemiGroup + Unital> Monoid for M {}
/// $\exists e \in T, \forall a \in T, \exists b,c \in T, b \circ a = a \circ c = e$
pub trait Invertible: Magma {
    /// $a$ where $a \circ x = e$
    fn inverse(&self, x: &Self::T) -> Self::T;
    #[inline]
    fn rinv_operate(&self, x: &Self::T, y: &Self::T) -> Self::T {
        self.operate(x, &self.inverse(y))
    }
}
/// associative binary operation and an identity element and inverse elements
pub trait Group: Monoid + Invertible {}
impl<G: Monoid + Invertible> Group for G {}
/// $\forall a,\forall b \in T, a \circ b = b \circ a$
pub trait Commutative {}
/// commutative monoid
pub trait AbelianMonoid: Monoid + Commutative {}
impl<M: Monoid + Commutative> AbelianMonoid for M {}
/// commutative group
pub trait AbelianGroup: Group + Commutative {}
impl<G: Group + Commutative> AbelianGroup for G {}
/// $\forall a \in T, a \circ a = a$
pub trait Idempotent {}
/// idempotent monoid
pub trait IdempotentMonoid: Monoid + Idempotent {}
impl<M: Monoid + Idempotent> IdempotentMonoid for M {}
#[derive(Clone, Debug)]
pub struct MonoidalOperation<T: Clone + PartialEq, F: Fn(&T, &T) -> T> {
    e: T,
    op: F,
}
mod monoidal_operation_impl {
    use super::*;
    impl<T: Clone + PartialEq, F: Fn(&T, &T) -> T> MonoidalOperation<T, F> {
        pub fn new(e: T, op: F) -> Self {
            Self { e, op }
        }
    }
    impl<T: Clone + PartialEq, F: Fn(&T, &T) -> T> Magma for MonoidalOperation<T, F> {
        type T = T;
        #[inline]
        fn operate(&self, x: &Self::T, y: &Self::T) -> Self::T {
            (self.op)(x, y)
        }
    }
    impl<T: Clone + PartialEq, F: Fn(&T, &T) -> T> Unital for MonoidalOperation<T, F> {
        #[inline]
        fn unit(&self) -> Self::T {
            self.e.clone()
        }
    }
    impl<T: Clone + PartialEq, F: Fn(&T, &T) -> T> Associative for MonoidalOperation<T, F> {}
    impl<T: Clone + PartialEq, F: Fn(&T, &T) -> T> Commutative for MonoidalOperation<T, F> {}
}
/// ^
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct BitXorOperation<T: Copy + PartialEq + BitXorIdentity> {
    _marker: std::marker::PhantomData<fn() -> T>,
}
pub trait BitXorIdentity: Sized + std::ops::BitXor<Output = Self> {
    fn xor_zero() -> Self;
}
mod bitxor_operation_impl {
    use super::*;
    #[macro_export(local_inner_macros)]
    macro_rules !impl_bitxor_identity {([$($wh :tt ) *] ,$t :ty ,$xor_zero :expr ) =>{impl <$($wh ) *>BitXorIdentity for $t {#[inline ] fn xor_zero () ->Self {$xor_zero } } } ;($t :ty ,$xor_zero :expr ) =>{impl BitXorIdentity for $t {#[inline ] fn xor_zero () ->Self {$xor_zero } } } ;}
    impl_bitxor_identity!(bool, false);
    impl_bitxor_identity!(usize, 0usize);
    impl_bitxor_identity!(u8, 0u8);
    impl_bitxor_identity!(u16, 0u16);
    impl_bitxor_identity!(u32, 0u32);
    impl_bitxor_identity!(u64, 0u64);
    impl_bitxor_identity!(isize, 0isize);
    impl_bitxor_identity!(i8, 0i8);
    impl_bitxor_identity!(i16, 0i16);
    impl_bitxor_identity!(i32, 0i32);
    impl_bitxor_identity!(i64, 0i64);
    impl<T: Copy + PartialEq + BitXorIdentity> BitXorOperation<T> {
        pub fn new() -> Self {
            Self {
                _marker: std::marker::PhantomData,
            }
        }
    }
    impl<T: Copy + PartialEq + BitXorIdentity> Magma for BitXorOperation<T> {
        type T = T;
        #[inline]
        fn operate(&self, x: &Self::T, y: &Self::T) -> Self::T {
            *x ^ *y
        }
    }
    impl<T: Copy + PartialEq + BitXorIdentity> Unital for BitXorOperation<T> {
        #[inline]
        fn unit(&self) -> Self::T {
            BitXorIdentity::xor_zero()
        }
    }
    impl<T: Copy + PartialEq + BitXorIdentity> Associative for BitXorOperation<T> {}
    impl<T: Copy + PartialEq + BitXorIdentity> Commutative for BitXorOperation<T> {}
    impl<T: Copy + PartialEq + BitXorIdentity> Idempotent for BitXorOperation<T> {}
}
/// M: folding Monoid
/// E: lazy Monoid
/// F: lazy evaluating
#[derive(Clone, Debug)]
pub struct LazySegmentTree<M: Monoid, E: Monoid, F: Fn(&M::T, &E::T) -> M::T> {
    n: usize,
    height: usize,
    seg: Vec<M::T>,
    lazy: Vec<E::T>,
    m: M,
    e: E,
    f: F,
}
impl<M: Monoid, E: Monoid, F: Fn(&M::T, &E::T) -> M::T> LazySegmentTree<M, E, F> {
    pub fn new(n: usize, m: M, e: E, f: F) -> Self {
        let height = format!("{:b}", n - 1).len();
        let n = 1 << height;
        let seg = vec![m.unit(); 2 * n];
        let lazy = vec![e.unit(); 2 * n];
        Self {
            n,
            height,
            seg,
            lazy,
            m,
            e,
            f,
        }
    }
    pub fn from_vec(v: Vec<M::T>, m: M, e: E, f: F) -> Self {
        let height = format!("{:b}", v.len() - 1).len();
        let n = 1 << height;
        let mut seg = vec![m.unit(); 2 * n];
        for (i, x) in v.into_iter().enumerate() {
            seg[i + n] = x;
        }
        for i in (1..n).rev() {
            seg[i] = m.operate(&seg[2 * i], &seg[2 * i + 1]);
        }
        let lazy = vec![e.unit(); 2 * n];
        Self {
            n,
            height,
            seg,
            lazy,
            m,
            e,
            f,
        }
    }
    #[inline]
    fn propagate(&mut self, k: usize) {
        debug_assert!(k < self.n);
        if self.lazy[k] != self.e.unit() {
            self.lazy[2 * k] = self.e.operate(&self.lazy[2 * k], &self.lazy[k]);
            self.lazy[2 * k + 1] = self.e.operate(&self.lazy[2 * k + 1], &self.lazy[k]);
            self.seg[k] = self.reflect(k);
            self.lazy[k] = self.e.unit();
        }
    }
    #[inline]
    fn thrust(&mut self, k: usize) {
        for i in (1..=self.height).rev() {
            self.propagate(k >> i);
        }
    }
    #[inline]
    fn reflect(&self, k: usize) -> M::T {
        if self.lazy[k] != self.e.unit() {
            (self.f)(&self.seg[k], &self.lazy[k])
        } else {
            self.seg[k].clone()
        }
    }
    #[inline]
    fn recalc(&mut self, mut k: usize) {
        k /= 2;
        while k > 0 {
            self.seg[k] = self
                .m
                .operate(&self.reflect(2 * k), &self.reflect(2 * k + 1));
            k /= 2;
        }
    }
    pub fn update(&mut self, l: usize, r: usize, x: E::T) {
        debug_assert!(l < self.n);
        debug_assert!(r <= self.n);
        let mut a = l + self.n;
        let mut b = r + self.n;
        self.thrust(a);
        self.thrust(b - 1);
        while a < b {
            if a & 1 != 0 {
                self.lazy[a] = self.e.operate(&self.lazy[a], &x);
                a += 1;
            }
            if b & 1 != 0 {
                b -= 1;
                self.lazy[b] = self.e.operate(&self.lazy[b], &x);
            }
            a /= 2;
            b /= 2;
        }
        self.recalc(l + self.n);
        self.recalc(r + self.n - 1);
    }
    pub fn fold(&mut self, l: usize, r: usize) -> M::T {
        debug_assert!(l < self.n);
        debug_assert!(r <= self.n);
        let mut l = l + self.n;
        let mut r = r + self.n;
        self.thrust(l);
        self.thrust(r - 1);
        let mut vl = self.m.unit();
        let mut vr = self.m.unit();
        while l < r {
            if l & 1 != 0 {
                vl = self.m.operate(&vl, &self.reflect(l));
                l += 1;
            }
            if r & 1 != 0 {
                r -= 1;
                vr = self.m.operate(&self.reflect(r), &vr);
            }
            l /= 2;
            r /= 2;
        }
        self.m.operate(&vl, &vr)
    }
    pub fn set(&mut self, k: usize, x: M::T) {
        let k = k + self.n;
        self.thrust(k);
        self.seg[k] = x;
        self.lazy[k] = self.e.unit();
        self.recalc(k);
    }
    pub fn get(&mut self, k: usize) -> M::T {
        self.fold(k, k + 1)
    }
    pub fn fold_all(&mut self) -> M::T {
        self.fold(0, self.n)
    }
    pub fn as_slice(&self) -> &[M::T] {
        &self.seg[self.n..]
    }
    pub fn as_slice_lazy(&self) -> &[E::T] {
        &self.lazy[self.n..]
    }
}
fn main() {
    #![allow(unused_imports, unused_macros)]
    use std::io::{stdin, stdout, BufWriter, Read as _, Write as _};
    let mut _in_buf = Vec::new();
    stdin().read_to_end(&mut _in_buf).expect("io error");
    let _in_buf = unsafe { String::from_utf8_unchecked(_in_buf) };
    let mut scanner = Scanner::new(&_in_buf);
    macro_rules !scan {() =>{scan !(usize ) } ;(($($t :tt ) ,*) ) =>{($(scan !($t ) ) ,*) } ;([$t :ty ;$len :expr ] ) =>{scanner .scan_vec ::<$t >($len ) } ;([$t :tt ;$len :expr ] ) =>{(0 ..$len ) .map (|_ |scan !($t ) ) .collect ::<Vec <_ >>() } ;([$t :ty ] ) =>{scanner .iter ::<$t >() } ;({$e :expr } ) =>{scanner .mscan ($e ) } ;($t :ty ) =>{scanner .scan ::<$t >() } ;}
    let _out = stdout();
    let mut _out = BufWriter::new(_out.lock());
    macro_rules !print {($($arg :tt ) *) =>(::std ::write !(_out ,$($arg ) *) .expect ("io error" ) ) }
    macro_rules !println {($($arg :tt ) *) =>(::std ::writeln !(_out ,$($arg ) *) .expect ("io error" ) ) }
    macro_rules! echo {
        ($iter :expr ) => {
            echo!($iter, '\n')
        };
        ($iter :expr ,$sep :expr ) => {
            let mut iter = $iter.into_iter();
            if let Some(item) = iter.next() {
                print!("{}", item);
            }
            for item in iter {
                print!("{}{}", $sep, item);
            }
            println!();
        };
    }
    let n = scan!();
    let q = scan!();
    let a = scan!([usize; n]);
    let c2 = |n: usize| n * n.saturating_sub(1) / 2;
    let inv = |(z, o, i): (usize, usize, usize)| {
        let s = z + o;
        c2(s) - c2(z) - c2(o) - i
    };
    let mut seg = LazySegmentTree::from_vec(
        a.into_iter().map(|a| (1 - a, a, 0)).collect(),
        MonoidalOperation::new((0, 0, 0), |x, y| {
            (x.0 + y.0, x.1 + y.1, x.2 + y.2 + x.1 * y.0)
        }),
        BitXorOperation::new(),
        |x, y| if *y { (x.1, x.0, inv(*x)) } else { *x },
    );
    for (t, l, r) in scan!([(marker::Usize1, marker::Usize1, usize)]).take(q) {
        if t == 0 {
            seg.update(l, r, true);
        } else {
            println!("{}", seg.fold(l, r).2);
        }
    }
}

Measured memory_bytes: 22360