//#include "bits/stdc++.h"

#define _USE_MATH_DEFINES
#include<cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <deque>
#include <algorithm>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <array>
#include <unordered_map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>
#include <iterator>
#include<iomanip>
#include<complex>
#include<fstream>
#include<assert.h>

using namespace std;

#define rep(i,a,b) for(int i=(a), i##_len=(b);i<i##_len;i++)
#define rrep(i,a,b) for(int i=(b)-1;i>=(a);i--)
#define all(c) begin(c),end(c)

#define int ll
#define SZ(x) ((int)(x).size())
#define pb push_back
#define mp make_pair

//typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> pli;
typedef pair<int, double> pid;
typedef pair<double, int> pdi;
typedef pair<double, double> pdd;
typedef vector< vector<int> > mat;

template<class T> bool chmax(T &a, const T &b) { if (a < b) { a = b; return true; } return false; }
template<class T> bool chmin(T &a, const T &b) { if (b < a) { a = b; return true; } return false; }

const int INF = sizeof(int) == sizeof(long long) ? 0x3f3f3f3f3f3f3f3fLL : 0x3f3f3f3f;
const int MOD = (int)1e9 + 7;

const double EPS = 1e-9;

template <typename T, typename E>
struct LazySegmentTree {
	typedef function<T(T, T)> F;//merge
	typedef function<T(T, E)> G;//dat lazy
	typedef function<E(E, E)> H;//lazy lazy
	typedef function<E(E, int)> P;//lazy len

	vector<T> dat; vector<E> laz;
	int n; F f; G g; H h; P p;
	T d1;//datの単位元
	E d0;//lazyの単位元

	LazySegmentTree(int m, F f, G g, H h, P p, T d1, E d0) : f(f), g(g), h(h), p(p), d1(d1), d0(d0)
	{
		n = 1;
		while (n < m) n *= 2;
		dat.assign(2 * n - 1, d1);
		laz.assign(2 * n - 1, d0);
	}

	void init(const vector<T> v)
	{
		for (int i = 0; i < SZ(v); i++) dat[i + n - 1] = v[i];
		for (int i = n - 2; i >= 0; i--) dat[i] = f(dat[i * 2 + 1], dat[i * 2 + 2]);
	}

	inline void eval(int len, int k)
	{
		if (laz[k] == d0) return;
		if (k * 2 + 1 < n * 2 - 1)
		{
			laz[k * 2 + 1] = h(laz[k * 2 + 1], laz[k]);
			laz[k * 2 + 2] = h(laz[k * 2 + 2], laz[k]);
		}
		dat[k] = g(dat[k], p(laz[k], len));
		laz[k] = d0;
	}

	void update(int a, int b, E x, int k, int l, int r)
	{
		eval(r - l, k);
		if (a <= l && r <= b)
		{
			laz[k] = h(laz[k], x);
			eval(r - l, k);
		}
		else if (a < r&&l < b)
		{
			update(a, b, x, k * 2 + 1, l, (l + r) / 2);
			update(a, b, x, k * 2 + 2, (l + r) / 2, r);

			dat[k] = f(dat[k * 2 + 1], dat[k * 2 + 2]);
		}
	}

	T query(int a, int b, int k, int l, int r)
	{
		eval(r - l, k);
		if (r <= a || b <= l) return d1;
		if (a <= l && r <= b) return dat[k];
		T vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
		T vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
		return f(vl, vr);
	}

	void update(int a, int b, E x) { update(a, b, x, 0, 0, n); }
	T query(int a, int b) { return query(a, b, 0, 0, n); }
	T operator[](const int &k) const { return dat[k + n - 1]; }
};

struct P
{
	int z, o, t;
	P(int z = 0, int o = 0, int t = 0) :z(z), o(o), t(t) {}
};

signed main()
{
	cin.tie(0);
	ios::sync_with_stdio(false);

	int N, Q;
	cin >> N >> Q;

	auto f = [&](P a, P b) {return P(a.z + b.z, a.o + b.o, a.t + b.t + a.o*b.z); };
	auto g = [&](P a, int b) 
	{
		int nz = a.o, no = a.z, nt;
		nt = (nz + no)*(nz + no - 1) / 2 - nz * (nz - 1) / 2 - no * (no - 1) / 2 - a.t;

		return P(nz, no, nt);
	};
	auto h = [&](int a, int b) {return a ^ b; };
	auto p = [&](int a, int b) {return a; };

	LazySegmentTree<P, int> st(N, f, g, h, p, P(), 0LL);

	vector<P> A(N);
	int V;
	rep(i, 0, N)
	{
		cin >> V;
		if (V == 0)A[i].z++;
		else A[i].o++;
	}

	st.init(A);

	int t, l, r, x;
	rep(i, 0, Q)
	{
		cin >> t;
		if (t == 1)
		{
			cin >> l >> r;
			st.update(l - 1, r, 1LL);
		}
		else
		{
			cin >> l >> r;
			cout << st.query(l - 1, r).t << endl;
		}
	}


	return 0;
}


Measured memory_bytes: 29076