#include #include #include using namespace std; const int N = 1 << 20; const int mod = 1e9 + 7; struct mint { int n; mint(int n_ = 0) : n(n_) {} }; mint operator+(mint a, mint b) { return (a.n += b.n) >= mod ? a.n - mod : a.n; } mint operator-(mint a, mint b) { return (a.n -= b.n) < 0 ? a.n + mod : a.n; } mint operator*(mint a, mint b) { return 1LL * a.n * b.n % mod; } mint &operator+=(mint &a, mint b) { return a = a + b; } mint &operator-=(mint &a, mint b) { return a = a - b; } mint &operator*=(mint &a, mint b) { return a = a * b; } ostream &operator<<(ostream &o, mint a) { return o << a.n; } struct F { mint a, b, c; F() : a(1), b(0), c(0) {} F(mint a_, mint b_, mint c_) : a(a_), b(b_), c(c_) {} }; F operator*(F x, F y) { mint A = x.a * y.a; mint B = x.a * y.b + x.b; mint C = x.c + x.a * y.c; return F(A, B, C); } mint dat[N * 2]; F lazy[N * 2]; mint fib[N + 1]; void apply(int k, int l, int r, F f) { lazy[k] = f * lazy[k]; dat[k] *= f.a; dat[k] += f.b * (r - l); dat[k] += f.c * (fib[r] - fib[l]); } void push(int k, int l, int r) { apply(k * 2 + 0, l, l + r >> 1, lazy[k]); apply(k * 2 + 1, l + r >> 1, r, lazy[k]); lazy[k] = F(); } void update(int l, int r, F f, int k = 1, int ll = 0, int rr = N) { if (rr <= l || r <= ll) return; if (l <= ll && rr <= r) { apply(k, ll, rr, f); return; } push(k, ll, rr); update(l, r, f, k * 2 + 0, ll, ll + rr >> 1); update(l, r, f, k * 2 + 1, ll + rr >> 1, rr); dat[k] = dat[k * 2] + dat[k * 2 + 1]; } mint query(int l, int r, int k = 1, int ll = 0, int rr = N) { if (rr <= l || r <= ll) return 0; if (l <= ll && rr <= r) return dat[k]; push(k, ll, rr); mint vl = query(l, r, k * 2 + 0, ll, ll + rr >> 1); mint vr = query(l, r, k * 2 + 1, ll + rr >> 1, rr); return vl + vr; } int main() { fib[1] = 0; fib[2] = 1; for (int i = 3; i <= N; i++) { fib[i] = fib[i - 1] + fib[i - 2]; } for (int i = 1; i <= N; i++) { fib[i] += fib[i - 1]; } for (int i = 0; i < N * 2; i++) { lazy[i] = F(); } int n, q; cin >> n >> q; while (q--) { int t, l, r, k; scanf("%d %d %d %d", &t, &l, &r, &k); r++; if (t == 0) { mint ans = k * query(l, r); printf("%d\n", ans.n); } else if (t == 1) { update(l, r, F(0, k, 0)); } else if (t == 2) { update(l, r, F(1, k, 0)); } else if (t == 3) { update(l, r, F(k, 0, 0)); } else { update(l, r, F(1, 0, k)); } } }