#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline void read(T &s) {
  s = 0;
  char ch = getchar();
  while (!isdigit(ch)) ch = getchar();
  while (isdigit(ch)) s = ((s + (s << 2)) << 1) + ch - '0', ch = getchar();
}
int n, q, zhi[310], zl, Inv[310], a[410000];
bool used[310];
bitset<63> val[310];
struct Point {
  int tot, tmp;
  bitset<63> s, tmps;
} tr[410000 << 3];
inline int Fast_Power(int u, int k = 1000000007 - 2) {
  int Sum = 1;
  while (k) {
    if (k & 1) Sum = 1ll * Sum * u % 1000000007;
    u = (long long)u * u % 1000000007, k >>= 1;
  }
  return Sum;
}
inline void Get_val() {
  for (int i = 2; i <= 300; ++i) {
    if (!used[i]) zhi[++zl] = i, Inv[zl] = Fast_Power(i);
    for (int j = 1; j <= zl && zhi[j] * i <= 300; ++j) {
      used[zhi[j] * i] = 1;
      if (i % zhi[j] == 0) break;
    }
  }
  for (int i = 2; i <= 300; ++i)
    for (int j = 1; j <= zl; ++j)
      if (i % zhi[j] == 0) val[i].set(j - 1);
}
inline void Update(int now) {
  tr[now].tot = 1ll * tr[now << 1].tot * tr[now << 1 | 1].tot % 1000000007,
  tr[now].s = tr[now << 1].s | tr[now << 1 | 1].s;
}
inline void Pushdown(int now, int l, int r) {
  int mid = (l + r) >> 1;
  if (tr[now].tmp != 1) {
    tr[now << 1].tot = 1ll * tr[now << 1].tot *
                       Fast_Power(tr[now].tmp, mid - l + 1) % 1000000007,
              tr[now << 1 | 1].tot = 1ll * tr[now << 1 | 1].tot *
                                     Fast_Power(tr[now].tmp, r - mid) %
                                     1000000007;
    tr[now << 1].tmp = 1ll * tr[now << 1].tmp * tr[now].tmp % 1000000007,
              tr[now << 1 | 1].tmp =
                  1ll * tr[now << 1 | 1].tmp * tr[now].tmp % 1000000007;
    tr[now].tmp = 1;
  }
  if (tr[now].tmps != 0) {
    tr[now << 1].s |= tr[now].tmps,
        tr[now << 1 | 1].s = tr[now << 1 | 1].s | tr[now].tmps;
    tr[now << 1].tmps |= tr[now].tmps, tr[now << 1 | 1].tmps |= tr[now].tmps;
    tr[now].tmps = 0;
  }
}
inline void Build(int now, int l, int r) {
  tr[now].s = tr[now].tmps = 0, tr[now].tot = tr[now].tmp = 1;
  if (l == r) return (void)(tr[now].tot = a[l], tr[now].s = val[a[l]]);
  int mid = (l + r) >> 1;
  Build(now << 1, l, mid), Build(now << 1 | 1, mid + 1, r), Update(now);
}
inline void Modify(int now, int l, int r, int ql, int qr, int x) {
  if (ql <= l && r <= qr) {
    tr[now].tot = 1ll * tr[now].tot * Fast_Power(x, r - l + 1) % 1000000007,
    tr[now].tmp = 1ll * tr[now].tmp * x % 1000000007;
    tr[now].s |= val[x], tr[now].tmps |= val[x];
    return;
  }
  Pushdown(now, l, r);
  int mid = (l + r) >> 1;
  if (mid < qr) Modify(now << 1 | 1, mid + 1, r, ql, qr, x);
  if (mid >= ql) Modify(now << 1, l, mid, ql, qr, x);
  Update(now);
}
inline int Querytot(int now, int l, int r, int ql, int qr) {
  if (ql <= l && r <= qr) return tr[now].tot;
  Pushdown(now, l, r);
  int mid = (l + r) >> 1, Sum = 1;
  if (mid < qr)
    Sum = 1ll * Sum * Querytot(now << 1 | 1, mid + 1, r, ql, qr) % 1000000007;
  if (mid >= ql)
    Sum = 1ll * Sum * Querytot(now << 1, l, mid, ql, qr) % 1000000007;
  return Sum;
}
inline bitset<63> Querys(int now, int l, int r, int ql, int qr) {
  if (ql <= l && r <= qr) return tr[now].s;
  Pushdown(now, l, r);
  int mid = (l + r) >> 1;
  bitset<63> Sum = 0;
  if (mid < qr) Sum |= Querys(now << 1 | 1, mid + 1, r, ql, qr);
  if (mid >= ql) Sum |= Querys(now << 1, l, mid, ql, qr);
  return Sum;
}
inline void Query(int l, int r) {
  int Sum = Querytot(1, 1, n, l, r);
  bitset<63> S = Querys(1, 1, n, l, r);
  for (int i = 0; i < zl; ++i)
    if (S.test(i))
      Sum = 1ll * Sum * Inv[i + 1] % 1000000007 * (zhi[i + 1] - 1) % 1000000007;
  printf("%d\n", Sum);
}
int main() {
  Get_val(), read(n), read(q);
  for (int i = 1; i <= n; ++i) read(a[i]);
  Build(1, 1, n);
  string s;
  int l, r, x;
  while (q--) {
    cin >> s;
    if (s == "MULTIPLY")
      read(l), read(r), read(x), Modify(1, 1, n, l, r, x);
    else
      read(l), read(r), Query(l, r);
  }
  return 0;
}
