#include <bits/stdc++.h>
using namespace std;
const int maxn = 100008, mod = (int)1e9 + 7;
int n, m, a[maxn], s[6][maxn], c[6][6];
inline int Mod(int x) { return x >= mod ? x - mod : x; }
struct SegmentTree {
  struct Node {
    Node *l, *r;
    int sum[6], cov;
    Node() {
      l = r = NULL;
      cov = -1;
    }
  } * Root;
  inline void Maintain(Node *x) {
    for (int i = 0; i < 6; i++) x->sum[i] = Mod(x->l->sum[i] + x->r->sum[i]);
  }
  Node *Build(int l, int r) {
    Node *x = new Node();
    if (l == r)
      for (int i = 0; i < 6; i++)
        x->sum[i] = (long long)a[l] * (s[i][l] - s[i][l - 1] + mod) % mod;
    else {
      int m = l + r >> 1;
      x->l = Build(l, m);
      x->r = Build(m + 1, r);
      Maintain(x);
    }
    return x;
  }
  inline void DoCov(Node *x, int d, int l, int r) {
    if (!x) return;
    x->cov = d;
    for (int i = 0; i < 6; i++)
      x->sum[i] = (long long)d * (s[i][r] - s[i][l - 1] + mod) % mod;
  }
  inline void PushDown(Node *x, int l, int r) {
    if (x->cov != -1) {
      int m = l + r >> 1;
      DoCov(x->l, x->cov, l, m);
      DoCov(x->r, x->cov, m + 1, r);
      x->cov = -1;
    }
  }
  void Cover(Node *x, int s, int t, int d, int l = 1, int r = n) {
    if (l > t || r < s) return;
    PushDown(x, l, r);
    if (l >= s && r <= t) {
      DoCov(x, d, l, r);
      return;
    }
    int m = l + r >> 1;
    Cover(x->l, s, t, d, l, m);
    Cover(x->r, s, t, d, m + 1, r);
    Maintain(x);
  }
  int Query(Node *x, int s, int t, int k, int l = 1, int r = n) {
    if (l > t || r < s) return 0;
    PushDown(x, l, r);
    if (l >= s && r <= t) return x->sum[k];
    int m = l + r >> 1, rep = 0;
    rep = Query(x->l, s, t, k, l, m);
    rep = Mod(rep + Query(x->r, s, t, k, m + 1, r));
    return rep;
  }
} T;
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) scanf("%d", a + i), s[0][i] = s[0][i - 1] + 1;
  for (int i = 1; i <= 5; i++)
    for (int j = 1; j <= n; j++)
      s[i][j] =
          Mod(s[i][j - 1] +
              ((long long)j * (s[i - 1][j] - s[i - 1][j - 1] + mod)) % mod);
  c[0][0] = 1;
  c[1][0] = 1;
  for (int i = 0; i < 6; i++)
    for (int j = c[i][0] = 1; j <= i; j++)
      c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod;
  T.Root = T.Build(1, n);
  while (m--) {
    char ch[10];
    int s, t, k;
    scanf("%s%d%d%d", ch, &s, &t, &k);
    if (ch[0] == '=')
      T.Cover(T.Root, s, t, k);
    else {
      int x = 1 - s, cur = 1, ans = 0;
      for (int i = k; i >= 0; i--, cur = (long long)cur * x % mod)
        ans = (ans + (long long)c[k][i] * T.Query(T.Root, s, t, i) % mod * cur %
                         mod) %
              mod;
      printf("%d\n", Mod(ans + mod));
    }
  }
  return 0;
}
