#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 100;
const int MAXNODE = maxn;
const int M = 1e9 + 7.1;
const int MAXVAL = 1e6 + 0.5;
struct node {
  int l, r, id;
  node(int _l = 0, int _r = 0, int _id = 0) {
    l = _l;
    r = _r;
    id = _id;
  }
};
int n, a[maxn], mul[maxn], tree[maxn], cur[maxn], p[maxn], pn, vis[maxn], qn,
    rev[maxn], ans[maxn];
node q[maxn];
vector<int> vec[maxn];
vector<int> num[maxn];
int mult(int a, int b) {
  int c = (long long)a * (long long)b % M;
  return c;
}
int pow_mod(int x, int n) {
  int res = 1;
  int tmp = x % M;
  while (n) {
    if (n & 1) res = mult(res, tmp);
    tmp = mult(tmp, tmp);
    n >>= 1;
  }
  return res;
}
int getRev(int x) { return pow_mod(x, M - 2); }
void prime() {
  memset(vis, 0, sizeof(vis));
  pn = 0;
  for (int i = 2; i <= MAXVAL; i++) {
    if (vis[i] == 0) {
      p[pn] = i;
      pn++;
    }
    for (int j = 0; j < pn && i * p[j] <= MAXVAL; j++) {
      vis[i * p[j]] = 1;
      if (i % p[j] == 0) break;
    }
  }
}
void pushDown(int rt) {
  if (tree[rt] == 1) return;
  tree[(rt << 1)] = mult(tree[(rt << 1)], tree[rt]);
  tree[((rt << 1) | 1)] = mult(tree[((rt << 1) | 1)], tree[rt]);
  tree[rt] = 1;
}
void change(int L, int R, int key, int rt, int l, int r) {
  if (L <= l && R >= r) {
    tree[rt] = mult(tree[rt], key);
    return;
  }
  pushDown(rt);
  if (L <= ((l + r) / 2)) change(L, R, key, (rt << 1), l, ((l + r) / 2));
  if (R >= ((l + r) / 2) + 1)
    change(L, R, key, ((rt << 1) | 1), ((l + r) / 2) + 1, r);
}
int query(int pos, int rt, int l, int r) {
  if (r == l && r == pos) {
    return tree[rt];
  }
  pushDown(rt);
  if (pos <= ((l + r) / 2))
    return query(pos, (rt << 1), l, ((l + r) / 2));
  else
    return query(pos, ((rt << 1) | 1), ((l + r) / 2) + 1, r);
}
void dfs_init(int rt, int l, int r) {
  if (l == r) {
    tree[rt] = 1;
    return;
  }
  tree[rt] = 1;
  dfs_init((rt << 1), l, ((l + r) / 2));
  dfs_init(((rt << 1) | 1), ((l + r) / 2) + 1, r);
}
void solve() {
  for (int i = 0; i <= MAXVAL; i++) vec[i].clear();
  mul[0] = 1;
  for (int i = 1; i <= n; i++) {
    mul[i] = mult(mul[i - 1], a[i]);
    num[i].clear();
    int x = a[i];
    for (int j = 0; j < pn; j++) {
      if (x == 1) break;
      if (p[j] * p[j] > x) break;
      if (x % p[j] == 0) {
        num[i].push_back(p[j]);
        vec[p[j]].push_back(i);
        while (x % p[j] == 0) x /= p[j];
      }
    }
    if (x != 1) {
      num[i].push_back(x);
      vec[x].push_back(i);
    }
  }
  dfs_init(1, 1, n);
  for (int i = 2; i <= MAXVAL; i++) {
    if (vec[i].size() >= 1)
      change(vec[i][0], n, (long long)(i - 1) * (long long)rev[i] % M, 1, 1, n);
    cur[i] = 0;
  }
  int tl = 1;
  for (int i = 0; i < qn; i++) {
    while (tl < q[i].l) {
      for (int j = 0; j < num[tl].size(); j++) {
        int x = num[tl][j], tr;
        if (cur[x] + 1 >= vec[x].size()) {
          cur[x]++;
          tr = n + 1;
        } else {
          tr = vec[x][cur[x] + 1];
          cur[x]++;
        }
        change(tl + 1, tr - 1, (long long)x * (long long)rev[x - 1] % M, 1, 1,
               n);
      }
      tl++;
    }
    int res = (long long)mul[q[i].r] * (long long)getRev(mul[q[i].l - 1]) % M *
              (long long)query(q[i].r, 1, 1, n) % M;
    ans[q[i].id] = res;
  }
  for (int i = 0; i < qn; i++) {
    printf("%d\n", ans[i]);
  }
}
bool cmp(node a, node b) { return a.l < b.l; }
int main() {
  prime();
  for (int i = 1; i <= MAXVAL; i++) rev[i] = getRev(i);
  while (scanf("%d", &n) != EOF) {
    for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
    scanf("%d", &qn);
    for (int i = 0; i < qn; i++) {
      scanf("%d%d", &q[i].l, &q[i].r);
      q[i].id = i;
    }
    sort(q, q + qn, cmp);
    solve();
  }
  return 0;
}
