#include <bits/stdc++.h>
using namespace std;
const int Z = (int)5e3 + 1;
const int inf = (int)1e9 + 111;
const int64_t llinf = (int64_t)1e18 + 5;
const int MOD = (int)1e9 + 7;
template <class Head, class... Tail>
Head Min(const Head& head, const Tail&... tail) {
  if constexpr (sizeof...(tail) > 0) {
    int res = Min(tail...);
    if (res > head) {
      res = head;
    }
    return res;
  } else {
    return head;
  }
}
template <class Head, class... Tail>
Head Max(const Head& head, const Tail&... tail) {
  if constexpr (sizeof...(tail) > 0) {
    int res = Max(tail...);
    if (res < head) {
      res = head;
    }
    return res;
  } else {
    return head;
  }
}
template <class T1, class... Args>
bool UpdateMin(T1& a, Args&&... args) {
  auto value = Min(forward<Args>(args)...);
  if (a > value) {
    a = value;
    return true;
  }
  return false;
}
template <class T1, class... Args>
bool UpdateMax(T1& a, Args&&... args) {
  auto value = Max(forward<Args>(args)...);
  if (a < value) {
    a = value;
    return true;
  }
  return false;
}
template <class T>
ostream& operator<<(ostream& out, const vector<T>& a) {
  for (const auto& it : a) {
    out << it << " ";
  }
  out << "\n";
  return out;
}
template <class T>
istream& operator>>(istream& in, vector<T>& a) {
  for (auto& it : a) {
    in >> it;
  }
  return in;
}
template <class T1, class T2>
ostream& operator<<(ostream& out, const pair<T1, T2>& p) {
  out << '(' << p.first << ", " << p.second << ')';
  return out;
}
class Debug {
 public:
  template <class Container>
  static void Print(const Container& s, const string& message = {}) {
    Print(s, '{', '}', message);
  }
  template <class T>
  static void Print(const vector<T>& a, const string& message = {}) {
    Print(a, '[', ']', message);
  }

 private:
  template <class Container>
  static void Print(const Container& s, char begin_c, char end_c,
                    const string& message) {
    cerr << begin_c;
    bool first = true;
    for (const auto& it : s) {
      if (!first) {
        cerr << ", ";
      }
      first = false;
      cerr << it;
    }
    cerr << end_c;
    if (!message.empty()) {
      cerr << " <--- " << message;
    }
    cerr << "\n";
  }
};
int num[301];
int inv_num[63];
int BinPow_[63];
bool IsPrime(int x) {
  for (int i = 2; i * i <= x; ++i) {
    if (x % i == 0) {
      return false;
    }
  }
  return true;
}
struct Node {
  int64_t cnt = 0;
  int mul = 1;
  void Update(const Node& other) {
    cnt |= other.cnt;
    mul = (static_cast<int64_t>(mul) * other.mul) % MOD;
  }
};
bool operator==(const Node& lhs, const Node& rhs) {
  return lhs.cnt == rhs.cnt && lhs.mul == rhs.mul;
}
Node GetFact(int x) {
  Node res;
  res.mul = x;
  for (int i = 2; i * i <= x; ++i) {
    while (x % i == 0) {
      res.cnt |= 1LL << num[i];
      x /= i;
    }
  }
  if (x != 1) {
    res.cnt |= 1LL << num[x];
  }
  return res;
}
int BinPow(int a, int n) {
  if (n == 0) return 1;
  int res = BinPow(a, n / 2);
  res = (static_cast<int64_t>(res) * res) % MOD;
  if (n % 2 == 1) {
    res = (static_cast<int64_t>(res) * a) % MOD;
  }
  return res;
}
void Init() {
  int cur = 0;
  for (int i = 2; i <= 300; ++i) {
    if (IsPrime(i)) {
      num[i] = cur++;
      inv_num[cur - 1] = i;
    }
  }
  for (int i = 0; i < 62; ++i) {
    BinPow_[i] = BinPow(inv_num[i], MOD - 2);
  }
}
class SegmentTree {
 public:
  explicit SegmentTree(const vector<int>& a)
      : n(a.size()), default_node_{}, tree_(4 * n), mul_(4 * n) {
    for (int i = 1; i <= n; ++i) {
      Modify(i, i, a[i - 1]);
    }
  }
  void Modify(int l, int r, int x) {
    Modify(0, 0, n - 1, l - 1, r - 1, GetFact(x));
  }
  int Get(int l, int r) {
    auto q = Get(0, 0, n - 1, l - 1, r - 1);
    int res = q.mul;
    for (int i = 0; i < 62; ++i) {
      if ((q.cnt >> i & 1) == 0) continue;
      res = (static_cast<int64_t>(res) * (inv_num[i] - 1)) % MOD;
      res = (static_cast<int64_t>(res) * BinPow_[i]) % MOD;
    }
    return res;
  }

 private:
  int n;
  vector<Node> tree_;
  vector<Node> mul_;
  const Node default_node_;
  void Push(int v, int vl, int vr) {
    if (mul_[v] == default_node_) return;
    tree_[v].Update(mul_[v]);
    tree_[v].mul =
        (static_cast<int64_t>(tree_[v].mul) * BinPow(mul_[v].mul, vr - vl)) %
        MOD;
    if (vl != vr) {
      mul_[2 * v + 1].Update(mul_[v]);
      mul_[2 * v + 2].Update(mul_[v]);
    }
    mul_[v] = default_node_;
  }
  void Modify(int v, int vl, int vr, int l, int r, Node value) {
    Push(v, vl, vr);
    if (vl > r || vr < l) return;
    if (l <= vl && r >= vr) {
      mul_[v] = value;
      Push(v, vl, vr);
      return;
    }
    int vm = (vl + vr) / 2;
    Modify(2 * v + 1, vl, vm, l, r, value);
    Modify(2 * v + 2, vm + 1, vr, l, r, value);
    tree_[v] = default_node_;
    tree_[v].Update(tree_[2 * v + 1]);
    tree_[v].Update(tree_[2 * v + 2]);
  }
  Node Get(int v, int vl, int vr, int l, int r) {
    Push(v, vl, vr);
    if (vl > r || vr < l) return default_node_;
    if (l <= vl && r >= vr) return tree_[v];
    int vm = (vl + vr) / 2;
    auto ql = Get(2 * v + 1, vl, vm, l, r);
    auto qr = Get(2 * v + 2, vm + 1, vr, l, r);
    ql.Update(qr);
    return ql;
  }
};
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  mt19937_64 random_generator(228);
  Init();
  int n, q;
  cin >> n >> q;
  vector<int> a(n);
  cin >> a;
  SegmentTree tree(a);
  while (q--) {
    string type;
    int l, r;
    cin >> type >> l >> r;
    if (type == "MULTIPLY") {
      int x;
      cin >> x;
      tree.Modify(l, r, x);
    } else {
      cout << tree.Get(l, r) << "\n";
    }
  }
  return 0;
}
