Problem: 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

Solution (in CPP):

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

template<typename Monoid,typename OperatorMonoid>
struct LazySegmentTree{
    typedef function<Monoid(Monoid,Monoid)> F;
    typedef function<Monoid(Monoid,OperatorMonoid)> G;
    typedef function<OperatorMonoid(OperatorMonoid,OperatorMonoid)> H;
    int n,hi;
    F f;
    G g;
    H h;
    Monoid id0;
    OperatorMonoid id1;
    vector<Monoid> dat;
    vector<OperatorMonoid> laz;
    LazySegmentTree(int n_,F f,G g,H h,Monoid id0,OperatorMonoid id1):
                    f(f),g(g),h(h),id0(id0),id1(id1){init(n_);}
    void init(int n_){
        n=1,hi=0;
        while(n<n_) n<<=1,++hi;
        dat.assign(n<<1,id0);
        laz.assign(n<<1,id1);
    }
    void build(const vector<Monoid> &v){
        for (int i=0;i<v.size();++i) dat[i+n]=v[i];
        for (int i=n-1;i;--i) dat[i]=f(dat[i<<1|0],dat[i<<1|1]);
    }
    inline Monoid reflect(int k){
        return laz[k]==id1?dat[k]:g(dat[k],laz[k]);
    }
    inline void propagate(int k){
        if (laz[k]==id1) return;
        laz[k<<1|0]=h(laz[k<<1|0],laz[k]);
        laz[k<<1|1]=h(laz[k<<1|1],laz[k]);
        dat[k]=reflect(k);
        laz[k]=id1;
    }
    inline void thrust(int k){
        for (int i=hi;i;--i) propagate(k>>i);
    }
    inline void recalc(int k){
        while(k>>=1) dat[k]=f(reflect(k<<1|0),reflect(k<<1|1));
    }
    void update(int a,int b,OperatorMonoid x){
        if (a>=b) return;
        thrust(a+=n),thrust(b+=n-1);
        for (int l=a,r=b+1;l<r;l>>=1,r>>=1){
            if (l&1) laz[l]=h(laz[l],x),++l;
            if (r&1) --r,laz[r]=h(laz[r],x);
        }
        recalc(a),recalc(b);
    }
    void set_val(int k,Monoid x){
        thrust(k+=n);
        dat[k]=x,laz[k]=id1;
        recalc(k);
    }
    Monoid query(int a,int b){
        if (a>=b) return id0;
        thrust(a+=n),thrust(b+=n-1);
        Monoid vl=id0,vr=id0;
        for (int l=a,r=b+1;l<r;l>>=1,r>>=1){
            if (l&1) vl=f(vl,reflect(l++));
            if (r&1) vr=f(reflect(--r),vr);
        }
        return f(vl,vr);
    }
    Monoid operator[](int i){return query(i,i+1);}
};

// https://onlinejudge.u-aizu.ac.jp/courses/library/3/DSL/all/DSL_2_D
// RUQ

void DSL_2_D(){
    int n,q; cin >> n >> q;
    auto f=[](int a,int b){return min(a,b);};
    auto g=[](int a,int b){return (~b?b:a);};
    auto h=[](int a,int b){return b;};
    LazySegmentTree<int,int> seg(n,f,g,h,INT_MAX,-1);
    for (;q--;){
        int c,s,t,x,i; cin >> c;
        if (!c){
            cin >> s >> t >> x;
            seg.update(s,t+1,x);
        } else {
            cin >> i;
            cout << seg[i] << '\n';
        }
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/3/DSL/2/DSL_2_E
// RAQ

void DSL_2_E(){
    int n,q; cin >> n >> q;
    auto f=[](int a,int b){return a+b;};
    LazySegmentTree<int,int> seg(n,f,f,f,0,0);
    for (;q--;){
        int c,s,t,x,i; cin >> c;
        if (!c){
            cin >> s >> t >> x;
            seg.update(s-1,t,x);
        } else {
            cin >> i;
            cout << seg[i-1] << '\n';
        }
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/3/DSL/2/DSL_2_F
// RMQ and RAQ

void DSL_2_F(){
    int n,q; cin >> n >> q;
    auto f=[](int a,int b){return min(a,b);};
    auto g=[](int a,int b){return (~b?b:a);};
    auto h=[](int a,int b){return b;};
    LazySegmentTree<int,int> seg(n,f,g,h,INT_MAX,-1);
    for (;q--;){
        int c,s,t,x; cin >> c >> s >> t;
        if (!c){
            cin >> x;
            seg.update(s,t+1,x);
        } else cout << seg.query(s,t+1) << '\n';
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/3/DSL/2/DSL_2_G
// RSQ and RUQ

void DSL_2_G(){
    int n,q; cin >> n >> q;
    auto f=[](pair<long long,long long> a,pair<long long,long long> b){return make_pair(a.first+b.first,a.second+b.second);};
    auto g=[](pair<long long,long long> a,long long x){return make_pair(a.first+a.second*x,a.second);};
    auto h=[](long long a,long long b){return a+b;};
    LazySegmentTree<pair<long long,long long>,long long> seg(n,f,g,h,{0,0},0);
    vector<pair<long long,long long>> v(n,{0,1});
    seg.build(v);
    for (;q--;){
        int c,s,t,x; cin >> c >> s >> t;
        if (!c){
            cin >> x;
            seg.update(s-1,t,x);
        } else cout << seg.query(s-1,t).first << '\n';
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/3/DSL/2/DSL_2_H
// RMQ and RAQ

void DSL_2_H(){
    int n,q; cin >> n >> q;
    auto f=[](int a,int b){return min(a,b);};
    auto g=[](int a,int b){return a+b;};
    LazySegmentTree<int,int> seg(n,f,g,g,INT_MAX,0);
    vector<int> v(n,0);
    seg.build(v);
    for (;q--;){
        int c,s,t,x; cin >> c >> s >> t;
        if (!c){
            cin >> x;
            seg.update(s,t+1,x);
        } else cout << seg.query(s,t+1) << '\n';
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/3/DSL/2/DSL_2_I
// RSQ and RUQ

void DSL_2_I(){
    const int inf=1<<30;
    int n,q; cin >> n >> q;
    auto f=[](pair<long long,long long> a,pair<long long,long long> b){return make_pair(a.first+b.first,a.second+b.second);};
    auto g=[](pair<long long,long long> a,long long x){return make_pair(x!=inf?x*a.second:a.first,a.second);};
    auto h=[](long long a,long long b){return b;};
    LazySegmentTree<pair<long long,long long>,long long> seg(n,f,g,h,{0,0},inf);
    vector<pair<long long,long long>> v(n,{0,1});
    seg.build(v);
    for (;q--;){
        int c,s,t,x; cin >> c >> s >> t;
        if (!c){
            cin >> x;
            seg.update(s,t+1,x);
        } else cout << seg.query(s,t+1).first << '\n';
    }
}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    DSL_2_I();
}