#include <bits/stdc++.h>
using namespace std;
struct huh {
  bitset<62> mask;
  long long n;
};
huh tree[1600005], lazy[1600005];
int n, l, r, m, q, arr[400005];
string tipe;
bool vis[1600005];
long long inv[62];
int prime[62] = {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 bigmod(long long a, long long b, long long c) {
  long long ans = 1;
  while (b) {
    if (b & 1) ans = (ans * a) % c;
    a = (a * a) % c;
    b >>= 1;
  }
  return ans;
}
void bersih(huh& a) {
  a.mask.reset();
  a.n = 1;
}
huh doit(huh a, huh b) {
  huh c;
  c.mask = a.mask | b.mask;
  c.n = (a.n * b.n) % 1000000007;
  return c;
}
huh mulit(huh a, int mul) {
  huh c;
  c.mask = a.mask;
  c.n = bigmod(a.n, mul, 1000000007);
  return c;
}
huh masking(int x) {
  huh c;
  c.n = (long long)x;
  for (int i = 0; i < 62; i++) {
    if (x % prime[i] == 0)
      c.mask[i] = 1;
    else
      c.mask[i] = 0;
  }
  return c;
}
void prog(int& id, int& L, int& R) {
  tree[id] = doit(tree[id], mulit(lazy[id], R - L + 1));
  if (L != R) {
    lazy[id * 2] = doit(lazy[id * 2], lazy[id]);
    vis[id * 2] = 1;
    lazy[id * 2 + 1] = doit(lazy[id * 2 + 1], lazy[id]);
    vis[id * 2 + 1] = 1;
  }
  bersih(lazy[id]);
  vis[id] = 0;
}
void built(int id, int L, int R, huh* tree) {
  if (L == R) {
    tree[id] = masking(arr[L]);
    return;
  }
  int mid = (L + R) / 2;
  built(id * 2, L, mid, tree);
  built(id * 2 + 1, mid + 1, R, tree);
  tree[id] = doit(tree[id * 2], tree[id * 2 + 1]);
}
void update(int ul, int ur, huh mm, int id, int L, int R, huh* tree,
            huh* lazy) {
  if (vis[id]) prog(id, L, R);
  if (L > ur || R < ul) return;
  if (L >= ul && R <= ur) {
    lazy[id] = mm;
    prog(id, L, R);
    return;
  }
  int mid = (L + R) / 2;
  update(ul, ur, mm, id * 2, L, mid, tree, lazy);
  update(ul, ur, mm, id * 2 + 1, mid + 1, R, tree, lazy);
  tree[id] = doit(tree[id * 2], tree[id * 2 + 1]);
}
huh query(int ql, int qr, int id, int L, int R, huh* tree, huh* lazy) {
  if (vis[id]) prog(id, L, R);
  if (L > qr || R < ql) {
    huh c;
    bersih(c);
    return c;
  }
  if (L >= ql && R <= qr) return tree[id];
  int mid = (L + R) / 2;
  return doit(query(ql, qr, id * 2, L, mid, tree, lazy),
              query(ql, qr, id * 2 + 1, mid + 1, R, tree, lazy));
}
long long totient(huh c) {
  long long ans = 1, n = 1, bawah = 1;
  for (int i = 0; i < 62; i++) {
    if (c.mask[i] == 0) continue;
    bawah *= (prime[i] - 1);
    bawah %= 1000000007;
    bawah *= inv[i];
    bawah %= 1000000007;
  }
  ans = c.n * bawah;
  ans %= 1000000007;
  return ans;
}
void pre() {
  for (int i = 0; i < 62; i++) {
    inv[i] = bigmod(prime[i], 1000000007 - 2, 1000000007);
  }
}
int main() {
  pre();
  memset(vis, 0, sizeof vis);
  for (int i = 0; i < 1600005; i++) bersih(lazy[i]);
  scanf("%d%d", &n, &q);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &arr[i]);
  }
  built(1, 1, n, tree);
  while (q--) {
    cin >> tipe;
    if (tipe == "TOTIENT") {
      scanf("%d%d", &l, &r);
      huh que = query(l, r, 1, 1, n, tree, lazy);
      long long ans = totient(que);
      printf("%lld\n", ans);
    } else {
      scanf("%d%d%d", &l, &r, &m);
      update(l, r, masking(m), 1, 1, n, tree, lazy);
    }
  }
  return 0;
}
