#include <bits/stdc++.h>
using namespace std;
mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count());
long long power(long long b, long long e, long long m) {
  if (e == 0) return 1;
  if (e & 1) return b * power(b * b % m, e / 2, m) % m;
  return power(b * b % m, e / 2, m);
}
long long power(long long b, long long e) {
  if (e == 0) return 1;
  if (e & 1) return b * power(b * b, e / 2);
  return power(b * b, e / 2);
}
template <typename T, typename U>
static inline void amin(T &x, U y) {
  if (y < x) x = y;
}
template <typename T, typename U>
static inline void amax(T &x, U y) {
  if (x < y) x = y;
}
bool notPrime[1000005];
long long divPrime[1000005];
int idx[305];
void sieve(int n = 301) {
  int k = sqrt(n);
  memset(notPrime, false, sizeof(notPrime));
  notPrime[1] = true;
  for (int i = 2; i <= k; ++i) {
    if (!notPrime[i]) {
      for (int k = i * i; k <= n; k += i) {
        notPrime[k] = true;
        divPrime[k] = i;
      }
    }
  }
}
vector<long long> pr, inv;
const int N = 400005;
long long a[N];
struct node {
  long long pro;
  bitset<62> bit;
} fake = {1};
node tree[4 * N];
node lazy[4 * N];
inline node combine(node a, node b) {
  node ret;
  ret.pro = a.pro * b.pro % 1000000007;
  ret.bit = a.bit | b.bit;
  return ret;
}
inline node make_node(long long val) {
  node ret;
  ret.pro = val;
  long long k = val;
  ret.bit.reset();
  while (k != 1 && notPrime[k]) {
    long long z = divPrime[k];
    ret.bit[idx[z]] = 1;
    while (k % z == 0) k /= z;
  }
  if (k > 1) ret.bit[idx[k]] = 1;
  return ret;
}
inline void pushdown(long long v, long long st, long long en) {
  if (lazy[v].pro == 1 && lazy[v].bit.count() == 0) return;
  tree[v].pro *= power(lazy[v].pro, en - st + 1, 1000000007) % 1000000007;
  tree[v].pro %= 1000000007;
  tree[v].bit |= lazy[v].bit;
  if (st != en) {
    lazy[v << 1].pro = lazy[v << 1].pro * lazy[v].pro % 1000000007;
    lazy[v << 1 | 1].pro = lazy[v << 1 | 1].pro * lazy[v].pro % 1000000007;
    lazy[v << 1].bit |= lazy[v].bit;
    lazy[v << 1 | 1].bit |= lazy[v].bit;
  }
  lazy[v].pro = 1;
  lazy[v].bit.reset();
  return;
}
void buildTree(long long v, long long st, long long en) {
  if (st == en) {
    tree[v] = make_node(a[st]);
    return;
  }
  long long mid = (st + en) >> 1;
  buildTree(v << 1, st, mid);
  buildTree(v << 1 | 1, mid + 1, en);
  tree[v] = combine(tree[v << 1], tree[v << 1 | 1]);
}
void update(long long v, long long st, long long en, long long in,
            long long val) {
  long long mid = (st + en) >> 1;
  if (st == en) {
    tree[v] = make_node(val);
    a[st] = val;
    return;
  }
  if (in <= mid)
    update(v << 1, st, mid, in, val);
  else
    update(v << 1 | 1, mid + 1, en, in, val);
  tree[v] = combine(tree[v << 1], tree[v << 1 | 1]);
}
void rupdate(long long v, long long st, long long en, long long l, long long r,
             long long val) {
  if (lazy[v].pro != 0) {
    pushdown(v, st, en);
  }
  if (en < l || st > r) return;
  if (st >= l && en <= r) {
    lazy[v].pro = val;
    lazy[v].bit.reset();
    long long k = val;
    while (k != 1 && notPrime[k]) {
      long long z = divPrime[k];
      lazy[v].bit[idx[z]] = 1;
      while (k % z == 0) k /= z;
    }
    if (k > 1) lazy[v].bit[idx[k]] = 1;
    pushdown(v, st, en);
    return;
  }
  long long mid = (st + en) >> 1;
  rupdate(v << 1, st, mid, l, r, val);
  rupdate(v << 1 | 1, mid + 1, en, l, r, val);
  tree[v] = combine(tree[v << 1], tree[v << 1 | 1]);
}
node query(long long v, long long st, long long en, long long l, long long r) {
  if (en < l || st > r) return fake;
  if (lazy[v].pro != 0) {
    pushdown(v, st, en);
  }
  if (st >= l && en <= r) return tree[v];
  long long mid = (st + en) >> 1;
  return combine(query(v << 1, st, mid, l, r),
                 query(v << 1 | 1, mid + 1, en, l, r));
}
long long getans(long long st, long long en, long long l, long long r) {
  node ans = query(1, st, en, l, r);
  long long ret = ans.pro;
  for (long long i = 0; i < 62; ++i) {
    if (ans.bit[i]) {
      ret *= (pr[i] - 1) * inv[i] % 1000000007;
      ret %= 1000000007;
    }
  }
  return ret;
}
int _runtimeTerror_() {
  long long n, i, q;
  cin >> n >> q;
  for (i = 0; i < n; ++i) cin >> a[i];
  buildTree(1, 0, n - 1);
  while (q--) {
    string s;
    long long l, r, val;
    cin >> s >> l >> r;
    if (s == "TOTIENT") {
      cout << getans(0, n - 1, l - 1, r - 1) << "\n";
    } else {
      cin >> val;
      rupdate(1, 0, n - 1, l - 1, r - 1, val);
    }
  }
  return 0;
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  sieve();
  for (long long i = 2; i <= 300; ++i)
    if (!notPrime[i])
      pr.push_back(i), inv.push_back(power(i, 1000000007 - 2, 1000000007));
  for (long long i = 0; i < (long long)pr.size(); ++i) idx[pr[i]] = i;
  for (long long i = 0; i < 4 * N; ++i) lazy[i].pro = 1, lazy[i].bit.reset();
  int TESTS = 1;
  while (TESTS--) _runtimeTerror_();
  cerr << "\n" << 1.0 * clock() / CLOCKS_PER_SEC;
  return 0;
}
