#include <bits/stdc++.h>
using namespace std;

long long gcd(long long a,long long b){
	return b ? gcd(b,a%b) : a;
}
long long lcm(long long a,long long b){
	return a / gcd(a,b) * b;
}

long long mul(long long a,long long b,const long long mod){
	return b?(mul(a*2,b/2,mod)+(b&1?a:0))%mod:0;
}

long long bpow(long long a,long long b,const long long mod){
	return (b?bpow(a*a%mod,b/2,mod)*(b&1?a:1):1)%mod;
}

long long inv(long long a,const long long mod){
	return bpow(a,mod-2,mod);
}

// to overflow
/*long long bpow(long long a,long long b,const long long mod){
	return (b?mul(bpow(mul(a,a,mod),b/2,mod),(b&1?a:1),mod):1)%mod;
}*/
class mInt{
public:
	static const long long mod = 1000000007;
	long long v;
	mInt():v(0){}
	mInt(long long v):v((v%mod+mod)%mod){}
};
mInt& operator += (mInt &a,mInt b){ return a = a.v + b.v; }
mInt& operator -= (mInt &a,mInt b){ return a = a.v - b.v; }
mInt& operator *= (mInt &a,mInt b){ return a = a.v * b.v; }
mInt& operator /= (mInt &a,mInt b){ return a = a.v * inv(b.v,mInt::mod); }
mInt operator + (mInt a,mInt b){ return a += b; }
mInt operator - (mInt a,mInt b){ return a -= b; }
mInt operator * (mInt a,mInt b){ return a *= b; }
mInt operator / (mInt a,mInt b){ return a /= b; }
ostream& operator<<(ostream& os, const mInt& x){ return os << x.v; }

int p[100010];
int done[100010];
vector<int> v;
int len = 0;
int dfs(int x){
	if( done[x]++ ) return 0;
	v.push_back(x);
	len++;
	dfs(p[x]);
}


template<class T>
struct SegmentTree{
	int n_;
	vector<T> seg;
	// [1,N]
	SegmentTree(int N){
		n_ = 1;
		while(n_ < N ) n_ *= 2;
		seg.resize(2*n_,1); //????¨????
	}
	void add(int i,int v){
		i += n_-1;
		seg[i] = v;
		i /= 2;
		while(i){
			seg[i] = lcm(seg[i*2],seg[i*2+1]); //????¨????
			i /= 2;
		}
	}
	T get(int l,int r,int k,int a,int b){
		if( b < l || r < a ) return 1; //????¨????
		if( l <= a && b <= r ){
			return seg[k];
		}
		int m = (a+b)/2;
		return lcm(get(l,r,k*2,a,m),get(l,r,k*2+1,m+1,b)); //????¨????
	}
	inline T get(int l,int r){
		return get(l,r,1,1,n_);
	}
};
template<class T>
struct SegmentTree2{
	int n_;
	vector<T> seg;
	// [1,N]
	SegmentTree2(int N){
		n_ = 1;
		while(n_ < N ) n_ *= 2;
		seg.resize(2*n_,1); //????¨????
	}
	void add(int i,int v){
		i += n_-1;
		seg[i] = v;
		i /= 2;
		while(i){
			seg[i] = max(seg[i*2],seg[i*2+1]); //????¨????
			i /= 2;
		}
	}
	T get(int l,int r,int k,int a,int b){
		if( b < l || r < a ) return 1; //????¨????
		if( l <= a && b <= r ){
			return seg[k];
		}
		int m = (a+b)/2;
		return max(get(l,r,k*2,a,m),get(l,r,k*2+1,m+1,b)); //????¨????
	}
	inline T get(int l,int r){
		return get(l,r,1,1,n_);
	}
};

struct BIT{
	vector<mInt> seg;
	// [1,n]
	BIT(int N){
		seg.resize(N+1,mInt(0));
	};
	void add(int i,mInt x){
		seg[i] = seg[i]+x;
	}
	void init(){
		for(int i = 1 ; i < seg.size() ; i++){
			seg[i] += seg[i-1];
		}
	}
	inline mInt get(int l,int r){
		return (seg[r] - seg[l-1]);
	}
};



int main(){
	int N,Q;
	cin >> N >> Q;
	for(int i = 1 ; i <= N ; i++){
		scanf("%d",&p[i]);
	}
	
	SegmentTree<long long> LCM(N);
	BIT bit1(N);

	for(int i = 1; i <= N ; i++){
		if( done[i] ) continue;
		len = 0;
		v.clear();
		dfs(i);
		mInt sum = 0;
		for(int j = 0 ; j < v.size() ; j++){
			sum += v[j];
			LCM.add(v[j],len);
		}
		for(int j = 0 ; j < v.size() ; j++){
			bit1.add(v[j],sum/len);
		}
	}
	bit1.init();
	for(int i = 0 ; i < Q ; i++){
		mInt ans = 0;
		long long l,r;
		cin >> l >> r;
		mInt len = LCM.get(l,r);
		ans += len * bit1.get(l,r);
		
		printf("%d\n",(int)ans.v);
	}
	
}

Measured memory_bytes: 4836