#include<bits/stdc++.h>
using namespace std;
using ll=long long;
using ld=long double;
using P=pair<ll,ll>;
#define MOD 1000000007ll
#define INF 1000000000ll
#define EPS 1e-7
#define FOR(i,n,m) for(ll i=n;i<(ll)m;i++)
#define REP(i,n) FOR(i,0,n)
#define DUMP(a) REP(d,a.size()){cout<<a[d];if(d!=a.size()-1)cout<<" ";else cout<<endl;}
#define ALL(v) v.begin(),v.end()
#define UNIQUE(v) sort(v.begin(),v.end());v.erase(unique(v.begin(),v.end()),v.end());
#define pb push_back

ll _pow(ll a, ll n) {
	if(n==0) return 1;
	else {
		ll res = 1;
		ll buf = a;
		while(n>0) {
			if(n%2==1) {
				res *= buf;
				res %= MOD;
			}
			buf *= buf;
			buf %= MOD;
			n/=2;
		}
		return res;
	}
}

class segtree {
public:
	segtree(int n) {
		_n=1;
		while(_n<n) _n*=2;
		_dat.resize(2*_n-1);
		_dat2.resize(2*_n-1);
		for(int i=0;i<2*_n-1;++i) {
			_dat[i]=vector<char>(200);
			_dat2[i]=0;
		}
	}
	int size() {
		return _n;
	}
	void update(int k,long long a) {
		k+=_n-1;
		_dat[k][a]++;
		while(k>0) {
			k=(k-1)/2;
			REP(i,200) _dat[k][i]=max(_dat[k*2+1][i],_dat[k*2+2][i]);
		}
	}
	void update2(int k,long long a) {
		k+=_n-1;
		_dat2[k]=a;
		while(k>0) {
			k=(k-1)/2;
			_dat2[k]=(_dat2[k*2+1]+_dat2[k*2+2])%MOD;
		}
	}
	vector<char> query(int a,int b,int k=0,int l=0,int r=-1) {
		if(r==-1) r=_n;
		if(r<=a||b<=l) return vector<char>(200,0);
		if(a<=l&&r<=b) return _dat[k];
		else {
			vector<char> vl=query(a,b,k*2+1,l,(l+r)/2);
			vector<char> vr=query(a,b,k*2+2,(l+r)/2,r);
			vector<char> ret(200,0);
			REP(i,200) ret[i]=max(vl[i],vr[i]);
			return ret;
		}
	}
	ll query2(int a,int b,int k=0,int l=0,int r=-1) {
		if(r==-1) r=_n;
		if(r<=a||b<=l) return 0;
		if(a<=l&&r<=b) return _dat2[k]%MOD;
		else {
			ll vl=query2(a,b,k*2+1,l,(l+r)/2);
			ll vr=query2(a,b,k*2+2,(l+r)/2,r);
			return (vl+vr)%MOD;
		}
	}
private:
	int _n;
	vector<vector<char>> _dat;
	vector<ll> _dat2;
};

struct dat {
	ll sum;
	ll lgt;
};

vector<int> p;
vector<dat> info;
ll c=0;
map<int,int> prim_dict;
vector<int> prim;

dat dfs(ll pos,vector<bool>& used,ll sum,ll cnt) {
	sum+=pos+1;
	cnt++;
	used[pos]=true;
	if(used[p[pos]]) return info[pos]=dat{sum,cnt};
	else return info[pos]=dfs(p[pos],used,sum,cnt);
}

void prifact(ll num, vector<ll>& v) {
	while(num>1) {
		bool upd=false;
		for(ll i=2; i*i<=num; i++) {
			if(num%i==0) {
				upd=true;
				v.pb(i);
				if(prim_dict.count(i)==0) {
					prim_dict[i]=c; c++;
					prim.pb(i);
				}
				num/=i;
				break;
			}
		}
		if(!upd) break;
	}
	if(num!=1) {
		if(prim_dict.count(num)==0) {
			prim_dict[num]=c; c++;
			prim.pb(num);
		}
		v.pb(num);
	}
	return;
}

int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);
	ll n,q;
	cin>>n>>q;
	p.assign(n,0);
	info.assign(n,dat{0,0});
	REP(i,n) cin>>p[i];
	REP(i,n) p[i]--;
	segtree seg(n);
	vector<bool> used(n,false);
	REP(i,n) if(!used[i]) dfs(i,used,0,0);
	map<ll,vector<ll>> prifact_dict;
	REP(i,n) if(!prifact_dict.count(info[i].lgt)) {
		vector<ll> v;
		prifact(info[i].lgt,v);
		prifact_dict[info[i].lgt]=v;
	}
	REP(i,n) {
		vector<ll> v=prifact_dict[info[i].lgt];
		REP(j,(ll)v.size()) seg.update(i,prim_dict[v[j]]);
	}
	REP(i,n) seg.update2(i,((info[i].sum%MOD)*_pow(info[i].lgt,MOD-2))%MOD);
	REP(query,q) {
		ll l,r;
		cin>>l>>r;
		l--;
		r--;
		vector<char> v=seg.query(l,r+1);
		ll mult=1;
		REP(i,c) {
			mult*=_pow(prim[i],v[i]);
			mult%=MOD;
		}
		cout<<((seg.query2(l,r+1)*mult)%MOD+MOD)%MOD<<endl;
	}
}



Measured memory_bytes: 66208