#include <iostream>
using namespace std;
using ll = long long;
// 常量定义:N为数组最大长度,M为模数(1e9+7是质数,满足费马小定理条件)
const ll N = 1e5 + 5, M = 1e9 + 7;
ll a[N];   // 存储原始数组
ll f[N];   // 存储前缀积数组,f[i] = a[1]*a[2]*...*a[i] mod M

/**
 * 快速幂算法(二分幂)
 * 算法思想:将幂运算拆解为二进制形式,通过二分思想降低时间复杂度(O(log power))
 * 功能:计算 (base^power) % M,用于求模运算下的乘法逆元
 * @param base 底数
 * @param power 指数
 * @return 计算结果 mod M
 */
ll qpow(ll base, ll power) {  // 传入base=3,power=5
    ll res = 1;  // 结果初始化为1(乘法的“单位元”,就像加法初始化为0一样)
    while (power) {  // 只要指数power>0,就继续循环(此时power=5→2→1→0)
        // 第一步:判断当前指数的二进制最后一位是不是1
        if (power &
                1) {  // power&1 是二进制运算,等价于“power%2==1”(判断奇偶)
            // 如果是1,就把当前的底数乘到结果里(并取模防止溢出)
            res = (res * base) % M;  // 我们例子里的变化:
            // 第一次循环(power=5):res=1*3=3
            // 第二次循环(power=2):power&1=0,跳过
            // 第三次循环(power=1):res=3*9=27(最终3^5=27)
        }
        // 第二步:底数平方(对应指数折半)
        base = (base * base) % M;  // 例子里的变化:
        // 第一次循环:base=3*3=9(对应3^2)
        // 第二次循环:base=9*9=81(对应3^4)
        // 第三次循环:base=81*81=6561(对应3^8)
        // 第三步:指数右移一位(等价于power=power/2,向下取整)
        power >>= 1;  // 例子里的变化:
        // 第一次循环:5>>1=2(二进制101→10)
        // 第二次循环:2>>1=1(二进制10→1)
        // 第三次循环:1>>1=0(二进制1→0,循环结束)
    }
    return res;  // 返回27,也就是3^5的结果
}

int main() {
    // 关闭同步流,加速cin/cout输入输出(算法优化步骤)
    ios::sync_with_stdio(0), cin.tie(0);
    ll n, q; // n为数组长度,q为查询次数
    cin >> n >> q;

    // 步骤1:初始化前缀积数组(空乘积为1,乘法单位元)
    f[0] = 1;
    // 步骤2:预处理前缀积数组
    // 算法思想:前缀积可以将区间[l,r]的乘积转化为 f[r]/f[l-1],降低查询时间复杂度
    for (ll i = 1; i <= n; i++) {
        cin >> a[i];
        // 前缀积递推公式:当前前缀积 = 前一个前缀积 * 当前元素 mod M(防止数值溢出)
        f[i] = (f[i - 1] * a[i]) % M;
    }

    // 步骤3:处理每次查询
    while (q--) {
        ll l, r; // 查询区间[l,r]
        cin >> l >> r;
        // 核心算法思想:模运算中除法不能直接计算,需用乘法逆元替代
        // 费马小定理:若M是质数,a的逆元为 a^(M-2) mod M
        // 区间[l,r]乘积 = (f[r] * 逆元(f[l-1])) mod M
        cout << (f[r] * qpow(f[l - 1], M - 2)) % M << " ";
    }
    return 0;
}