#include <bits/stdc++.h>
template <long long mod>
class Combination
{
    std::vector<long long> fact, finv, inv;
public:
    Combination() {}
    Combination(int sz)
    {
        fact.resize(sz);
        finv.resize(sz);
        inv.resize(sz);
        fact[0] = 1;
        for (int i = 1; i < sz; ++i)
        {
            fact[i] = fact[i - 1] * i % mod;
        }
        inv[0] = 0;
        inv[1] = 1;
        for (int i = 2; i < sz; ++i)
        {
            inv[i] = mod - inv[mod % i] * (mod / i) % mod;
        }
        finv[0] = 1;
        for (int i = 1; i < sz; ++i)
        {
            finv[i] = finv[i - 1] * inv[i] % mod;
        }
    }
    long long C(long long n, long long k)
    {
        if (n < k)
            return 0;
        if (n < 0 || k < 0)
            return 0;
        return (fact[n] * finv[k] % mod) * finv[n - k] % mod;
    }
    long long P(long long n, long long k)
    {
        if (n < k)
            return 0;
        if (n < 0 || k < 0)
            return 0;
        return fact[n] * finv[n - k] % mod;
    }
    long long H(long long n, long long k)
    {
        return this->C(n + k - 1, k);
    }
    long long getfact(int i)
    {
        return fact[i];
    }
    long long getinv(int i)
    {
        return inv[i];
    }
    long long getfinv(int i)
    {
        return finv[i];
    }
};
template< typename T >
T mod_pow(T x, T n, const T &p) {
  if(x < 0) return 0;
  T ret = 1;
  while(n > 0) {
    if(n & 1) (ret *= x) %= p;
    (x *= x) %= p;
    n >>= 1;
  }
  return ret;
}
using namespace std;
using ll = long long;
using vi = vector<ll>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using P = pair<ll, ll>;
const double eps = 1e-8;
const ll MOD = 1000000007;
const ll INF = INT_MAX / 2;
const ll LINF = LLONG_MAX / 2;
template<typename T1, typename T2>
bool chmax(T1 &a, const T2 &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template<typename T1, typename T2>
bool chmin(T1 &a, const T2 &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template<typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> p) {
  os << p.first << ":" << p.second;
  return os;
}
template<class T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  for(ll i=0;i<((ll)(v.size()));++i) {
    if (i) os << " ";
    os << v[i];
  }
  return os;
}
struct SegmentTree1 {
  ll n;
  vll node;
  SegmentTree1(ll sz) {
    n = 1;
    while(n < sz) n <<= 1;
    node.resize(2*n+1);
  }
  SegmentTree1(vll v) {
    ll sz = (ll)(v.size());
    n = 1;
    while(n < sz) n <<= 1;
    node.resize(2*n+1);
    for(ll i=0;i<((ll)(v.size()));++i) {
      node[i+n-1] = v[i];
    }
    for(ll i=(ll)(n-2);i>=0;--i) {
      node[i] = (node[2*i+1] + node[2*i+2]) % MOD;
    }
  }
  ll query(ll a, ll b, ll l, ll r, ll k) {
    if(a <= l && r <= b) return node[k];
    if(r <= a || b <= l) return 0;
    ll v1 = query(a, b, l, (l+r)/2, 2*k+1);
    ll v2 = query(a, b, (l+r)/2, r, 2*k+2);
    return (v1 + v2) % MOD;
  }
  ll query(ll a, ll b) {
    return query(a, b, 0, n, 0);
  }
};
struct SegmentTree2 {
  ll n;
  vvll node;
  SegmentTree2(vll v) {
    ll sz = (ll)(v.size());
    n = 1;
    while(n < sz) n <<= 1;
    node.resize(2*n+1, vll(40));
    for(ll i=0;i<(sz);++i) {
      ll now = v[i];
      for(ll j=2;j*j<=now;++j) {
        while(now % j == 0) {
          node[i+n-1][j]++;
          now /= j;
        }
      }
      if(now > 0) node[i+n-1][now]++;
    }
    for(ll i=(ll)(n-2);i>=0;--i) {
      for(ll j=0;j<(40);++j) {
        node[i][j] = max(node[2*i+1][j], node[2*i+2][j]);
      }
    }
  }
  vll query(ll a, ll b, ll l, ll r, ll k) {
    if(a <= l && r <= b) return node[k];
    if(r <= a || b <= l) return vll(40, 0);
    vll v1 = query(a, b, l, (l+r)/2, 2*k+1);
    vll v2 = query(a, b, (l+r)/2, r, 2*k+2);
    vll res(40);
    for(ll i=0;i<(40);++i) res[i] = max(v1[i], v2[i]);
    return res;
  }
  ll query(ll a, ll b) {
    vll v = query(a, b, 0, n, 0);
    ll res = 1;
    for(ll i=0;i<(40);++i) {
      if(v[i] != 0) res *= mod_pow<ll>(i, v[i], MOD);
      res %= MOD;
    }
    return res;
  }
};
signed main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(10);
  ll n, q;
  cin >> n >> q;
  vi p(n);
  for(ll i=0;i<(n);++i) cin >> p[i], p[i]--;
  vi comp(n, -1);
  vll len(n, -1);
  vll su(n, -1);
  for(ll i=0;i<(n);++i) {
    if (comp[i] == -1) {
      ll now = i;
      comp[i] = i;
      ll l = 1;
      ll s = now;
      now = p[now];
      while (now != i) {
        comp[now] = i;
        l++;
        s += now;
        now = p[now];
      }
      len[now] = l;
      su[now] = s + l;
      su[now] %= MOD;
      now = p[now];
      while (now != i) {
        len[now] = l;
        su[now] = s + l;
        su[now] %= MOD;
        now = p[now];
      }
    }
  }
  Combination<MOD> comb(1000000);
  vll init1(n);
  for(ll i=0;i<(n);++i) {
    init1[i] = su[i] * comb.getinv(len[i]) % MOD;
  }
  SegmentTree1 st1(init1);
  SegmentTree2 st2(len);
  for(ll _=0;_<(q);++_) {
    ll l, r;
    cin >> l >> r;
    l--;
    cout << st1.query(l, r) * st2.query(l, r) % MOD << endl;
  }
}



Measured memory_bytes: 125396