#include "bits/stdc++.h"

using namespace std;

using ll = long long;
using ld = long double;
using P = pair<ll, ll>;
constexpr int INF = numeric_limits<int>::max() / 2;
constexpr ll MOD = 1e9 + 7;

template <typename T>
void printv(const vector<T> &v)
{
    int sz = v.size();
    for (int i = 0; i < sz; i++)
    {
        cout << v[i] << " \n"[i == sz - 1];
    }
}

template <typename T>
T mygcd(T a, T b)
{
    if (b == 0)
        return a;
    return mygcd(b, a % b);
}

template <typename T>
T mylcm(T a, T b)
{
    T g = mygcd(a, b);
    return (a / g) * b;
}

template <typename T>
T mypow(T a, T b)
{
    if (b == 0)
        return 1;
    T tmp = mypow(a, b / 2);
    if (b % 2)
        return (((tmp * tmp) % MOD) * a) % MOD;
    else
        return (tmp * tmp) % MOD;
}

struct PermQuery
{
    using type = P;
    static type id() { return P(1, 0); }
    static type op(const type &l, const type &r)
    {
        ll f = mylcm(l.first, r.first);
        ll a = ((l.second % MOD) * (f % MOD) % MOD) * mypow(l.first % MOD, MOD - 2) % MOD;
        ll b = ((r.second % MOD) * (f % MOD) % MOD) * mypow(r.first % MOD, MOD - 2) % MOD;
        ll s = (a + b) % MOD;
        return P(f, s);
    }
};

template <typename M>
class SegmentTree
{
    using T = typename M::type;
    int n;
    std::vector<T> node;

public:
    // v を基に初期化
    SegmentTree(const std::vector<T> &v)
    {
        // n は v.size() 以上の最小の2冪
        n = 1;
        while (n < int(v.size()))
            n *= 2;
        node.resize(2 * n, M::id());

        // i の子 -> 2*i+1, 2*i+2 , 親 -> (i-1)/2
        for (int i = 0; i < int(v.size()); i++)
            node[i + n] = v[i];
        for (int i = n - 1; i >= 0; i--)
            node[i] = M::op(node[2 * i], node[2 * i + 1]);
    }
    // Monoid::id 初期化
    SegmentTree(int _n)
    {
        // n は v.size() 以上の最小の2冪
        n = 1;
        while (n < _n)
            n *= 2;
        node.resize(2 * n, M::id());
    }
    // x 番目を val に更新
    void update(int x, T val)
    {
        x += n;
        node[x] = val;
        while (x >>= 1)
        {
            node[x] = M::op(node[2 * x], node[2 * x + 1]);
        }
    }
    // v[x] を M::op(v[x], val) に更新
    void operation(int x, T val)
    {
        x += n;
        node[x] = M::op(node[x], val);
        while (x >>= 1)
        {
            node[x] = M::op(node[2 * x], node[2 * x + 1]);
        }
    }
    // [a, b) の op
    T query(int l, int r)
    {
        l += n;
        r += n;
        T retl = M::id(), retr = M::id();
        while (l < r)
        {
            if (l & 1)
                retl = M::op(retl, node[l++]);
            if (r & 1)
                retr = M::op(node[--r], retr);
            l >>= 1;
            r >>= 1;
        }
        return M::op(retl, retr);
    }
};

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);

    int n, q;
    cin >> n >> q;
    vector<ll> p(n);
    for (int i = 0; i < n; i++)
    {
        cin >> p[i];
        p[i]--;
    }
    // per[i] := i の周期, sum[i] := 一周期での和
    vector<ll> per(n, 1), sum(n, 0);
    for (int i = 0; i < n; i++)
    {
        ll cur = p[i];
        while (cur != i)
        {
            sum[i] += (cur + 1);
            per[i]++;
            cur = p[cur];
        }
        sum[i] += (cur + 1);
        // cout << per[i] << " " << sum[i] << endl;
    }
    vector<P> v(n);
    for (int i = 0; i < n; i++)
        v[i] = P(per[i], sum[i]);
    SegmentTree<PermQuery> st(v);
    while (q--)
    {
        int l, r;
        cin >> l >> r;
        l--;
        cout << st.query(l, r).second << endl;
    }
}



Measured memory_bytes: 10764