#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


int N = 1;
bool check[100000];
ll pre[100000],current[100000],p[100000],cicle[100000],first_sum[100000];
ll *LCM_TREE,*SUM_TREE;

void init(int first_N){
	while(N < first_N)N *= 2;
}

ll calc(ll x,ll y){
	if(y == 0){
		return x;
	}else{
		return calc(y,x%y);
	}
}

void updateLCM(int loc,ll value){
	loc += N-1;

	LCM_TREE[loc] = value;

	if(N == 1)return;

	int parent = (loc-1)/2;

	ll common;

	while(true){

		if(LCM_TREE[2*parent+1] >= LCM_TREE[2*parent+2]){
			common = calc(LCM_TREE[2*parent+1],LCM_TREE[2*parent+2]);
		}else{
			common = calc(LCM_TREE[2*parent+2],LCM_TREE[2*parent+1]);
		}

		LCM_TREE[parent] = (LCM_TREE[2*parent+1]*(LCM_TREE[2*parent+2]/common));

		if(parent == 0)break;
		else{
			parent = (parent-1)/2;
		}
	}
}

ll queryLCM(int search_left,int search_right,int node_id,int node_left,int node_right){

	if(search_right < node_left || search_left > node_right)return 1;

	if(search_left <= node_left && search_right >= node_right){
		return LCM_TREE[node_id];
	}

	ll left_LCM = queryLCM(search_left,search_right,2*node_id+1,node_left,(node_left+node_right)/2);
	ll right_LCM = queryLCM(search_left,search_right,2*node_id+2,(node_left+node_right)/2+1,node_right);

	ll common;
	if(left_LCM < right_LCM)swap(left_LCM,right_LCM);
	common = calc(left_LCM,right_LCM);

	return (left_LCM*(right_LCM/common));

}

void updateSUM(int loc,ll value){

	loc += N-1;

	SUM_TREE[loc] = value;

	if(N == 1)return;

	int parent = (loc-1)/2;

	while(true){

		ll range_LCM = LCM_TREE[parent];

		SUM_TREE[parent] = ((range_LCM/LCM_TREE[2*parent+1])%MOD*SUM_TREE[2*parent+1]+
									(range_LCM/LCM_TREE[2*parent+2])%MOD*SUM_TREE[2*parent+2])%MOD;

		if(parent == 0)break;
		else{
			parent = (parent-1)/2;
		}
	}
}


ll querySUM(int search_left,int search_right,int node_id,int node_left,int node_right,ll range_LCM){

	if(search_right < node_left || search_left > node_right)return 0;

	if(search_left <= node_left && search_right >= node_right){
		return (SUM_TREE[node_id]*((range_LCM/queryLCM(node_left,node_right,0,0,N-1))%MOD))%MOD;
	}

	ll left_SUM = querySUM(search_left,search_right,2*node_id+1,node_left,(node_left+node_right)/2,range_LCM);
	ll right_SUM = querySUM(search_left,search_right,2*node_id+2,(node_left+node_right)/2+1,node_right,range_LCM);

	return (left_SUM+right_SUM)%MOD;
}



int main(){

	int first_N,Q;
	scanf("%d %d",&first_N,&Q);
	for(int i = 0; i < first_N; i++){
		pre[i] = i+1;
		check[i] = false;
		first_sum[i] = i+1;
	}

	for(int i = 0; i < first_N; i++){
		scanf("%lld",&p[i]);
	}

	for(int count = 1; count <= 40; count++){
		for(int i = 0; i < first_N; i++)current[i] = p[pre[i]-1];
		for(int i = 0; i < first_N; i++){
			if(check[i])continue;
			if(current[i] == i+1){
				cicle[i] = count;
				check[i] = true;
			}
		}
		for(int i = 0; i < first_N; i++){
			pre[i] = current[i];
			if(check[i])continue;
			first_sum[i] += current[i];
		}
	}

	init(first_N);
	LCM_TREE = new ll[2*N-1];
	SUM_TREE = new ll[2*N-1];

	for(int i = 0; i <= 2*N-2; i++){
		LCM_TREE[i] = 1;
		SUM_TREE[i] = 0;
	}

	for(int i = 0; i < first_N; i++)updateLCM(i,cicle[i]);

	for(int i = 0; i < first_N; i++)updateSUM(i,first_sum[i]);

	int left,right;
	for(int loop = 0; loop < Q; loop++){
		scanf("%d %d",&left,&right);
		left--;
		right--;
		printf("%lld\n",querySUM(left,right,0,0,N-1,queryLCM(left,right,0,0,N-1))%MOD);
	}

	return 0;
}

Measured memory_bytes: 11312