#include <bits/stdc++.h>
using namespace std;
inline long long rd() {
  long long _x = 0;
  int _ch = getchar(), _f = 1;
  for (; !isdigit(_ch) && (_ch != '-') && (_ch != EOF); _ch = getchar())
    ;
  if (_ch == '-') {
    _f = 0;
    _ch = getchar();
  }
  for (; isdigit(_ch); _ch = getchar()) _x = _x * 10 + _ch - '0';
  return _f ? _x : -_x;
}
void write(long long _x) {
  if (_x >= 10)
    write(_x / 10), putchar(_x % 10 + '0');
  else
    putchar(_x + '0');
}
inline void wrt(long long _x, char _p) {
  if (_x < 0) putchar('-'), _x = -_x;
  write(_x);
  if (_p) putchar(_p);
}
int n, q;
inline int qpow(int x, int k = 1000000007 - 2) {
  int ans = 1;
  for (; k; k >>= 1, x = 1ll * x * x % 1000000007)
    if (k & 1) ans = 1ll * ans * x % 1000000007;
  return ans;
}
int pri[70], tp, vis[305], ipri[70];
void euler(int mx) {
  for (int i = int(2); i <= (int)(mx); i++) {
    if (!vis[i]) pri[++tp] = i, ipri[tp] = qpow(i);
    for (int j = 1; j <= tp && i * pri[j] <= mx; j++) {
      vis[i * pri[j]] = 1;
      if (i % pri[j] == 0) break;
    }
  }
}
long long fj(int x) {
  long long bt = 0;
  for (int i = int(1); i <= (int)(tp); i++)
    if (x % pri[i] == 0) bt |= 1ll << i;
  return bt;
}
int calc(long long bt) {
  int ans = 1;
  for (int i = int(1); i <= (int)(tp); i++) {
    if (bt & (1ll << i))
      ans = 1ll * ans * (pri[i] - 1) % 1000000007 * ipri[i] % 1000000007;
  }
  return ans;
}
struct node {
  long long bt, lazy1;
  int sum, lazy;
} tr[400005 << 2];
void pushdown(int pos, int l, int r) {
  if (tr[pos].lazy > 1) {
    int x = tr[pos].lazy;
    long long y = tr[pos].lazy1;
    tr[pos << 1].lazy = 1ll * tr[pos << 1].lazy * x % 1000000007;
    tr[pos << 1].sum =
        1ll * tr[pos << 1].sum * qpow(x, ((l + r) >> 1) - l + 1) % 1000000007;
    tr[pos << 1 | 1].lazy = 1ll * tr[pos << 1 | 1].lazy * x % 1000000007;
    tr[pos << 1 | 1].sum =
        1ll * tr[pos << 1 | 1].sum * qpow(x, r - ((l + r) >> 1)) % 1000000007;
    tr[pos << 1].lazy1 |= y;
    tr[pos << 1].bt |= y;
    tr[pos << 1 | 1].lazy1 |= y;
    tr[pos << 1 | 1].bt |= y;
    tr[pos].lazy = 1, tr[pos].lazy1 = 0;
  }
}
void pushup(int pos) {
  tr[pos].sum = 1ll * tr[pos << 1].sum * tr[pos << 1 | 1].sum % 1000000007;
  tr[pos].bt = tr[pos << 1 | 1].bt | tr[pos << 1].bt;
}
void update(int pos, int l, int r, int ql, int qr, int x) {
  if (r < ql || l > qr) return;
  if (ql <= l && r <= qr) {
    tr[pos].sum = 1ll * tr[pos].sum * qpow(x, r - l + 1) % 1000000007;
    tr[pos].lazy = 1ll * tr[pos].lazy * x % 1000000007;
    long long BT = fj(x);
    tr[pos].lazy1 |= BT;
    tr[pos].bt |= BT;
    return;
  }
  pushdown(pos, l, r);
  update(pos << 1, l, ((l + r) >> 1), ql, qr, x);
  update(pos << 1 | 1, ((l + r) >> 1) + 1, r, ql, qr, x);
  pushup(pos);
}
int Sum;
long long Bt;
void query(int pos, int l, int r, int ql, int qr) {
  if (r < ql || l > qr) return;
  if (ql <= l && r <= qr) {
    Sum = 1ll * Sum * tr[pos].sum % 1000000007;
    Bt |= tr[pos].bt;
    return;
  }
  pushdown(pos, l, r);
  query(pos << 1, l, ((l + r) >> 1), ql, qr),
      query(pos << 1 | 1, ((l + r) >> 1) + 1, r, ql, qr);
}
int a[400005];
void build(int pos, int l, int r) {
  tr[pos].lazy = 1;
  if (l == r) {
    tr[pos].sum = a[l], tr[pos].bt = fj(a[l]);
    return;
  }
  pushdown(pos, l, r);
  build(pos << 1, l, ((l + r) >> 1)),
      build(pos << 1 | 1, ((l + r) >> 1) + 1, r);
  pushup(pos);
}
int main() {
  n = rd(), q = rd();
  euler(300);
  for (int i = int(1); i <= (int)(n); i++) a[i] = rd();
  build(1, 1, n);
  for (int i = int(1); i <= (int)(q); i++) {
    char ch = getchar();
    while (ch != 'M' && ch != 'T') ch = getchar();
    if (ch == 'M') {
      int l = rd(), r = rd(), x = rd();
      update(1, 1, n, l, r, x);
    } else {
      int l = rd(), r = rd();
      Sum = 1, Bt = 0;
      query(1, 1, n, l, r);
      wrt(1ll * Sum * calc(Bt) % 1000000007, '\n');
    }
  }
}
