#include
#define ll unsigned long long
using namespace std;
const ll INFINITE = INT_MAX;
const ll MAXNUM = 100005*4;
ll mod=10007;
struct segNode
{
ll p1,p2,p3;
ll l,r;
ll addMark;//加数标记
ll mulMark;//乘数标记
ll assignMark;//赋值标记
} seg[MAXNUM];
void pushup(ll rt)
{
seg[rt].p1 = (seg[rt*2].p1 + seg[rt*2+1].p1)%mod;
seg[rt].p2 = (seg[rt*2].p2 + seg[rt*2+1].p2)%mod;
seg[rt].p3 = (seg[rt*2].p3 + seg[rt*2+1].p3)%mod;
}
void build(ll rt, ll arr[], ll L, ll R)
{
seg[rt].addMark = 0;
seg[rt].mulMark = 1;
seg[rt].assignMark = 0;
seg[rt].l=L;
seg[rt].r=R;
if(L == R)//叶子节点
{
seg[rt].p1 = seg[rt].p2=seg[rt].p3=0;
}
else
{
ll mid = (L + R) / 2;
build(rt*2, arr, L, mid);
build(rt*2+1, arr, mid+1, R);
pushup(rt);
}
}
void pushDown(ll rt)
{
segNode &rt=seg[rt];
segNode &lson=seg[rt*2];
segNode &rson=seg[rt*2+1];
ll len1=(lson.r-lson.l+1)%mod;
ll len2=(rson.r-rson.l+1)%mod;
if(rt.assignMark)
{
rt.assignMark%=mod;
lson.assignMark =rson.assignMark= rt.assignMark%mod;
lson.addMark=rson.addMark=0;
lson.mulMark=rson.mulMark=1;
lson.p1=(len1*rt.assignMark)%mod;
lson.p2=((len1*rt.assignMark)%mod*rt.assignMark)%mod;
lson.p3=(((len1*rt.assignMark)%mod*rt.assignMark)%mod*rt.assignMark)%mod;
rson.p1=(len2*rt.assignMark)%mod;
rson.p2=((len2*rt.assignMark)%mod*rt.assignMark)%mod;
rson.p3=(((len2*rt.assignMark)%mod*rt.assignMark)%mod*rt.assignMark)%mod;
rt.assignMark = 0;
}
if(rt.mulMark != 1)
{
rt.mulMark%=mod;
lson.mulMark = (lson.mulMark*rt.mulMark)%mod;
rson.mulMark = (rson.mulMark*rt.mulMark)%mod;
if(lson.addMark)lson.addMark=(lson.addMark*rt.mulMark)%mod;
if(rson.addMark)rson.addMark=(rson.addMark*rt.mulMark)%mod;
lson.p1=(lson.p1*rt.mulMark)%mod;
lson.p2=((lson.p2*rt.mulMark)%mod*rt.mulMark)%mod;
lson.p3=(lson.p3*(((rt.mulMark*rt.mulMark)%mod*rt.mulMark)%mod))%mod;
rson.p1=(rson.p1*rt.mulMark)%mod;
rson.p2=((rson.p2*rt.mulMark)%mod*rt.mulMark)%mod;
rson.p3=(rson.p3*(((rt.mulMark*rt.mulMark)%mod*rt.mulMark)%mod))%mod;
rt.mulMark = 1;
}
if(rt.addMark)
{
rt.addMark%=mod;
lson.addMark = (lson.addMark+rt.addMark)%mod;
rson.addMark = (rson.addMark+rt.addMark)%mod;
lson.p3 = ((lson.p3+(((len1*rt.addMark)%mod*rt.addMark)%mod*rt.addMark)%mod)%mod+(((3*rt.addMark)%mod)*(((lson.p1*rt.addMark)%mod+lson.p2)%mod))%mod)%mod;
lson.p2 = ((lson.p2+ ((len1*rt.addMark)%mod*rt.addMark)%mod)%mod+((2*rt.addMark)%mod*lson.p1)%mod)%mod;
lson.p1 =( lson.p1+ (len1*rt.addMark)%mod)%mod;
rson.p3 = ((rson.p3+(((len2*rt.addMark)%mod*rt.addMark)%mod*rt.addMark)%mod)%mod+(((3*rt.addMark)%mod)*(((rson.p1*rt.addMark)%mod+rson.p2)%mod))%mod)%mod;
rson.p2 = ((rson.p2+ ((len2*rt.addMark)%mod*rt.addMark)%mod)%mod+((2*rt.addMark)%mod*rson.p1)%mod)%mod;
rson.p1 =(rson.p1+ (len2*rt.addMark)%mod)%mod;
rt.addMark = 0;
}
}
ll query(ll rt,ll L, ll R,ll p)
{
if(L == seg[rt].l&& seg[rt].r==R)
{
if(p==1)return seg[rt].p1%mod;
if(p==2)return seg[rt].p2%mod;
if(p==3)return seg[rt].p3%mod;
}
pushDown(rt); //----延迟标志域向下传递
ll mid = (seg[rt].l+seg[rt].r)/2;
if(R <= mid) return query(rt*2,L, R,p);
else if(L > mid) return query(rt*2+1,L, R,p);
else return (query(rt*2,L,mid,p)+query(rt*2+1,mid+1, R,p))%mod;
}
void update(ll rt, ll L, ll R, ll c,ll p)
{
if(L == seg[rt].l&& seg[rt].r==R)
{
segNode &rt=seg[rt];
segNode &lson=seg[rt*2];
segNode &rson=seg[rt*2+1];
ll len=(rt.r-rt.l+1)%mod;
if(p==1)
{
rt.addMark = (rt.addMark+c)%mod;
rt.p3 =((rt.p3+(((len*c)%mod*c)%mod*c)%mod)%mod+(((3*c)%mod)*(((rt.p1*c)%mod+rt.p2)%mod))%mod)%mod;
rt.p2 =((rt.p2+((len*c)%mod*c)%mod)%mod+((2*rt.p1)%mod*c)%mod)%mod;
rt.p1 =(rt.p1+ (len*c)%mod)%mod;
}
else if(p==2)
{
rt.mulMark = (rt.mulMark*c)%mod;
if(rt.addMark)rt.addMark=(rt.addMark*c)%mod;
rt.p1 = (rt.p1*c)%mod;
rt.p2 = ((rt.p2*c)%mod*c)%mod;
rt.p3 = (((rt.p3*c)%mod*c)%mod*c)%mod;
}
else if(p==3)
{
rt.addMark = 0;
rt.mulMark = 1;
rt.assignMark=c;
rt.p1 = (len*c)%mod;
rt.p2 = ((len*c)%mod*c)%mod;
rt.p3 = (((len*c)%mod*c)%mod*c)%mod;
}
return ;
}
pushDown(rt); //延迟标记向下传递
ll mid = (seg[rt].l+seg[rt].r)/2;
if(R <= mid) update(rt*2,L, R, c,p);
else if(L > mid) update(rt*2+1,L, R, c,p);
else update(rt<<1, L, mid, c, p),update(rt*2+1,mid+1, R, c,p);
pushup(rt);
}
int main()
{
// freopen("C://Users//13553//Desktop//in.txt","r",stdin);
// freopen("C://Users//13553//Desktop//out.txt","w",stdout);
ll n,m;
while(scanf("%llu%llu",&n,&m)&&n+m)
{
build(1,NULL,1,n);
while(m--)
{
ll op,x,y,p;
scanf("%llu%llu%llu%llu",&op,&x,&y,&p);
if(op==4)
{
ll ans=query(1,x,y,p);
printf("%llu\n",ans);
}
else
update(1,x,y,p,op);
}
}
return 0;
}