← Home
```go
package main

import (
	"io"
	"os"
)

const M = 1000000007

type Node struct {
	ls, rs int32
	val    int32
}

var tree []Node

func update(old int32, l, r int32, idx int32, v int32) int32 {
	curr := int32(len(tree))
	tree = append(tree, tree[old])
	tree[curr].val = int32((int64(tree[curr].val) * int64(v)) % M)
	if l == r {
		return curr
	}
	mid := (l + r) / 2
	if idx <= mid {
		tree[curr].ls = update(tree[old].ls, l, mid, idx, v)
	} else {
		tree[curr].rs = update(tree[old].rs, mid+1, r, idx, v)
	}
	return curr
}

func query(node int32, l, r int32, ql, qr int32) int32 {
	if node == 0 {
		return 1
	}
	if ql <= l && r <= qr {
		return tree[node].val
	}
	mid := (l + r) / 2
	ans := int32(1)
	if ql <= mid {
		ans = int32((int64(ans) * int64(query(tree[node].ls, l, mid, ql, qr))) % M)
	}
	if qr > mid {
		ans = int32((int64(ans) * int64(query(tree[node].rs, mid+1, r, ql, qr))) % M)
	}
	return ans
}

type PrimePower struct {
	p, val int32
}

func main() {
	input, _ := io.ReadAll(os.Stdin)
	offset := 0

	nextInt := func() int {
		for offset < len(input) && input[offset] <= ' ' {
			offset++
		}
		if offset >= len(input) {
			return 0
		}
		res := 0
		for offset < len(input) && input[offset] > ' ' {
			res = res*10 + int(input[offset]-'0')
			offset++
		}
		return res
	}

	n := nextInt()
	if n == 0 {
		return
	}
	a := make([]int32, n+1)
	for i := 1; i <= n; i++ {
		a[i] = int32(nextInt())
	}
	q := nextInt()

	max_prime := make([]int32, 200005)
	for i := int32(2); i <= 200000; i++ {
		if max_prime[i] == 0 {
			for j := i; j <= 200000; j += i {
				max_prime[j] = i
			}
		}
	}

	var pps []PrimePower
	for p := int32(2); p <= 447; p++ {
		if max_prime[p] == p {
			val := p
			for val <= 200000 {
				pps = append(pps, PrimePower{p, val})
				val *= p
			}
		}
	}

	pref := make([]int32, len(pps)*(n+1))
	for j, pp := range pps {
		rowOffset := j * (n + 1)
		for i := 1; i <= n; i++ {
			pref[rowOffset+i] = pref[rowOffset+i-1]
			if a[i]%pp.val == 0 {
				pref[rowOffset+i]++
			}
		}
	}

	inv := make([]int32, 200005)
	inv[1] = 1
	for i := int32(2); i <= 200000; i++ {
		inv[i] = int32((int64(M) - int64(M/i)) * int64(inv[M%i]) % M)
	}

	tree = make([]Node, 0, 4000000)
	tree = append(tree, Node{0, 0, 1})

	root := make([]int32, n+1)
	last_pos := make([]int32, 200005)

	for i := 1; i <= n; i++ {
		root[i] = root[i-1]
		lp := max_prime[a[i]]
		if lp > 447 {
			if last_pos[lp] != 0 {
				root[i] = update(root[i], 1, int32(n), last_pos[lp], inv[lp])
			}
			root[i] = update(root[i], 1, int32(n), int32(i), lp)
			last_pos[lp] = int32(i)
		}
	}

	out := make([]byte, 0, 1024*1024)
	formatInt := func(val int) {
		if val == 0 {
			out = append(out, '0')
			return
		}
		var buf [20]byte
		pos := 20
		for val > 0 {
			pos--
			buf[pos] = byte('0' + val%10)
			val /= 10
		}
		out = append(out, buf[pos:]...)
	}

	last := 0
	for i := 0; i < q; i++ {
		x := nextInt()
		y := nextInt()
		l := (last+x)%n + 1
		r := (last+y)%n + 1
		if l > r {
			l, r = r, l
		}

		ans := 1
		for j := 0; j < len(pps); j++ {
			rowOffset := j * (n + 1)
			if pref[rowOffset+r]-pref[rowOffset+l-1] > 0 {
				ans = int((int64(ans) * int64(pps[j].p)) % M)
			}
		}

		ansLarge := query(root[r], 1, int32(n), int32(l), int32(r))
		ans = int((int64(ans) * int64(ansLarge)) % M)

		formatInt(ans)
		out = append(out, '\n')

		last = ans
	}

	os.Stdout.Write(out)
}
```