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 <iostream>
#include <vector>
#include <climits>
#include <functional>
using namespace std;

template<typename Monoid, typename OpMonoid = Monoid>
class LazySegmentTree{
private:
    using F = function<Monoid(Monoid, Monoid)>;
    using G = function<Monoid(Monoid,OpMonoid)>;
    using H = function<OpMonoid(OpMonoid,OpMonoid)>;
    using P = function<OpMonoid(OpMonoid,int)>;
    int sz;
    vector<Monoid> data;
    vector<OpMonoid> lazy;
    const F func;
    const G op;
    const H mergeOp;
    const P multmergeOp;
    const Monoid e;
    const OpMonoid op_e;
public:
    LazySegmentTree(int n, const F f, const G g, const H h, const P p,
    const Monoid &e, const OpMonoid op_e)
    :func(f), op(g), mergeOp(h), multmergeOp(p), e(e), op_e(op_e){
        sz = 1;
        while(sz<n) sz <<= 1;
        data.assign(2*sz,e);
        lazy.assign(2*sz,op_e);
    }
    //初期化
    void set(int k, const Monoid &x){
        data[k+sz] = x;
    }
    //前計算
    void build(){
        for(int k=sz-1;k>0;k--){
            data[k] = func(data[2*k],data[2*k+1]);
        }
    }
    //kの子に長さlenの遅延を伝搬
    void propagate(int k, int len){
        if(lazy[k]!=op_e){
            if(k<sz){
                //遅延を下の段に伝搬、結果を分割する
                lazy[2*k] = mergeOp(lazy[2*k],lazy[k]);
                lazy[2*k+1] = mergeOp(lazy[2*k+1],lazy[k]);
            }
            data[k] = op(data[k],multmergeOp(lazy[k],len));
            lazy[k] = op_e;
        }
    }
    //更新
    Monoid update(int a, int b, const OpMonoid &x, int k, int l, int r){
        propagate(k,r-l);
        if(r<=a || b<=l) return data[k];
        else if(a<=l && r<=b){
            lazy[k] = mergeOp(lazy[k],x);
            propagate(k,r-l);
            return data[k];
        }else{
            return data[k] = func(update(a,b,x,2*k,l,(l+r)>>1),update(a,b,x,2*k+1,(l+r)>>1,r));
        }
    }
    Monoid update(int a, int b, const OpMonoid &x){
        return update(a,b,x,1,0,sz);
    }
    //クエリ回答
    Monoid query(int a, int b, int k, int l, int r){
        propagate(k,r-l);
        if(r<=a || b<=l){
            return e;
        }else if(a<=l && r<=b){
            return data[k];
        }else{
            return func(query(a,b,2*k,l,(l+r)>>1),query(a,b,2*k+1,(l+r)>>1,r));
        }
    }
    Monoid query(int a, int b){
        return query(a,b,1,0,sz);
    }
    Monoid operator[](const int &k){
        return query(k,k+1);
    }
};

typedef long long ll;
typedef pair<ll,ll> P;

int main(){
    int N,Q;
    cin >> N >> Q;
    auto func = [](P a, P b){return P(a.first+b.first,a.second+b.second);};
    auto op = [](P a, ll b){return P(a.second*b,a.second);};
    auto merge = [](ll a, ll b){return b!=INT_MAX? b:a;};
    auto multmergeop = [](ll a, int b){return a;};
    LazySegmentTree<P,ll>
    seg(N,func,op,merge,multmergeop,P(0,0),INT_MAX);
    for(int i=0;i<N;i++) seg.set(i,P(0,1));
    seg.build();
    for(int i=0;i<Q;i++){
        ll c,s,t,x;
        cin >> c;
        if(c==0){
            cin >> s >> t >> x;
            seg.update(s,t+1,x);
        }else{
            cin >> s >> t;
            cout << seg.query(s,t+1).first << endl;
        }
    }
}
