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 <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <utility>
#include <tuple>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <cmath>
#include <iomanip>
#include <cassert>
#define REP(i, n) for (int i = 0; i < (n); ++i)
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) (int)(x).size()
using namespace std;
using ll = long long;
constexpr ll INF = 3000000000000000000;

template <typename Operator>
struct LazySegmentTree {
    Operator OP;
    using NodeType = decltype(OP.NodeE);
    using FuncType = decltype(OP.FuncE);
    int length, height;
    vector<NodeType> node;
    vector<FuncType> lazy;
    vector<int> width;
    LazySegmentTree(int n) {
        length = 1;
        height = 0;
        while (length < n) {
            length <<= 1;
            ++height;
        }
        node.resize(length << 1, OP.NodeE);
        lazy.resize(length << 1, OP.FuncE);
        width.resize(length << 1, 1);
        for (int i = length - 1; i > 0; --i) width[i] = width[i << 1] << 1;
    }
    LazySegmentTree(vector<NodeType> &vec) {
        length = 1;
        height = 0;
        while (length < SZ(vec)) {
            length <<= 1;
            ++height;
        }
        node.resize(length << 1, OP.NodeE);
        REP(i, SZ(vec)) node[i + length] = vec[i];
        for (int i = length - 1; i > 0; --i) node[i] = OP.MergeNode(node[(i << 1) | 0], node[(i << 1) | 1]);
        lazy.resize(length << 1, OP.FuncE);
        width.resize(length << 1, 1);
        for (int i = length - 1; i > 0; --i) width[i] = width[i << 1] << 1;
    }
    void eval(int n) {
        node[n] = OP.NodeFunc(node[n], lazy[n], width[n]);
        if (n < length) {
            lazy[(n << 1) | 0] = OP.MergeFunc(lazy[(n << 1) | 0], lazy[n]);
            lazy[(n << 1) | 1] = OP.MergeFunc(lazy[(n << 1) | 1], lazy[n]);
        }
        lazy[n] = OP.FuncE;
    }
    void update(int a, int b, FuncType x) {
        int l = a + length, r = b + length - 1;
        for (int i = height; i > 0; --i) {
            eval(l >> i);
            eval(r >> i);
        }
        ++r;
        while (r > l) {
            if (l & 1) {
                lazy[l] = OP.MergeFunc(lazy[l], x);
                eval(l);
                ++l;
            }
            if (r & 1) {
                --r;
                lazy[r] = OP.MergeFunc(lazy[r], x);
                eval(r);
            }
            l >>= 1; r >>= 1;
        }
        l = a + length; r = b + length - 1;
        while (l >>= 1) node[l] = OP.MergeNode(OP.NodeFunc(node[(l << 1) | 0], lazy[(l << 1) | 0], width[(l << 1) | 0]), OP.NodeFunc(node[(l << 1) | 1], lazy[(l << 1) | 1], width[(l << 1) | 1]));
        while (r >>= 1) node[r] = OP.MergeNode(OP.NodeFunc(node[(r << 1) | 0], lazy[(r << 1) | 0], width[(r << 1) | 0]), OP.NodeFunc(node[(r << 1) | 1], lazy[(r << 1) | 1], width[(r << 1) | 1]));
    }
    NodeType get(int a, int b) {
        int l = a + length, r = b + length - 1;
        for (int i = height; i >= 0; --i) {
            eval(l >> i);
            eval(r >> i);
        }
        ++r;
        NodeType vl = OP.NodeE, vr = OP.NodeE;
        while (l < r) {
            if (l & 1) {
                vl = OP.MergeNode(vl, OP.NodeFunc(node[l], lazy[l], width[l]));
                ++l;
            }
            if (r & 1) {
                --r;
                vr = OP.MergeNode(OP.NodeFunc(node[r], lazy[r], width[r]), vr);
            }
            l >>= 1; r >>= 1;
        }
        return OP.MergeNode(vl, vr);
    }
};

struct hoge {
    ll NodeE = 0;
    ll FuncE = INF;
    ll MergeNode(ll x, ll y) {
        return x + y;
    }
    ll MergeFunc(ll x, ll y) {
        if (y == INF) return x;
        else return y;
    }
    ll NodeFunc(ll x, ll y, int len) {
        if (y == INF) return x;
        else return y * len;
    }
};

int main() {
    int n, q;
    cin >> n >> q;
    LazySegmentTree<hoge> LST(n);
    REP(_, q) {
        int num;
        cin >> num;
        if (!num) {
            int s, t, x;
            cin >> s >> t >> x;
            ++t;
            LST.update(s, t, x);
        } else {
            int s, t;
            cin >> s >> t;
            ++t;
            cout << LST.get(s, t) << "\n";
        }
    }
    
    return 0;
}