Write a program which manipulates a sequence $A$ = {$a_0, a_1, ..., a_{n-1}$} with the following operations:

* $update(s, t, x)$: change $a_s, a_{s+1}, ..., a_t$ to $x$.
* $getSum(s, t)$: print the sum of $a_s, a_{s+1}, ..., a_t$.



Note that the initial values of $a_i ( i = 0, 1, ..., n-1 )$ are 0.

Constraints

* $1 ≤ n ≤ 100000$
* $1 ≤ q ≤ 100000$
* $0 ≤ s ≤ t < n$
* $-1000 ≤ x ≤ 1000$

Input


$n$ $q$
$query_1$
$query_2$
:
$query_q$


In the first line, $n$ (the number of elements in $A$) and $q$ (the number of queries) are given. Then, $i$-th query $query_i$ is given in the following format:


0 $s$ $t$ $x$


or


1 $s$ $t$


The first digit represents the type of the query. '0' denotes $update(s, t, x)$ and '1' denotes $find(s, t)$.

Output

For each $getSum$ query, print the sum in a line.

Example

Input

6 7
0 1 3 1
0 2 4 -2
1 0 5
1 0 1
0 3 5 3
1 3 4
1 0 5


Output

-5
1
6
8
#include <bits/stdc++.h>
using namespace std;
typedef long long lint;

template <class T>
class LazySegmentTree{
private:
    int n;
    vector<T> dat, lazy;
    vector<bool> flag;
    T def;

    void _eval(int k, int l, int r){
        if(flag[k]){
            dat[k] = (r-l) * lazy[k];
            if(1<r-l){
                lazy[2*k+1] = lazy[k];
                lazy[2*k+2] = lazy[k];
                flag[2*k+1] = true;
                flag[2*k+2] = true;
            }
            flag[k] = false;
        }
    }

    T _query(int a, int b, int k, int l, int r){
        // [a, b), [l, r)
        if(r<=a or b<=l) return def;
        _eval(k, l, r);
        if(a<=l and r<=b) return dat[k];
        else{
            T c1 = _query(a, b, 2*k+1, l, (l+r)/2);
            T c2 = _query(a, b, 2*k+2, (l+r)/2, r);
            return c1 + c2;
        }
    }

    void _change(int a, int b, T x, int k, int l, int r){
        _eval(k, l, r);
        if(b<=l or r<=a) return;
        else if(a<=l and r<=b){
            lazy[k] = x;
            flag[k] = true;
            _eval(k, l, r);
        } else {
            _change(a, b, x, 2*k+1, l, (l+r)/2);
            _change(a, b, x, 2*k+2, (l+r)/2, r);
            dat[k] = dat[2*k+1] + dat[2*k+2];
        }
    }

    int _find(T x, int k, int l, int r){
        if(r-l==1) return k - n + 1;
        _eval(2*k+1, l, (l+r)/2);
        _eval(k, 2*k+2, (l+r)/2, r);
        if(dat[2*k+1]>=x) return _find(x, 2*k+1, l, (l+r)/2);
        else return _find(x, 2*k+2, (l+r)/2, r);
    }

public:
    // [a, b)
    T query(int a, int b){
        return _query(a, b, 0, 0, n);
    }

    void change(int a, int b, T x){
        _change(a, b, x, 0, 0, n);
    }

    int find(T x){
        _eval(0, 0, n);
        if(dat[0]<x) return -1;
        return _find(x, 0, 0, n);
    }

    T operator[](int i){
        return dat[i+n-1];
    }

    LazySegmentTree(size_t _n, T _def)
            : def(_def){
        n = 1;
        while(n < _n){
            n *= 2;
        }
        dat.assign(2*n-1, def);
        flag.assign(2*n-1, false);
        lazy.resize(2*n-1);
    }

    LazySegmentTree(size_t _n, T _def, vector<T>& _v)
            : def(_def){
        n = 1;
        while(n < _n){
            n *= 2;
        }
        dat.assign(2*n-1, def);
        flag.assign(2*n-1, false);
        lazy.resize(2*n-1);
        for(int i=0;i<_n;++i) dat[n-1+i] = _v[i];
        for(int i=n-2;0<=i;--i) dat[i] = dat[2*i+1] + dat[2*i+2];
    }
};

class Task{
public:
    void solve(istream& in, ostream& out){
        int N, tt;
        in>>N>>tt;
        LazySegmentTree<int> ldat(N, 0);
        while(tt--){
            int t;
            in>>t;
            if(t){
                int l, r;
                in>>l>>r;
                out<<ldat.query(l, r+1)<<'\n';
            }else{
                int l, r, x;
                in>>l>>r>>x;
                ldat.change(l, r+1, x);
            }
        }
    }
};

int main(){
    Task solver;
    istream& in(cin);
    ostream& out(cout);
    ios::sync_with_stdio(false);
    in.tie(nullptr), out.tie(nullptr);
    solver.solve(in, out);
    return 0;
}

