#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
const int maxN = 1 << 20, maxTS = maxN * 2, mod = 1000000007;
template <class T1, class T2>
inline void addMod(T1& a, T2 b) {
  a = (a + b) % mod;
}
template <class T1, class T2>
inline void multMod(T1& a, T2 b) {
  a = a * b % mod;
}
long long qpow(long long a, long long b) {
  long long res0 = 1;
  for (; b != 0; b >>= 1) {
    if (b & 1) multMod(res0, a);
    multMod(a, a);
  }
  return res0;
}
template <class T1, class T2>
inline void divMod(T1& a, T2 b) {
  multMod(a, qpow(b, mod - 2));
}
struct Tree {
  int offset, qbegin, qend;
  long long T[maxTS], res;
  void qpriv(int v, int left, int right) {
    if (left >= qend or right <= qbegin) return;
    if (left >= qbegin and right <= qend) {
      multMod(res, T[v]);
      return;
    }
    qpriv(v * 2, left, (left + right) / 2);
    qpriv(v * 2 + 1, (left + right) / 2, right);
  }
  void init(long long* t, int n) {
    for (offset = 1; offset < n; offset *= 2)
      ;
    for (int i = (0); i < (int)(n); i++) T[offset + i] = t[i];
    for (int i = (n); i < (int)(offset); i++) T[offset + i] = 1ll;
    for (int i = offset - 1; i > (int)(0); i--)
      T[i] = T[i * 2] * T[i * 2 + 1] % mod;
  }
  void updt(int v, long long val) {
    for (v += offset; v != 0; v /= 2) multMod(T[v], val);
  }
  long long query(int a, int b) {
    qbegin = a + offset;
    qend = b + offset + 1;
    res = 1;
    qpriv(1, offset, offset * 2);
    return res;
  }
} tree;
long long apd[maxN], T[maxN], res[maxN];
vector<pair<int, int> > Qs[maxN];
vector<int> pos[maxN];
int it[maxN];
void sito() {
  for (int i = (1); i < (int)(maxN); i++) apd[i] = i;
  for (int i = 2; i * i < maxN; i++)
    if (apd[i] == i)
      for (int j = i * i; j < maxN; j += i) apd[j] = i;
}
long long f(int p) { return 1ll * (p - 1) * qpow(p, mod - 2) % mod; }
vector<int> primes(int n) {
  vector<int> ret(0);
  while (n != 1) {
    int p = apd[n];
    ret.push_back(p);
    while (n % p == 0) n /= p;
  }
  return ret;
}
void solve() {
  sito();
  int n;
  scanf("%d", &n);
  T[0] = T[n + 1] = 1ll;
  for (int i = (1); i < (int)(n + 1); i++) {
    scanf("%lld", T + i);
    for (int p : primes(T[i])) pos[p].push_back(i);
  }
  tree.init(T, n + 2);
  for (int i = (0); i < (int)(maxN); i++)
    if (!pos[i].empty()) {
      pos[i].push_back(n + 1);
      tree.updt(pos[i][0], f(i));
    }
  int q;
  scanf("%d", &q);
  for (int i = (0); i < (int)(q); i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    Qs[a].push_back({b, i});
  }
  for (int i = (0); i < (int)(n + 1); i++) {
    for (auto p : Qs[i]) res[p.second] = tree.query(i, p.first);
    for (int p : primes(T[i])) tree.updt(pos[p][++it[p]], f(p));
  }
  for (int i = (0); i < (int)(q); i++) printf("%lld\n", res[i]);
}
int main() {
  int t = 1;
  while (t--) solve();
  return 0;
}
