/*
		Panama sum - editorial




*/

#include<bits/stdc++.h>
#pragma GCC optimize("O3")
#define fi first
#define se second
#define pb push_back
#define pf push_front
 
// #define fisier 1 
 
using namespace std;
 
typedef long long ll;
 
const int mod = 1000000007;
const double PI = 3.14159265359; 
const double eps = 1e-9;


int n, q, v[200002];

struct segtree
{
	ll sum;
	ll pmax;
	ll smax;
	ll maxi;
};

segtree aint[2][800002];

void build(int node, int L, int R)
{
	if(L == R)
	{
		aint[0][node].sum = aint[0][node].pmax = aint[0][node].smax = aint[0][node].maxi = ((L % 2 == 1) ? v[L] : -v[L]);
		aint[1][node].sum = aint[1][node].pmax = aint[1][node].smax = aint[1][node].maxi = ((L % 2 == 0) ? v[L] : -v[L]);
		return;
	}
	
	int mid = (L + R) / 2;
	build(node << 1, L, mid);
	build(node << 1|1, mid+1, R);
	
	for(int st = 0; st <= 1; st++)
	{
		aint[st][node].sum = aint[st][node << 1].sum + aint[st][node << 1|1].sum;
		aint[st][node].pmax = max(aint[st][node << 1].pmax, aint[st][node << 1].sum + aint[st][node << 1|1].pmax);
		aint[st][node].smax = max(aint[st][node << 1|1].smax, aint[st][node << 1|1].sum + aint[st][node << 1].smax);
		aint[st][node].maxi = max(aint[st][node].pmax, max(aint[st][node].smax, max(aint[st][node << 1].maxi, aint[st][node << 1|1].maxi)));
		aint[st][node].maxi = max(aint[st][node].maxi, aint[st][node << 1].smax + aint[st][node << 1|1].pmax);
	}
	
//	cout << node << " " << L << " " << R << " " << aint[0][node].maxi << " " << aint[1][node].maxi << '\n';
}

void update(int node, int L, int R, int pos, int val)
{
	if(L == R)
	{
		aint[0][node].sum = aint[0][node].pmax = aint[0][node].smax = aint[0][node].maxi = ((L % 2 == 1) ? val : -val);
		aint[1][node].sum = aint[1][node].pmax = aint[1][node].smax = aint[1][node].maxi = ((L % 2 == 0) ? val : -val);
		return;
	}
	
	int mid = (L + R) / 2;
	if(pos <= mid)
		update(node << 1, L, mid, pos, val);
	else
		update(node << 1|1, mid+1, R, pos, val);
		
	for(int st = 0; st <= 1; st++)
	{
		aint[st][node].sum = aint[st][node << 1].sum + aint[st][node << 1|1].sum;
		aint[st][node].pmax = max(aint[st][node << 1].pmax, aint[st][node << 1].sum + aint[st][node << 1|1].pmax);
		aint[st][node].smax = max(aint[st][node << 1|1].smax, aint[st][node << 1|1].sum + aint[st][node << 1].smax);
		aint[st][node].maxi = max(aint[st][node].pmax, max(aint[st][node].smax, max(aint[st][node << 1].maxi, aint[st][node << 1|1].maxi)));
		aint[st][node].maxi = max(aint[st][node].maxi, aint[st][node << 1].smax + aint[st][node << 1|1].pmax);
	}	
}

ll sumplus = 0, maxsumplus = 0;

ll summinus = 0, maxsumminus = 0;

void query(int node, int L, int R, int Lq, int Rq)
{
	if(R < Lq || L > Rq)
		return;
	
	if(Lq <= L && R <= Rq) // process the query
	{
		
		// plus
		
		if(sumplus + aint[0][node].pmax > maxsumplus)
			maxsumplus = sumplus + aint[0][node].pmax;
			
		sumplus = max(sumplus + aint[0][node].sum, max(aint[0][node].smax, aint[0][node].sum));
				
		if(aint[0][node].maxi > maxsumplus)
			maxsumplus = aint[0][node].maxi;	
		
		if(sumplus > maxsumplus)
			maxsumplus = sumplus;
		// minus
		
		if(summinus + aint[1][node].pmax > maxsumminus)
			maxsumminus = summinus + aint[1][node].pmax;
			
		summinus = max(summinus + aint[1][node].sum, max(aint[1][node].smax, aint[1][node].sum));
				
		if(aint[1][node].maxi > maxsumminus)
			maxsumminus = aint[1][node].maxi;		

		if(summinus > maxsumminus)
			maxsumminus = summinus;
		return;
	}
	
	int mid = (L + R) / 2;
	query(node << 1, L, mid, Lq, Rq);
	query(node << 1|1, mid+1, R, Lq, Rq);
	
}
int main()
{
	#ifdef fisier
		ifstream cin("input.in");
		ofstream cout("output.out");
	#endif
	
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	
	cin >> n >> q;
	for(int i = 1; i <= n; i++)
		cin >> v[i];
	
	build(1, 1, n);
	
	
	for(int i = 1; i <= q; i++)
	{
		int tip, a, b;
		cin >> tip >> a >> b;
		if(tip == 1)
			update(1, 1, n, a, b);
		else if(tip == 2){
			int c; cin >> c;
			for(int i = a; i <= b; i ++){
				update(1, 1, n, i, c);
			}
		}
		else if(tip == 3)
		{
			sumplus = 0;
			summinus = 0;
			maxsumplus = -(1LL<<60);
			maxsumminus = -(1LL<<60);
			
			query(1, 1, n, a, b);
			
			long long ans = 0;
			
			if(a % 2 == 1)
				ans = maxsumplus;
			else
				ans = maxsumminus;
				
			sumplus = 0;
			summinus = 0;
			maxsumplus = -(1LL<<60);
			maxsumminus = -(1LL<<60);
			
			if(a < b)
			{
				query(1, 1, n, a+1, b);
				
				if(a % 2 == 1)
					ans = max(ans, maxsumminus);
				else
					ans = max(ans, maxsumplus);
			}
			
			cout << ans << '\n';
		}
	}
	
	return 0;
}
