#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <queue>
#include <set>
#include <map>
#include <string.h>
#include <cmath>

using namespace std;
typedef long long i64;
typedef long double ld;
#define rep(i,s,e) for(int (i) = (s);(i) <= (e);++(i))
typedef long long i64;

const i64 MOD = 1e9 + 7;

template <i64 MOD>
struct ModInt {
  i64 value;

  ModInt(i64 v = 0) { value = v % MOD; }

  operator i64() { return value; }
  ModInt<MOD> operator+(int v) { return (value + v) % MOD; }
  ModInt<MOD> operator+(i64 v) { return (value + v) % MOD; }

  ModInt<MOD> operator-(i64 v) {
    v %= MOD;
    return (MOD + value - v) % MOD;
  }

  ModInt<MOD> operator*(i64 v) { return (value * v) % MOD; }
};

/* include file*/
#include <functional>
#include <vector>
using namespace std;

template <class Monoid>
struct Segment {
  using Func = function<Monoid(Monoid, Monoid)>;

  vector<Monoid> node;
  Monoid ide;
  int n = 1;

  Func bin_f;
  Func update_f;

  Segment(const vector<Monoid>& init, Monoid ide_, Func f_, Func u_f)
      : bin_f(f_), ide(ide_), update_f(u_f) {
    int sz = init.size();
    while (n < sz)
      n *= 2;
    node.assign(n * 2 - 1, ide);
    for (int i = 0; i < sz; i++)
      node[i + n - 1] = init[i];
    for (int i = n - 2; i >= 0; i--)
      node[i] = bin_f(node[i * 2 + 1], node[i * 2 + 2]);
  }

  void update(int i, Monoid x) {
    i += n - 1;
    node[i] = update_f(node[i], x);
    while (i) {
      i = (i - 1) / 2;
      node[i] = bin_f(node[i * 2 + 1], node[i * 2 + 2]);
    }
  }

  Monoid get_inter(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r < 0)
      r = n;
    if (a <= l && r <= b)
      return node[k];
    if (r <= a || b <= l)
      return ide;

    Monoid lm = get_inter(a, b, k * 2 + 1, l, (l + r) / 2);
    Monoid rm = get_inter(a, b, k * 2 + 2, (l + r) / 2, r);
    return bin_f(lm, rm);
  }
};

// http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=2730414#1
// http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=2730425#1
int n;
int q;

using mint = ModInt<MOD>;
using P = pair<mint,i64>;
int p[101010];

i64 cou[101010];
mint sum[101010];

i64 gcd(i64 a,i64 b){
    if(b == 0) return a;
    return gcd(b , a % b);
}


int main(){
    cin >> n >> q;
    vector<int> now(n + 1);
    for(int i = 1;i <= n;i++){
        cin >> p[i];
        now[i] = i;
    }
    for(int k = 1;k <= 40;k++){
        vector<int> next(n + 1);
        for(int i = 1;i <= n;i++){
            next[i] = p[now[i]];
            if(cou[i] == 0){
                sum[i] = sum[i] + next[i];
                if(next[i] == i){
                    cou[i] = k;
                }
            }
        }
        now = next;
    }

    vector<P> vec;
    for(int i = 1;i <= n;i++){
        vec.push_back({sum[i],cou[i]});
    }

    Segment<P> seg(vec,{0,1},[](P a,P b){
        i64 g = gcd(a.second,b.second);
        return (P){(a.first * ((b.second / g ) % MOD) + b.first * ((a.second / g) % MOD)), a.second / g * b.second};
    } , [](P node,P x){
        return x;
    });

    for(int i = 0;i < q;i++){
        int l,r;
        cin >> l >> r;
        l--;
        r--;
        cout << seg.get_inter(l,r + 1).first << endl;
    }
}





Measured memory_bytes: 11424