You are given an array a_1, a_2, …, a_n.

You need to perform q queries of the following two types:

  1. "MULTIPLY l r x" — for every i (l ≤ i ≤ r) multiply a_i by x.
  2. "TOTIENT l r" — print \varphi(∏ _{i=l}^{r} a_i) taken modulo 10^9+7, where \varphi denotes Euler's totient function. 



The [Euler's totient function](http://gg.gg/euler_totient) of a positive integer n (denoted as \varphi(n)) is the number of integers x (1 ≤ x ≤ n) such that \gcd(n,x) = 1.

Input

The first line contains two integers n and q (1 ≤ n ≤ 4 ⋅ 10^5, 1 ≤ q ≤ 2 ⋅ 10^5) — the number of elements in array a and the number of queries.

The second line contains n integers a_1, a_2, …, a_n (1 ≤ a_i ≤ 300) — the elements of array a.

Then q lines follow, describing queries in the format given in the statement.

  1. "MULTIPLY l r x" (1 ≤ l ≤ r ≤ n, 1 ≤ x ≤ 300) — denotes a multiplication query.
  2. "TOTIENT l r" (1 ≤ l ≤ r ≤ n) — denotes a query on the value of Euler's totient function. 



It is guaranteed that there is at least one "TOTIENT" query.

Output

For each "TOTIENT" query, print the answer to it.

Example

Input

4 4
5 9 1 2
TOTIENT 3 3
TOTIENT 3 4
MULTIPLY 4 4 3
TOTIENT 4 4


Output

1
1
2

Note

In the first example, \varphi(1) = 1 for the first query, \varphi(2) = 1 for the second query and \varphi(6) = 2 for the third one.
#include <bits/stdc++.h>
using namespace std;
template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  os << '{';
  string sep;
  for (const auto &x : v) os << sep << x, sep = ", ";
  return os << '}';
}
template <typename T, size_t size>
ostream &operator<<(ostream &os, const array<T, size> &arr) {
  os << '{';
  string sep;
  for (const auto &x : arr) os << sep << x, sep = ", ";
  return os << '}';
}
template <typename A, typename B>
ostream &operator<<(ostream &os, const pair<A, B> &p) {
  return os << '(' << p.first << ", " << p.second << ')';
}
void dbg_out() { cerr << endl; }
template <typename Head, typename... Tail>
void dbg_out(Head H, Tail... T) {
  cerr << ' ' << H;
  dbg_out(T...);
}
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) {
          ;
          long long mul =
              (primes[i] - 1) * power(primes[i], mod - 2, mod) % mod;
          ans = (ans * mul) % mod;
        }
      }
      cout << ans << '\n';
    } else {
      long long L, R, x;
      cin >> L >> R >> x;
      T.update(L, R, x);
    }
  }
}
