#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
#define REP(i,n) for(int i=0;i<(int)(n);i++)
#define FOR(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define FORR(i,a,b) for(int i=(int)(b)-1;i>=(int)(a);i--)

const ll INF = 1ll<<60;

int n,q;
ll a[125252];
ll sum[125252];

// segment tree
const int N = 1<<17;
ll datMin[2*N], datMax[2*N];  // range min/max
ll datVal[2*N];               // (max. dat[j]-dat[i] s.t. l<=i<j<=r)
bool lazyFlag[2*N];
ll lazyVal[2*N];
void push(int k){
  if(!lazyFlag[k])return;
  datMin[k] += lazyVal[k];
  datMax[k] += lazyVal[k];
  if(k<N-1){
    lazyFlag[2*k+1] = lazyFlag[2*k+2] = true;
    lazyVal[2*k+1] += lazyVal[k];
    lazyVal[2*k+2] += lazyVal[k];
  }
  lazyFlag[k] = false;
  lazyVal[k] = 0;
}
void queryAdd(int l, int r, ll v, int a, int b, int k){
  push(k);
  if(r<=a || b<=l)return;
  if(l<=a && b<=r){
    lazyFlag[k] = true;
    lazyVal[k] += v;
    push(k);
    return;
  }
  int m = (a+b)/2;
  queryAdd(l,r,v,a,m,2*k+1);
  queryAdd(l,r,v,m,b,2*k+2);
  datMin[k] = min(datMin[2*k+1], datMin[2*k+2]);
  datMax[k] = max(datMax[2*k+1], datMax[2*k+2]);
  datVal[k] = max(datVal[2*k+1], datVal[2*k+2]);
  datVal[k] = max(datVal[k], datMax[2*k+2] - datMin[2*k+1]);
}
void queryAdd(int l, int r, ll v){
  queryAdd(l,r,v,0,N,0);
}
// <<min, max>, val>
pair<pair<ll,ll>,ll> queryGet(int l, int r, int a, int b, int k){
  push(k);
  if(r<=a || b<=l)return make_pair(make_pair(INF, -INF), -INF);
  if(l<=a && b<=r)return make_pair(make_pair(datMin[k], datMax[k]), datVal[k]);
  int m = (a+b)/2;
  pair<pair<ll,ll>,ll> lft, rgt;
  lft = queryGet(l,r,a,m,2*k+1);
  rgt = queryGet(l,r,m,b,2*k+2);
  ll mn = min(lft.first.first, rgt.first.first);
  ll mx = max(lft.first.second,rgt.first.second);
  ll vl = max(lft.second, rgt.second);
  vl = max(vl, rgt.first.second - lft.first.first);
  return make_pair(make_pair(mn,mx),vl);
}
ll queryMin(int l, int r){
  return queryGet(l,r,0,N,0).first.first;
}
ll queryMax(int l, int r){
  return queryGet(l,r,0,N,0).first.second;
}
ll queryVal(int l, int r){
  return queryGet(l,r,0,N,0).second;
}

ll f1(int l1, int l2, int r1, int r2){
  assert(l2<=r1);
  return queryMax(r1+1, r2+2) - queryMin(l1, l2+1);
}

int main(){
  // input
  scanf("%d%d",&n,&q);
  REP(i,n)scanf("%lld",a+i);
  // construct segment tree
  REP(i,n)sum[i+1] = sum[i]+a[i];
  REP(i,n+1){
    datMin[i+N-1] = datMax[i+N-1] = sum[i];
    datVal[i+N-1] = -INF;
  }
  FOR(i,n+1,N){
    datMin[i+N-1] = INF;
    datMax[i+N-1] = -INF;
    datVal[i+N-1] = -INF;
  }
  FORR(i,0,N-1){
    datMin[i] = min(datMin[2*i+1], datMin[2*i+2]);
    datMax[i] = max(datMax[2*i+1], datMax[2*i+2]);
    datVal[i] = max(datVal[2*i+1], datVal[2*i+2]);
    datVal[i] = max(datVal[i], datMax[2*i+2] - datMin[2*i+1]);
  }
  // query
  while(q--){
    char buf[5];
    scanf("%s",buf);
    if(buf[0]=='s'){
      // set i x
      int i,x;
      scanf("%d%d",&i,&x); --i;
      ll diff = x - a[i];
      a[i] = x;
      queryAdd(i+1, n+1, diff);
    }else{
      // max l1 l2 r1 r2
      int l1,l2,r1,r2;
      scanf("%d%d%d%d",&l1,&l2,&r1,&r2); --l1; --l2; --r1; --r2;
      r1 = max(r1, l1); l2 = min(l2, r2);
      assert(l1<=r1 && l2<=r2);

      ll ans = -INF;
      if(l2<=r1){
        ans = f1(l1, l2, r1, r2);
      }else{
        ans = max(ans, f1(l1, l2, l2, r2));
        ans = max(ans, f1(l1, r1, r1, r2));
        ans = max(ans, queryVal(r1, l2+1));
      }
      printf("%lld\n",ans);
    }
  }
  return 0;
}