#include <iostream>
#include <vector>
#include <cmath>
#include <string>
#include <algorithm>
#include <iomanip>
#include <map>
#include <set>
#include <bitset>
#include <fstream>
#include <unordered_set>
#include <unordered_map>
#include <ext/pb_ds/assoc_container.hpp>
#include <stack>
                 
using namespace std;
using namespace __gnu_pbds;
        
         
        
/*#pragma GCC optimize("Ofast")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,popcnt,abm,mmx,tune=native")
#pragma GCC optimize("fast-math")*/
             
#define int long long
#define eb emplace_back
#define pb push_back
#define ld long double
#define mp make_pair
#define f first
#define s second
#define gleg(x) return cout << x, 0
#define pii pair <int, int> 
#define deb(a) cerr << #a << " = " << a << '\n';
#define fast() { \
    ios_base::sync_with_stdio(0); \
    cin.tie(0); \
    cout << fixed << setprecision(30); \
    cerr << fixed << setprecision(11); \
}
        
template < typename firstType, typename secondType = null_type, class compare = less < firstType > >
struct sett {
    typedef tree <
        firstType,
        secondType,
        compare,
        rb_tree_tag,
        tree_order_statistics_node_update
    > _ ;
};
        
         
const int INF = 1e18 + 7;
const ld EPS = 1e-9;
const int MAXI = 350;
const int MOD = 998244353;
const int MOD1 = 1e9 + 7;
const int MAXST = 2000000;
const int P = 31;
const int P1 = 37;
const int N = 8e5 + 2e4;
const ld PI = 3.14159265358979323;
       
               
ostream &operator<<(ostream &stream, const pair <int, int> &p) {
    stream << p.first << ' ' << p.second << ' ';
    return stream;
}

int t[N], lm[N], rm[N], l1[N], r1[N], u[N], a[210000];

void push(int v, int l, int r){
    if (u[v] != 0){
        lm[v] += u[v];
        rm[v] += u[v];
        if (l != r){
            u[v * 2] += u[v];
            u[v * 2 + 1] += u[v];
        }
        u[v] = 0;
    }
}

void build(int v, int l, int r){
    if (l == r){
        t[v] = l1[v] = r1[v] = 1;
        lm[v] = a[l];
        rm[v] = a[l];
    }
    else{
        int m = (r + l) / 2;
        build(v * 2, l, m);
        build(v * 2 + 1, m + 1, r);
        if (r1[v * 2] == m - l + 1 && abs(lm[v * 2 + 1] - rm[v * 2]) == 1)
            l1[v] = r1[v * 2] + l1[v * 2 + 1];
        else
            l1[v] = l1[v * 2];
        if (r1[v * 2 + 1] == r - m && abs(lm[v * 2 + 1] - rm[v * 2]) == 1)
            r1[v] = r1[v * 2] + l1[v * 2 + 1];
        else
            r1[v] = r1[v * 2];
        lm[v] = lm[v * 2];
        rm[v] = rm[v * 2 + 1];
        t[v] = max({t[v * 2], t[v * 2 + 1], l1[v], r1[v]});
        if (abs(lm[v * 2 + 1] - rm[v * 2]) == 1)
            t[v] = max(t[v], r1[v * 2] + l1[v * 2 + 1]);
    }
}

pair < int, pair < int, int > > fns(int v, int l, int r, int lf, int rf){
    push(v, lf, rf);
    if (l > r)
        return {-INF, {-INF, -INF}};
    else if (l == lf && r == rf)
        return {t[v], {l1[v], r1[v]}};
    else{
        int m = (rf + lf) / 2;
        pair < int, pair < int, int > > ans = fns(v * 2, l, min(r, m), lf, m);
        pair < int, pair < int, int > > ans1 = fns(v * 2 + 1, max(l, m + 1), r, m + 1, rf);
        int t1 = 0, l2 = 0, r2 = 0;
        if (ans.s.s == m - l + 1 && abs(lm[v * 2 + 1] - rm[v * 2]) == 1)
            l2 = max(ans.s.s + ans1.s.f, ans.s.f);
        else if (l >= m)
            l2 = ans.s.f;
        else if (r > m)
            l2 = ans1.s.f;
        if (ans1.s.f == r - m && abs(lm[v * 2 + 1] - rm[v * 2]) == 1)
            r2 = max(ans.s.s + ans1.s.s, ans1.s.s);
        else if (m <= r)
            r2 = ans1.s.s;
        else
            r2 = ans.s.s;
        t1 = max({ans.f, ans1.f, l2, r2});
        if (abs(lm[v * 2 + 1] - rm[v * 2]) == 1)
            t1 = max(t1, ans.s.s + ans1.s.f);
        return {t1, {l2, r2}};
    }
}

void update(int v, int l, int r, int lf, int rf, int nv){
    push(v, lf, rf);
    if (l > r)
        return;
    else if (l == lf && r == rf){
        u[v] += nv;
        push(v, lf, rf);
    }
    else{
        int m = (rf + lf) / 2;
        update(v * 2, l, min(r, m), lf, m, nv);
        update(v * 2 + 1, max(l, m + 1), r, m + 1, rf, nv);
        if (r1[v * 2] == m - lf + 1 && abs(lm[v * 2 + 1] - rm[v * 2]) == 1)
            l1[v] = r1[v * 2] + l1[v * 2 + 1];
        else
            l1[v] = l1[v * 2];
        if (r1[v * 2 + 1] == rf - m && abs(lm[v * 2 + 1] - rm[v * 2]) == 1)
            r1[v] = r1[v * 2] + l1[v * 2 + 1];
        else
            r1[v] = r1[v * 2];
        lm[v] = lm[v * 2];
        rm[v] = rm[v * 2 + 1];
        t[v] = max({t[v * 2], t[v * 2 + 1], l1[v], r1[v]});
        if (abs(lm[v * 2 + 1] - rm[v * 2]) == 1)
            t[v] = max(t[v], r1[v * 2] + l1[v * 2 + 1]);
    }
}

signed main(){
    fast();
    srand(time(0));
    //#ifdef _LOCAL                 
        //freopen("seq.in", "r", stdin);
        //freopen("seq.out", "w", stdout);
    //#endif
    #ifdef _LOCAL               
        freopen("input.txt", "r", stdin);
        freopen("output.txt", "w", stdout);
    #endif 
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)
        cin >> a[i];
    int m;
    cin >> m;
    for (int qq = 0; qq < m; qq++){
        char c;
        cin >> c;
        if (c == '?'){
            int l, r;
            cin >> l >> r;
            l--;
            r--;
            cout << fns(1, l, r, 0, n - 1).f << '\n';
        }
        else{
            int l, r, val;
            cin >> l >> r >> val;
            l--;
            r--;
            update(1, l, r, 0, n - 1, val);
        }
    }
    return 0;
}