#include <bits/stdc++.h>   using namespace std;   const long long mod = 1000000007;   const long long inv2 = 500000004;   const long long inv6 = 166666668;   const long long inv4 = 250000002;   const long long inv30 = 233333335;   const long long inv12 = 83333334;   const int KKK = 5;   long long ipow(long long b, int e) {     b = b % mod;     long long r = 1;     while (e-- > 0) r = (r * b) % mod;     return r;   }   struct node {     node *lc, *rc;     size_t l, r;     long long v;     int k;     bool flazy;     long long lazy;   };   const int max_n = 100100;   const int max_t = 13 * max_n;   int tn;   node T[max_t], *troot[KKK + 1];   int n, m, a[max_n];   long long C[KKK + 1][KKK + 1];   long long P[max_n][KKK + 1];   long long Q[max_n][KKK + 1];   void lazy(node *x) {     if (x->flazy) {       x->v = (((x->lazy) * ((Q[x->r][x->k] - Q[x->l - 1][x->k] + mod))) % mod);       x->flazy = false;       if (x->l < x->r) {         x->lc->flazy = true;         x->rc->flazy = true;         x->lc->lazy = x->lazy;         x->rc->lazy = x->lazy;       }     }   }   long long query(node *x, size_t ql, size_t qr) {     lazy(x);     if (ql <= x->l && x->r <= qr)       return x->v;     else {       long long ans = 0;       if (ql <= x->lc->r) ans += query(x->lc, ql, qr);       if (qr >= x->rc->l) ans += query(x->rc, ql, qr);       return ans < mod ? ans : ans % mod;     }   }   void modify(node *x, size_t ql, size_t qr, long long v) {     lazy(x);     if (ql <= x->l && x->r <= qr) {       x->flazy = true;       x->lazy = v;       lazy(x);     } else {       if (ql <= x->lc->r) modify(x->lc, ql, qr, v);       if (qr >= x->rc->l) modify(x->rc, ql, qr, v);       lazy(x->lc);       lazy(x->rc);       x->v = x->lc->v + x->rc->v;       x->v = x->v < mod ? x->v : x->v % mod;     }   }   void build(node *x) {     if (x->l == x->r) x->v = (((a[x->l]) * (P[x->l][x->k])) % mod);     if (x->l < x->r) {       int mid = (x->l + x->r) / 2;       x->lc = &T[tn++];       x->lc->l = x->l;       x->lc->r = mid;       x->lc->k = x->k;       build(x->lc);       x->rc = &T[tn++];       x->rc->l = mid + 1;       x->rc->r = x->r;       x->rc->k = x->k;       build(x->rc);       x->v = x->lc->v + x->rc->v;       x->v = x->v < mod ? x->v : x->v % mod;     }   }   int op_query(int l, int r, int k) {     long long ans = 0;     for (int i = 0; i <= k; ++i)       ans = (ans +              ((((((C[k][i]) *                   (((((k - i) & 1 ? mod - 1 : 1) * (P[l - 1][k - i])) % mod))) %                  mod)) *                (query(troot[i], l, r))) %               mod)) %             mod;     return ans % mod;   }   long long iin() {     char c = 0;     long long u = 0;     int b = 1;     while (c <  0  || c >  9 ) {       c = getchar();       if (c ==  - ) b = -1;     }     while (c >=  0  && c <=  9 ) {       u = u * 10 + c -  0 ;       c = getchar();     }     return u;   }   int main() {     for (int k = 0; k <= KKK; ++k) C[k][0] = 1;     for (int k = 1; k <= KKK; ++k)       for (int i = 1; i <= k; ++i)         C[k][i] = (C[k - 1][i] + C[k - 1][i - 1]) % mod;     scanf( %d%d , &n, &m);     for (int i = 1; i <= n; ++i) scanf( %d , &a[i]);     for (int i = 0; i <= n; ++i)       for (int k = 0; k <= KKK; ++k) P[i][k] = ipow(i, k);     for (int k = 0; k <= KKK; ++k)       for (int i = 0, z = 0; i <= n; ++i, z = (z + P[i][k]) % mod) Q[i][k] = z;     for (int i = 0; i <= KKK; ++i) {       troot[i] = &T[tn++];       troot[i]->k = i;       troot[i]->l = 1;       troot[i]->r = n;       build(troot[i]);     }     for (int i = 0; i < m; ++i) {       char op[10];       scanf( %s , op);       if (op[0] ==  ? ) {         int l, r, k;         scanf( %d%d%d , &l, &r, &k);         int ans = op_query(l, r, k);         printf( %d n , ans);       }       if (op[0] ==  = ) {         int l, r, x;         scanf( %d%d%d , &l, &r, &x);         for (int k = 0; k <= KKK; ++k) modify(troot[k], l, r, x);       }     }     return 0;   }