#include <bits/stdc++.h>
using namespace std;
template <class T>
bool cmin(T& a, const T& b) {
  return b < a ? a = b, 1 : 0;
}
template <class T>
bool cmax(T& a, const T& b) {
  return a < b ? a = b, 1 : 0;
}
const long long N = 4e5 + 5, mod = 1e9 + 7;
long long n, q, a[N], val_mask[301];
vector<long long> primes;
long long power(long long a, long long b, long long mod) {
  long long ret = 1;
  a %= mod;
  while (b > 0) {
    if (b % 2) ret = ret * a % mod;
    b /= 2;
    a = a * a % mod;
  }
  return ret;
}
class node {
 public:
  static const long long inf = 1e18;
  long long prod, primes_mask;
  node(long long prod_, long long primes_mask_) {
    prod = prod_;
    primes_mask = primes_mask_;
  }
  node() {
    prod = 1;
    primes_mask = 0;
  }
};
struct segtree {
  long long N;
  vector<node> st;
  vector<bool> cLazy;
  vector<node> lazy;
  void init(long long n) {
    N = n;
    st.resize((N << 2) + 2);
    cLazy.assign((N << 2) + 2, false);
    lazy.resize((N << 2) + 1);
    build(1, 1, N);
  }
  void merge(node& ret, node& left, node& right) {
    ret.prod = (left.prod * right.prod) % mod;
    ret.primes_mask = left.primes_mask | right.primes_mask;
  }
  void propagate(long long u, long long L, long long R) {
    if (L != R) {
      cLazy[u * 2] = 1;
      cLazy[u * 2 + 1] = 1;
      lazy[u * 2].prod = lazy[u * 2].prod * lazy[u].prod % mod;
      lazy[u * 2].primes_mask |= lazy[u].primes_mask;
      lazy[u * 2 + 1].prod = lazy[u * 2 + 1].prod * lazy[u].prod % mod;
      lazy[u * 2 + 1].primes_mask |= lazy[u].primes_mask;
    }
    {
      st[u].prod = (st[u].prod * power(lazy[u].prod, R - L + 1, mod)) % mod;
      st[u].primes_mask |= lazy[u].primes_mask;
    }
    cLazy[u] = 0;
    lazy[u] = node();
  }
  void build(long long u, long long L, long long R) {
    if (L == R) {
      st[u] = node(a[L], val_mask[a[L]]);
      return;
    }
    long long M = (L + R) / 2;
    build(u * 2, L, M);
    build(u * 2 + 1, M + 1, R);
    merge(st[u], st[u * 2], st[u * 2 + 1]);
  }
  node Query(long long u, long long L, long long R, long long i, long long j) {
    if (cLazy[u]) propagate(u, L, R);
    if (j < L || i > R) return node();
    if (i <= L && R <= j) return st[u];
    long long M = (L + R) / 2;
    node left = Query(u * 2, L, M, i, j);
    node right = Query(u * 2 + 1, M + 1, R, i, j);
    node ret;
    merge(ret, left, right);
    return ret;
  }
  node pQuery(long long u, long long L, long long R, long long pos) {
    if (cLazy[u]) propagate(u, L, R);
    if (L == R) return st[u];
    long long M = (L + R) / 2;
    if (pos <= M)
      return pQuery(u * 2, L, M, pos);
    else
      return pQuery(u * 2 + 1, M + 1, R, pos);
  }
  void Update(long long u, long long L, long long R, long long i, long long j,
              long long val) {
    if (cLazy[u]) propagate(u, L, R);
    if (j < L || i > R) return;
    if (i <= L && R <= j) {
      cLazy[u] = 1;
      lazy[u] = node(val, val_mask[val]);
      propagate(u, L, R);
      return;
    }
    long long M = (L + R) / 2;
    Update(u * 2, L, M, i, j, val);
    Update(u * 2 + 1, M + 1, R, i, j, val);
    merge(st[u], st[u * 2], st[u * 2 + 1]);
  }
  void pUpdate(long long u, long long L, long long R, long long pos,
               long long val) {
    if (cLazy[u]) propagate(u, L, R);
    if (L == R) {
      cLazy[u] = 1;
      lazy[u] = node(val, val_mask[val]);
      propagate(u, L, R);
      return;
    }
    long long M = (L + R) / 2;
    if (pos <= M)
      pUpdate(u * 2, L, M, pos, val);
    else
      pUpdate(u * 2 + 1, M + 1, R, pos, val);
    merge(st[u], st[u * 2], st[u * 2 + 1]);
  }
  node query(long long pos) { return pQuery(1, 1, N, pos); }
  node query(long long l, long long r) { return Query(1, 1, N, l, r); }
  void update(long long pos, long long val) { pUpdate(1, 1, N, pos, val); }
  void update(long long l, long long r, long long val) {
    Update(1, 1, N, l, r, val);
  }
} T;
bool checkPrime(long long n) {
  if (n < 2) return false;
  for (long long i = 2; i * i <= n; i++)
    if (n % i == 0) return false;
  return true;
}
int32_t main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cin >> n >> q;
  for (long long i = (1); i <= (n); i++) cin >> a[i];
  for (long long i = (1); i <= (300); i++)
    if (checkPrime(i)) primes.push_back(i);
  for (long long val = (1); val <= (300); val++) {
    for (long long i = 0; i < (long long)(primes.size()); i++) {
      if (val % primes[i] == 0) {
        val_mask[val] |= (1LL << i);
      }
    }
  }
  T.init(n);
  while (q--) {
    string type;
    cin >> type;
    if (type[0] == 'T') {
      long long L, R;
      cin >> L >> R;
      node get = T.query(L, R);
      long long ans = get.prod % mod;
      for (long long i = 0; i < (long long)(primes.size()); i++) {
        if (get.primes_mask >> i & 1LL) {
          ans *= (primes[i] - 1) * power(primes[i], mod - 2, mod) % mod;
          ans %= mod;
        }
      }
      cout << ans << '\n';
    } else {
      long long L, R, x;
      cin >> L >> R >> x;
      T.update(L, R, x);
    }
  }
}
