线段树
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define maxn 110000
#define INF 100000000
#define mod 10007
#define ls (rt<<1)
#define rs (rt<<1|1)
#define mid ((t[rt].l+t[rt].r)>>1)
int n,m;
struct tree
{
int l,r;
int lazy1,lazy2,lazy3;
int sum;
}t[maxn<<2];
void pushdown(int rt)
{
if(t[rt].lazy3!=INF)
{
t[ls].sum = t[rs].sum = t[rt].sum;
t[ls].lazy1 =t[rs].lazy1 = 0;
t[ls].lazy2 =t[rs].lazy2 = 1;
t[ls].lazy3 = t[rs].lazy3 = t[rt].lazy3;
t[rt].lazy3 = INF;
return;
}
if(t[rt].lazy1)
{
if(t[ls].lazy3!=INF)
{
t[ls].sum+=t[rt].lazy1;
t[ls].sum%=mod;
}
else
{
pushdown(ls);
t[ls].lazy1+= t[rt].lazy1;
t[ls].lazy1%= mod;
}
if(t[rs].lazy3!=INF)
{
t[rs].sum+=t[rt].lazy1;
t[rs].sum%=mod;
}
else
{
pushdown(rs);
t[rs].lazy1+=t[rt].lazy1;
t[rs].lazy1%=mod;
}
t[rt].lazy1=0;
}
if(t[rt].lazy2!=1)
{
if(t[ls].lazy3!=INF)
{
t[ls].sum*=t[rt].lazy2;
t[ls].sum%=mod;
}
else
{
pushdown(ls);
t[ls].lazy2*= t[rt].lazy2;
t[ls].lazy2%= mod;
}
if(t[rs].lazy3!=INF)
{
t[rs].sum*=t[rt].lazy2;
t[rs].sum%=mod;
}
else
{
pushdown(rs);
t[rs].lazy2*=t[rt].lazy2;
t[rs].lazy2%=mod;
}
t[rt].lazy2=1;
}
}
void build(int rt,int l,int r)
{
t[rt].l=l,t[rt].r=r;
t[rt].sum=0;
t[rt].lazy1=0;
t[rt].lazy2=1;
t[rt].lazy3=INF;//lazy3=INF表示无此操作
if(l==r)
{
t[rt].lazy3=0;
return;
}
build(ls,l,mid);
build(rs,mid+1,r);
}
void update(int rt,int l,int r,int c,int q)
{
if(t[rt].l==l&&t[rt].r==r)
{
if(q==3)
{
t[rt].sum=c;
t[rt].lazy3=c;
t[rt].lazy1=0;
t[rt].lazy2=1;
return;
}
if(t[rt].lazy3!=INF)
{
if(q==1)
{
t[rt].sum+=c;
t[rt].sum%=mod;
}
else
{
t[rt].sum*=c;
t[rt].sum%=mod;
}
}
else
{
pushdown(rt);
if(q==1)
{
t[rt].lazy1+=c;
t[rt].lazy1%=mod;
}
else
{
t[rt].lazy2*=c;
t[rt].lazy2%=mod;
}
}
return;
}
pushdown(rt);
if(r<=mid)
update(ls,l,r,c,q);
else if(l>mid)
update(rs,l,r,c,q);
else
{
update(ls,l,mid,c,q);
update(rs,mid+1,r,c,q);
}
}
int query(int rt,int l,int r,int c)
{
if(t[rt].l==l&&t[rt].r==r&&t[rt].lazy3!=INF)
{
int ans=1;
while(c--)
{
ans*=t[rt].sum;
ans%=mod;
}
ans*=(r-l+1);
ans%=mod;
return ans;
}
pushdown(rt);
if(r<=mid)
return query(ls,l,r,c);
else if(l>mid)
return query(rs,l,r,c);
else
return (query(ls,l,mid,c)+query(rs,mid+1,r,c))%mod;
}
int main()
{
int q,l,r,c;
while(~scanf("%d%d",&n,&m)&&n+m)
{
build(1,1,n);
for(int i=1;i<=n;i++)
{
scanf("%d%d%d%d",&q,&l,&r,&c);
if(q<=3)
update(1,l,r,c,q);
else
printf("%d\n",query(1,l,r,c));
}
}
}