#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
typedef long long ll;
using namespace std;
const int maxn = 1e5 + 10;
const int mod = 10007;
struct SegTree {
int p[4][maxn<<2], lazy[4][maxn<<2];
void change_equ(int root, int c, int len) {
lazy[1][root] = 0, lazy[2][root] = 1, lazy[3][root] = c;
p[1][root] = (ll)c*len%mod;
p[2][root] = (ll)c*c*len%mod;
p[3][root] = (ll)c*c*c*len%mod;
}
void change_add(int root, int c1, int c2, int len) {
lazy[1][root] = (lazy[1][root]*c2%mod + c1)%mod, lazy[2][root] = lazy[2][root]*c2%mod;
p[3][root] = ((ll)p[3][root]*c2*c2*c2%mod + (ll)c1*c1*c1*len%mod + (ll)3*c2*c2*c1*p[2][root]%mod
+ (ll)3*c2*c1*c1*p[1][root]%mod)%mod;
p[2][root] = ((ll)p[2][root]*c2*c2%mod + (ll)c1*c1*len%mod + (ll)2*c2*c1*p[1][root]%mod)%mod;
p[1][root] = ((ll)c2*p[1][root]+c1*len)%mod;
}
void pushup(int root) {
for (int i = 1; i <= 3; i++) p[i][root] = (p[i][root<<1] + p[i][root<<1|1]) % mod;
}
void pushdown(int root, int cntL, int cntR) {
if (lazy[3][root]) {
change_equ(root<<1, lazy[3][root], cntL);
change_equ(root<<1|1, lazy[3][root], cntR);
lazy[3][root] = 0;
}
if (lazy[1][root] || lazy[2][root] != 1) {
change_add(root<<1, lazy[1][root], lazy[2][root], cntL);
change_add(root<<1|1, lazy[1][root], lazy[2][root], cntR);
lazy[1][root] = 0, lazy[2][root] = 1;
}
}
void build(int x) {
for (int i = 1; i <= 3; i++) {
int temp = (i == 2) ? 1 : 0;
for (int j = 1; j <= x<<2; j++) {
p[i][j] = 0; lazy[i][j] = temp;
}
}
}
void update(int L, int R, int root, int uL, int uR, int flag, int c) {
if (uL <= L && R <= uR) {
int len = R - L + 1;
if (flag == 1) {
lazy[1][root] = (lazy[1][root] + c) % mod;
p[3][root] = (p[3][root] + (ll)3*c*p[2][root]%mod + (ll)3*c*c*p[1][root]%mod + (ll)c*c*c*len%mod)%mod;
p[2][root] = (p[2][root] + (ll)2*p[1][root]*c%mod + (ll)c*c*len%mod)%mod;
p[1][root] = (p[1][root] + (ll)c*len%mod)%mod;
}
else if (flag == 2) {
lazy[1][root] = lazy[1][root] * c % mod;
lazy[2][root] = lazy[2][root] * c % mod;
p[1][root] = (ll)p[1][root]*c%mod;
p[2][root] = (ll)p[2][root]*c*c%mod;
p[3][root] = (ll)p[3][root]*c*c*c%mod;
}
else if (flag == 3) change_equ(root, c, len);
return;
}
int mid = (L + R)>>1;
pushdown(root, mid - L + 1, R - mid);
if (uL <= mid) update(L, mid, root<<1, uL, uR, flag, c);
if (mid < uR) update(mid + 1, R, root<<1|1, uL, uR, flag, c);
pushup(root);
}
int query(int L, int R, int root, int qL, int qR, int flag) {
if (qL <= L && R <= qR) {
return p[flag][root] % mod;
}
int mid = (L + R)>>1;
pushdown(root, mid - L + 1, R - mid);
int sum = 0;
if (qL <= mid) sum = (sum + query(L, mid, root<<1, qL, qR, flag)) % mod;
if (mid < qR) sum = (sum + query(mid + 1, R, root<<1|1, qL, qR, flag)) % mod;
return sum % mod;
}
}segtree;
int main() {
int n, m, flag, l, r, c;
while (~scanf("%d %d", &n, &m) && n && m) {
segtree.build(n);
while (m--) {
scanf("%d %d %d %d", &flag, &l, &r, &c);
if (flag != 4) segtree.update(1, n, 1, l, r, flag, c);
else printf("%d\n", segtree.query(1, n, 1, l, r, c));
}
}
return 0;
}