#include <bits/stdc++.h>
using namespace std;
const long long mod = 1e9 + 7;
long long c[6][6];
long long x[6][100002];
long long sum[6][100002 << 2];
long long col[100002 << 2];
long long a[100002];
long long xx[6][100002];
void init() {
  c[0][0] = 1;
  for (int i = 1; i < 6; i++) {
    c[i][0] = c[i][i] = 1;
    for (int j = 1; j < i; j++) c[i][j] = c[i - 1][j] + c[i - 1][j - 1];
  }
  for (int i = 0; i < 100002; i++) x[0][i] = 1;
  x[0][0] = 1;
  x[1][0] = 0;
  for (int i = 1; i < 100002; i++) x[1][i] = -i;
  for (int i = 2; i < 6; i++) {
    x[i][0] = 0;
    for (int j = 1; j < 100002; j++)
      x[i][j] = ((x[i - 1][j] * (-j)) % mod + mod) % mod;
  }
  for (int i = 0; i < 100002; i++) xx[0][i] = i;
  for (int i = 1; i < 6; i++) {
    xx[i][0] = 0;
    for (int j = 1; j < 100002; j++)
      xx[i][j] =
          (xx[i][j - 1] +
           ((((xx[i - 1][j] - xx[i - 1][j - 1] + mod) % mod) * j) % mod) +
           mod) %
          mod;
  }
}
void ups(int l, int r, int rt) {
  if (col[rt] != -1) {
    col[rt << 1] = col[rt << 1 | 1] = col[rt];
    int len = r - l + 1;
    long long k = col[rt] * (len - (len >> 1));
    sum[0][rt << 1] = k;
    int mid = (l + r) >> 1;
    for (int i = 1; i <= 5; i++)
      sum[i][rt << 1] =
          (col[rt] * ((xx[i][mid] - xx[i][l - 1] + mod) % mod)) % mod;
    k = col[rt] * (len >> 1);
    sum[0][rt << 1 | 1] = k;
    for (int i = 1; i < 6; i++)
      sum[i][rt << 1 | 1] =
          (col[rt] * ((xx[i][r] - xx[i][mid] + mod) % mod)) % mod;
    col[rt] = -1;
  }
}
void uprt(int rt) {
  for (int i = 0; i < 6; i++)
    sum[i][rt] = (sum[i][rt << 1] + sum[i][rt << 1 | 1]) % mod;
}
void build(int l, int r, int rt) {
  col[rt] = -1;
  if (l == r) {
    sum[0][rt] = a[l];
    for (int i = 1; i < 6; i++) sum[i][rt] = (sum[i - 1][rt] * l) % mod;
    return;
  }
  int mid = (l + r) >> 1;
  build(l, mid, rt << 1);
  build(mid + 1, r, rt << 1 | 1);
  uprt(rt);
}
void updata(int L, int R, long long c, int l, int r, int rt) {
  if (L <= l && r <= R) {
    sum[0][rt] = (c * (r - l + 1)) % mod;
    for (int i = 1; i < 6; i++)
      sum[i][rt] = (c * ((xx[i][r] - xx[i][l - 1] + mod) % mod)) % mod;
    col[rt] = c;
    return;
  }
  ups(l, r, rt);
  int mid = (l + r) >> 1;
  if (L <= mid) updata(L, R, c, l, mid, rt << 1);
  if (mid < R) updata(L, R, c, mid + 1, r, rt << 1 | 1);
  uprt(rt);
}
long long query(int L, int R, int c, int l, int r, int rt) {
  if (L <= l && r <= R) return sum[c][rt];
  ups(l, r, rt);
  int mid = (l + r) >> 1;
  long long ans = 0;
  if (L <= mid) ans = query(L, R, c, l, mid, rt << 1);
  if (mid < R) ans = (ans + query(L, R, c, mid + 1, r, rt << 1 | 1)) % mod;
  return ans;
}
int main() {
  int n, k;
  scanf("%d%d", &n, &k);
  for (int i = 1; i <= n; i++) scanf("%lld", &a[i]);
  build(1, n, 1);
  char cc;
  int l, r, kk;
  cin.get();
  init();
  while (k--) {
    scanf("%c%d%d%d%*c", &cc, &l, &r, &kk);
    if (cc == '?') {
      long long ans = 0;
      for (int i = 0; i <= kk; i++) {
        ans = ((ans + (((query(l, r, i, 1, n, 1) * c[kk][i]) % mod) *
                       x[kk - i][l - 1]) %
                          mod) %
                   mod +
               mod) %
              mod;
      }
      printf("%lld\n", ans);
    } else
      updata(l, r, kk, 1, n, 1);
  }
}
