#include <bits/stdc++.h>
using namespace std;
const int mod = 1e9 + 7;
const int maxn = 4e5 + 400;
int prime[] = {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};
long long poww(long long a, long long b) {
  long long res = 1;
  long long base = a;
  while (b) {
    if (b & 1) {
      res *= base;
      res %= mod;
    }
    base *= base;
    base %= mod;
    b >>= 1;
  }
  return res;
}
struct node {
  int l, r;
  long long mul;
  long long p;
  long long lazy;
  long long lazy2;
} Node[maxn << 2];
void build(int l, int r, int step) {
  Node[step].l = l;
  Node[step].r = r;
  Node[step].mul = Node[step].lazy = 1;
  Node[step].p = Node[step].lazy2 = 0;
  if (l == r) return;
  build(l, (l + r) >> 1, step << 1);
  build(((l + r) >> 1) + 1, r, step << 1 | 1);
}
void push_up(int step) {
  Node[step].mul = Node[step << 1].mul * Node[step << 1 | 1].mul % mod;
  Node[step].p = Node[step << 1].p | Node[step << 1 | 1].p;
}
void push_down(int step) {
  if (Node[step].lazy != 1) {
    Node[step << 1].lazy = Node[step << 1].lazy * Node[step].lazy % mod;
    Node[step << 1].mul =
        Node[step << 1].mul *
        poww(Node[step].lazy, (Node[step << 1].r - Node[step << 1].l + 1)) %
        mod;
    Node[step << 1 | 1].lazy = Node[step << 1 | 1].lazy * Node[step].lazy % mod;
    Node[step << 1 | 1].mul =
        Node[step << 1 | 1].mul *
        poww(Node[step].lazy,
             (Node[step << 1 | 1].r - Node[step << 1 | 1].l + 1)) %
        mod;
    Node[step].lazy = 1;
  }
  if (Node[step].lazy2) {
    Node[step << 1].lazy2 |= Node[step].lazy2;
    Node[step << 1].p |= Node[step].lazy2;
    Node[step << 1 | 1].lazy2 |= Node[step].lazy2;
    Node[step << 1 | 1].p |= Node[step].lazy2;
    Node[step].lazy2 = 0;
  }
}
void update(int l, int r, int step, long long val) {
  if (Node[step].l == l && Node[step].r == r) {
    Node[step].mul = Node[step].mul * poww(val, (r - l + 1)) % mod;
    int vval = val;
    for (int i = 0; prime[i]; i++) {
      while (vval % prime[i] == 0) {
        Node[step].p |= (1ll << i);
        Node[step].lazy2 |= (1ll << i);
        vval /= prime[i];
      }
      if (vval == 1) break;
    }
    Node[step].lazy = Node[step].lazy * val % mod;
    return;
  }
  push_down(step);
  int mid = (Node[step].l + Node[step].r) >> 1;
  if (mid >= r)
    update(l, r, step << 1, val);
  else if (mid < l)
    update(l, r, step << 1 | 1, val);
  else {
    update(l, mid, step << 1, val);
    update(mid + 1, r, step << 1 | 1, val);
  }
  push_up(step);
}
long long qqq = 0;
long long query(int l, int r, int step) {
  if (Node[step].l == l && Node[step].r == r) {
    long long val = Node[step].p;
    long long res = 1;
    qqq |= val;
    res = res * Node[step].mul % mod;
    return res;
  }
  push_down(step);
  int mid = (Node[step].l + Node[step].r) >> 1;
  if (mid >= r)
    return query(l, r, step << 1);
  else if (mid < l)
    return query(l, r, step << 1 | 1);
  else {
    return (query(l, mid, step << 1) * query(mid + 1, r, step << 1 | 1)) % mod;
  }
}
int n, q;
int main() {
  scanf("%d%d", &n, &q);
  build(1, n, 1);
  for (int i = 1; i <= n; i++) {
    long long a;
    scanf("%lld", &a);
    update(i, i, 1, a);
  }
  while (q--) {
    char ss[20];
    scanf("%s", ss);
    if (ss[0] == 'M') {
      int l, r;
      long long val;
      scanf("%d%d%lld", &l, &r, &val);
      update(l, r, 1, val);
    } else {
      int l, r;
      scanf("%d%d", &l, &r);
      qqq = 0;
      long long ans = query(l, r, 1);
      int tot = 0;
      while (qqq) {
        if (qqq & 1) {
          ans *= (1 - poww(prime[tot], mod - 2));
          ans %= mod;
        }
        qqq >>= 1;
        tot++;
      }
      ans %= mod;
      ans += mod;
      ans %= mod;
      printf("%lld\n", ans);
    }
  }
}
