#include <bits/stdc++.h>
inline int in() {
  int x = 0;
  char c = getchar();
  bool f = false;
  while (c < '0' || c > '9') f |= c == '-', c = getchar();
  while (c >= '0' && c <= '9')
    x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
  return f ? -x : x;
}
const int N = 4e5 + 5, mod = 1e9 + 7;
int pri[505], inv[505], pcnt;
bool inp[505];
inline int qpow(int base, int b) {
  int ret = 1;
  for (; b; b >>= 1, base = (long long)base * base % mod)
    if (b & 1) ret = (long long)ret * base % mod;
  return ret;
}
struct Segment_Tree {
  int sum[N << 2], lazy[N << 2];
  long long st[N << 2], tag[N << 2];
  inline void push_up(int p) {
    st[p] = st[p << 1] | st[p << 1 | 1];
    sum[p] = (long long)sum[p << 1] * sum[p << 1 | 1] % mod;
  }
  inline void spread(int p, int tl, int tr) {
    if (tag[p]) {
      st[p << 1] |= tag[p], st[p << 1 | 1] |= tag[p], tag[p << 1] |= tag[p],
          tag[p << 1 | 1] |= tag[p];
      tag[p] = 0;
    }
    if (lazy[p] != 1) {
      int mid = (tl + tr) >> 1;
      sum[p << 1] = (long long)sum[p << 1] * qpow(lazy[p], mid - tl + 1) % mod;
      sum[p << 1 | 1] =
          (long long)sum[p << 1 | 1] * qpow(lazy[p], tr - mid) % mod;
      lazy[p << 1] = (long long)lazy[p << 1] * lazy[p] % mod;
      lazy[p << 1 | 1] = (long long)lazy[p << 1 | 1] * lazy[p] % mod;
      lazy[p] = 1;
    }
  }
  inline void calc(int x, long long &b) {
    for (int i = 0; i < pcnt && pri[i] <= x; ++i)
      if (x % pri[i] == 0) b |= (1ll << i);
  }
  void build(int tl, int tr, int p) {
    lazy[p] = 1;
    if (tl == tr) {
      sum[p] = in();
      calc(sum[p], st[p]);
      return;
    }
    int mid = (tl + tr) >> 1;
    build(tl, mid, p << 1), build(mid + 1, tr, p << 1 | 1);
    push_up(p);
  }
  void update(int l, int r, int k, int tl, int tr, int p) {
    if (l <= tl && tr <= r) {
      sum[p] = (long long)sum[p] * qpow(k, tr - tl + 1) % mod;
      lazy[p] = (long long)lazy[p] * k % mod;
      calc(k, st[p]), calc(k, tag[p]);
      return;
    }
    spread(p, tl, tr);
    int mid = (tl + tr) >> 1;
    if (mid >= l) update(l, r, k, tl, mid, p << 1);
    if (mid < r) update(l, r, k, mid + 1, tr, p << 1 | 1);
    push_up(p);
  }
  std::pair<int, long long> query(int l, int r, int tl, int tr, int p) {
    if (l <= tl && tr <= r) return std::pair<int, long long>(sum[p], st[p]);
    spread(p, tl, tr);
    int mid = (tl + tr) >> 1;
    std::pair<int, long long> ret = std::pair<int, long long>(1, 0);
    if (mid >= l) {
      std::pair<int, long long> tmp = query(l, r, tl, mid, p << 1);
      ret.first *= tmp.first, ret.second |= tmp.second;
    }
    if (mid < r) {
      std::pair<int, long long> tmp = query(l, r, mid + 1, tr, p << 1 | 1);
      ret.first = (long long)ret.first * tmp.first % mod,
      ret.second |= tmp.second;
    }
    return ret;
  }
} T;
inline void pre() {
  const int n = 300;
  for (int i = 2; i <= n; ++i)
    if (!inp[i]) {
      pri[pcnt++] = i;
      for (int j = 1; j <= n / i; ++j) inp[i * j] = true;
    }
  inv[1] = 1;
  for (int i = 2; i <= n; ++i)
    inv[i] = ((long long)mod - (long long)(mod / i) * inv[mod % i] % mod) % mod;
}
char opt[10];
int main() {
  pre();
  int n = in(), m = in();
  T.build(1, n, 1);
  while (m--) {
    scanf("%s", opt);
    if (opt[0] == 'M') {
      int a = in(), b = in(), c = in();
      T.update(a, b, c, 1, n, 1);
    } else {
      int a = in(), b = in();
      std::pair<int, long long> res = T.query(a, b, 1, n, 1);
      for (int i = 0; i < pcnt; ++i)
        if (res.second & (1ll << i))
          res.first =
              (long long)res.first * (pri[i] - 1) % mod * inv[pri[i]] % mod;
      printf("%d\n", res.first);
    }
  }
  return 0;
}
