typedeflonglong ll; constint N = 100005; constint P = 1e9+7;
int lim; structST_list { int f[N][20]; voidinsert(int pos, int val) { f[pos][0] = val; } voidprework() { for(int k = 1; k < 20; k++) for(int i = 1; i+(1<<k)-1 <= lim; i++) f[i][k] = max(f[i][k-1], f[i+(1<<(k-1))][k-1]); } intquery(int l, int r) { int k = log2(r-l+1); returnmax(f[l][k], f[r-(1<<k)+1][k]); } }; namespace Prime { constint SIZE = 450; bool vis[SIZE+1]; int prime[SIZE+1], pcnt; voidprework(); } namespace HJT_tree { int root[N], node_cnt; structnode {int ls, rs; ll val = 1; } t[N*30]; voidinsert(int &p, int s, int pos, ll val, int l = 0, int r = lim); ll query(int i, int ql, int qr, int l = 0, int r = lim); } usingnamespace Prime; usingnamespace HJT_tree;
int n, q; int a[N]; int last[N*2]; ST_list st[100];
ll qpow(ll a, ll b);
intmain() { // freopen("2.in", "r", stdin); // freopen("2.out", "w", stdout); cin >> n >> q; lim = n; Prime::prework(); for(int i = 1; i <= n; i++) { cin >> a[i]; for(int j = 1; j <= pcnt; j++) { int cnt = 0; while(a[i]%prime[j] == 0) cnt++, a[i] /= prime[j]; st[j].insert(i, cnt); } } for(int i = 1; i <= pcnt; i++) st[i].prework(); for(int i = 1; i <= n; i++) { HJT_tree::insert(root[i], root[i-1], last[a[i]], a[i]); last[a[i]] = i; } int l, r; ll lastans = 0; for(int i = 1; i <= q; i++) { cin >> l >> r; l = (l+lastans)%n+1; r = (r+lastans)%n+1; if(l > r) swap(l, r); ll ans = 1; for(int i = 1; i <= pcnt; i++) (ans *= qpow(prime[i], st[i].query(l, r))) %= P; (ans *= HJT_tree::query(root[r], 0, l-1)) %= P; (ans *= qpow(HJT_tree::query(root[l-1], 0, l-1), P-2)) %= P; cout << (lastans=ans) << "\n"; } }
namespace HJT_tree{ #define ls(i) (t[i].ls) #define rs(i) (t[i].rs) #define lmid ((l+r)>>1) #define rmid ((l+r+2)>>1) voidinsert(int &p, int s, int pos, ll val, int l, int r) { if(p == 0) p = ++node_cnt; t[p].val = t[s].val*val%P; if(l == r) returnvoid(); if(pos <= lmid) rs(p) = rs(s), insert(ls(p), ls(s), pos, val, l, lmid); if(pos >= rmid) ls(p) = ls(s), insert(rs(p), rs(s), pos, val, rmid, r); } ll query(int i, int ql, int qr, int l, int r) { if(ql <= l and r <= qr) return t[i].val; ll ans = 1; if(ql <= lmid) (ans *= query(ls(i), ql, qr, l, lmid)) %= P; if(qr >= rmid) (ans *= query(rs(i), ql, qr, rmid, r)) %= P; return ans; } } namespace Prime { voidprework() { for(int i = 2; i <= SIZE; i++) { if(!vis[i]) prime[++pcnt] = i; for(int j = 1; j <= pcnt and i*prime[j] <= SIZE; j++) { vis[i*prime[j]] = true; if(i%prime[j] == 0) break; } } } }
ll qpow(ll a, ll b) { ll ans = 1; for(; b; b >>= 1, a = a*a%P) if(b&1) ans = ans*a%P; return ans; }