#pragma GCC optimize("Ofast") #include using namespace std; #define rep(i, n) for(int i = 0; i < (n); ++i) #define all(x) (x).begin(),(x).end() #define ln '\n' const long long MOD = 1000000007LL; //const long long MOD = 998244353LL; typedef long long ll; typedef unsigned long long ull; typedef pair pii; typedef pair pll; template inline bool chmax(T &a, T b) { if (a < b) { a = b; return true;} return false; } template inline bool chmin(T &a, T b) { if (a > b) { a = b; return true;} return false; } /////////////////////////////////////////////////////////////////////////////////////////////////// template struct LazySegmentTree { T unitynode; U unitylazy; F f; G g; H h; int N; int height; vector node; vector lazy; LazySegmentTree(F f, G g, H h, T unitynode, U unitylazy) : f(f), g(g), h(h), unitynode(unitynode), unitylazy(unitylazy) {} void init(int sz) { N = 1; height = 0; while (N < sz) { N *= 2; ++height; } node.assign(2*N,unitynode); lazy.assign(2*N,unitylazy); } void set(int k, const T &val) {node[k+N] = val;} void build() { for (int i = N-1; i > 0; --i) { node[i] = f(node[i<<1|0],node[i<<1|1]); } } inline T reflect(int k) { return lazy[k] == unitylazy ? node[k] : g(node[k],lazy[k]); } void eval(int k) { if (lazy[k] == unitylazy) return; if (k < N) { lazy[k<<1|0] = h(lazy[k<<1|0],lazy[k]); lazy[k<<1|1] = h(lazy[k<<1|1],lazy[k]); } node[k] = reflect(k); lazy[k] = unitylazy; } inline void recalc(int k) { while (k >>= 1) { node[k] = f(reflect(k<<1|0),reflect(k<<1|1)); } } // [l,r) (0-indexed) void update(int l, int r, U val) { if (l >= r) return; l += N; r += N-1; for (int i = height; i > 0; --i) { eval(l>>i); eval(r>>i); } int a = l; int b = r++; while (l < r) { if (l & 1) lazy[l] = h(lazy[l],val), ++l; if (r & 1) --r, lazy[r] = h(lazy[r],val); l >>= 1; r >>= 1; } recalc(a); recalc(b); } T get(int l, int r) { if (l >= r) return unitynode; l += N; r += N-1; for (int i = height; i > 0; --i) { eval(l>>i); eval(r>>i); } ++r; T vl = unitynode, vr = unitynode; while (l < r) { if (l & 1) vl = f(vl,reflect(l++)); if (r & 1) vr = f(reflect(--r),vr); l >>= 1; r >>= 1; } return f(vl,vr); } T operator[](int x) {return reflect(x+N);} }; /* example auto f=[](ll a, ll b) {return min(a,b);}; auto g=[](ll a, ll b) {return b;}; auto h=[](ll a, ll b) {return b;}; ll id1 = 1e18; ll id2 = -1; LazySegmentTree seg(f,g,h,id1,id2); seg.init(N); for (int i = 0; i < N; ++i) seg.set(i,(1LL<<31)-1); seg.build(); */ struct Node { ll head,tail,cnt; Node () = default; Node (ll head, ll tail, ll cnt) : head(head), tail(tail), cnt(cnt) {} bool operator== (const Node &p) const { return (head == p.head && tail == p.tail && cnt == p.cnt);} }; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int N,Q; cin >> N >> Q; vector A(N); rep(i,N) cin >> A[i]; const Node id1 = Node(-1e18,-1e18,1); const ll id2 = 0; auto f=[&] (Node a, Node b) { if (a == id1) return b; if (b == id1) return a; ll c = a.cnt + b.cnt; if (a.tail == b.head) c--; return Node(a.head, b.tail, c); }; auto g=[] (Node a, ll val) { a.head += val; a.tail += val; return a; }; auto h=[] (ll a, ll b) {return a+b;}; LazySegmentTree seg(f,g,h,id1,id2); seg.init(N); rep(i,N) { seg.set(i, Node(A[i],A[i],1)); } seg.build(); while (Q--) { int com; cin >> com; if (com==1) { int l,r,x; cin >> l >> r >> x; --l; seg.update(l,r,x); } else { int l,r; cin >> l >> r; --l; cout << seg.get(l,r).cnt << ln; } } }