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>
#define int long long
#define endl '\n'
#define FOR(i, a, n) for (int i = (a); i < (n); ++i)
#define REP(i, n) FOR(i, 0, n)
using namespace std;

// Lazy Segment Tree
template <class M, class OM> struct LST {
    int n, lev;
    vector<M> d;
    vector<OM> lz;
    virtual M f(M, M) = 0;
    virtual M g(M, OM) = 0;
    virtual OM h(OM, OM) = 0;
    virtual OM p(OM, int) = 0;
    const M e1;
    const OM e0;

    LST(int n_, M e1, OM e0) : e1(e1), e0(e0) {
        for (n = 1, lev = 0; n < n_; n <<= 1, ++lev);
        d.assign(n << 1, e1);
        lz.assign(n << 1, e0);
    }

    // k: 0-indexed
    void set(int k, const M& x) {
        d[k + n] = x;
    }

    void build() {
        for (int i = n - 1; i > 0; --i) {
            d[i] = f(d[(i << 1) | 0], d[(i << 1) | 1]);
        }
    }

    inline M reflect(int k, int len) {
        return lz[k] == e0 ? d[k] : g(d[k], p(lz[k], len));
    }

    inline void push(int k) {
        for (int i = lev, len = n; i > 0; --i, len >>= 1) {
            int j = k >> i;
            if (lz[j] == e0) continue;
            lz[(j << 1) | 0] = h(lz[(j << 1) | 0], lz[j]);
            lz[(j << 1) | 1] = h(lz[(j << 1) | 1], lz[j]);
            d[j] = reflect(j, len);
            lz[j] = e0;
        }
    }

    inline void recalc(int k) {
        int len = 1;
        while (len <<= 1, k >>= 1) {
            M lhs = reflect((k << 1) | 0, len >> 1);
            M rhs = reflect((k << 1) | 1, len >> 1);
            d[k] = f(lhs, rhs);
        }
    }

    // [l, r)
    // l, r: 0-indexed
    void update(int l, int r, const OM& x) {
        push(l += n);
        push(r += n - 1);
        int l0 = l, r0 = r;
        for (++r; l < r; l >>= 1, r >>= 1) {
            if (l & 1) lz[l] = h(lz[l], x), l++;
            if (r & 1) --r, lz[r] = h(lz[r], x);
        }
        recalc(l0);
        recalc(r0);
    }

    // [l, r)
    // l, r: 0-indexed
    M query(int l, int r) {
        push(l += n);
        push(r += n - 1);
        M L = e1, R = e1;
        int len;
        for (++r, len = 1; l < r; l >>= 1, r >>= 1, len <<= 1) {
            if (l & 1) L = f(L, reflect(l++, len));
            if (r & 1) R = f(reflect(--r, len), R);
        }
        return f(L, R);
    }
    
    void print(int time = -1) {
        if (~time) cerr << "time = " << time << endl;
        for (int i = 0; i <= lev; ++i) {
            const int m = 1 << i;
            for (int j = 0; j < m; ++j) {
                cerr << "  (" << d[j + m] << ", " << lz[j + m] << ")";
            }
            cerr << endl;
        }
        cerr << endl;
    }
};

// RmQ and RUQ
template <class M, class OM> struct RmQRUQ : LST<M, OM> {
    RmQRUQ(int n, M e1 = numeric_limits<M>::max(), OM e0 = numeric_limits<OM>::max()) : LST<M, OM>(n, e1, e0) {}
    M f(M a, M b) override { return min(a, b); }
    M g(M a, OM b) override { return b; }
    OM h(OM a, OM b) override { return b; }
    OM p(OM a, int b) override { return a; }
};

// RSQ and RAQ
template <class M, class OM> struct RSQRAQ : LST<M, OM> {
    RSQRAQ(int n, M e1 = 0, OM e0 = 0) : LST<M, OM>(n, e1, e0) {}
    M f(M a, M b) override { return a + b; }
    M g(M a, OM b) override { return a + b; }
    OM h(OM a, OM b) override { return a + b; }
    OM p(OM a, int b) override { return a * b; }
};

// RmQ and RAQ
template <class M, class OM> struct RmQRAQ : LST<M, OM> {
    RmQRAQ(int n, M e1 = numeric_limits<M>::max(), OM e0 = 0) : LST<M, OM>(n, e1, e0) {
        for (int i = 0; i < n; ++i) this->set(i, 0);
        this->build();
    }
    M f(M a, M b) override { return min(a, b); }
    M g(M a, OM b) override { return a + b; }
    OM h(OM a, OM b) override { return a + b; }
    OM p(OM a, int b) override { return a; }
};

// RSQ and RUQ
template <class M, class OM> struct RSQRUQ : LST<M, OM> {
    RSQRUQ(int n, M e1 = 0, OM e0 = numeric_limits<OM>::max()) : LST<M, OM>(n, e1, e0) {}
    M f(M a, M b) override { return a + b; }
    M g(M a, OM b) override { return b; }
    OM h(OM a, OM b) override { return b; }
    OM p(OM a, int b) override { return a * b; }
};

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, q;
    cin >> n >> q;
    RSQRUQ<int, int> r(n);
    REP (i, q) {
        int c, s, t;
        cin >> c >> s >> t;
        if (c == 0) {
            int x;
            cin >> x;
            r.update(s, t + 1, x);
        } else {
            cout << r.query(s, t + 1) << endl;
        }
    }
}
