#include <bits/stdc++.h>
const int N = 4e5 + 5, M = 301, M2 = 1e5 + 1, LIM = 62;
const int P[LIM] = {2,   3,   5,   7,   11,  13,  17,  19,  23,  29,  31,
                    37,  41,  43,  47,  53,  59,  61,  67,  71,  73,  79,
                    83,  89,  97,  101, 103, 107, 109, 113, 127, 131, 137,
                    139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193,
                    197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257,
                    263, 269, 271, 277, 281, 283, 293};
const int ref[M] = {
    0, 0,  0,  1, 0,  2,  0, 3, 0,  0, 0,  4,  0, 5,  0, 0, 0,  6,  0, 7,  0,
    0, 0,  8,  0, 0,  0,  0, 0, 9,  0, 10, 0,  0, 0,  0, 0, 11, 0,  0, 0,  12,
    0, 13, 0,  0, 0,  14, 0, 0, 0,  0, 0,  15, 0, 0,  0, 0, 0,  16, 0, 17, 0,
    0, 0,  0,  0, 18, 0,  0, 0, 19, 0, 20, 0,  0, 0,  0, 0, 21, 0,  0, 0,  22,
    0, 0,  0,  0, 0,  23, 0, 0, 0,  0, 0,  0,  0, 24, 0, 0, 0,  25, 0, 26, 0,
    0, 0,  27, 0, 28, 0,  0, 0, 29, 0, 0,  0,  0, 0,  0, 0, 0,  0,  0, 0,  0,
    0, 30, 0,  0, 0,  31, 0, 0, 0,  0, 0,  32, 0, 33, 0, 0, 0,  0,  0, 0,  0,
    0, 0,  34, 0, 35, 0,  0, 0, 0,  0, 36, 0,  0, 0,  0, 0, 37, 0,  0, 0,  38,
    0, 0,  0,  0, 0,  39, 0, 0, 0,  0, 0,  40, 0, 41, 0, 0, 0,  0,  0, 0,  0,
    0, 0,  42, 0, 43, 0,  0, 0, 44, 0, 45, 0,  0, 0,  0, 0, 0,  0,  0, 0,  0,
    0, 46, 0,  0, 0,  0,  0, 0, 0,  0, 0,  0,  0, 47, 0, 0, 0,  48, 0, 49, 0,
    0, 0,  50, 0, 0,  0,  0, 0, 51, 0, 52, 0,  0, 0,  0, 0, 0,  0,  0, 0,  53,
    0, 0,  0,  0, 0,  54, 0, 0, 0,  0, 0,  55, 0, 0,  0, 0, 0,  56, 0, 57, 0,
    0, 0,  0,  0, 58, 0,  0, 0, 59, 0, 60, 0,  0, 0,  0, 0, 0,  0,  0, 0,  61};
inline int read();
struct Segment_Tree {
  int val[N << 2], tag[N << 2];
  long long now, Ans, f[N << 2], tagf[N << 2];
  inline int FP(int x, int k) {
    int t = 1;
    for (; k; k >>= 1, x = 1ll * x * x % 1000000007)
      if (k & 1) t = 1ll * t * x % 1000000007;
    return t;
  }
  void Build(int l, int r, int rt) {
    tag[rt] = 1;
    if (l == r) {
      int v = read();
      val[rt] = v;
      for (int i = 0; i < LIM && P[i] * P[i] <= v; ++i)
        if (!(v % P[i])) {
          f[rt] |= 1ll << i, v /= P[i];
          while (!(v % P[i])) v /= P[i];
        }
      if (v != 1) f[rt] |= 1ll << ref[v];
      return;
    }
    int m = l + r >> 1;
    Build(l, m, rt << 1), Build(m + 1, r, rt << 1 | 1),
        f[rt] = f[rt << 1] | f[rt << 1 | 1],
        val[rt] = 1ll * val[rt << 1] * val[rt << 1 | 1] % 1000000007;
  }
  inline void PushDown(int rt, int m) {
    int l = rt << 1, r = rt << 1 | 1;
    val[l] = 1ll * val[l] * FP(tag[rt], m - (m >> 1)) % 1000000007,
    tag[l] = 1ll * tag[l] * tag[rt] % 1000000007, f[l] |= tagf[rt],
    tagf[l] |= tagf[rt],
    val[r] = 1ll * val[r] * FP(tag[rt], m >> 1) % 1000000007,
    tag[r] = 1ll * tag[r] * tag[rt] % 1000000007, f[r] |= tagf[rt],
    tagf[r] |= tagf[rt], tag[rt] = 1, tagf[rt] = 0;
  }
  void Modify(int l, int r, int rt, int L, int R, int v) {
    if (L <= l && r <= R) {
      val[rt] = 1ll * val[rt] * FP(v, r - l + 1) % 1000000007,
      tag[rt] = 1ll * tag[rt] * v % 1000000007, f[rt] |= now, tagf[rt] |= now;
      return;
    }
    if (tag[rt] != 1) PushDown(rt, r - l + 1);
    int m = l + r >> 1;
    if (L <= m) Modify(l, m, rt << 1, L, R, v);
    if (m < R) Modify(m + 1, r, rt << 1 | 1, L, R, v);
    f[rt] = f[rt << 1] | f[rt << 1 | 1],
    val[rt] = 1ll * val[rt << 1] * val[rt << 1 | 1] % 1000000007;
  }
  int Query(int l, int r, int rt, int L, int R) {
    if (L <= l && r <= R) return Ans |= f[rt], val[rt];
    if (tag[rt] != 1) PushDown(rt, r - l + 1);
    int m = l + r >> 1;
    if (L <= m)
      if (m < R)
        return 1ll * Query(l, m, rt << 1, L, R) *
               Query(m + 1, r, rt << 1 | 1, L, R) % 1000000007;
      else
        return Query(l, m, rt << 1, L, R);
    return Query(m + 1, r, rt << 1 | 1, L, R);
  }
} T;
inline int read() {
  int now = 0;
  register char c = getchar();
  for (; !isdigit(c); c = getchar())
    ;
  for (; isdigit(c); now = now * 10 + c - 48, c = getchar())
    ;
  return now;
}
inline char GetOpt() {
  register char c;
  while (!isalpha(c = getchar()))
    ;
  return c;
}
int main() {
  static int inv[N], coef[N];
  inv[1] = 1;
  for (int i = 2; i < M; ++i)
    inv[i] =
        1ll * (1000000007 - 1000000007 / i) * inv[1000000007 % i] % 1000000007;
  for (int i = 0; i < LIM; ++i)
    coef[i] = 1ll * (P[i] - 1) * inv[P[i]] % 1000000007;
  int n = read(), q = read();
  T.Build(1, n, 1);
  while (q--) {
    if (GetOpt() == 'T') {
      T.Ans = 0;
      int l = read(), r = read(), val = T.Query(1, n, 1, l, r);
      for (int i = 0; i < LIM; ++i)
        if (T.Ans >> i & 1) val = 1ll * val * coef[i] % 1000000007;
      printf("%d\n", val);
    } else {
      int l = read(), r = read(), x = read(), v = x;
      long long now = 0;
      for (int i = 0; i < LIM && P[i] * P[i] <= v; ++i)
        if (!(v % P[i])) {
          now |= 1ll << i, v /= P[i];
          while (!(v % P[i])) v /= P[i];
        }
      if (v != 1) now |= 1ll << ref[v];
      T.now = now, T.Modify(1, n, 1, l, r, x);
    }
  }
  return 0;
}
