#include <bits/stdc++.h>
#define ll long long
#define el cout << '\n'
#define ii pair<int, int>
#define fi first
#define se second
using namespace std;
const int maxn = 2e5;
const int block_size = 447;
const int max_cnt = maxn/block_size + 316;
int n, q, L[maxn + 10], R[maxn + 10], cnt_block = 0;
ll a[maxn + 10], sum[maxn + 10];
bool rev[maxn + 10];
vector<ll> block[maxn + 10];
int get_id(int p)
{
return p / block_size + 1; // 1-based block id
}
void lazy(int id)
{
if (id < 1 || id > cnt_block) return;
if (rev[id])
{
rev[id] = false;
reverse(block[id].begin(), block[id].end());
}
}
void split(int p)
{
if (p <= 0 || p >= n) return; // guard: only split meaningful positions
for (int i = 1; i <= cnt_block; i++)
if (L[i] <= p && p <= R[i])
{
if (p == R[i]) return;
// shift blocks right by one starting from cnt_block down to i+1
for (int j = cnt_block; j > i; j--)
{
swap(block[j + 1], block[j]);
L[j + 1] = L[j];
R[j + 1] = R[j];
sum[j + 1] = sum[j];
rev[j + 1] = rev[j];
}
cnt_block++;
lazy(i);
vector<ll> tmp = block[i];
block[i].clear();
block[i + 1].clear();
int oldLi = L[i];
int oldRi = R[i];
L[i + 1] = p + 1;
R[i + 1] = oldRi;
R[i] = p;
L[i] = oldLi;
sum[i] = sum[i + 1] = 0;
rev[i] = rev[i + 1] = 0;
// redistribute elements from tmp (which correspond to positions oldLi..oldRi)
for (int offset = 0; offset < (int)tmp.size(); offset++)
{
int pos = oldLi + offset;
int nxt_i = i + (pos > p);
block[nxt_i].push_back(tmp[offset]);
sum[nxt_i] += tmp[offset];
}
return;
}
}
int find_id(int p)
{
if (p <= 0 || p > n) return 0;
for (int i = 1; i <= cnt_block; i++)
if (L[i] <= p && p <= R[i])
return i;
return 0;
}
void rebuild()
{
// gather all elements in order
vector<ll> v;
v.reserve(n + 5);
for (int i = 1; i <= cnt_block; i++)
{
lazy(i);
for (ll x : block[i]) v.push_back(x);
block[i].clear();
}
// v should have size n
if ((int)v.size() != n)
{
// If there's discrepancy, try to pad or truncate safely
v.resize(n, 0);
}
// clear sums and rev
for (int i = 1; i <= cnt_block; i++) { sum[i] = 0; rev[i] = 0; }
// recompute cnt_block based on n
cnt_block = get_id(n);
// ensure block vectors cleared for ids we'll use
for (int id = 1; id <= cnt_block; id++) block[id].clear();
// fill blocks from v (v is 0-based)
for (int i = 1; i <= n; i++)
{
int id = get_id(i);
ll val = v[i - 1];
block[id].push_back(val);
sum[id] += val;
}
// recompute L/R
int cur = 1;
for (int id = 1; id <= cnt_block; id++)
{
L[id] = cur;
R[id] = cur + (int)block[id].size() - 1;
cur = R[id] + 1;
}
}
void rever(int l, int r)
{
if (l >= r) return;
split(l - 1);
split(r);
int id_l = find_id(l);
int id_r = find_id(r);
if (id_l == 0 || id_r == 0) return;
// swap whole blocks between id_l..id_r
for (int i = id_l, j = id_r; i < j; i++, j--)
{
swap(block[i], block[j]);
swap(rev[i], rev[j]);
swap(sum[i], sum[j]);
}
// toggle rev for blocks inside [id_l, id_r]
for (int i = id_l; i <= id_r; i++)
rev[i] = !rev[i];
// recompute L/R according to current block sizes
int cur = 1;
for (int i = 1; i <= cnt_block; i++)
{
L[i] = cur;
R[i] = cur + (int)block[i].size() - 1;
cur = R[i] + 1;
}
}
ll get_sum(int l, int r, int id)
{
if (id < 1 || id > cnt_block) return 0;
ll ans = 0;
int len = (int)block[id].size();
// ensure lazy applied so physical order matches indices L..R
lazy(id);
for (int i = L[id], j = 0; i <= R[id] && j < len; i++, j++)
if (l <= i && i <= r)
ans += block[id][j];
return ans;
}
int main()
{
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
if (fopen("SUMS.INP", "r"))
{
freopen("SUMS.INP", "r", stdin);
freopen("SUMS.OUT", "w", stdout);
}
// init
memset(L, 0, sizeof L);
memset(R, 0, sizeof R);
memset(sum, 0, sizeof sum);
memset(rev, 0, sizeof rev);
for (int i = 0; i <= maxn; i++) block[i].clear();
cnt_block = 0;
cin >> n >> q;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
int id = get_id(i);
if (i == 1 || get_id(i - 1) != get_id(i))
L[id] = i;
R[id] = i;
sum[id] += a[i];
block[id].push_back(a[i]);
}
cnt_block = get_id(n);
while (q--)
{
int t, l, r;
cin >> t >> l >> r;
if (t == 1)
rever(l, r);
else
{
ll ans = 0;
int id_l = find_id(l);
int id_r = find_id(r);
if (id_l == 0 || id_r == 0) {
cout << 0 << '\n';
if (cnt_block > max_cnt) rebuild();
continue;
}
if (id_l != id_r)
{
lazy(id_l);
lazy(id_r);
ans += get_sum(l, R[id_l], id_l);
for (int i = id_l + 1; i <= id_r - 1; i++)
ans += sum[i];
ans += get_sum(L[id_r], r, id_r);
}
else
{
lazy(id_l);
ans = get_sum(l, r, id_l);
}
cout << ans << '\n';
}
if (cnt_block > max_cnt)
rebuild();
}
return 0;
}