#include <bits/stdc++.h>
using namespace std;
const int N = 4e5 + 5;
const int MOD = 1e9 + 7;
int n, q, sz;
long long tree[N * 4], lazy[N * 4];
long long btree[N * 4], blazy[N * 4];
vector<long long> primes, invp;
long long mult(long long aa, long long bb) {
  aa *= bb;
  aa %= MOD;
  return aa;
}
long long modpow(long long aa, long long bb) {
  long long res = 1;
  while (bb) {
    if (bb & 1) res = mult(res, aa);
    aa = mult(aa, aa);
    bb >>= 1;
  }
  return res;
}
bool isprime(int u) {
  for (int i = 2; i * i <= u; i++)
    if (u % i == 0) return false;
  return true;
}
void pre() {
  for (int i = 2; i < 301; i++)
    if (isprime(i)) primes.emplace_back(i);
  for (int i : primes) invp.emplace_back(modpow(i, MOD - 2));
  sz = primes.size();
}
void updateLazy(int node, int st, int ed) {
  int lc = 2 * node, rc = 2 * node + 1;
  if (lazy[node] == 1) return;
  tree[node] = mult(tree[node], modpow(lazy[node], ed - st + 1));
  btree[node] |= blazy[node];
  if (st != ed) {
    lazy[lc] = mult(lazy[lc], lazy[node]);
    lazy[rc] = mult(lazy[rc], lazy[node]);
    blazy[lc] |= blazy[node];
    blazy[rc] |= blazy[node];
  }
  lazy[node] = 1;
  blazy[node] = 0;
}
void update(int node, int st, int ed, int l, int r, long long val) {
  int lc = 2 * node, rc = 2 * node + 1;
  updateLazy(node, st, ed);
  if (r < st || ed < l) return;
  if (l <= st && ed <= r) {
    long long msk = 0;
    long long vl = modpow(val, ed - st + 1);
    tree[node] = mult(tree[node], vl);
    for (int i = 0; i < sz; i++)
      if (val % primes[i] == 0) msk |= (1LL << i);
    btree[node] |= msk;
    if (st != ed) {
      lazy[lc] = mult(lazy[lc], val);
      lazy[rc] = mult(lazy[rc], val);
      blazy[lc] |= msk;
      blazy[rc] |= msk;
    }
    return;
  }
  int mid = (st + ed) >> 1;
  update(lc, st, mid, l, r, val);
  update(rc, mid + 1, ed, l, r, val);
  tree[node] = mult(tree[lc], tree[rc]);
  btree[node] = btree[lc] | btree[rc];
}
pair<long long, long long> query(int node, int st, int ed, int l, int r) {
  int lc = 2 * node, rc = 2 * node + 1;
  updateLazy(node, st, ed);
  if (r < st || ed < l) return {1, 0};
  if (l <= st && ed <= r) return {tree[node], btree[node]};
  int mid = (st + ed) >> 1;
  pair<long long, long long> q1 = query(lc, st, mid, l, r);
  pair<long long, long long> q2 = query(rc, mid + 1, ed, l, r);
  long long p1 = mult(q1.first, q2.first);
  long long p2 = q1.second | q2.second;
  return {p1, p2};
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  pre();
  for (int i = 0; i < N * 4; i++) tree[i] = 1, lazy[i] = 1;
  int n, q;
  cin >> n >> q;
  int x;
  for (int i = 1; i <= n; i++) {
    cin >> x;
    update(1, 1, n, i, i, x);
  }
  string str;
  int y, z;
  for (int i = 1; i <= q; i++) {
    cin >> str >> x >> y;
    if (str[0] == 'M') {
      cin >> z;
      update(1, 1, n, x, y, 1LL * z);
      continue;
    }
    pair<long long, long long> qry = query(1, 1, n, x, y);
    long long ans = qry.first;
    for (int i = 0; i < sz; i++) {
      if (qry.second & (1LL << i)) {
        ans = mult(ans, primes[i] - 1);
        ans = mult(ans, invp[i]);
      }
    }
    cout << ans << "\n";
  }
}
