#include <bits/stdc++.h>
using namespace std;
struct qrs {
  int l, r, id;
};
long long tree1[524292];
long long tree2[524292];
long long tree3[524292];
int pre[524292 << 1];
int n, q;
set<long long> fac1[524292];
set<long long> fac2[524292];
vector<long long> primes;
bool visited[524292 << 1];
void build(long long tree[], int l, int r, int index) {
  if (l > r) return;
  if (l == r) {
    tree[index] = 1;
    return;
  }
  int mid = l + (r - l) / 2;
  build(tree, l, mid, index * 2);
  build(tree, mid + 1, r, index * 2 + 1);
  tree[index] = 1;
}
void preprocess() {
  int i, j;
  for (i = 2; i <= 1011; i++) {
    if (!visited[i]) {
      primes.push_back((long long)i);
      visited[i] = true;
      for (j = 1; j * i <= 1011; j++) {
        visited[i * j] = true;
      }
    }
  }
}
void fac(int index, long long num) {
  for (auto p : primes) {
    if (num <= 1) break;
    while (num % p == 0) {
      num = num / p;
      fac1[index].insert(p);
      fac2[index].insert(p - 1);
    }
  }
  if (num > 1) {
    fac1[index].insert(num);
    fac2[index].insert(num - 1);
  }
}
long long getfac1(int index) {
  if (fac1[index].empty()) {
    return 1;
  }
  long long ret = 1;
  for (auto num : fac1[index]) {
    ret = ret * num;
  }
  return ret;
}
long long getfac2(int index) {
  if (fac2[index].empty()) {
    return 1;
  }
  long long ret = 1;
  for (auto num : fac2[index]) {
    ret = ret * num;
  }
  return ret;
}
void update(long long tree[], int pt, int l, int r, int index, long long val) {
  if (l > r || l > pt || pt > r) return;
  if (l == r && pt == l) {
    tree[index] = val;
    return;
  }
  int mid = l + (r - l) / 2;
  if (pt <= mid) {
    update(tree, pt, l, mid, index * 2, val);
  } else {
    update(tree, pt, mid + 1, r, index * 2 + 1, val);
  }
  tree[index] = (tree[index * 2] * tree[index * 2 + 1]) % 1000000007;
}
long long query(long long tree[], int start, int end, int l, int r, int index) {
  if (start > end || l > r || start > r || l > end) return 1;
  if (start <= l && r <= end) return tree[index];
  int mid = l + (r - l) / 2;
  if (end <= mid) {
    return query(tree, start, end, l, mid, index * 2);
  }
  if (start >= mid + 1) {
    return query(tree, start, end, mid + 1, r, index * 2 + 1);
  }
  return (query(tree, start, end, l, mid, index * 2) *
          query(tree, start, end, mid + 1, r, index * 2 + 1)) %
         1000000007;
}
vector<qrs> qs;
long long ans[524292 >> 1];
static bool cmp(const qrs &a, const qrs &b) { return a.r < b.r; }
long long arr[524292 >> 1];
long long ivt(long long num) {
  long long ret = 1;
  long long base = num, ep = 1000000007 - 2;
  while (ep >= 1) {
    if (ep % 2 == 0) {
      base = (base * base) % 1000000007;
      ep /= 2;
    } else {
      ret = (ret * base) % 1000000007;
      ep--;
    }
  }
  return ret;
}
int main(int argc, char *argv[]) {
  scanf("%d", &n);
  preprocess();
  build(tree1, 1, n, 1);
  build(tree2, 1, n, 1);
  build(tree3, 1, n, 1);
  int i, j;
  for (i = 1; i <= n; i++) {
    scanf("%d", &arr[i]);
  }
  scanf("%d", &q);
  for (i = 1; i <= q; i++) {
    int v1, v2;
    scanf("%d%d", &v1, &v2);
    qs.push_back(qrs{v1, v2, i});
  }
  sort(qs.begin(), qs.end(), cmp);
  for (i = 0, j = 1; i < q; i++) {
    while (j <= n && qs[i].r >= j) {
      fac(j, arr[j]);
      update(tree1, j, 1, n, 1, arr[j]);
      for (auto fc : fac1[j]) {
        if (pre[fc] != 0) {
          fac1[pre[fc]].erase(fc);
          fac2[pre[fc]].erase(fc - 1);
          update(tree2, pre[fc], 1, n, 1, getfac1(pre[fc]));
          update(tree3, pre[fc], 1, n, 1, getfac2(pre[fc]));
        }
      }
      for (auto fc : fac1[j]) {
        pre[fc] = j;
      }
      update(tree2, j, 1, n, 1, getfac1(j));
      update(tree3, j, 1, n, 1, getfac2(j));
      j++;
    }
    long long nterm = query(tree1, qs[i].l, qs[i].r, 1, n, 1);
    long long numer = query(tree3, qs[i].l, qs[i].r, 1, n, 1);
    long long deno = query(tree2, qs[i].l, qs[i].r, 1, n, 1);
    ans[qs[i].id] = (((nterm * numer) % 1000000007) * ivt(deno)) % 1000000007;
  }
  for (i = 1; i <= q; i++) {
    printf("%lld\n", ans[i]);
  }
  return 0;
}
