#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
template <typename T, typename second>
ostream& operator<<(ostream& s, pair<T, second>& p) {
  s << '{' << p.first << ", " << p.second << '}';
  return s;
}
template <typename T>
ostream& operator<<(ostream& s, vector<T>& v) {
  if (v.empty()) {
    s << "[]";
    return s;
  }
  s << '[';
  for (int i = 0; i < v.size() - 1; i++) {
    s << v[i] << ", ";
  }
  s << v.back() << ']';
  return s;
}
int n, q;
int mpf[1000006];
int mopw[1000006];
int moarr[200005];
int pnum[1000];
int smpw[200005][169];
int pw[100002][169];
const int SQMO = 450;
const int md = 1e9 + 7;
vector<int> primes;
vector<int> smpr;
vector<int> psm[1000];
vector<array<int, 3>> sqs;
int64_t ans[200005];
int64_t inv[1000006];
int64_t tans = 1;
void linear_sieve() {
  for (int i = 2; i < 1000006; i++) {
    if (mpf[i] == 0) {
      mpf[i] = i;
      primes.push_back(i);
    }
    for (auto x : primes) {
      if (x > mpf[i] || i * x >= 1000006) break;
      mpf[i * x] = x;
    }
  }
}
inline void factor(int pos, int num) {
  unordered_map<int, int> facts;
  while (mpf[num]) {
    facts[mpf[num]]++;
    num /= mpf[num];
  }
  for (auto x : facts) {
    if (x.first < 1000) {
      smpw[pos + 1][pnum[x.first]] = x.second;
    } else
      moarr[pos] = x.first;
  }
}
inline void rem(int pos) {
  if (!moarr[pos]) return;
  tans *= (mopw[moarr[pos]] > 1) ? inv[moarr[pos]] : inv[moarr[pos] - 1];
  mopw[moarr[pos]]--;
  tans %= md;
}
inline void add(int pos) {
  if (!moarr[pos]) return;
  mopw[moarr[pos]]++;
  if (mopw[moarr[pos]] > 1) {
    tans *= moarr[pos];
  } else {
    tans *= moarr[pos] - 1;
  }
  tans %= md;
}
int64_t modpow(int64_t bs, int pw) {
  int64_t ans = 1;
  if (pw < 0) return 0;
  while (pw) {
    if (pw & 1) {
      ans *= bs;
      ans %= md;
    }
    bs *= bs;
    bs %= md;
    pw >>= 1;
  }
  return ans;
}
bool cmp(const array<int, 3>& a, const array<int, 3>& b) {
  if (a[0] / SQMO != b[0] / SQMO) return a[0] < b[0];
  return (a[0] / SQMO) & 1 ? a[1] < b[1] : a[1] > b[1];
}
int main() {
  primes.reserve(100000);
  linear_sieve();
  scanf("%d", &n);
  for (auto x : primes)
    inv[x] = modpow(x, md - 2), inv[x - 1] = modpow(x - 1, md - 2);
  smpr.reserve(169);
  for (auto x : primes) {
    if (__builtin_expect(x > 1000, 0)) break;
    pnum[x] = smpr.size();
    pw[0][pnum[x]] = 1;
    smpr.push_back(x);
  }
  for (int i = 1; i < 100002; i++) {
    for (int j = 0; j < 168; j++) {
      pw[i][j] = (pw[i - 1][j] * 1LL * smpr[j]) % md;
    }
  }
  int a;
  for (int i = 0; i < n; i++) {
    scanf("%d", &a);
    factor(i, a);
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 0; j < 169; j++) smpw[i][j] += smpw[i - 1][j];
  }
  scanf("%d", &q);
  sqs.reserve(q + 2);
  int l, r;
  for (int i = 0; i < q; i++) {
    ans[i] = 1;
    scanf("%d%d", &l, &r);
    l--;
    r--;
    for (int j = 0; j < 168; j++) {
      auto x = smpw[r + 1][j] - smpw[l][j];
      if (x <= 0) continue;
      if (x >= 100002) {
        if (x < 200005 - 2)
          ans[i] *= ((smpr[j] - 1) *
                     (pw[(x >> 1) - 1][j] * 1LL * pw[(x + 1) >> 1][j] % md)) %
                    md;
        else
          ans[i] *= ((smpr[j] - 1) * 1LL * modpow(smpr[j], x - 1)) % md;
      } else {
        ans[i] *= ((smpr[j] - 1) * 1LL * pw[x - 1][j]) % md;
      }
      ans[i] %= md;
    }
    sqs.push_back({l, r, i});
  }
  sort(sqs.begin(), sqs.end(), cmp);
  int mol = 0;
  int mor = -1;
  for (auto x : sqs) {
    int tl = x[0];
    int tr = x[1];
    while (mol < tl) {
      rem(mol);
      mol++;
    }
    while (mol > tl) {
      mol--;
      add(mol);
    }
    while (mor < tr) {
      mor++;
      add(mor);
    }
    while (mor > tr) {
      rem(mor);
      mor--;
    }
    ans[x[2]] *= tans;
    ans[x[2]] %= md;
  }
  for (int i = 0; i < q; i++) {
    printf("%d\n", ans[i]);
  }
  return 0;
}
