#include <bits/stdc++.h>
using namespace std;
const int maxn = 400005;
const long long mod = 1e9 + 7;
long long idx[305];
long long prime[63];
long long inv[63];
long long a[maxn];
long long q_pow(long long a, long long b) {
  long long ans = 1;
  while (b) {
    if (b & 1) ans = ans * a % mod;
    b >>= 1;
    a = a * a % mod;
  }
  return ans;
}
void init() {
  int tot = 0;
  for (int i = 2; i <= 300; i++) {
    bool flag = true;
    for (int j = 2; j <= sqrt(i); j++) {
      if (i % j == 0) {
        flag = false;
        break;
      }
    }
    if (flag) {
      idx[i] = ++tot;
      prime[tot] = i;
    }
  }
  for (int i = 1; i <= tot; i++) inv[i] = q_pow(prime[i], mod - 2);
}
struct node {
  bitset<63> prime;
  long long num;
} tr[4 * maxn], tag[4 * maxn];
node comb(node x, node y) {
  node ret;
  ret.num = x.num * y.num % mod;
  ret.prime = x.prime | y.prime;
  return ret;
}
inline void pushup(int o) {
  tr[o].num = tr[o * 2].num * tr[o * 2 + 1].num % mod;
  tr[o].prime = tr[o * 2].prime | tr[o * 2 + 1].prime;
}
inline void pushdown(int o, int l, int r) {
  if (tag[o].num != 1) {
    tr[o * 2].num =
        tr[o * 2].num * q_pow(tag[o].num, (l + r) / 2 - l + 1) % mod;
    tr[o * 2 + 1].num =
        tr[o * 2 + 1].num * q_pow(tag[o].num, r - (l + r) / 2) % mod;
    tag[o * 2].num = tag[o * 2].num * tag[o].num % mod;
    tag[o * 2 + 1].num = tag[o * 2 + 1].num * tag[o].num % mod;
    tag[o].num = 1;
  }
  tr[o * 2].prime |= tag[o].prime;
  tr[o * 2 + 1].prime |= tag[o].prime;
  tag[o * 2].prime |= tag[o].prime;
  tag[o * 2 + 1].prime |= tag[o].prime;
  tag[o].prime.reset();
}
void build(int o, int l, int r) {
  tag[o].num = 1;
  if (l == r) {
    tr[o].num = a[l];
    for (int i = 1; i <= 62; i++)
      if (a[l] % prime[i] == 0) tr[o].prime[i] = 1;
    return;
  }
  build(o * 2, l, (l + r) / 2);
  build(o * 2 + 1, (l + r) / 2 + 1, r);
  pushup(o);
}
void update(int o, int l, int r, int ql, int qr, long long x) {
  if (ql <= l && qr >= r) {
    tr[o].num = tr[o].num * q_pow(x, r - l + 1) % mod;
    tag[o].num = tag[o].num * x % mod;
    for (int i = 1; i <= 62; i++)
      if (x % prime[i] == 0) tr[o].prime[i] = 1, tag[o].prime[i] = 1;
    return;
  }
  pushdown(o, l, r);
  if (qr <= (l + r) / 2)
    update(o * 2, l, (l + r) / 2, ql, qr, x);
  else if (ql > (l + r) / 2)
    update(o * 2 + 1, (l + r) / 2 + 1, r, ql, qr, x);
  else {
    update(o * 2, l, (l + r) / 2, ql, qr, x);
    update(o * 2 + 1, (l + r) / 2 + 1, r, ql, qr, x);
  }
  pushup(o);
}
node query(int o, int l, int r, int ql, int qr) {
  if (ql <= l && qr >= r) return tr[o];
  pushdown(o, l, r);
  if (qr <= (l + r) / 2)
    query(o * 2, l, (l + r) / 2, ql, qr);
  else if (ql > (l + r) / 2)
    query(o * 2 + 1, (l + r) / 2 + 1, r, ql, qr);
  else {
    node x = query(o * 2, l, (l + r) / 2, ql, qr);
    node y = query(o * 2 + 1, (l + r) / 2 + 1, r, ql, qr);
    return comb(x, y);
  }
}
int main() {
  init();
  int n, q;
  scanf("%d%d", &n, &q);
  for (int i = 1; i <= n; i++) scanf("%lld", a + i);
  build(1, 1, n);
  while (q--) {
    char t[15];
    scanf("%s", t);
    if (t[0] == 'M') {
      int l, r;
      long long x;
      scanf("%d%d%lld", &l, &r, &x);
      update(1, 1, n, l, r, x);
    } else {
      int l, r;
      scanf("%d%d", &l, &r);
      node ans = query(1, 1, n, l, r);
      long long res = 1;
      for (int i = 1; i <= 62; i++) {
        if (ans.prime[i]) res = res * (prime[i] - 1) % mod * inv[i] % mod;
      }
      res = res * ans.num % mod;
      printf("%lld\n", res);
    }
  }
}
