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 rep(i,n)for(int i=0;i<(n);i++)
using namespace std;
typedef pair<int,int>P;
typedef long long ll;

enum SegtreeType{
	CUSTOM,
	RAQ_RMQ,
	RAQ_RSQ,
	RUQ_RMQ,
	RUQ_RSQ,
	RMQ_RMQ
};
template<SegtreeType ty,class T>
class LazySegtree{
	int n;
	vector<T>dat,lazy;
	T INIT;
	T E0,E1;
	function<T(T,T,int)>F0;
	function<T(T,T)>F1,F2;
public:
	LazySegtree(int n_,T INIT,T E0,T E1
	,function<T(T,T,int)>F0,function<T(T,T)>F1,function<T(T,T)>F2):
		INIT(INIT),E0(E0),E1(E1),F0(F0),F1(F1),F2(F2){
		n=1;while(n<n_)n<<=1;
		dat=lazy=vector<T>(2*n);
		for(int i=0;i<2*n-1;i++){
			dat[i]=INIT;
			lazy[i]=E1;
		}
	}
	LazySegtree(int n_){
		switch(ty){
		case RAQ_RMQ:
			INIT=0;
			E0=numeric_limits<T>::max();
			E1=0;
			F0=[](T a,T b,int s){return a+b;};
			F1=[](T a,T b){return a+b;};
			F2=[](T a,T b){return min(a,b);};
			break;
		case RAQ_RSQ:
			INIT=0;
			E0=0;
			E1=0;
			F0=[](T a,T b,int s){return a+b*s;};
			F1=[](T a,T b){return a+b;};
			F2=[](T a,T b){return a+b;};
			break;
		case RUQ_RMQ:
			INIT=numeric_limits<T>::max();
			E0=numeric_limits<T>::max();
			E1=numeric_limits<T>::min();
			F0=[](T a,T b,int s){return b;};
			F1=[](T a,T b){return b;};
			F2=[](T a,T b){return min(a,b);};
			break;
		case RUQ_RSQ:
			INIT=0;
			E0=0;
			E1=numeric_limits<T>::min();
			F0=[](T a,T b,int s){return b*s;};
			F1=[](T a,T b){return b;};
			F2=[](T a,T b){return a+b;};
			break;
		case RMQ_RMQ:
			INIT=numeric_limits<T>::max();
			E0=numeric_limits<T>::max();
			E1=numeric_limits<T>::max();
			F0=[](T a,T b,int s){return min(a,b);};
			F1=[](T a,T b){return min(a,b);};
			F2=[](T a,T b){return min(a,b);};
			break;
		}
		n=1;while(n<n_)n<<=1;
		dat=lazy=vector<T>(2*n);
		for(int i=0;i<2*n-1;i++){
			dat[i]=INIT;
			lazy[i]=E1;
		}
	}
	inline void push(int k,int s){
		if(lazy[k]==E1)return;
		dat[k]=F0(dat[k],lazy[k],s);
		if(k<n-1){
			lazy[k*2+1]=F1(lazy[k*2+1],lazy[k]);
			lazy[k*2+2]=F1(lazy[k*2+2],lazy[k]);
		}
		lazy[k]=E1;
	}
	inline void upnode(int k){
		dat[k]=F2(dat[k*2+1],dat[k*2+2]);
	}
	inline void update(int a,int b,T x,int k,int l,int r){
		push(k,r-l);
		if(r<=a||b<=l)return;
		if(a<=l&&r<=b){
			lazy[k]=F1(lazy[k],x);
			push(k,r-l);
			return;
		}
		update(a,b,x,k*2+1,l,(l+r)/2);
		update(a,b,x,k*2+2,(l+r)/2,r);
		upnode(k);
	}
	inline T query(int a,int b,int k,int l,int r){
		push(k,r-l);
		if(b<=l||r<=a)return E0;
		if(a<=l&&r<=b)return dat[k];
		T lb=query(a,b,k*2+1,l,(l+r)/2);
		T rb=query(a,b,k*2+2,(l+r)/2,r);
		upnode(k);
		return F2(lb,rb);
	}
	inline void update(int a,int b,T x){
		update(a,b,x,0,0,n);
	}
	inline void update(int a,T x){
		update(a,a+1,x);
	}
	inline T query(int a,int b){
		return query(a,b,0,0,n);
	}
	inline T query(int a){
		return query(a,a+1);
	}
};

int main(){
	int n,q;cin>>n>>q;
	LazySegtree<RUQ_RSQ,int>seg(n);
	rep(i,q){
		int ty;scanf("%d",&ty);
		if(ty==0){
			int l,r,x;scanf("%d%d%d",&l,&r,&x);r++;
			seg.update(l,r,x);
		}
		else{
			int l,r;scanf("%d%d",&l,&r);r++;
			printf("%d\n",seg.query(l,r));
		}
	}
}
