#include <bits/stdc++.h>
using namespace std;
const int mo = 1000000007;
int n, m, l, r;
long long x, k, ans[6], s[100001][6], tree[400001][6], lan[400001];
char ch;
long long js(int l, int r, int k) { return (s[r][k] - s[l - 1][k] + mo) % mo; }
void pushup(int k) {
  for (int i = 0; i <= 5; i++)
    tree[k][i] = (tree[k * 2][i] + tree[k * 2 + 1][i]) % mo;
}
void pushdown(int k, int l, int r) {
  if (lan[k] != -1) {
    int mid = (l + r) >> 1;
    lan[k * 2] = lan[k * 2 + 1] = lan[k];
    for (int i = 0; i <= 5; i++)
      tree[k * 2][i] = lan[k] * js(l, mid, i) % mo,
               tree[k * 2 + 1][i] = lan[k] * js(mid + 1, r, i) % mo;
    lan[k] = -1;
  }
}
void build(int k, int l, int r) {
  lan[k] = -1;
  if (l == r) {
    scanf("%lld", &x);
    for (int i = 0; i <= 5; i++) tree[k][i] = x * js(l, l, i) % mo;
    return;
  }
  int mid = (l + r) >> 1;
  build(k * 2, l, mid);
  build(k * 2 + 1, mid + 1, r);
  pushup(k);
}
void change(int k, int l, int r, int x, int y, int z) {
  if (x <= l && r <= y) {
    lan[k] = z;
    for (int i = 0; i <= 5; i++) tree[k][i] = z * js(l, r, i) % mo;
    return;
  }
  pushdown(k, l, r);
  int mid = (l + r) >> 1;
  if (x <= mid) change(k * 2, l, mid, x, y, z);
  if (y > mid) change(k * 2 + 1, mid + 1, r, x, y, z);
  pushup(k);
}
void query(int k, int l, int r, int x, int y) {
  if (x <= l && r <= y) {
    for (int i = 0; i <= 5; i++) ans[i] = (ans[i] + tree[k][i]) % mo;
    return;
  }
  pushdown(k, l, r);
  int mid = (l + r) >> 1;
  if (x <= mid) query(k * 2, l, mid, x, y);
  if (y > mid) query(k * 2 + 1, mid + 1, r, x, y);
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) {
    s[i][0] = 1;
    for (int j = 1; j <= 5; j++) s[i][j] = s[i][j - 1] * i % mo;
  }
  for (int i = 0; i <= 5; i++)
    for (int j = 1; j <= n; j++) s[j][i] = s[j - 1][i] + s[j][i] % mo;
  build(1, 1, n);
  getchar();
  for (int i = 1; i <= m; i++) {
    ch = getchar();
    scanf("%d%d%lld", &l, &r, &k);
    getchar();
    if (ch == '=')
      change(1, 1, n, l, r, k);
    else {
      long long sum = 0;
      memset(ans, 0, sizeof(ans));
      query(1, 1, n, l, r);
      if (k == 0)
        sum = (sum + ans[0]) % mo;
      else if (k == 1) {
        sum = (sum + ans[1]) % mo;
        sum = (sum - ans[0] * (l - 1) % mo + mo) % mo;
      } else if (k == 2) {
        sum = (sum + ans[2]) % mo;
        sum = (sum - ans[1] * 2 % mo * (l - 1) % mo + mo) % mo;
        sum = (sum + ans[0] * (l - 1) % mo * (l - 1) % mo) % mo;
      } else if (k == 3) {
        sum = (sum + ans[3]) % mo;
        sum = (sum - ans[2] * 3 % mo * (l - 1) % mo + mo) % mo;
        sum = (sum + ans[1] * 3 % mo * (l - 1) % mo * (l - 1) % mo) % mo;
        sum = (sum - ans[0] * (l - 1) % mo * (l - 1) % mo * (l - 1) % mo) % mo;
      } else if (k == 4) {
        sum = (sum + ans[4]) % mo;
        sum = (sum - ans[3] * 4 % mo * (l - 1) % mo + mo) % mo;
        sum = (sum + ans[2] * 6 % mo * (l - 1) % mo * (l - 1) % mo) % mo;
        sum = (sum -
               ans[1] * 4 % mo * (l - 1) % mo * (l - 1) % mo * (l - 1) % mo +
               mo) %
              mo;
        sum = (sum + ans[0] * (l - 1) % mo * (l - 1) % mo * (l - 1) % mo *
                         (l - 1) % mo) %
              mo;
      } else {
        sum = (sum + ans[5]) % mo;
        sum = (sum - ans[4] * 5 % mo * (l - 1) % mo + mo) % mo;
        sum = (sum + ans[3] * 10 % mo * (l - 1) % mo * (l - 1) % mo) % mo;
        sum = (sum -
               ans[2] * 10 % mo * (l - 1) % mo * (l - 1) % mo * (l - 1) % mo +
               mo) %
              mo;
        sum = (sum + ans[1] * 5 % mo * (l - 1) % mo * (l - 1) % mo * (l - 1) %
                         mo * (l - 1) % mo) %
              mo;
        sum = (sum -
               ans[0] * (l - 1) % mo * (l - 1) % mo * (l - 1) % mo * (l - 1) %
                   mo * (l - 1) % mo +
               mo) %
              mo;
      }
      sum = (sum + mo) % mo;
      printf("%lld\n", sum);
    }
  }
  return 0;
}
