#include <bits/stdc++.h>
using namespace std;
const int64_t INF = 1e18;
const int MOD = 1e9 + 7;
const long double PI = acosl(-1.0);
const long double EPS = 1e-9;
int64_t powm(int64_t a, int64_t b, int64_t m = MOD) {
  int64_t ans = 1;
  while (b > 0) {
    if ((b & 1) == 1) ans = (ans * a) % m;
    b >>= 1;
    a = (a * a) % m;
  }
  return ans % m;
}
int64_t InverseMOD(int64_t a, int64_t m = MOD) { return powm(a, m - 2, m); }
class segTree {
 public:
  segTree *lchild, *rchild;
  int leftindex, rightindex;
  int64_t val = 0;
  int64_t combine() {
    if (leftindex == rightindex) return val;
    return (lchild->val * rchild->val) % MOD;
  }
  segTree() {}
  segTree(int leftindex, int rightindex, std::vector<int> &v) {
    this->leftindex = leftindex;
    this->rightindex = rightindex;
    if (leftindex == rightindex) {
      val = v[leftindex];
      return;
    }
    int mid = (leftindex + rightindex) >> 1;
    lchild = new segTree(leftindex, mid, v);
    rchild = new segTree(mid + 1, rightindex, v);
    this->val = combine();
  }
  void pUpdate(int pos, int v) {
    if (pos < leftindex or pos > rightindex) {
      return;
    }
    if (leftindex == rightindex) {
      val = ((val * v) % MOD);
      return;
    }
    if (pos <= lchild->rightindex)
      lchild->pUpdate(pos, v);
    else
      rchild->pUpdate(pos, v);
    this->val = combine();
  }
  int64_t rQuery(int l, int r) {
    if (r < leftindex || l > rightindex) {
      return 1;
    }
    if (l <= leftindex && r >= rightindex) {
      return val;
    }
    return lchild->rQuery(l, r) * rchild->rQuery(l, r) % MOD;
  }
};
void sieve(int n, std::vector<int> &is_prime) {
  is_prime[0] = is_prime[1] = 1;
  for (int i = 2; i * i <= n; i++) {
    if (!is_prime[i]) {
      for (int j = i * i; j <= n; j += i) is_prime[j] = i;
    }
  }
  for (int i = 2; i <= n; ++i) {
    if (!is_prime[i]) is_prime[i] = i;
  }
}
const int N = 1e6 + 2;
std::vector<int> idx[N];
set<int> f[N];
void solve() {
  std::vector<int> minP(N + 1);
  sieve(N, minP);
  int n;
  cin >> n;
  std::vector<int> a(n);
  for (int i = 0; i < n; ++i) cin >> a[i];
  for (int i = n - 1; i >= 0; --i) {
    int x = a[i];
    while (x > 1) {
      f[i].insert(minP[x]);
      x /= minP[x];
    }
    for (auto k : f[i]) {
      idx[k].push_back(i);
    }
  }
  segTree *t = new segTree(0, n - 1, a);
  for (int i = 2; i < N; ++i) {
    if (minP[i] == i && (int)idx[i].size()) {
      t->pUpdate(idx[i].back(), ((i - 1) * InverseMOD(i)) % MOD);
      idx[i].pop_back();
    }
  }
  int Q;
  cin >> Q;
  std::vector<pair<pair<int, int>, int> > q;
  for (int i = 0; i < Q; ++i) {
    int l, r;
    cin >> l >> r;
    q.push_back({{l - 1, r - 1}, i});
  }
  sort(q.begin(), q.end());
  std::vector<int> ans(Q);
  int p = 0;
  for (int i = 0; i < n; ++i) {
    while (p < (int)q.size() && q[p].first.first == i) {
      ans[q[p].second] = t->rQuery(q[p].first.first, q[p].first.second);
      ++p;
    }
    for (auto x : f[i]) {
      if ((int)idx[x].size()) {
        t->pUpdate(idx[x].back(), ((x - 1) * InverseMOD(x)) % MOD);
        idx[x].pop_back();
      }
    }
  }
  for (int i = 0; i < Q; ++i) {
    cout << ans[i] << endl;
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  ;
  int T = 1;
  while (T--) {
    solve();
  }
}
