#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <cassert>
#include <cstdio>
#include <iostream>
#include <unordered_map>

using namespace std;
typedef long long ll;

/// a??¨b???gcd
ll gcd(ll a, ll b) {
    if (b==0) return a;
    return gcd(b, a%b);
}

ll lcm(ll a, ll b) {
    return a/gcd(a, b)*b;
}

// x^n % md
ll pow_mod(ll x, ll n, ll md) {
    ll r = 1;
    while (n) {
        if (n & 1) r = (r * x) % md;
        x = (x * x) % md;
        n >>= 1;
    }
    return r;
}

/// x?????????, ??????, md????´???°??????x???md????????°??§????????????????????????
ll invp(ll x, ll md) {
    return pow_mod(x, md-2, md);
}

template <int N>
struct FenwickTree {
//    using D = ll; ///????´???????
    typedef ll D;
    D seg[N+1];
    
    /// ????´???????????????????
    void init() {
        for (int i = 0; i <= N; i++) {
            seg[i] = 0;
        }
    }

    /// i?????????????´????x???????????????
    void add(int i, D x) {
        i++;
        while (i <= N) {
            seg[i] += x;
            i += i & -i;
        }
    }

    /// [0, i)???sum????±???????
    D sum(int i) {
        D s = 0;
        while (i > 0) {
            s += seg[i];
            i -= i & -i;
        }
        return s;
    }

    /// [a, b)???sum????±???????
    D sum(int a, int b) {
        return sum(b) - sum(a);
    }
};



template <int S>
struct LCMTree {
    typedef ll D;
    static const int N = 1<<S;

    D seg[2*N];
    int sz[2*N];
    LCMTree() {
        for (int i = 2*N-1; i >= N; i--) {
            sz[i] = 1;
        }
        for (int i = N-1; i >= 1; i--) {
            sz[i] = sz[i*2]+sz[i*2+1];
        }
    }
    void init() {
        for (int i = 1; i < 2*N; i++) {
            seg[i] = 1;
        }
    }

    void push(int k) {
        assert(1 <= k && k < N);
    }
    void update(int k) {
        assert(1 <= k && k < N);
        seg[k] = lcm(seg[k*2], seg[k*2+1]);
    }

    /// k?????????????´????x????¶????
    void set(int k, D x) {
        k += N;
        seg[k] = x;
        for (int i = 1; i <= S; i++) {
            update(k>>i);
        }
    }


    /// [a, b)????????§????±???????
    D get(int a, int b, int k = 1) {
        if (sz[k] <= a || b <= 0) return 1;
        if (a <= 0 && sz[k] <= b) return seg[k];
        push(k);
        D dl = get(a, b, k*2);
        D dr = get(a-sz[k]/2, b-sz[k]/2, k*2+1);
        return lcm(dl, dr);
    }
};

FenwickTree<100100> fw;
LCMTree<17> lt;

const ll MD = 1e9+7;

int p[100100];
int used[100100];
int c[100100];
ll sm[100100];
int main() {
    int n, q;
    cin >> n >> q;
    for (int i = 0; i < n; i++) {
        cin >> p[i]; p[i]--;
    }
    memset(used, -1, sizeof(used));
    for (int i = 0; i < n; i++) {
        if (used[i] != -1) continue;
        used[i] = i;
        int j = p[i];
        c[i] = 1;
        sm[i] = i+1;
        while (j != i) {
            c[i]++;
            used[j] = i;
            sm[i] += (j+1);
            j = p[j];
        }
        sm[i] %= MD;
    }
    for (int i = 0; i < n; i++) {
//        printf("%d %d %d\n", i, used[i], c[i]);
    }
    lt.init();
    fw.init();
    for (int i = 0; i < n; i++) {
        lt.set(i, c[used[i]]);
        fw.add(i, sm[used[i]]*invp(c[used[i]], MD) % MD);
    }
    for (int i = 0; i < q; i++) {
        int l, r;
        cin >> l >> r; l--;
        ll lc = lt.get(l, r) % MD;
        cout << lc * (fw.sum(l, r) % MD) % MD << endl;
    }
    return 0;
}

Measured memory_bytes: 6852