#include<bits/stdc++.h>
#define FILE "read"
#define MAXN 50010
using namespace std;
typedef long long ll;
struct event{int L,R,A,B,opt;}eve[MAXN],tree[MAXN<<3];
int tot,hash[MAXN<<1];ll sum[MAXN<<3];
inline int read(){
int x=0,f=1; char ch=getchar();
while(ch>'9'||ch<'0') {if(ch=='-') f=-1; ch=getchar();}
while(ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
inline int hash_L(int x){return hash[x];}
inline int hash_R(int x){return hash[x+1]-1;}
inline int gcd(int a,int b){return !b?a:gcd(b,a%b);}
inline ll Simgcd(int a,int b,int c,ll n){
if(!a){
return b>=c?(n+1):0;
}
else if(a>=c||b>=c){
return 1LL*n*(n+1)/2*(a/c)+1LL*(n+1)*(b/c)+Simgcd(a%c,b%c,c,n);
}
else if(a<=c&&b<=c){
ll m=1LL*(a*n+b)/c;
return 1LL*n*m-Simgcd(c,c-b-1,a,m-1);
}
}
inline ll solve(int n,int A,int B){
int Gcd=gcd(A,B);
return 1LL*n*(n+1)/2*A-1LL*B*Simgcd(A/Gcd,0,B/Gcd,n);
}
inline void calc(int p){
int A=tree[p].A,B=tree[p].B;
sum[p]=solve(tree[p].R,A,B)-solve(tree[p].L-1,A,B);
}
inline void pushdown(int p,int l,int r){
if(tree[p].B){
int mid=(l+r)>>1,A=tree[p].A,B=tree[p].B;
tree[p<<1].A=tree[p<<1|1].A=A;
tree[p<<1].B=tree[p<<1|1].B=B;
tree[p<<1].L=tree[p].L;
tree[p<<1].R=tree[p].L+hash_R(mid)-hash_L(l);
tree[p<<1|1].L=tree[p].L+hash_L(mid+1)-hash_L(l);
tree[p<<1|1].R=tree[p].R;
calc(p<<1); calc(p<<1|1);
}
tree[p].B=0;
}
inline void modify(int p,int l,int r,int L,int R,int A,int B){
if(L<=l&&R>=r){
tree[p].A=A;
tree[p].B=B;
tree[p].L=hash_L(l)-hash_L(L)+1;
tree[p].R=hash_R(r)-hash_L(L)+1;
calc(p);
return;
}
int mid=(l+r)>>1; pushdown(p,l,r);
if(L<=mid) modify(p<<1,l,mid,L,R,A,B);
if(R>=mid+1) modify(p<<1|1,mid+1,r,L,R,A,B);
sum[p]=sum[p<<1]+sum[p<<1|1];
}
inline ll query(int p,int l,int r,int L,int R){
if(L<=l&&R>=r) return sum[p];
int mid=(l+r)>>1; pushdown(p,l,r);
ll ret=0;
if(L<=mid) ret+=query(p<<1,l,mid,L,R);
if(R>=mid+1) ret+=query(p<<1|1,mid+1,r,L,R);
return ret;
}
int main(){
freopen(FILE".in","r",stdin);
freopen(FILE".out","w",stdout);
int n=read(),Q=read();
for(int i=1;i<=Q;++i){
eve[i].opt=read(); eve[i].L=read(); eve[i].R=read();
hash[++tot]=eve[i].L; hash[++tot]=eve[i].R+1;
if(eve[i].opt&1){
eve[i].A=read();
eve[i].B=read();
eve[i].A%=eve[i].B;
}
}
sort(hash+1,hash+tot+1);
tot=unique(hash+1,hash+tot+1)-hash-1;
for(int i=1;i<=Q;++i){
int L=lower_bound(hash+1,hash+tot+1,eve[i].L)-hash;
int R=lower_bound(hash+1,hash+tot+1,eve[i].R+1)-hash-1;
if(eve[i].opt&1) modify(1,1,tot,L,R,eve[i].A,eve[i].B);
else printf("%lld\n",query(1,1,tot,L,R));
}
return 0;
}