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

#define fs first
#define sc second

#define pb push_back
#define mp make_pair

const int MAX_SQRT = 450;
const int MAX_P = 20;

const int maxn = 100000 + 1;
const int mod = 1000000000 + 7;

vector<int> vals[MAX_SQRT];

int pows[MAX_SQRT][MAX_P];

int ln;

void _set(vector<int> &vc, int pos, int val) {
	if (vc.size() == 0) vc.assign(2 * ln + 1, 0);
	vc[ln + pos - 1] = val;
}

int _get(const vector<int> &arr, int v, int vl, int vr, int L, int R) {
	vl = L, vr = R;
	vl += ln - 1;
	vr += ln - 1;

	int ans = 0;
	while (vl <= vr) {
		if (vl % 2 == 1) {
			ans = max(ans, arr[vl]);
			vl++;
		}
		if (vr % 2 == 0) {
			ans = max(ans, arr[vr]);
			vr--;
		}

		vl /= 2;
		vr /= 2;
	}

	return ans;

}

int get(const vector<int>& arr, int v, int vl, int vr, int L, int R) {
	if (arr.empty()) return 0;
	return _get(arr, v, vl, vr, L, R);
}

struct node;
typedef node* Node;

struct node{
	int mult;
	Node left, right;
	node(int v) : mult(v) {
		left = right = NULL;
	}
};

void _build(Node &root, int vl, int vr) {
	root = new node(1);
	if (vl == vr) return;

	int m = (vl + vr) / 2;
	_build(root->left, vl, m);
	_build(root->right, m + 1, vr);
}

void upd(Node& new_root, Node old_root, int vl, int vr, int pos, int val) {
	new_root = old_root;
	if (vl > pos || vr < pos) return;

	new_root = new node(old_root->mult);
	if (vl == vr) {
		new_root->mult = val;
		return;
	}

	int m = (vl + vr) / 2;
	upd(new_root->left, old_root->left, vl, m, pos, val);
	upd(new_root->right, old_root->right, m + 1, vr, pos, val);

	new_root->mult = 1LL * new_root->left->mult * new_root->right->mult % mod;
}

int get_pers(Node v, int vl, int vr, int L, int R) {
	if (vl > R || vr < L) return 1;
	if (vl >= L && vr <= R) return v->mult;

	int m = (vl + vr) / 2;
	return 1LL * get_pers(v->left, vl, m, L, R) * get_pers(v->right, m + 1, vr, L, R) % mod;
}

void _print(Node v) {
	if (!v) return;

	_print(v->left);
	cout << v->mult << " ";
	_print(v->right);
}

void print(Node v) {
	_print(v);
	cout << endl;
}

int main() {
	ios_base::sync_with_stdio(0); cin.tie(0);
	int n; cin >> n;
	vector<int> vc(n);
	int cnt;
	for (cnt = 1; 1 << cnt < n; ++cnt); ln = 1 << cnt;
	for (auto& it : vc) cin >> it;

	vector<int> big(n + 1, 1);

	for (int i = 1; i <= n; ++i) {
		int x = vc[i - 1];
		for (int j = 2; j * j <= x; ++j) {
			int p = 0;
			while (x % j == 0) {
				++p;
				x /= j;
			}

			if (p != 0) {
				_set(vals[j], i, p);
			}
		}
		if (x != 1) {
			if (x >= MAX_SQRT) big[i] = x;
			else _set(vals[x], i, 1);
		}
	}
	for (int i = 2; i < MAX_SQRT; ++i) {
		auto& arr = vals[i];
		if (arr.empty()) continue;

		for (int i = ln - 1; i >= 1; --i) arr[i] = max(arr[2 * i], arr[2 * i + 1]);
		pows[i][0] = 1;
		for (int j = 1; j < MAX_P; ++j)
			pows[i][j] = 1LL * pows[i][j - 1] * i % mod;
	}

	vector<int> last_pos(2 * maxn, -1);
	vector<Node> versions(n + 1, (Node)NULL);
//	cout << "ln = " << ln << endl;
	_build(versions[0], 1, ln);

	for (int i = 1; i <= n; ++i) {
		int x = big[i];

		if (last_pos[x] == -1) {
			upd(versions[i], versions[i - 1], 1, ln, i, x);
		} else {
			Node tmp = NULL;
			upd(tmp, versions[i - 1], 1, ln, last_pos[x], 1);
			upd(versions[i], tmp, 1, ln, i, x);
		}

		last_pos[x] = i;
	}
//	if (n > 10) return 1;

//return 0;
	int q; cin >> q;
	int last = 0;
	for (int i = 0; i < q; ++i) {
		int l, r; cin >> l >> r;
		l = (last + l) % n + 1;
		r = (last + r) % n + 1;
		if (l > r) swap(l, r);
		if (l == r) {
			last = vc[l - 1];
			cout << last << "\n";
			continue;
		}
//		cout << l << " " << r << endl;

		int mult = 1;
		for (int j = 2; j < MAX_SQRT; ++j) {
			mult = 1LL * mult * max(1, pows[j][get(vals[j], 1, 1, ln, l, r)]) % mod;

/*			if (j < 10 && vals[j].size() != 0) {
				cout << j << ": " << get(vals[j], 1, 1, ln, l, r) << endl;
			}*/
		}
		int mult2 = get_pers(versions[r], 1, ln, l, ln);
//		print(versions[r]);
		last = 1LL * mult * mult2 % mod;
//		cout << mult << " " << mult2 << endl;
		cout << last << "\n";
	}
	return 0;
}


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

#define fs first
#define sc second

#define pb push_back
#define mp make_pair

const int MAX_SQRT = 450;
const int MAX_P = 20;

const int maxn = 100000 + 1;
const int mod = 1000000000 + 7;

vector<int> vals[MAX_SQRT];

int pows[MAX_SQRT][MAX_P];

int ln;

void _set(vector<int> &vc, int pos, int val) {
	if (vc.size() == 0) vc.assign(2 * ln + 1, 0);
	vc[ln + pos - 1] = val;
}

int _get(const vector<int> &arr, int v, int vl, int vr, int L, int R) {
	if (vl > R || vr < L) return 0;
	if (vl == vr) return arr[v];

	int m = (vl + vr) / 2;
	return max(_get(arr, 2 * v, vl, m, L, R), _get(arr, 2 * v + 1, m + 1, vr, L, R));
}

int get(const vector<int>& arr, int v, int vl, int vr, int L, int R) {
	if (arr.empty()) return 0;
	return _get(arr, v, vl, vr, L, R);
}

struct node;
typedef node* Node;

struct node{
	int mult;
	Node left, right;
	node(int v) : mult(v) {
		left = right = NULL;
	}
};

void _build(Node &root, int vl, int vr) {
	root = new node(1);
	if (vl == vr) return;

	int m = (vl + vr) / 2;
	_build(root->left, vl, m);
	_build(root->right, m + 1, vr);
}

void upd(Node& new_root, Node old_root, int vl, int vr, int pos, int val) {
	new_root = old_root;
	if (vl > pos || vr < pos) return;

	new_root = new node(old_root->mult);
	if (vl == vr) {
		new_root->mult = val;
		return;
	}

	int m = (vl + vr) / 2;
	upd(new_root->left, old_root->left, vl, m, pos, val);
	upd(new_root->right, old_root->right, m + 1, vr, pos, val);

	new_root->mult = 1LL * new_root->left->mult * new_root->right->mult % mod;
}

int get_pers(Node v, int vl, int vr, int L, int R) {
	if (vl > R || vr < L) return 1;
	if (vl >= L && vr <= R) return v->mult;

	int m = (vl + vr) / 2;
	return 1LL * get_pers(v->left, vl, m, L, R) * get_pers(v->right, m + 1, vr, L, R) % mod;
}

void _print(Node v) {
	if (!v) return;

	_print(v->left);
	cout << v->mult << " ";
	_print(v->right);
}

void print(Node v) {
	_print(v);
	cout << endl;
}

int main() {
	ios_base::sync_with_stdio(0); cin.tie(0);
	int n; cin >> n;
	vector<int> vc(n);
	int cnt;
	for (cnt = 1; 1 << cnt < n; ++cnt); ln = 1 << cnt;
	for (auto& it : vc) cin >> it;

	vector<int> big(n + 1, 1);

	for (int i = 1; i <= n; ++i) {
		int x = vc[i - 1];
		for (int j = 2; j * j <= x; ++j) {
			int p = 0;
			while (x % j == 0) {
				++p;
				x /= j;
			}

			if (p != 0) {
				_set(vals[j], i, p);
			}
		}
		if (x != 1) {
			if (x >= MAX_SQRT) big[i] = x;
			else _set(vals[x], i, 1);
		}
	}
	for (int i = 2; i < MAX_SQRT; ++i) {
		auto& arr = vals[i];
		if (arr.empty()) continue;

		for (int i = ln - 1; i >= 1; --i) arr[i] = max(arr[2 * i], arr[2 * i + 1]);
		pows[i][0] = 1;
		for (int j = 1; j < MAX_P; ++j)
			pows[i][j] = 1LL * pows[i][j - 1] * i % mod;
	}

	vector<int> last_pos(2 * maxn, -1);
	vector<Node> versions(n + 1, (Node)NULL);
//	cout << "ln = " << ln << endl;
	_build(versions[0], 1, ln);

	for (int i = 1; i <= n; ++i) {
		int x = big[i];

		if (last_pos[x] == -1) {
			upd(versions[i], versions[i - 1], 1, ln, i, x);
		} else {
			Node tmp = NULL;
			upd(tmp, versions[i - 1], 1, ln, last_pos[x], 1);
			upd(versions[i], tmp, 1, ln, i, x);
		}

		last_pos[x] = i;
	}
//	if (n > 10) return 1;

	int q; cin >> q;
	int last = 0;
	for (int i = 0; i < q; ++i) {
		int l, r; cin >> l >> r;
		l = (last + l) % n + 1;
		r = (last + r) % n + 1;
		if (l > r) swap(l, r);
		if (l == r) {
			last = vc[l - 1];
			cout << last << "\n";
			continue;
		}
//		cout << l << " " << r << endl;

		int mult = 1;
		for (int j = 2; j < MAX_SQRT; ++j) {
			mult = 1LL * mult * max(1, pows[j][get(vals[j], 1, 1, ln, l, r)]) % mod;

/*			if (j < 10 && vals[j].size() != 0) {
				cout << j << ": " << get(vals[j], 1, 1, ln, l, r) << endl;
			}*/
		}
		int mult2 = get_pers(versions[r], 1, ln, l, ln);
//		print(versions[r]);
		last = mult * mult2 % mod;
//		cout << mult << " " << mult2 << endl;
		cout << last << "\n";
	}
	return 0;
}


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

#define fs first
#define sc second

#define pb push_back
#define mp make_pair

const int MAX_SQRT = 450;
const int MAX_P = 20;

const int maxn = 100000 + 1;
const int mod = 1000000000 + 7;

vector<int> vals[MAX_SQRT];

int pows[MAX_SQRT][MAX_P];

int ln;

void _set(vector<int> &vc, int pos, int val) {
	if (vc.size() == 0) vc.assign(2 * ln + 1, 0);
	vc[ln + pos - 1] = val;
}

int _get(const vector<int> &arr, int v, int vl, int vr, int L, int R) {
	if (vl > R || vr < L) return 0;
	if (vl == vr) return arr[v];

	int m = (vl + vr) / 2;
	return max(_get(arr, 2 * v, vl, m, L, R), _get(arr, 2 * v + 1, m + 1, vr, L, R));
}

int get(const vector<int>& arr, int v, int vl, int vr, int L, int R) {
	if (arr.empty()) return 0;
	return _get(arr, v, vl, vr, L, R);
}

struct node;
typedef node* Node;

struct node{
	int mult;
	Node left, right;
	node(int v) : mult(v) {
		left = right = NULL;
	}
};

void _build(Node &root, int vl, int vr) {
	root = new node(1);
	if (vl == vr) return;

	int m = (vl + vr) / 2;
	_build(root->left, vl, m);
	_build(root->right, m + 1, vr);
}

void upd(Node& new_root, Node old_root, int vl, int vr, int pos, int val) {
	new_root = old_root;
	if (vl > pos || vr < pos) return;

	new_root = new node(old_root->mult);
	if (vl == vr) {
		new_root->mult = val;
		return;
	}

	int m = (vl + vr) / 2;
	upd(new_root->left, old_root->left, vl, m, pos, val);
	upd(new_root->right, old_root->right, m + 1, vr, pos, val);

	new_root->mult = 1LL * new_root->left->mult * new_root->right->mult % mod;
}

int get_pers(Node v, int vl, int vr, int L, int R) {
	if (vl > R || vr < L) return 1;
	if (vl >= L && vr <= R) return v->mult;

	int m = (vl + vr) / 2;
	return 1LL * get_pers(v->left, vl, m, L, R) * get_pers(v->right, m + 1, vr, L, R) % mod;
}

void _print(Node v) {
	if (!v) return;

	_print(v->left);
	cout << v->mult << " ";
	_print(v->right);
}

void print(Node v) {
	_print(v);
	cout << endl;
}

int main() {
	ios_base::sync_with_stdio(0); cin.tie(0);
	int n; cin >> n;
	vector<int> vc(n);
	int cnt;
	for (cnt = 1; 1 << cnt < n; ++cnt); ln = 1 << cnt;
	for (auto& it : vc) cin >> it;

	vector<int> big(n + 1, 1);

	for (int i = 1; i <= n; ++i) {
		int x = vc[i - 1];
		for (int j = 2; j * j <= x; ++j) {
			int p = 0;
			while (x % j == 0) {
				++p;
				x /= j;
			}

			if (p != 0) {
				_set(vals[j], i, p);
			}
		}
		if (x != 1) {
			if (x >= MAX_SQRT) big[i] = x;
			else _set(vals[x], i, 1);
		}
	}
	for (int i = 2; i < MAX_SQRT; ++i) {
		auto& arr = vals[i];
		if (arr.empty()) continue;

		for (int i = ln - 1; i >= 1; --i) arr[i] = max(arr[2 * i], arr[2 * i + 1]);
		pows[i][0] = 1;
		for (int j = 1; j < MAX_P; ++j)
			pows[i][j] = pows[i][j - 1] * i % mod;
	}

	vector<int> last_pos(2 * maxn, -1);
	vector<Node> versions(n + 1, (Node)NULL);
//	cout << "ln = " << ln << endl;
	_build(versions[0], 1, ln);

	for (int i = 1; i <= n; ++i) {
		int x = big[i];

		if (last_pos[x] == -1) {
			upd(versions[i], versions[i - 1], 1, ln, i, x);
		} else {
			Node tmp = NULL;
			upd(tmp, versions[i - 1], 1, ln, last_pos[x], 1);
			upd(versions[i], tmp, 1, ln, i, x);
		}

		last_pos[x] = i;
	}
	if (n > 10) return 1;

	int q; cin >> q;
	int last = 0;
	for (int i = 0; i < q; ++i) {
		int l, r; cin >> l >> r;
		l = (last + l) % n + 1;
		r = (last + r) % n + 1;
		if (l > r) swap(l, r);
		if (l == r) {
			last = vc[l - 1];
			cout << last << "\n";
			continue;
		}
//		cout << l << " " << r << endl;

		int mult = 1;
		for (int j = 2; j < MAX_SQRT; ++j) {
			mult = 1LL * mult * max(1, pows[j][get(vals[j], 1, 1, ln, l, r)]) % mod;

/*			if (j < 10 && vals[j].size() != 0) {
				cout << j << ": " << get(vals[j], 1, 1, ln, l, r) << endl;
			}*/
		}
		int mult2 = get_pers(versions[r], 1, ln, l, ln);
//		print(versions[r]);
		last = mult * mult2 % mod;
//		cout << mult << " " << mult2 << endl;
		cout << last << "\n";
	}
	return 0;
}


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

#define fs first
#define sc second

#define pb push_back
#define mp make_pair

int gcd(int a, int b) {
	return b ? gcd(b, a % b) : a;
}

vector<int> gcd_arr;
vector<int> mult_arr;

const int mod = 1000000000 + 7;

int get(vector<int>& arr, int v, int vl, int vr, int L, int R, bool is_gcd) {
	if (vl > R || vr < L) {
		if (is_gcd) return 0;
		else return 1;
	}
	if (vl >= L && vr <= R) return arr[v];

	int m = (vl + vr) / 2;
	int lv = get(arr, 2 * v, vl, m, L, R, is_gcd);
	int rv = get(arr, 2 * v + 1, m + 1, vr, L, R, is_gcd);

	if (is_gcd) return gcd(lv, rv);
	else return 1LL * lv * rv % mod;
}

int pow_mod(int x, int n) {
	if (n == 0) return 1;
	if (n % 2 == 0) {
		int b = pow_mod(x, n  /2);
		return 1LL * b * b % mod;
	}

	return 1LL * x * pow_mod(x, n - 1) % mod;
}

int main() {
	ios_base::sync_with_stdio(0); cin.tie(0);
	int n; cin >> n;
	vector<int> vc(n);
	for (auto& it : vc) cin >> it;
	int cnt, ln;
	for (cnt = 1; 1 << cnt < n; ++cnt); ln = 1 << cnt;

	gcd_arr.assign(2 * ln + 1, 0);
	for (int i = 0; i < n; ++i) gcd_arr[ln + i] = vc[i];
	for (int i = ln - 1; i >= 1; --i)
		gcd_arr[i] = gcd(gcd_arr[2 * i], gcd_arr[2 * i + 1]);

	mult_arr.assign(2 * ln + 1, 1);
	for (int i = 0; i < n; ++i) mult_arr[ln + i] = vc[i];
	for (int i = ln - 1; i >= 1; --i)
		mult_arr[i] = (1LL * mult_arr[2 * i] * mult_arr[2 * i + 1]) % mod;

	int last = 0;
	int q; cin >> q;
	for (int i = 0; i < q; ++i) {
		int l, r; cin >> l >> r;
		l = (last + l) % n + 1;
		r = (last + r) % n + 1;
		if (l > r) swap(l, r);

		int _gcd = l == r ? 1 : get(gcd_arr, 1, 1, ln, l, r, true);
		int _mult = get(mult_arr, 1, 1, ln, l, r, false);

		last = 1LL * _mult * pow_mod(_gcd, mod - 2) % mod;
		cout << last << "\n";
	}
	return 0;
}


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

#define fs first
#define sc second

#define pb push_back
#define mp make_pair

const int MAX_SQRT = 450;
const int MAX_P = 20;

const int maxn = 100000 + 1;
const int mod = 1000000000 + 7;

vector<int> vals[MAX_SQRT];

int pows[MAX_SQRT][MAX_P];

int ln;

void _set(vector<int> &vc, int pos, int val) {
	if (vc.size() == 0) vc.assign(2 * ln + 1, 0);
	vc[ln + pos - 1] = val;
}

int _get(const vector<int> &arr, int v, int vl, int vr, int L, int R) {
	if (vl > R || vr < L) return 0;
	if (vl >= L && vr <= R) return arr[v];

	int m = (vl + vr) / 2;
	return max(_get(arr, 2 * v, vl, m, L, R), _get(arr, 2 * v + 1, m + 1, vr, L, R));
}

int get(const vector<int>& arr, int v, int vl, int vr, int L, int R) {
	if (arr.empty()) return 0;
	return _get(arr, v, vl, vr, L, R);
}

struct node;
typedef node* Node;

struct node{
	int mult;
	Node left, right;
	node(int v) : mult(v) {
		left = right = NULL;
	}
};

void _build(Node &root, int vl, int vr) {
	root = new node(1);
	if (vl == vr) return;

	int m = (vl + vr) / 2;
	_build(root->left, vl, m);
	_build(root->right, m + 1, vr);
}

void upd(Node& new_root, Node old_root, int vl, int vr, int pos, int val) {
	new_root = old_root;
	if (vl > pos || vr < pos) return;

	new_root = new node(old_root->mult);
	if (vl == vr) {
		new_root->mult = val;
		return;
	}

	int m = (vl + vr) / 2;
	upd(new_root->left, old_root->left, vl, m, pos, val);
	upd(new_root->right, old_root->right, m + 1, vr, pos, val);

	new_root->mult = 1LL * new_root->left->mult * new_root->right->mult % mod;
}

int get_pers(Node v, int vl, int vr, int L, int R) {
	if (vl > R || vr < L) return 1;
	if (vl >= L && vr <= R) return v->mult;

	int m = (vl + vr) / 2;
	return 1LL * get_pers(v->left, vl, m, L, R) * get_pers(v->right, m + 1, vr, L, R) % mod;
}

void _print(Node v) {
	if (!v) return;

	_print(v->left);
	cout << v->mult << " ";
	_print(v->right);
}

void print(Node v) {
	_print(v);
	cout << endl;
}

int main() {
	ios_base::sync_with_stdio(0); cin.tie(0);
	int n; cin >> n;
	vector<int> vc(n);
	int cnt;
	for (cnt = 1; 1 << cnt < n; ++cnt); ln = 1 << cnt;
	for (auto& it : vc) cin >> it;

	vector<int> big(n + 1, 1);

	for (int i = 1; i <= n; ++i) {
		int x = vc[i - 1];
		for (int j = 2; j * j <= x; ++j) {
			int p = 0;
			while (x % j == 0) {
				++p;
				x /= j;
			}

			if (p != 0) {
				_set(vals[j], i, p);
			}
		}
		if (x != 1) {
			if (x >= MAX_SQRT) big[i] = x;
			else _set(vals[x], i, 1);
		}
	}
	for (int i = 2; i < MAX_SQRT; ++i) {
		auto& arr = vals[i];
		if (arr.empty()) continue;

		for (int i = ln - 1; i >= 1; --i) arr[i] = max(arr[2 * i], arr[2 * i + 1]);
		pows[i][0] = 1;
		for (int j = 1; j < MAX_P; ++j)
			pows[i][j] = 1LL * pows[i][j - 1] * i % mod;
	}

	vector<int> last_pos(2 * maxn, -1);
	vector<Node> versions(n + 1, (Node)NULL);
//	cout << "ln = " << ln << endl;
	_build(versions[0], 1, ln);

	for (int i = 1; i <= n; ++i) {
		int x = big[i];

		if (last_pos[x] == -1) {
			upd(versions[i], versions[i - 1], 1, ln, i, x);
		} else {
			Node tmp = NULL;
			upd(tmp, versions[i - 1], 1, ln, last_pos[x], 1);
			upd(versions[i], tmp, 1, ln, i, x);
		}

		last_pos[x] = i;
	}
//	if (n > 10) return 1;

//return 0;
	int q; cin >> q;
	int last = 0;
	for (int i = 0; i < q; ++i) {
		int l, r; cin >> l >> r;
		l = (last + l) % n + 1;
		r = (last + r) % n + 1;
		if (l > r) swap(l, r);
		if (l == r) {
			last = vc[l - 1];
			cout << last << "\n";
			continue;
		}
//		cout << l << " " << r << endl;

		int mult = 1;
		for (int j = 2; j < MAX_SQRT; ++j) {
			mult = 1LL * mult * max(1, pows[j][get(vals[j], 1, 1, ln, l, r)]) % mod;

/*			if (j < 10 && vals[j].size() != 0) {
				cout << j << ": " << get(vals[j], 1, 1, ln, l, r) << endl;
			}*/
		}
		int mult2 = get_pers(versions[r], 1, ln, l, ln);
//		print(versions[r]);
		last = 1LL * mult * mult2 % mod;
//		cout << mult << " " << mult2 << endl;
		cout << last << "\n";
	}
	return 0;
}


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

#define fs first
#define sc second

#define pb push_back
#define mp make_pair

const int MAX_SQRT = 450;
const int MAX_P = 20;

const int maxn = 100000 + 1;
const int mod = 1000000000 + 7;

vector<int> vals[MAX_SQRT];

int pows[MAX_SQRT][MAX_P];

int ln;

void _set(vector<int> &vc, int pos, int val) {
	if (vc.size() == 0) vc.assign(2 * ln + 1, 0);
	vc[ln + pos - 1] = val;
}

int _get(const vector<int> &arr, int v, int vl, int vr, int L, int R) {
	if (vl > R || vr < L) return 0;
	if (vl == vr) return arr[v];

	int m = (vl + vr) / 2;
	return max(_get(arr, 2 * v, vl, m, L, R), _get(arr, 2 * v + 1, m + 1, vr, L, R));
}

int get(const vector<int>& arr, int v, int vl, int vr, int L, int R) {
	if (arr.empty()) return 0;
	return _get(arr, v, vl, vr, L, R);
}

struct node;
typedef node* Node;

struct node{
	int mult;
	Node left, right;
	node(int v) : mult(v) {
		left = right = NULL;
	}
};

void _build(Node &root, int vl, int vr) {
	root = new node(1);
	if (vl == vr) return;

	int m = (vl + vr) / 2;
	_build(root->left, vl, m);
	_build(root->right, m + 1, vr);
}

void upd(Node& new_root, Node old_root, int vl, int vr, int pos, int val) {
	new_root = old_root;
	if (vl > pos || vr < pos) return;

	new_root = new node(old_root->mult);
	if (vl == vr) {
		new_root->mult = val;
		return;
	}

	int m = (vl + vr) / 2;
	upd(new_root->left, old_root->left, vl, m, pos, val);
	upd(new_root->right, old_root->right, m + 1, vr, pos, val);

	new_root->mult = 1LL * new_root->left->mult * new_root->right->mult % mod;
}

int get_pers(Node v, int vl, int vr, int L, int R) {
	if (vl > R || vr < L) return 1;
	if (vl >= L && vr <= R) return v->mult;

	int m = (vl + vr) / 2;
	return 1LL * get_pers(v->left, vl, m, L, R) * get_pers(v->right, m + 1, vr, L, R) % mod;
}

void _print(Node v) {
	if (!v) return;

	_print(v->left);
	cout << v->mult << " ";
	_print(v->right);
}

void print(Node v) {
	_print(v);
	cout << endl;
}

int main() {
	ios_base::sync_with_stdio(0); cin.tie(0);
	int n; cin >> n;
	vector<int> vc(n);
	int cnt;
	for (cnt = 1; 1 << cnt < n; ++cnt); ln = 1 << cnt;
	for (auto& it : vc) cin >> it;

	vector<int> big(n + 1, 1);

	for (int i = 1; i <= n; ++i) {
		int x = vc[i - 1];
		for (int j = 2; j * j <= x; ++j) {
			int p = 0;
			while (x % j == 0) {
				++p;
				x /= j;
			}

			if (p != 0) {
				_set(vals[j], i, p);
			}
		}
		if (x != 1) {
			if (x >= MAX_SQRT) big[i] = x;
			else _set(vals[x], i, 1);
		}
	}
	for (int i = 2; i < MAX_SQRT; ++i) {
		auto& arr = vals[i];
		if (arr.empty()) continue;

		for (int i = ln - 1; i >= 1; --i) arr[i] = max(arr[2 * i], arr[2 * i + 1]);
		pows[i][0] = 1;
		for (int j = 1; j < MAX_P; ++j)
			pows[i][j] = 1LL * pows[i][j - 1] * i % mod;
	}

	vector<int> last_pos(2 * maxn, -1);
	vector<Node> versions(n + 1, (Node)NULL);
//	cout << "ln = " << ln << endl;
	_build(versions[0], 1, ln);

	for (int i = 1; i <= n; ++i) {
		int x = big[i];

		if (last_pos[x] == -1) {
			upd(versions[i], versions[i - 1], 1, ln, i, x);
		} else {
			Node tmp = NULL;
			upd(tmp, versions[i - 1], 1, ln, last_pos[x], 1);
			upd(versions[i], tmp, 1, ln, i, x);
		}

		last_pos[x] = i;
	}
//	if (n > 10) return 1;

	int q; cin >> q;
	int last = 0;
	for (int i = 0; i < q; ++i) {
		int l, r; cin >> l >> r;
		l = (last + l) % n + 1;
		r = (last + r) % n + 1;
		if (l > r) swap(l, r);
		if (l == r) {
			last = vc[l - 1];
			cout << last << "\n";
			continue;
		}
//		cout << l << " " << r << endl;

		int mult = 1;
		for (int j = 2; j < MAX_SQRT; ++j) {
			mult = 1LL * mult * max(1, pows[j][get(vals[j], 1, 1, ln, l, r)]) % mod;

/*			if (j < 10 && vals[j].size() != 0) {
				cout << j << ": " << get(vals[j], 1, 1, ln, l, r) << endl;
			}*/
		}
		int mult2 = get_pers(versions[r], 1, ln, l, ln);
//		print(versions[r]);
		last = 1LL * mult * mult2 % mod;
//		cout << mult << " " << mult2 << endl;
		cout << last << "\n";
	}
	return 0;
}


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

#define fs first
#define sc second

#define pb push_back
#define mp make_pair

const int MAX_SQRT = 450;
const int MAX_P = 20;

const int maxn = 100000 + 1;
const int mod = 1000000000 + 7;

vector<int> vals[MAX_SQRT];

int pows[MAX_SQRT][MAX_P];

int ln;

void _set(vector<int> &vc, int pos, int val) {
	if (vc.size() == 0) vc.assign(2 * ln + 1, 0);
	vc[ln + pos - 1] = val;
}

int _get(const vector<int> &arr, int v, int vl, int vr, int L, int R) {
	if (vl > R || vr < L) return 0;
	if (vl == vr) return arr[v];

	int m = (vl + vr) / 2;
	return max(_get(arr, 2 * v, vl, m, L, R), _get(arr, 2 * v + 1, m + 1, vr, L, R));
}

int get(const vector<int>& arr, int v, int vl, int vr, int L, int R) {
	if (arr.empty()) return 0;
	return _get(arr, v, vl, vr, L, R);
}

struct node;
typedef node* Node;

struct node{
	int mult;
	Node left, right;
	node(int v) : mult(v) {
		left = right = NULL;
	}
};

void _build(Node &root, int vl, int vr) {
	root = new node(1);
	if (vl == vr) return;

	int m = (vl + vr) / 2;
	_build(root->left, vl, m);
	_build(root->right, m + 1, vr);
}

void upd(Node& new_root, Node old_root, int vl, int vr, int pos, int val) {
	new_root = old_root;
	if (vl > pos || vr < pos) return;

	new_root = new node(old_root->mult);
	if (vl == vr) {
		new_root->mult = val;
		return;
	}

	int m = (vl + vr) / 2;
	upd(new_root->left, old_root->left, vl, m, pos, val);
	upd(new_root->right, old_root->right, m + 1, vr, pos, val);

	new_root->mult = 1LL * new_root->left->mult * new_root->right->mult % mod;
}

int get_pers(Node v, int vl, int vr, int L, int R) {
	if (vl > R || vr < L) return 1;
	if (vl >= L && vr <= R) return v->mult;

	int m = (vl + vr) / 2;
	return 1LL * get_pers(v->left, vl, m, L, R) * get_pers(v->right, m + 1, vr, L, R) % mod;
}

void _print(Node v) {
	if (!v) return;

	_print(v->left);
	cout << v->mult << " ";
	_print(v->right);
}

void print(Node v) {
	_print(v);
	cout << endl;
}

int main() {
	ios_base::sync_with_stdio(0); cin.tie(0);
	int n; cin >> n;
	vector<int> vc(n);
	int cnt;
	for (cnt = 1; 1 << cnt < n; ++cnt); ln = 1 << cnt;
	for (auto& it : vc) cin >> it;

	vector<int> big(n + 1, 1);

	for (int i = 1; i <= n; ++i) {
		int x = vc[i - 1];
		for (int j = 2; j * j <= x; ++j) {
			int p = 0;
			while (x % j == 0) {
				++p;
				x /= j;
			}

			if (p != 0) {
				_set(vals[j], i, p);
			}
		}
		if (x != 1) {
			if (x >= MAX_SQRT) big[i] = x;
			else _set(vals[x], i, 1);
		}
	}
	for (int i = 2; i < MAX_SQRT; ++i) {
		auto& arr = vals[i];
		if (arr.empty()) continue;

		for (int i = ln - 1; i >= 1; --i) arr[i] = max(arr[2 * i], arr[2 * i + 1]);
		pows[i][0] = 1;
		for (int j = 1; j < MAX_P; ++j)
			pows[i][j] = pows[i][j - 1] * i % mod;
	}

	vector<int> last_pos(2 * maxn, -1);
	vector<Node> versions(n + 1, (Node)NULL);
//	cout << "ln = " << ln << endl;
	_build(versions[0], 1, ln);

	for (int i = 1; i <= n; ++i) {
		int x = big[i];

		if (last_pos[x] == -1) {
			upd(versions[i], versions[i - 1], 1, ln, i, x);
		} else {
			Node tmp = NULL;
			upd(tmp, versions[i - 1], 1, ln, last_pos[x], 1);
			upd(versions[i], tmp, 1, ln, i, x);
		}

		last_pos[x] = i;
	}

	int q; cin >> q;
	int last = 0;
	for (int i = 0; i < q; ++i) {
		int l, r; cin >> l >> r;
		l = (last + l) % n + 1;
		r = (last + r) % n + 1;
		if (l > r) swap(l, r);
		if (l == r) {
			last = vc[l - 1];
			cout << last << "\n";
			continue;
		}
//		cout << l << " " << r << endl;

		int mult = 1;
		for (int j = 2; j < MAX_SQRT; ++j) {
			mult = 1LL * mult * max(1, pows[j][get(vals[j], 1, 1, ln, l, r)]) % mod;

/*			if (j < 10 && vals[j].size() != 0) {
				cout << j << ": " << get(vals[j], 1, 1, ln, l, r) << endl;
			}*/
		}
		int mult2 = get_pers(versions[r], 1, ln, l, ln);
//		print(versions[r]);
		last = mult * mult2 % mod;
//		cout << mult << " " << mult2 << endl;
		cout << last << "\n";
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define SZ(a) ((int)(a).size())
typedef long long int64;

const int mod = 1e9 + 7;
const int maxm = 100000 * 300;
int tr[100000 + 9];
int L[maxm], R[maxm], V[maxm], tot;
int build(int l, int r) {
  int res = ++tot;
  V[res] = 1;
  if (l == r) {
    return res;
  }
  int mid = (l + r) >> 1;
  L[res] = build(l, mid);
  R[res] = build(mid + 1, r);
  return res;
}
int upd(int l, int r, int p, int v, int rt) {
  int res = ++tot;
  L[res] = L[rt];
  R[res] = R[rt];
  V[res] = V[rt];
  if (l == r) {
    V[res] = 1ll * V[res] * v % mod;
    return res;
  }
  int mid = (l + r) >> 1;
  if (p <= mid)
    L[res] = upd(l, mid, p, v, L[rt]);
  else
    R[res] = upd(mid + 1, r, p, v, R[rt]);
  V[res] = 1ll * V[L[res]] * V[R[res]] % mod;
  return res;
}
int query(int rt, int l, int r, int ll, int rr) {
  if (ll <= l && rr >= r) {
    return V[rt];
  }
  int mid = (l + r) >> 1, res = 1;
  if (ll <= mid) res = 1ll * res * query(L[rt], l, mid, ll, rr) % mod;
  if (rr > mid) res = 1ll * res * query(R[rt], mid + 1, r, ll, rr) % mod;
  return res;
}
int main() {
#ifdef LOCAL
  freopen(".a.in", "r", stdin);
#endif
  ios_base::sync_with_stdio(false);
  cout.tie(0);
  cin.tie(0);
  int n;
  cin >> n;
  vector<int> A(n + 1);
  for (int i = 1; i <= n; ++i) cin >> A[i];
  int Max=*max_element(A.begin(),A.end())+5;
  vector<int> p(Max);
  for (int i = 2; i < Max; ++i)
    if (!p[i]) {
      p[i] = i;
      for (int64 j = 1ll * i * i; j < Max; j += i)
        if (p[j] == 0) p[j] = i;
    }
  tr[0] = build(1, n);
  struct Z {
    int h, v, idx;
    Z(int a = 0, int b = 0, int c = 0) : h(a), v(b), idx(c) {}
  };
  vector<vector<Z>> que(Max, vector<Z>(1, Z(1e9, 1, 0)));
  vector<int> inv(Max);
  inv[1] = 1;
  for (int i = 2; i < Max; ++i) inv[i] = 1ll * (mod - (mod / i)) * inv[mod % i] % mod;
  for (int i = 1; i <= n; ++i) {
    tr[i] = tr[i - 1];
    while (A[i] != 1) {
      int q = 1, a = p[A[i]];
      while (p[A[i]] == a) {
        A[i] /= p[A[i]];
        q *= a;
      }
      tr[i] = upd(1, n, i, q, tr[i]);
      while (que[a].back().h <= q) {
        auto [h, v, idx] = que[a].back();
        tr[i] = upd(1, n, idx, inv[v], tr[i]);
        que[a].pop_back();
      }
      if (SZ(que[a]) > 1) {
        auto [h, v, idx] = que[a].back();
        tr[i] = upd(1, n, idx, 1ll * h / q * inv[v] % mod, tr[i]);
        que[a].back().v = h / q;
      }
      que[a].emplace_back(q, q, i);
    }
  }
  int m, lst = 0;
  cin >> m;
  while (m--) {
    int l, r;
    cin >> l >> r;
    l = (lst + l) % n + 1;
    r = (lst + r) % n + 1;
    if (l > r) swap(l, r);
    //cout << l << " " << r << '\n';
    lst = query(tr[r], 1, n, l, r);
    cout << lst << '\n';
  }
  return 0;
}
//06.10.2020 17:04:06 CST


#include <bits/stdc++.h>
using namespace std;
#define SZ(a) ((int)(a).size())
typedef long long int64;

const int maxn = 200000 + 9;
const int mod = 1e9 + 7;
int tr[100000 + 9];
int L[maxn << 5], R[maxn << 5], V[maxn << 5], tot;
int build(int l, int r) {
  int res = ++tot;
  V[res] = 1;
  if (l == r) {
    return res;
  }
  int mid = (l + r) >> 1;
  L[res] = build(l, mid);
  R[res] = build(mid + 1, r);
  return res;
}
int upd(int l, int r, int p, int v, int rt) {
  int res = ++tot;
  L[res] = L[rt];
  R[res] = R[rt];
  V[res] = V[rt];
  if (l == r) {
    V[res] = 1ll * V[res] * v % mod;
    return res;
  }
  int mid = (l + r) >> 1;
  if (p <= mid)
    L[res] = upd(l, mid, p, v, L[rt]);
  else
    R[res] = upd(mid + 1, r, p, v, R[rt]);
  V[res] = 1ll * V[L[res]] * V[R[res]] % mod;
  return res;
}
int query(int rt, int l, int r, int ll, int rr) {
  if (ll <= l && rr >= r) {
    return V[rt];
  }
  int mid = (l + r) >> 1, res = 1;
  if (ll <= mid) res = 1ll * res * query(L[rt], l, mid, ll, rr) % mod;
  if (rr > mid) res = 1ll * res * query(R[rt], mid + 1, r, ll, rr) % mod;
  return res;
}
int main() {
#ifdef LOCAL
  freopen(".a.in", "r", stdin);
#endif
  ios_base::sync_with_stdio(false);
  cout.tie(0);
  cin.tie(0);
  int n;
  cin >> n;
  vector<int> A(n + 1);
  for (int i = 1; i <= n; ++i) cin >> A[i];
  vector<int> p(maxn);
  for (int i = 2; i < maxn; ++i)
    if (!p[i]) {
      p[i] = i;
      for (int64 j = 1ll * i * i; j < maxn; j += i)
        if (p[j] == 0) p[j] = i;
    }
  tr[0] = build(1, n);
  struct Z {
    int h, v, idx;
    Z(int a = 0, int b = 0, int c = 0) : h(a), v(b), idx(c) {}
  };
  vector<vector<Z>> que(maxn, vector<Z>(1, Z(1e9, 1, 0)));
  vector<int> inv(maxn);
  inv[1] = 1;
  for (int i = 2; i < maxn; ++i) inv[i] = 1ll * (mod - (mod / i)) * inv[mod % i] % mod;
  for (int i = 1; i <= n; ++i) {
    tr[i] = tr[i - 1];
    while (A[i] != 1) {
      int q = 1, a = p[A[i]];
      while (p[A[i]] == a) {
        A[i] /= p[A[i]];
        q *= a;
      }
      tr[i] = upd(1, n, i, q, tr[i]);
      while (que[a].back().h <= q) {
        auto [h, v, idx] = que[a].back();
        tr[i] = upd(1, n, idx, inv[v], tr[i]);
        que[a].pop_back();
      }
      if (SZ(que[a]) > 1) {
        auto [h, v, idx] = que[a].back();
        tr[i] = upd(1, n, idx, 1ll * h / q * inv[v] % mod, tr[i]);
        que[a].back().v = h / q;
      }
      que[a].emplace_back(q, q, i);
    }
  }
  int m, lst = 0;
  cin >> m;
  while (m--) {
    int l, r;
    cin >> l >> r;
    l = (lst + l) % n + 1;
    r = (lst + r) % n + 1;
    if (l > r) swap(l, r);
    //cout << l << " " << r << '\n';
    lst = query(tr[r], 1, n, l, r);
    cout << lst << '\n';
  }
  return 0;
}
//06.10.2020 17:04:06 CST


#include <bits/stdc++.h>
using namespace std;
#define SZ(a) ((int)(a).size())
typedef long long int64;

const int mod = 1e9 + 7;
const int maxm = 100000 * 100;
int tr[100000 + 9];
int L[maxm], R[maxm], V[maxm], tot;
int build(int l, int r) {
  int res = ++tot;
  V[res] = 1;
  if (l == r) {
    return res;
  }
  int mid = (l + r) >> 1;
  L[res] = build(l, mid);
  R[res] = build(mid + 1, r);
  return res;
}
int upd(int l, int r, int p, int v, int rt) {
  int res = ++tot;
  L[res] = L[rt];
  R[res] = R[rt];
  V[res] = V[rt];
  if (l == r) {
    V[res] = 1ll * V[res] * v % mod;
    return res;
  }
  int mid = (l + r) >> 1;
  if (p <= mid)
    L[res] = upd(l, mid, p, v, L[rt]);
  else
    R[res] = upd(mid + 1, r, p, v, R[rt]);
  V[res] = 1ll * V[L[res]] * V[R[res]] % mod;
  return res;
}
int query(int rt, int l, int r, int ll, int rr) {
  if (ll <= l && rr >= r) {
    return V[rt];
  }
  int mid = (l + r) >> 1, res = 1;
  if (ll <= mid) res = 1ll * res * query(L[rt], l, mid, ll, rr) % mod;
  if (rr > mid) res = 1ll * res * query(R[rt], mid + 1, r, ll, rr) % mod;
  return res;
}
int main() {
#ifdef LOCAL
  freopen(".a.in", "r", stdin);
#endif
  ios_base::sync_with_stdio(false);
  cout.tie(0);
  cin.tie(0);
  int n;
  cin >> n;
  vector<int> A(n + 1);
  for (int i = 1; i <= n; ++i) cin >> A[i];
  int Max=*max_element(A.begin(),A.end())+5;
  vector<int> p(Max);
  for (int i = 2; i < Max; ++i)
    if (!p[i]) {
      p[i] = i;
      for (int64 j = 1ll * i * i; j < Max; j += i)
        if (p[j] == 0) p[j] = i;
    }
  tr[0] = build(1, n);
  struct Z {
    int h, v, idx;
    Z(int a = 0, int b = 0, int c = 0) : h(a), v(b), idx(c) {}
  };
  vector<vector<Z>> que(Max, vector<Z>(1, Z(1e9, 1, 0)));
  vector<int> inv(Max);
  inv[1] = 1;
  for (int i = 2; i < Max; ++i) inv[i] = 1ll * (mod - (mod / i)) * inv[mod % i] % mod;
  for (int i = 1; i <= n; ++i) {
    tr[i] = tr[i - 1];
    while (A[i] != 1) {
      int q = 1, a = p[A[i]];
      while (p[A[i]] == a) {
        A[i] /= p[A[i]];
        q *= a;
      }
      tr[i] = upd(1, n, i, q, tr[i]);
      while (que[a].back().h <= q) {
        auto [h, v, idx] = que[a].back();
        tr[i] = upd(1, n, idx, inv[v], tr[i]);
        que[a].pop_back();
      }
      if (SZ(que[a]) > 1) {
        auto [h, v, idx] = que[a].back();
        tr[i] = upd(1, n, idx, 1ll * h / q * inv[v] % mod, tr[i]);
        que[a].back().v = h / q;
      }
      que[a].emplace_back(q, q, i);
    }
  }
  int m, lst = 0;
  cin >> m;
  while (m--) {
    int l, r;
    cin >> l >> r;
    l = (lst + l) % n + 1;
    r = (lst + r) % n + 1;
    if (l > r) swap(l, r);
    //cout << l << " " << r << '\n';
    lst = query(tr[r], 1, n, l, r);
    cout << lst << '\n';
  }
  return 0;
}
//06.10.2020 17:04:06 CST


#include <bits/stdc++.h>
using namespace std;
#define SZ(a) ((int)(a).size())
typedef long long int64;

const int mod = 1e9 + 7;
const int maxm = 100000 * 400;
int tr[100000 + 9];
int L[maxm], R[maxm], V[maxm], tot;
int build(int l, int r) {
  int res = ++tot;
  V[res] = 1;
  if (l == r) {
    return res;
  }
  int mid = (l + r) >> 1;
  L[res] = build(l, mid);
  R[res] = build(mid + 1, r);
  return res;
}
int upd(int l, int r, int p, int v, int rt) {
  int res = ++tot;
  L[res] = L[rt];
  R[res] = R[rt];
  V[res] = V[rt];
  if (l == r) {
    V[res] = 1ll * V[res] * v % mod;
    return res;
  }
  int mid = (l + r) >> 1;
  if (p <= mid)
    L[res] = upd(l, mid, p, v, L[rt]);
  else
    R[res] = upd(mid + 1, r, p, v, R[rt]);
  V[res] = 1ll * V[L[res]] * V[R[res]] % mod;
  return res;
}
int query(int rt, int l, int r, int ll, int rr) {
  if (ll <= l && rr >= r) {
    return V[rt];
  }
  int mid = (l + r) >> 1, res = 1;
  if (ll <= mid) res = 1ll * res * query(L[rt], l, mid, ll, rr) % mod;
  if (rr > mid) res = 1ll * res * query(R[rt], mid + 1, r, ll, rr) % mod;
  return res;
}
int main() {
#ifdef LOCAL
  freopen(".a.in", "r", stdin);
#endif
  ios_base::sync_with_stdio(false);
  cout.tie(0);
  cin.tie(0);
  int n;
  cin >> n;
  vector<int> A(n + 1);
  for (int i = 1; i <= n; ++i) cin >> A[i];
  int Max=*max_element(A.begin(),A.end())+5;
  vector<int> p(Max);
  for (int i = 2; i < Max; ++i)
    if (!p[i]) {
      p[i] = i;
      for (int64 j = 1ll * i * i; j < Max; j += i)
        if (p[j] == 0) p[j] = i;
    }
  tr[0] = build(1, n);
  struct Z {
    int h, v, idx;
    Z(int a = 0, int b = 0, int c = 0) : h(a), v(b), idx(c) {}
  };
  vector<vector<Z>> que(Max, vector<Z>(1, Z(1e9, 1, 0)));
  vector<int> inv(Max);
  inv[1] = 1;
  for (int i = 2; i < Max; ++i) inv[i] = 1ll * (mod - (mod / i)) * inv[mod % i] % mod;
  for (int i = 1; i <= n; ++i) {
    tr[i] = tr[i - 1];
    while (A[i] != 1) {
      int q = 1, a = p[A[i]];
      while (p[A[i]] == a) {
        A[i] /= p[A[i]];
        q *= a;
      }
      tr[i] = upd(1, n, i, q, tr[i]);
      while (que[a].back().h <= q) {
        auto [h, v, idx] = que[a].back();
        tr[i] = upd(1, n, idx, inv[v], tr[i]);
        que[a].pop_back();
      }
      if (SZ(que[a]) > 1) {
        auto [h, v, idx] = que[a].back();
        tr[i] = upd(1, n, idx, 1ll * h / q * inv[v] % mod, tr[i]);
        que[a].back().v = h / q;
      }
      que[a].emplace_back(q, q, i);
    }
  }
  int m, lst = 0;
  cin >> m;
  while (m--) {
    int l, r;
    cin >> l >> r;
    l = (lst + l) % n + 1;
    r = (lst + r) % n + 1;
    if (l > r) swap(l, r);
    //cout << l << " " << r << '\n';
    lst = query(tr[r], 1, n, l, r);
    cout << lst << '\n';
  }
  return 0;
}
//06.10.2020 17:04:06 CST


#include <bits/stdc++.h>
using namespace std;
#define SZ(a) ((int)(a).size())
typedef long long int64;

const int mod = 1e9 + 7;
const int maxm = 100000 * 500;
int tr[100000 + 9];
int L[maxm], R[maxm], V[maxm], tot;
int build(int l, int r) {
  int res = ++tot;
  V[res] = 1;
  if (l == r) {
    return res;
  }
  int mid = (l + r) >> 1;
  L[res] = build(l, mid);
  R[res] = build(mid + 1, r);
  return res;
}
int upd(int l, int r, int p, int v, int rt) {
  int res = ++tot;
  L[res] = L[rt];
  R[res] = R[rt];
  V[res] = V[rt];
  if (l == r) {
    V[res] = 1ll * V[res] * v % mod;
    return res;
  }
  int mid = (l + r) >> 1;
  if (p <= mid)
    L[res] = upd(l, mid, p, v, L[rt]);
  else
    R[res] = upd(mid + 1, r, p, v, R[rt]);
  V[res] = 1ll * V[L[res]] * V[R[res]] % mod;
  return res;
}
int query(int rt, int l, int r, int ll, int rr) {
  if (ll <= l && rr >= r) {
    return V[rt];
  }
  int mid = (l + r) >> 1, res = 1;
  if (ll <= mid) res = 1ll * res * query(L[rt], l, mid, ll, rr) % mod;
  if (rr > mid) res = 1ll * res * query(R[rt], mid + 1, r, ll, rr) % mod;
  return res;
}
int main() {
#ifdef LOCAL
  freopen(".a.in", "r", stdin);
#endif
  ios_base::sync_with_stdio(false);
  cout.tie(0);
  cin.tie(0);
  int n;
  cin >> n;
  vector<int> A(n + 1);
  for (int i = 1; i <= n; ++i) cin >> A[i];
  int Max=*max_element(A.begin(),A.end())+5;
  vector<int> p(Max);
  for (int i = 2; i < Max; ++i)
    if (!p[i]) {
      p[i] = i;
      for (int64 j = 1ll * i * i; j < Max; j += i)
        if (p[j] == 0) p[j] = i;
    }
  tr[0] = build(1, n);
  struct Z {
    int h, v, idx;
    Z(int a = 0, int b = 0, int c = 0) : h(a), v(b), idx(c) {}
  };
  vector<vector<Z>> que(Max, vector<Z>(1, Z(1e9, 1, 0)));
  vector<int> inv(Max);
  inv[1] = 1;
  for (int i = 2; i < Max; ++i) inv[i] = 1ll * (mod - (mod / i)) * inv[mod % i] % mod;
  for (int i = 1; i <= n; ++i) {
    tr[i] = tr[i - 1];
    while (A[i] != 1) {
      int q = 1, a = p[A[i]];
      while (p[A[i]] == a) {
        A[i] /= p[A[i]];
        q *= a;
      }
      tr[i] = upd(1, n, i, q, tr[i]);
      while (que[a].back().h <= q) {
        auto [h, v, idx] = que[a].back();
        tr[i] = upd(1, n, idx, inv[v], tr[i]);
        que[a].pop_back();
      }
      if (SZ(que[a]) > 1) {
        auto [h, v, idx] = que[a].back();
        tr[i] = upd(1, n, idx, 1ll * h / q * inv[v] % mod, tr[i]);
        que[a].back().v = h / q;
      }
      que[a].emplace_back(q, q, i);
    }
  }
  int m, lst = 0;
  cin >> m;
  while (m--) {
    int l, r;
    cin >> l >> r;
    l = (lst + l) % n + 1;
    r = (lst + r) % n + 1;
    if (l > r) swap(l, r);
    //cout << l << " " << r << '\n';
    lst = query(tr[r], 1, n, l, r);
    cout << lst << '\n';
  }
  return 0;
}
//06.10.2020 17:04:06 CST


#include <bits/stdc++.h>
using namespace std;
#define SZ(a) ((int)(a).size())
typedef long long int64;

const int mod = 1e9 + 7;
const int maxm = 100000 * 50;
int tr[100000 + 9];
int L[maxm], R[maxm], V[maxm], tot;
int build(int l, int r) {
  int res = ++tot;
  V[res] = 1;
  if (l == r) {
    return res;
  }
  int mid = (l + r) >> 1;
  L[res] = build(l, mid);
  R[res] = build(mid + 1, r);
  return res;
}
int upd(int l, int r, int p, int v, int rt) {
  int res = ++tot;
  L[res] = L[rt];
  R[res] = R[rt];
  V[res] = V[rt];
  if (l == r) {
    V[res] = 1ll * V[res] * v % mod;
    return res;
  }
  int mid = (l + r) >> 1;
  if (p <= mid)
    L[res] = upd(l, mid, p, v, L[rt]);
  else
    R[res] = upd(mid + 1, r, p, v, R[rt]);
  V[res] = 1ll * V[L[res]] * V[R[res]] % mod;
  return res;
}
int query(int rt, int l, int r, int ll, int rr) {
  if (ll <= l && rr >= r) {
    return V[rt];
  }
  int mid = (l + r) >> 1, res = 1;
  if (ll <= mid) res = 1ll * res * query(L[rt], l, mid, ll, rr) % mod;
  if (rr > mid) res = 1ll * res * query(R[rt], mid + 1, r, ll, rr) % mod;
  return res;
}
int main() {
#ifdef LOCAL
  freopen(".a.in", "r", stdin);
#endif
  ios_base::sync_with_stdio(false);
  cout.tie(0);
  cin.tie(0);
  int n;
  cin >> n;
  vector<int> A(n + 1);
  for (int i = 1; i <= n; ++i) cin >> A[i];
  int Max=*max_element(A.begin(),A.end())+5;
  vector<int> p(Max);
  for (int i = 2; i < Max; ++i)
    if (!p[i]) {
      p[i] = i;
      for (int64 j = 1ll * i * i; j < Max; j += i)
        if (p[j] == 0) p[j] = i;
    }
  tr[0] = build(1, n);
  struct Z {
    int h, v, idx;
    Z(int a = 0, int b = 0, int c = 0) : h(a), v(b), idx(c) {}
  };
  vector<vector<Z>> que(Max, vector<Z>(1, Z(1e9, 1, 0)));
  vector<int> inv(Max);
  inv[1] = 1;
  for (int i = 2; i < Max; ++i) inv[i] = 1ll * (mod - (mod / i)) * inv[mod % i] % mod;
  for (int i = 1; i <= n; ++i) {
    tr[i] = tr[i - 1];
    while (A[i] != 1) {
      int q = 1, a = p[A[i]];
      while (p[A[i]] == a) {
        A[i] /= p[A[i]];
        q *= a;
      }
      tr[i] = upd(1, n, i, q, tr[i]);
      while (que[a].back().h <= q) {
        auto [h, v, idx] = que[a].back();
        tr[i] = upd(1, n, idx, inv[v], tr[i]);
        que[a].pop_back();
      }
      if (SZ(que[a]) > 1) {
        auto [h, v, idx] = que[a].back();
        tr[i] = upd(1, n, idx, 1ll * h / q * inv[v] % mod, tr[i]);
        que[a].back().v = h / q;
      }
      que[a].emplace_back(q, q, i);
    }
  }
  int m, lst = 0;
  cin >> m;
  while (m--) {
    int l, r;
    cin >> l >> r;
    l = (lst + l) % n + 1;
    r = (lst + r) % n + 1;
    if (l > r) swap(l, r);
    //cout << l << " " << r << '\n';
    lst = query(tr[r], 1, n, l, r);
    cout << lst << '\n';
  }
  return 0;
}
//06.10.2020 17:04:06 CST


#include <bits/stdc++.h>
using namespace std;
#define SZ(a) ((int)(a).size())
typedef long long int64;

const int maxn = 200000 + 9;
const int mod = 1e9 + 7;
int tr[100000 + 9];
int L[maxn << 6], R[maxn << 6], V[maxn << 6], tot;
int build(int l, int r) {
  int res = ++tot;
  V[res] = 1;
  if (l == r) {
    return res;
  }
  int mid = (l + r) >> 1;
  L[res] = build(l, mid);
  R[res] = build(mid + 1, r);
  return res;
}
int upd(int l, int r, int p, int v, int rt) {
  int res = ++tot;
  L[res] = L[rt];
  R[res] = R[rt];
  V[res] = V[rt];
  if (l == r) {
    V[res] = 1ll * V[res] * v % mod;
    return res;
  }
  int mid = (l + r) >> 1;
  if (p <= mid)
    L[res] = upd(l, mid, p, v, L[rt]);
  else
    R[res] = upd(mid + 1, r, p, v, R[rt]);
  V[res] = 1ll * V[L[res]] * V[R[res]] % mod;
  return res;
}
int query(int rt, int l, int r, int ll, int rr) {
  if (ll <= l && rr >= r) {
    return V[rt];
  }
  int mid = (l + r) >> 1, res = 1;
  if (ll <= mid) res = 1ll * res * query(L[rt], l, mid, ll, rr) % mod;
  if (rr > mid) res = 1ll * res * query(R[rt], mid + 1, r, ll, rr) % mod;
  return res;
}
int main() {
#ifdef LOCAL
  freopen(".a.in", "r", stdin);
#endif
  ios_base::sync_with_stdio(false);
  cout.tie(0);
  cin.tie(0);
  int n;
  cin >> n;
  vector<int> A(n + 1);
  for (int i = 1; i <= n; ++i) cin >> A[i];
  vector<int> p(maxn);
  for (int i = 2; i < maxn; ++i)
    if (!p[i]) {
      p[i] = i;
      for (int64 j = 1ll * i * i; j < maxn; j += i)
        if (p[j] == 0) p[j] = i;
    }
  tr[0] = build(1, n);
  struct Z {
    int h, v, idx;
    Z(int a = 0, int b = 0, int c = 0) : h(a), v(b), idx(c) {}
  };
  vector<vector<Z>> que(maxn, vector<Z>(1, Z(1e9, 1, 0)));
  vector<int> inv(maxn);
  inv[1] = 1;
  for (int i = 2; i < maxn; ++i) inv[i] = 1ll * (mod - (mod / i)) * inv[mod % i] % mod;
  for (int i = 1; i <= n; ++i) {
    tr[i] = tr[i - 1];
    while (A[i] != 1) {
      int q = 1, a = p[A[i]];
      while (p[A[i]] == a) {
        A[i] /= p[A[i]];
        q *= a;
      }
      tr[i] = upd(1, n, i, q, tr[i]);
      while (que[a].back().h <= q) {
        auto [h, v, idx] = que[a].back();
        tr[i] = upd(1, n, idx, inv[v], tr[i]);
        que[a].pop_back();
      }
      if (SZ(que[a]) > 1) {
        auto [h, v, idx] = que[a].back();
        tr[i] = upd(1, n, idx, 1ll * h / q * inv[v] % mod, tr[i]);
        que[a].back().v = h / q;
      }
      que[a].emplace_back(q, q, i);
    }
  }
  int m, lst = 0;
  cin >> m;
  while (m--) {
    int l, r;
    cin >> l >> r;
    l = (lst + l) % n + 1;
    r = (lst + r) % n + 1;
    if (l > r) swap(l, r);
    //cout << l << " " << r << '\n';
    lst = query(tr[r], 1, n, l, r);
    cout << lst << '\n';
  }
  return 0;
}
//06.10.2020 17:04:06 CST


#include <bits/stdc++.h>
using namespace std;
#define SZ(a) ((int)(a).size())
typedef long long int64;

const int mod = 1e9 + 7;
const int maxm = 100000 * 32;
int tr[100000 + 9];
int L[maxm], R[maxm], V[maxm], tot;
int build(int l, int r) {
  int res = ++tot;
  V[res] = 1;
  if (l == r) {
    return res;
  }
  int mid = (l + r) >> 1;
  L[res] = build(l, mid);
  R[res] = build(mid + 1, r);
  return res;
}
int upd(int l, int r, int p, int v, int rt) {
  int res = ++tot;
  L[res] = L[rt];
  R[res] = R[rt];
  V[res] = V[rt];
  if (l == r) {
    V[res] = 1ll * V[res] * v % mod;
    return res;
  }
  int mid = (l + r) >> 1;
  if (p <= mid)
    L[res] = upd(l, mid, p, v, L[rt]);
  else
    R[res] = upd(mid + 1, r, p, v, R[rt]);
  V[res] = 1ll * V[L[res]] * V[R[res]] % mod;
  return res;
}
int query(int rt, int l, int r, int ll, int rr) {
  if (ll <= l && rr >= r) {
    return V[rt];
  }
  int mid = (l + r) >> 1, res = 1;
  if (ll <= mid) res = 1ll * res * query(L[rt], l, mid, ll, rr) % mod;
  if (rr > mid) res = 1ll * res * query(R[rt], mid + 1, r, ll, rr) % mod;
  return res;
}
int main() {
#ifdef LOCAL
  freopen(".a.in", "r", stdin);
#endif
  ios_base::sync_with_stdio(false);
  cout.tie(0);
  cin.tie(0);
  int n;
  cin >> n;
  vector<int> A(n + 1);
  for (int i = 1; i <= n; ++i) cin >> A[i];
  int Max=*max_element(A.begin(),A.end())+5;
  vector<int> p(Max);
  for (int i = 2; i < Max; ++i)
    if (!p[i]) {
      p[i] = i;
      for (int64 j = 1ll * i * i; j < Max; j += i)
        if (p[j] == 0) p[j] = i;
    }
  tr[0] = build(1, n);
  struct Z {
    int h, v, idx;
    Z(int a = 0, int b = 0, int c = 0) : h(a), v(b), idx(c) {}
  };
  vector<vector<Z>> que(Max, vector<Z>(1, Z(1e9, 1, 0)));
  vector<int> inv(Max);
  inv[1] = 1;
  for (int i = 2; i < Max; ++i) inv[i] = 1ll * (mod - (mod / i)) * inv[mod % i] % mod;
  for (int i = 1; i <= n; ++i) {
    tr[i] = tr[i - 1];
    while (A[i] != 1) {
      int q = 1, a = p[A[i]];
      while (p[A[i]] == a) {
        A[i] /= p[A[i]];
        q *= a;
      }
      tr[i] = upd(1, n, i, q, tr[i]);
      while (que[a].back().h <= q) {
        auto [h, v, idx] = que[a].back();
        tr[i] = upd(1, n, idx, inv[v], tr[i]);
        que[a].pop_back();
      }
      if (SZ(que[a]) > 1) {
        auto [h, v, idx] = que[a].back();
        tr[i] = upd(1, n, idx, 1ll * h / q * inv[v] % mod, tr[i]);
        que[a].back().v = h / q;
      }
      que[a].emplace_back(q, q, i);
    }
  }
  int m, lst = 0;
  cin >> m;
  while (m--) {
    int l, r;
    cin >> l >> r;
    l = (lst + l) % n + 1;
    r = (lst + r) % n + 1;
    if (l > r) swap(l, r);
    //cout << l << " " << r << '\n';
    lst = query(tr[r], 1, n, l, r);
    cout << lst << '\n';
  }
  return 0;
}
//06.10.2020 17:04:06 CST


#include <bits/stdc++.h>
using namespace std;
#define SZ(a) ((int)(a).size())
typedef long long int64;

const int maxn = 200000 + 9;
const int mod = 1e9 + 7;
const int maxm = maxn<<7;
int tr[100000 + 9];
int L[maxm], R[maxm], V[maxm], tot;
int build(int l, int r) {
  int res = ++tot;
  V[res] = 1;
  if (l == r) {
    return res;
  }
  int mid = (l + r) >> 1;
  L[res] = build(l, mid);
  R[res] = build(mid + 1, r);
  return res;
}
int upd(int l, int r, int p, int v, int rt) {
  int res = ++tot;
  L[res] = L[rt];
  R[res] = R[rt];
  V[res] = V[rt];
  if (l == r) {
    V[res] = 1ll * V[res] * v % mod;
    return res;
  }
  int mid = (l + r) >> 1;
  if (p <= mid)
    L[res] = upd(l, mid, p, v, L[rt]);
  else
    R[res] = upd(mid + 1, r, p, v, R[rt]);
  V[res] = 1ll * V[L[res]] * V[R[res]] % mod;
  return res;
}
int query(int rt, int l, int r, int ll, int rr) {
  if (ll <= l && rr >= r) {
    return V[rt];
  }
  int mid = (l + r) >> 1, res = 1;
  if (ll <= mid) res = 1ll * res * query(L[rt], l, mid, ll, rr) % mod;
  if (rr > mid) res = 1ll * res * query(R[rt], mid + 1, r, ll, rr) % mod;
  return res;
}
int main() {
#ifdef LOCAL
  freopen(".a.in", "r", stdin);
#endif
  ios_base::sync_with_stdio(false);
  cout.tie(0);
  cin.tie(0);
  int n;
  cin >> n;
  vector<int> A(n + 1);
  for (int i = 1; i <= n; ++i) cin >> A[i];
  vector<int> p(maxn);
  for (int i = 2; i < maxn; ++i)
    if (!p[i]) {
      p[i] = i;
      for (int64 j = 1ll * i * i; j < maxn; j += i)
        if (p[j] == 0) p[j] = i;
    }
  tr[0] = build(1, n);
  struct Z {
    int h, v, idx;
    Z(int a = 0, int b = 0, int c = 0) : h(a), v(b), idx(c) {}
  };
  vector<vector<Z>> que(maxn, vector<Z>(1, Z(1e9, 1, 0)));
  vector<int> inv(maxn);
  inv[1] = 1;
  for (int i = 2; i < maxn; ++i) inv[i] = 1ll * (mod - (mod / i)) * inv[mod % i] % mod;
  for (int i = 1; i <= n; ++i) {
    tr[i] = tr[i - 1];
    while (A[i] != 1) {
      int q = 1, a = p[A[i]];
      while (p[A[i]] == a) {
        A[i] /= p[A[i]];
        q *= a;
      }
      tr[i] = upd(1, n, i, q, tr[i]);
      while (que[a].back().h <= q) {
        auto [h, v, idx] = que[a].back();
        tr[i] = upd(1, n, idx, inv[v], tr[i]);
        que[a].pop_back();
      }
      if (SZ(que[a]) > 1) {
        auto [h, v, idx] = que[a].back();
        tr[i] = upd(1, n, idx, 1ll * h / q * inv[v] % mod, tr[i]);
        que[a].back().v = h / q;
      }
      que[a].emplace_back(q, q, i);
    }
  }
  int m, lst = 0;
  cin >> m;
  while (m--) {
    int l, r;
    cin >> l >> r;
    l = (lst + l) % n + 1;
    r = (lst + r) % n + 1;
    if (l > r) swap(l, r);
    //cout << l << " " << r << '\n';
    lst = query(tr[r], 1, n, l, r);
    cout << lst << '\n';
  }
  return 0;
}
//06.10.2020 17:04:06 CST


#include<bits/stdc++.h>

void wssert(bool b) {
	if (!b) {
		std::cout << "GARBAGE" << '\n';
		exit(0);
	}
}
/** Binary-indexed tree
 *
 *  A binary indexed tree with N nodes of type T implicitly provides the
 *  following two functions for 0 <= i <= N:
 *
 *      prefix(int i) -> list<T&>
 *      suffix(int i) -> list<T&>
 *
 *  such that size(suffix(i) intersect prefix(j)) = (1 if i < j else 0).
 *  Furthermore, the resulting lists always have size at most log_2(N).
 *
 *  This can be used to implement either point-update/(prefix|suffix)-query or
 *  (prefix|suffix)-update/point-query over a virtual array of size N of a
 *  commutative monoid. This can be generalized to implement
 *  point-update/range-query or range-update/point-query over a virtual array
 *  of size N of a commutative group.
 *
 *  With 0-indexed data, prefixes are more natural:
 *   * For range update/query, use for_prefix for the ranges and for_suffix for the points.
 *   * For prefix update/query, no change.
 *   * For suffix update/query, use for_prefix(point + 1); 1-index the data.
 */
template <typename T> struct binary_indexed_tree {
private:
public:
	std::vector<T> dat;
	binary_indexed_tree() {}
	explicit binary_indexed_tree(size_t N) : dat(N) {}
	binary_indexed_tree(size_t N, const T& t) : dat(N, t) {}

	template <typename F> void for_prefix(int i, F f) const {
		wssert(0 <= i && i <= int(dat.size()));
		for (int a = i; a; a &= a-1) {
			f(dat[a-1]);
		}
	}

	template <typename F> void for_prefix(int i, F f) {
		wssert(0 <= i && i <= int(dat.size()));
		for (int a = i; a; a &= a-1) {
			f(dat[a-1]);
		}
	}

	template <typename F> void for_suffix(int i, F f) const {
		wssert(0 <= i && i <= int(dat.size()));
		for (int a = i; a < int(dat.size()); a |= a+1) {
			f(dat[a]);
		}
	}

	template <typename F> void for_suffix(int i, F f) {
		wssert(0 <= i && i <= int(dat.size()));
		for (int a = i; a < int(dat.size()); a |= a+1) {
			f(dat[a]);
		}
	}
};

template <int MOD_> struct modnum {
	static constexpr int MOD = MOD_;
	static_wssert(MOD_ > 0, "MOD must be positive");

private:
	using ll = long long;

	int v;

	static int minv(int a, int m) {
		a %= m;
		wssert(a);
		return a == 1 ? 1 : int(m - ll(minv(m, a)) * ll(m) / a);
	}

public:

	modnum() : v(0) {}
	modnum(ll v_) : v(int(v_ % MOD)) { if (v < 0) v += MOD; }
	explicit operator int() const { return v; }
	friend std::ostream& operator << (std::ostream& out, const modnum& n) { return out << int(n); }
	friend std::istream& operator >> (std::istream& in, modnum& n) { ll v_; in >> v_; n = modnum(v_); return in; }

	friend bool operator == (const modnum& a, const modnum& b) { return a.v == b.v; }
	friend bool operator != (const modnum& a, const modnum& b) { return a.v != b.v; }

	modnum inv() const {
		modnum res;
		res.v = minv(v, MOD);
		return res;
	}
	friend modnum inv(const modnum& m) { return m.inv(); }
	modnum neg() const {
		modnum res;
		res.v = v ? MOD-v : 0;
		return res;
	}
	friend modnum neg(const modnum& m) { return m.neg(); }

	modnum operator- () const {
		return neg();
	}
	modnum operator+ () const {
		return modnum(*this);
	}

	modnum& operator ++ () {
		v ++;
		if (v == MOD) v = 0;
		return *this;
	}
	modnum& operator -- () {
		if (v == 0) v = MOD;
		v --;
		return *this;
	}
	modnum& operator += (const modnum& o) {
		v -= MOD-o.v;
		v = (v < 0) ? v + MOD : v;
		return *this;
	}
	modnum& operator -= (const modnum& o) {
		v -= o.v;
		v = (v < 0) ? v + MOD : v;
		return *this;
	}
	modnum& operator *= (const modnum& o) {
		v = int(ll(v) * ll(o.v) % MOD);
		return *this;
	}
	modnum& operator /= (const modnum& o) {
		return *this *= o.inv();
	}

	friend modnum operator ++ (modnum& a, int) { modnum r = a; ++a; return r; }
	friend modnum operator -- (modnum& a, int) { modnum r = a; --a; return r; }
	friend modnum operator + (const modnum& a, const modnum& b) { return modnum(a) += b; }
	friend modnum operator - (const modnum& a, const modnum& b) { return modnum(a) -= b; }
	friend modnum operator * (const modnum& a, const modnum& b) { return modnum(a) *= b; }
	friend modnum operator / (const modnum& a, const modnum& b) { return modnum(a) /= b; }
};

int main() {
	using namespace std;
	ios_base::sync_with_stdio(false), cin.tie(nullptr);

	int N; cin >> N;
	vector<int> A(N); for (auto& a : A) cin >> a;

	const int V = int(2e5);
	wssert(*max_element(A.begin(), A.end()) <= V);

	vector<int> primes; primes.reserve(V);
	vector<int> pfac(V+1);
	for (int i = 2; i <= V; i++) {
		if (!pfac[i]) { pfac[i] = i; primes.push_back(i); }
		for (int p : primes) {
			if (p > V/i) break;
			pfac[p*i] = p;
			if (p == pfac[i]) break;
		}
	}

	using num = modnum<int(1e9)+7>;
	binary_indexed_tree<vector<pair<int, num>>> bit(N);

	vector<int> last_seen(V+1, -1);

	for (int i = 0; i < N; i++) {
		int a = A[i];
		while (a > 1) {
			int p = pfac[a];
			int e = 0, q = 1;

			num invP = inv(num(p));

			while (a % p == 0) {
				a /= p;
				e++, q *= p;

				bit.for_suffix(i, [&](auto& v) {
					v.push_back({last_seen[q], invP});
					v.push_back({i, num(p)});
				});
				last_seen[q] = i;
			}
		}
	}
	auto cmp = [](const pair<int, num>& a, const pair<int, num>& b) { return a.first < b.first; };

	for (auto& v : bit.dat) {
		sort(v.begin(), v.end(), cmp);
		for (int i = int(v.size())-1; i; i--) {
			v[i-1].second *= v[i].second;
		}
	}

	auto query = [&](int l, int r) -> num {
		wssert(0 <= l && l < r && r <= N);

		num ans = 1;
		bit.for_prefix(r, [&](const auto& v) {
			auto it = lower_bound(v.begin(), v.end(), pair<int, num>{l, num(0)}, cmp);
			if (it != v.end()) ans *= it->second;
		});
		return ans;
	};

	int Q; cin >> Q;
	int last = 0;
	while (Q--) {
		int x, y; cin >> x >> y;
		int l = (last + x) % N + 1;
		int r = (last + y) % N + 1;
		if (l > r) swap(l, r);
		// half-open interval
		l--;
		num ans = query(l, r);
		cout << (last = int(ans)) << '\n';
	}

	return 0;
}


#define DEBUG 0

#include <algorithm>
#include <functional>
#include <numeric>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <complex>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <cassert>
#include <string>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <sstream>
using namespace std;

#define LL long long
#define LD long double
#define PR pair<int,int>

#define Fox(i,n) for (i=0; i<n; i++)
#define Fox1(i,n) for (i=1; i<=n; i++)
#define FoxI(i,a,b) for (i=a; i<=b; i++)
#define FoxR(i,n) for (i=(n)-1; i>=0; i--)
#define FoxR1(i,n) for (i=n; i>0; i--)
#define FoxRI(i,a,b) for (i=b; i>=a; i--)
#define Foxen(i,s) for (i=s.begin(); i!=s.end(); i++)
#define Min(a,b) a=min(a,b)
#define Max(a,b) a=max(a,b)
#define Sz(s) int((s).size())
#define All(s) (s).begin(),(s).end()
#define Fill(s,v) memset(s,v,sizeof(s))
#define pb push_back
#define mp make_pair
#define x first
#define y second

template<typename T> T Abs(T x) { return(x<0 ? -x : x); }
template<typename T> T Sqr(T x) { return(x*x); }
string plural(string s) { return(Sz(s) && s[Sz(s)-1]=='x' ? s+"en" : s+"s"); }

const int INF = (int)1e9;
const LD EPS = 1e-12;
const LD PI = acos(-1.0);

//#if DEBUG
#define GETCHAR getchar
/*#else
#define GETCHAR getchar_unlocked
#endif*/

bool Read(int &x)
{
	char c,r=0,n=0;
	x=0;
		for(;;)
		{
			c=GETCHAR();
				if ((c<0) && (!r))
					return(0);
				if ((c=='-') && (!r))
					n=1;
				else
				if ((c>='0') && (c<='9'))
					x=x*10+c-'0',r=1;
				else
				if (r)
					break;
		}
		if (n)
			x=-x;
	return(1);
}

bool ReadLL(LL &x)
{
	char c,r=0,n=0;
	x=0;
		for(;;)
		{
			c=GETCHAR();
				if ((c<0) && (!r))
					return(0);
				if ((c=='-') && (!r))
					n=1;
				else
				if ((c>='0') && (c<='9'))
					x=x*10+c-'0',r=1;
				else
				if (r)
					break;
		}
		if (n)
			x=-x;
	return(1);
}

#define MOD 1000000007
#define LIM 5000

struct St {
	int i,f,e[4];
};

int A[2001],B[2001];
int dyn[2001][9][10][10][10][10];
queue<St> Q;

void Go(St s,int d)
{
	if (dyn[s.i][s.f][s.e[0]][s.e[1]][s.e[2]][s.e[3]]<0)
	{
		Q.push(s);
		dyn[s.i][s.f][s.e[0]][s.e[1]][s.e[2]][s.e[3]]=d;
	}
}

int main()
{
		if (DEBUG)
			freopen("in.txt","r",stdin);
	int N,M,K;
	int i,j,k,c,x,y,z;
	St s,s2;
	Read(N);
	Fill(dyn,-1);
	s.i=s.f=0;
	Fill(s.e,0);
	Go(s,0);
		Fox(i,N)
			Read(A[i]),Read(B[i]);
		while (!Q.empty())
		{
			s=Q.front(),Q.pop();
			int d=dyn[s.i][s.f][s.e[0]][s.e[1]][s.e[2]][s.e[3]];
			//printf("%d %d: %d %d %d %d %d\n",d,s.i,s.f,s.e[0],s.e[1],s.e[2],s.e[3]);
			//done?
				if (s.e[0]+s.e[1]+s.e[2]+s.e[3]==0 && s.i==N)
				{
					printf("%d\n",d);
					return(0);
				}
			d++;
			//up
				if (s.f+1<9)
				{
					s2=s;
					s2.f++;
					Go(s2,d);
				}
			//down
				if (s.f-1>=0)
				{
					s2=s;
					s2.f--;
					Go(s2,d);
				}
			//drop off
				Fox(k,4)
					if (s.f==s.e[k]-1)
					{
						s2=s;
						s2.e[k]=0;
						Go(s2,d);
					}
			//get next guy
				if (s.i<N && s.f==A[s.i]-1)
					Fox(k,4)
						if (!s.e[k])
						{
							s2=s;
							s2.e[k]=B[s.i];
							s2.i++;
							Go(s2,d);
							break;
						}
		}
	return(0);
}


#define DEBUG 0

#include <unordered_map>
#include <algorithm>
#include <functional>
#include <numeric>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <complex>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <cassert>
#include <string>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <sstream>
using namespace std;

#define LL long long
#define LD long double
#define PR pair<int,int>

#define Fox(i,n) for (i=0; i<n; i++)
#define Fox1(i,n) for (i=1; i<=n; i++)
#define FoxI(i,a,b) for (i=a; i<=b; i++)
#define FoxR(i,n) for (i=(n)-1; i>=0; i--)
#define FoxR1(i,n) for (i=n; i>0; i--)
#define FoxRI(i,a,b) for (i=b; i>=a; i--)
#define Foxen(i,s) for (i=s.begin(); i!=s.end(); i++)
#define Min(a,b) a=min(a,b)
#define Max(a,b) a=max(a,b)
#define Sz(s) int((s).size())
#define All(s) (s).begin(),(s).end()
#define Fill(s,v) memset(s,v,sizeof(s))
#define pb push_back
#define mp make_pair
#define x first
#define y second

template<typename T> T Abs(T x) { return(x<0 ? -x : x); }
template<typename T> T Sqr(T x) { return(x*x); }
string plural(string s) { return(Sz(s) && s[Sz(s)-1]=='x' ? s+"en" : s+"s"); }

const int INF = (int)1e9;
const LD EPS = 1e-12;
const LD PI = acos(-1.0);

//#if DEBUG
#define GETCHAR getchar
/*#else
#define GETCHAR getchar_unlocked
#endif*/

bool Read(int &x)
{
	char c,r=0,n=0;
	x=0;
		for(;;)
		{
			c=GETCHAR();
				if ((c<0) && (!r))
					return(0);
				if ((c=='-') && (!r))
					n=1;
				else
				if ((c>='0') && (c<='9'))
					x=x*10+c-'0',r=1;
				else
				if (r)
					break;
		}
		if (n)
			x=-x;
	return(1);
}

bool ReadLL(LL &x)
{
	char c,r=0,n=0;
	x=0;
		for(;;)
		{
			c=GETCHAR();
				if ((c<0) && (!r))
					return(0);
				if ((c=='-') && (!r))
					n=1;
				else
				if ((c>='0') && (c<='9'))
					x=x*10+c-'0',r=1;
				else
				if (r)
					break;
		}
		if (n)
			x=-x;
	return(1);
}

#define MOD 1000000007
#define LIM 5000

struct St {
	int i,f,e[4],d;
};

int A[2001],B[2001];
unordered_map<int,int> M;
//map<int,int> M;
queue<int> Q;

void Go(St s)
{
	int k;
	int h=s.i;
	h*=10;
	h+=s.f;
	sort(s.e,s.e+4);
		Fox(k,4)
		{
			h*=10;
			h+=s.e[k];
		}
		if (!M.count(h))
		{
			Q.push(h);
			M[h]=s.d;
		}
}

St Get(int h)
{
	int k;
	St s;
	s.d=M[h];
		FoxR(k,4)
		{
			s.e[k]=h%10;
			h/=10;
		}
	s.f=h%10;
	h/=10;
	s.i=h;
	return(s);
}

int main()
{
		if (DEBUG)
			freopen("in.txt","r",stdin);
	int N,K;
	int i,j,k,c,x,y,z;
	int h;
	St s,s2;
	Read(N);
//N=2000;
	s.i=s.f=s.d=0;
	Fill(s.e,0);
	Go(s);
		Fox(i,N)
			Read(A[i]),Read(B[i]);
//A[i]=rand()%9+1,B[i]=rand()%9+1;
		while (!Q.empty())
		{
			h=Q.front(),Q.pop();
			s=Get(h);
			//printf("%d %d: %d %d %d %d %d\n",s.d,s.i,s.f,s.e[0],s.e[1],s.e[2],s.e[3]);
			//done?
				if (s.e[0]+s.e[1]+s.e[2]+s.e[3]==0 && s.i==N)
				{
					printf("%d\n",s.d);
					return(0);
				}
			s.d++;
			//drop off
				Fox(k,4)
					if (s.f==s.e[k]-1)
					{
						s2=s;
						s2.e[k]=0;
						Go(s2);
goto Done;
					}
			//get next guy
				if (s.i<N && s.f==A[s.i]-1)
					FoxR(k,4)
						if (!s.e[k])
						{
							s2=s;
							s2.e[k]=B[s.i];
							s2.i++;
							Go(s2);
goto Done;
						}
int mn=INF,mx=-INF;
if (s.i<N)
{
Min(mn,A[s.i]-1);
Max(mx,A[s.i]-1);
}
Fox(k,4)
if (s.e[k])
{
Min(mn,s.e[k]-1);
Max(mx,s.e[k]-1);
}
			//up
				if (s.f+1<=mx)
				{
					s2=s;
					s2.f++;
					Go(s2);
				}
			//down
				if (s.f-1>=mn)
				{
					s2=s;
					s2.f--;
					Go(s2);
				}
Done:;
		}
	return(0);
}


#define DEBUG 0

#include <unordered_map>
#include <algorithm>
#include <functional>
#include <numeric>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <complex>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <cassert>
#include <string>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <sstream>
using namespace std;

#define LL long long
#define LD long double
#define PR pair<int,int>

#define Fox(i,n) for (i=0; i<n; i++)
#define Fox1(i,n) for (i=1; i<=n; i++)
#define FoxI(i,a,b) for (i=a; i<=b; i++)
#define FoxR(i,n) for (i=(n)-1; i>=0; i--)
#define FoxR1(i,n) for (i=n; i>0; i--)
#define FoxRI(i,a,b) for (i=b; i>=a; i--)
#define Foxen(i,s) for (i=s.begin(); i!=s.end(); i++)
#define Min(a,b) a=min(a,b)
#define Max(a,b) a=max(a,b)
#define Sz(s) int((s).size())
#define All(s) (s).begin(),(s).end()
#define Fill(s,v) memset(s,v,sizeof(s))
#define pb push_back
#define mp make_pair
#define x first
#define y second

template<typename T> T Abs(T x) { return(x<0 ? -x : x); }
template<typename T> T Sqr(T x) { return(x*x); }
string plural(string s) { return(Sz(s) && s[Sz(s)-1]=='x' ? s+"en" : s+"s"); }

const int INF = (int)1e9;
const LD EPS = 1e-12;
const LD PI = acos(-1.0);

//#if DEBUG
#define GETCHAR getchar
/*#else
#define GETCHAR getchar_unlocked
#endif*/

bool Read(int &x)
{
	char c,r=0,n=0;
	x=0;
		for(;;)
		{
			c=GETCHAR();
				if ((c<0) && (!r))
					return(0);
				if ((c=='-') && (!r))
					n=1;
				else
				if ((c>='0') && (c<='9'))
					x=x*10+c-'0',r=1;
				else
				if (r)
					break;
		}
		if (n)
			x=-x;
	return(1);
}

bool ReadLL(LL &x)
{
	char c,r=0,n=0;
	x=0;
		for(;;)
		{
			c=GETCHAR();
				if ((c<0) && (!r))
					return(0);
				if ((c=='-') && (!r))
					n=1;
				else
				if ((c>='0') && (c<='9'))
					x=x*10+c-'0',r=1;
				else
				if (r)
					break;
		}
		if (n)
			x=-x;
	return(1);
}

#define MOD 1000000007
#define LIM 5000

struct St {
	int i,f,e[4],d;
};

int A[2001],B[2001];
unordered_map<LL,int> M;
//map<int,int> M;
queue<int> Q;

void Go(St s)
{
	int k;
	int h=s.i;
	h*=10;
	h+=s.f;
	sort(s.e,s.e+4);
		Fox(k,4)
		{
			h*=10;
			h+=s.e[k];
		}
		if (!M.count(h))
		{
			Q.push(h);
			M[h]=s.d;
		}
}

St Get(int h)
{
	int k;
	St s;
	s.d=M[h];
		FoxR(k,4)
		{
			s.e[k]=h%10;
			h/=10;
		}
	s.f=h%10;
	h/=10;
	s.i=h;
	return(s);
}

int main()
{
		if (DEBUG)
			freopen("in.txt","r",stdin);
	int N,K;
	int i,j,k,c,x,y,z;
	int h;
	St s,s2;
	Read(N);
	s.i=s.f=s.d=0;
	Fill(s.e,0);
	Go(s);
		Fox(i,N)
			Read(A[i]),Read(B[i]);
		while (!Q.empty())
		{
			h=Q.front(),Q.pop();
			s=Get(h);
			//printf("%d %d: %d %d %d %d %d\n",s.d,s.i,s.f,s.e[0],s.e[1],s.e[2],s.e[3]);
			//done?
				if (s.e[0]+s.e[1]+s.e[2]+s.e[3]==0 && s.i==N)
				{
					printf("%d\n",s.d);
					return(0);
				}
			s.d++;
			//up
				if (s.f+1<9)
				{
					s2=s;
					s2.f++;
					Go(s2);
				}
			//down
				if (s.f-1>=0)
				{
					s2=s;
					s2.f--;
					Go(s2);
				}
			//drop off
				Fox(k,4)
					if (s.f==s.e[k]-1)
					{
						s2=s;
						s2.e[k]=0;
						Go(s2);
					}
			//get next guy
				if (s.i<N && s.f==A[s.i]-1)
					FoxR(k,4)
						if (!s.e[k])
						{
							s2=s;
							s2.e[k]=B[s.i];
							s2.i++;
							Go(s2);
							break;
						}
		}
	return(0);
}


#define DEBUG 0

#include <unordered_set>
#include <unordered_map>
#include <algorithm>
#include <functional>
#include <numeric>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <complex>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <cassert>
#include <string>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <sstream>
using namespace std;

#define LL long long
#define LD long double
#define PR pair<int,int>

#define Fox(i,n) for (i=0; i<n; i++)
#define Fox1(i,n) for (i=1; i<=n; i++)
#define FoxI(i,a,b) for (i=a; i<=b; i++)
#define FoxR(i,n) for (i=(n)-1; i>=0; i--)
#define FoxR1(i,n) for (i=n; i>0; i--)
#define FoxRI(i,a,b) for (i=b; i>=a; i--)
#define Foxen(i,s) for (i=s.begin(); i!=s.end(); i++)
#define Min(a,b) a=min(a,b)
#define Max(a,b) a=max(a,b)
#define Sz(s) int((s).size())
#define All(s) (s).begin(),(s).end()
#define Fill(s,v) memset(s,v,sizeof(s))
#define pb push_back
#define mp make_pair
#define x first
#define y second

template<typename T> T Abs(T x) { return(x<0 ? -x : x); }
template<typename T> T Sqr(T x) { return(x*x); }
string plural(string s) { return(Sz(s) && s[Sz(s)-1]=='x' ? s+"en" : s+"s"); }

const int INF = (int)1e9;
const LD EPS = 1e-12;
const LD PI = acos(-1.0);

//#if DEBUG
#define GETCHAR getchar
/*#else
#define GETCHAR getchar_unlocked
#endif*/

bool Read(int &x)
{
	char c,r=0,n=0;
	x=0;
		for(;;)
		{
			c=GETCHAR();
				if ((c<0) && (!r))
					return(0);
				if ((c=='-') && (!r))
					n=1;
				else
				if ((c>='0') && (c<='9'))
					x=x*10+c-'0',r=1;
				else
				if (r)
					break;
		}
		if (n)
			x=-x;
	return(1);
}

bool ReadLL(LL &x)
{
	char c,r=0,n=0;
	x=0;
		for(;;)
		{
			c=GETCHAR();
				if ((c<0) && (!r))
					return(0);
				if ((c=='-') && (!r))
					n=1;
				else
				if ((c>='0') && (c<='9'))
					x=x*10+c-'0',r=1;
				else
				if (r)
					break;
		}
		if (n)
			x=-x;
	return(1);
}

#define MOD 1000000007
#define LIM 5000

struct St {
	int i,f,e[4],d;
};

int A[2001],B[2001];
unordered_set<LL> S;
unordered_map<LL,int> M;
/*set<LL> S;
map<LL,int> M;*/
queue<LL> Q;

void Go(St s)
{
	int k;
	LL h=s.i;
	h*=10;
	h+=s.f;
	sort(s.e,s.e+4);
		Fox(k,4)
		{
			h*=10;
			h+=s.e[k];
		}
		if (!S.count(h))
		{
			S.insert(h);
			Q.push(h);
			M[h]=s.d;
		}
}

St Get(LL h)
{
	int k;
	St s;
	s.d=M[h];
		FoxR(k,4)
		{
			s.e[k]=h%10;
			h/=10;
		}
	s.f=h%10;
	h/=10;
	s.i=h;
	return(s);
}

int main()
{
		if (DEBUG)
			freopen("in.txt","r",stdin);
	int N,K;
	int i,j,k,c,x,y,z;
	LL h;
	St s,s2;
	Read(N);
	s.i=s.f=s.d=0;
	Fill(s.e,0);
	Go(s);
		Fox(i,N)
			Read(A[i]),Read(B[i]);
		while (!Q.empty())
		{
			h=Q.front(),Q.pop();
			s=Get(h);
			//printf("%d %d: %d %d %d %d %d\n",s.d,s.i,s.f,s.e[0],s.e[1],s.e[2],s.e[3]);
			//done?
				if (s.e[0]+s.e[1]+s.e[2]+s.e[3]==0 && s.i==N)
				{
					printf("%d\n",s.d);
					return(0);
				}
			s.d++;
			//up
				if (s.f+1<9)
				{
					s2=s;
					s2.f++;
					Go(s2);
				}
			//down
				if (s.f-1>=0)
				{
					s2=s;
					s2.f--;
					Go(s2);
				}
			//drop off
				Fox(k,4)
					if (s.f==s.e[k]-1)
					{
						s2=s;
						s2.e[k]=0;
						Go(s2);
					}
			//get next guy
				if (s.i<N && s.f==A[s.i]-1)
					FoxR(k,4)
						if (!s.e[k])
						{
							s2=s;
							s2.e[k]=B[s.i];
							s2.i++;
							Go(s2);
							break;
						}
		}
	return(0);
}


#define DEBUG 0

#include <unordered_set>
#include <unordered_map>
#include <algorithm>
#include <functional>
#include <numeric>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <complex>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <cassert>
#include <string>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <sstream>
using namespace std;

#define LL long long
#define LD long double
#define PR pair<int,int>

#define Fox(i,n) for (i=0; i<n; i++)
#define Fox1(i,n) for (i=1; i<=n; i++)
#define FoxI(i,a,b) for (i=a; i<=b; i++)
#define FoxR(i,n) for (i=(n)-1; i>=0; i--)
#define FoxR1(i,n) for (i=n; i>0; i--)
#define FoxRI(i,a,b) for (i=b; i>=a; i--)
#define Foxen(i,s) for (i=s.begin(); i!=s.end(); i++)
#define Min(a,b) a=min(a,b)
#define Max(a,b) a=max(a,b)
#define Sz(s) int((s).size())
#define All(s) (s).begin(),(s).end()
#define Fill(s,v) memset(s,v,sizeof(s))
#define pb push_back
#define mp make_pair
#define x first
#define y second

template<typename T> T Abs(T x) { return(x<0 ? -x : x); }
template<typename T> T Sqr(T x) { return(x*x); }
string plural(string s) { return(Sz(s) && s[Sz(s)-1]=='x' ? s+"en" : s+"s"); }

const int INF = (int)1e9;
const LD EPS = 1e-12;
const LD PI = acos(-1.0);

//#if DEBUG
#define GETCHAR getchar
/*#else
#define GETCHAR getchar_unlocked
#endif*/

bool Read(int &x)
{
	char c,r=0,n=0;
	x=0;
		for(;;)
		{
			c=GETCHAR();
				if ((c<0) && (!r))
					return(0);
				if ((c=='-') && (!r))
					n=1;
				else
				if ((c>='0') && (c<='9'))
					x=x*10+c-'0',r=1;
				else
				if (r)
					break;
		}
		if (n)
			x=-x;
	return(1);
}

bool ReadLL(LL &x)
{
	char c,r=0,n=0;
	x=0;
		for(;;)
		{
			c=GETCHAR();
				if ((c<0) && (!r))
					return(0);
				if ((c=='-') && (!r))
					n=1;
				else
				if ((c>='0') && (c<='9'))
					x=x*10+c-'0',r=1;
				else
				if (r)
					break;
		}
		if (n)
			x=-x;
	return(1);
}

#define MOD 1000000007
#define LIM 5000

struct St {
	int i,f,e[4],d;
};

int A[2001],B[2001];
unordered_set<LL> S;
//set<LL> S;
unordered_map<LL,int> M;
//map<LL,int> M;
queue<LL> Q;

void Go(St s)
{
	int k;
	LL h=s.i;
	h*=10;
	h+=s.f;
		Fox(k,4)
		{
			h*=10;
			h+=s.e[k];
		}
		if (!S.count(h))
		{
			S.insert(h);
			Q.push(h);
			M[h]=s.d;
		}
}

St Get(LL h)
{
	int k;
	St s;
	s.d=M[h];
		FoxR(k,4)
		{
			s.e[k]=h%10;
			h/=10;
		}
	s.f=h%10;
	h/=10;
	s.i=h;
	return(s);
}

int main()
{
		if (DEBUG)
			freopen("in.txt","r",stdin);
	int N,K;
	int i,j,k,c,x,y,z;
	LL h;
	St s,s2;
	Read(N);
	s.i=s.f=s.d=0;
	Fill(s.e,0);
	Go(s);
		Fox(i,N)
			Read(A[i]),Read(B[i]);
		while (!Q.empty())
		{
			h=Q.front(),Q.pop();
			s=Get(h);
			//printf("%d %d: %d %d %d %d %d\n",s.d,s.i,s.f,s.e[0],s.e[1],s.e[2],s.e[3]);
			//done?
				if (s.e[0]+s.e[1]+s.e[2]+s.e[3]==0 && s.i==N)
				{
					printf("%d\n",s.d);
					return(0);
				}
			s.d++;
			//up
				if (s.f+1<9)
				{
					s2=s;
					s2.f++;
					Go(s2);
				}
			//down
				if (s.f-1>=0)
				{
					s2=s;
					s2.f--;
					Go(s2);
				}
			//drop off
				Fox(k,4)
					if (s.f==s.e[k]-1)
					{
						s2=s;
						s2.e[k]=0;
						Go(s2);
					}
			//get next guy
				if (s.i<N && s.f==A[s.i]-1)
					Fox(k,4)
						if (!s.e[k])
						{
							s2=s;
							s2.e[k]=B[s.i];
							s2.i++;
							Go(s2);
							break;
						}
		}
	return(0);
}


#define DEBUG 0

#include <unordered_set>
#include <algorithm>
#include <functional>
#include <numeric>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <complex>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <cassert>
#include <string>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <sstream>
using namespace std;

#define LL long long
#define LD long double
#define PR pair<int,int>

#define Fox(i,n) for (i=0; i<n; i++)
#define Fox1(i,n) for (i=1; i<=n; i++)
#define FoxI(i,a,b) for (i=a; i<=b; i++)
#define FoxR(i,n) for (i=(n)-1; i>=0; i--)
#define FoxR1(i,n) for (i=n; i>0; i--)
#define FoxRI(i,a,b) for (i=b; i>=a; i--)
#define Foxen(i,s) for (i=s.begin(); i!=s.end(); i++)
#define Min(a,b) a=min(a,b)
#define Max(a,b) a=max(a,b)
#define Sz(s) int((s).size())
#define All(s) (s).begin(),(s).end()
#define Fill(s,v) memset(s,v,sizeof(s))
#define pb push_back
#define mp make_pair
#define x first
#define y second

template<typename T> T Abs(T x) { return(x<0 ? -x : x); }
template<typename T> T Sqr(T x) { return(x*x); }
string plural(string s) { return(Sz(s) && s[Sz(s)-1]=='x' ? s+"en" : s+"s"); }

const int INF = (int)1e9;
const LD EPS = 1e-12;
const LD PI = acos(-1.0);

//#if DEBUG
#define GETCHAR getchar
/*#else
#define GETCHAR getchar_unlocked
#endif*/

bool Read(int &x)
{
	char c,r=0,n=0;
	x=0;
		for(;;)
		{
			c=GETCHAR();
				if ((c<0) && (!r))
					return(0);
				if ((c=='-') && (!r))
					n=1;
				else
				if ((c>='0') && (c<='9'))
					x=x*10+c-'0',r=1;
				else
				if (r)
					break;
		}
		if (n)
			x=-x;
	return(1);
}

bool ReadLL(LL &x)
{
	char c,r=0,n=0;
	x=0;
		for(;;)
		{
			c=GETCHAR();
				if ((c<0) && (!r))
					return(0);
				if ((c=='-') && (!r))
					n=1;
				else
				if ((c>='0') && (c<='9'))
					x=x*10+c-'0',r=1;
				else
				if (r)
					break;
		}
		if (n)
			x=-x;
	return(1);
}

#define MOD 1000000007
#define LIM 5000

struct St {
	int i,f,e[4],d;
};

int A[2001],B[2001];
unordered_set<LL> S;
queue<St> Q;

void Go(St s)
{
	int k;
	LL h=s.i;
	h*=2001;
	h+=s.f;
		Fox(k,4)
		{
			h*=10;
			h+=s.e[k];
		}
		if (!S.count(h))
		{
			S.insert(h);
			Q.push(s);
		}
}

int main()
{
		if (DEBUG)
			freopen("in.txt","r",stdin);
	int N,M,K;
	int i,j,k,c,x,y,z;
	St s,s2;
	Read(N);
	s.i=s.f=s.d=0;
	Fill(s.e,0);
	Go(s);
		Fox(i,N)
			Read(A[i]),Read(B[i]);
		while (!Q.empty())
		{
			s=Q.front(),Q.pop();
			//printf("%d %d: %d %d %d %d %d\n",s.d,s.i,s.f,s.e[0],s.e[1],s.e[2],s.e[3]);
			//done?
				if (s.e[0]+s.e[1]+s.e[2]+s.e[3]==0 && s.i==N)
				{
					printf("%d\n",s.d);
					return(0);
				}
			s.d++;
			//up
				if (s.f+1<9)
				{
					s2=s;
					s2.f++;
					Go(s2);
				}
			//down
				if (s.f-1>=0)
				{
					s2=s;
					s2.f--;
					Go(s2);
				}
			//drop off
				Fox(k,4)
					if (s.f==s.e[k]-1)
					{
						s2=s;
						s2.e[k]=0;
						Go(s2);
					}
			//get next guy
				if (s.i<N && s.f==A[s.i]-1)
					Fox(k,4)
						if (!s.e[k])
						{
							s2=s;
							s2.e[k]=B[s.i];
							s2.i++;
							Go(s2);
							break;
						}
		}
	return(0);
}


#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<string>
#include<sstream>
#include<deque>
#include<math.h>
#include<cstring>
#include <bitset>
#include<algorithm>
#include<stdio.h>
#include<stdlib.h>

#define all(v) v.begin(),v.end()
#define mpair make_pair

using namespace std;
typedef long double ld;
const ld epsilon = 1e-9;
typedef long long ll;

int vis[9 * 1024 * 2048];
int combinations[1024][4];
void deduceCombinations() {
	int idx = 0;
	for (int i = 0; i < 10; i++) {
		for (int j = 0; j < 10; j++) {
			for (int k = 0; k < 10; k++) {
				for (int l = 0; l < 10; l++) {
					if (i <= j && j <= k && k <= l) {
						combinations[idx][0] = i;
						combinations[idx][1] = j;
						combinations[idx][2] = k;
						combinations[idx][3] = l;
						idx++;
					}
				}
			}
		}

	}
}
int cmb[4];
int greaterEqual(int idx) {
	for (int i = 0; i < 4; i++) {
		if (cmb[i] > combinations[idx][i]) return true;
		if (cmb[i] < combinations[idx][i]) return false;
	}
	return true;
}
int encodeCmb() {
	sort(cmb, cmb + 4);
	int beg = 0;
	int end = 714;
	int mid;
	while (beg + 1 < end) {
		mid = (beg + end) / 2;
		if (greaterEqual(mid)) {
			beg = mid;
		} else {
			end = mid;
		}
	}
	if (greaterEqual(end)) return end;
	return beg;
}

int mask1 = (1 << 11) - 1;
int mask2 = ((1 << 10) - 1) << 11;
int mask3 = 15 << 21;
struct state {
	int floor;
	int mask;
	int idx;
	int encode() {
		return idx | (mask << 11) | (floor << 21);
	}
	void decode(int num) {
		idx = (num & mask1);
		mask = (num & mask2) >> 11;
		floor = (num & mask3) >> 21;
	}

};
int main()
{
	deduceCombinations();
	//freopen("bobi.in", "r", stdin);
	int n;
	cin >> n;
	vector<pair<int, int> > v(n);
	for (int i = 0; i < n; i++) {
		cin >> v[i].first >> v[i].second;
		v[i].first--;
		v[i].second--;
	}

	memset(vis, -1, sizeof(vis));
	state cur;
	cur.floor = 0;
	cur.mask = 0;
	cur.idx = 0;
	int curVal = cur.encode();
	vis[curVal] = 0;

	deque<int> toProcess;
	int tmp;
	toProcess.push_back(curVal);
	state cur2;
	int num, numFloor;
	bool changed;
	int cmbIdx = 0;
	int flr;
	while (!toProcess.empty()) {
		curVal = toProcess.front();
		toProcess.pop_front();
		cur.decode(curVal);
		cur2 = cur;
		num = 0;
		numFloor = 0;
		flr = cur.floor + 1;
		for (int i = 0; i < 4; i++) {
			num += (combinations[cur.mask][i] != 0);
			if (combinations[cur.mask][i] == flr) {
				numFloor++;
			}
		}
		if (numFloor > 0 || num < 4) {
			num -= numFloor;
			changed = (numFloor != 0);
			memset(cmb, 0, sizeof(cmb));
			cmbIdx = 0;
			for (int i = 0; i < 4; i++) {
				if (combinations[cur.mask][i] != 0 && combinations[cur.mask][i] != flr) {
					cmb[cmbIdx++] = combinations[cur.mask][i];
				}
			}
			while(cur.idx < n && v[cur.idx].first == cur.floor && num < 4) {
				cmb[cmbIdx++] = v[cur.idx].second + 1;
				cur.idx++;
				num++;
				changed = true;

			}
			if (changed) {
				cur.mask = encodeCmb();
				tmp = cur.encode();
				if (vis[tmp] == -1) {
					vis[tmp] = vis[curVal];
					toProcess.push_front(tmp);
				}
			}
		}
		cur = cur2;
		if(cur.floor != 0) {
			cur.floor--;
			tmp = cur.encode();
			if (vis[tmp] == -1) {
				vis[tmp] = vis[curVal] + 1;
				toProcess.push_back(tmp);
			}
			cur.floor++;
		}
		if(cur.floor != 8) {
			cur.floor++;
			tmp = cur.encode();
			if (vis[tmp] == -1) {
				vis[tmp] = vis[curVal] + 1;
				toProcess.push_back(tmp);
			}
			cur.floor--;
		}
	}
	int minm = 1 << 30;
	for (int i = 0; i < 9; i++) {
		tmp = i << 21 | n;
		if (vis[tmp] != -1 && minm > vis[tmp]) {
			minm = vis[tmp];
		}

	}
	cout << minm + 2 * n << endl;
	return 0;
}


# python3
from copy import copy
from itertools import chain
from bisect import bisect_left as lower_bound, bisect_right as upper_bound, \
                   insort

def readline(): return map(int, input().split())

def readlines(count): return (readline() for __ in range(count))

class Slots(object):
    def __init__(self, **kwargs):
        for (key, value) in kwargs.items():
            setattr(self, key, value)

    def __iter__(self):
        for slot in self.__slots__:
            yield slot, copy(getattr(self, slot))

    def __eq__(self, other):
        return all(getattr(self, slot) == getattr(other, slot)
                   for slot in self.__slots__)

    def __repr__(self):
        return f"{self.__class__.__name__}(" \
               + ", ".join(f"{k}={v}" for (k, v) in self) + ")"

    def copy(self):
        return self.__class__(**dict(self))

class Position(Slots):
    __slots__ = 'floor payload time'.split()

    def is_not_full(self):
        return len(self.payload) < 4

    def take(self, b):
        insort(self.payload, b)
        return self

    def free(self, x, y):
        lo = lower_bound(self.payload, min(x, y))
        up = upper_bound(self.payload, max(x, y))
        del self.payload[lo:up]
        return self

    def hook(self, pivot, finish):
        self.time += abs(self.floor - pivot) + abs(pivot - finish)
        self.floor = finish
        self.free(*sorted([pivot, finish]))
        return self

    def possibilities_to_take_next(self, a, b):
        pivots = self.payload[upper_bound(self.payload, self.floor):] \
                 if a <= self.floor else \
                 self.payload[:lower_bound(self.payload, self.floor)]
        pivots.append(self.floor)

        for pivot in pivots:
            possibility = self.copy().hook(pivot, a)
            if possibility.is_not_full():
                yield possibility.take(b)

    def get_free(self):
        if self.payload:
            lo, up = self.payload[0], self.payload[-1]
            if self.floor <= (lo + up) // 2:
                self.hook(lo, up)
            else:
                self.hook(up, lo)
            assert not self.payload
        return self

assert Position(floor=2, payload=[1, 2, 3, 3, 4, 5, 5, 6, 7], time=3)\
       .free(3, 5) == Position(floor=2, payload=[1, 2, 6, 7], time=3)

assert Position(floor=4, payload=[1, 2, 3, 3, 4, 5, 5, 6, 7], time=3)\
       .hook(2, 6) == Position(floor=6, payload=[1, 7], time=9)

assert Position(floor=4, payload=[1, 5], time=0)\
       .take(9) == Position(floor=4, payload=[1, 5, 9], time=0)

assert list(Position(floor=4, payload=[1, 2, 5], time=0)
            .possibilities_to_take_next(2, 9))\
       == [Position(floor=2, payload=[1, 9], time=4),
           Position(floor=2, payload=[1, 5, 9], time=2)]

assert list(Position(floor=4, payload=[1, 2, 5], time=0)
            .possibilities_to_take_next(5, 1)) \
       == [Position(floor=5, payload=[1], time=7),
           Position(floor=5, payload=[1, 1], time=5),
           Position(floor=5, payload=[1, 1, 2], time=1)]

def main():
    n, = readline()

    positions = [Position(floor=1, payload=list(), time=0)]
    for (a, b) in readlines(n):
        positions = list(chain.from_iterable(p.possibilities_to_take_next(a, b)
                                             for p in positions))

    return min(pos.get_free().time for pos in positions) + 2 * n

print(main())


# python3
import sys
from collections import namedtuple

def readline(): return map(int, input().split())

def readlines():
    for line in sys.stdin.readlines():
        yield map(int, line.split())

class State(namedtuple('State', 'payload time floor')):
    def hook(self, pivot, a, b):
        lo, up = min(pivot, a, self.floor), max(pivot, a, self.floor)
        return tuple(x for x in self.payload if x < lo or up < x) + (b,), \
            self.time + abs(self.floor - pivot) + abs(pivot - a)

    def choices_to_take_next(self, a, b):
        floor = self.floor

        payload, time = self.hook(floor, a, b)
        if len(payload) < 5:
            yield payload, time
            if floor > a:
                pivots = (x for x in self.payload if x > floor)
            elif floor == a:
                pivots = ()
            else:
                pivots = (x for x in self.payload if x < floor)
        else:
            pivots = self.payload

        for pivot in pivots:
            yield self.hook(pivot, a, b)

def time_to_get_free(payload, floor):
    if payload:
        lo, up = min(payload), max(payload)
        return abs(lo-up) + min(abs(floor-lo), abs(floor-up))
    else:
        return 0

def main():
    n, = readline()

    floor = 1
    positions = {(): 0}  # empty elevator, time = 0
    for (a, b) in readlines():
        max_acceptable_time = min(positions.values()) + 16 - abs(floor - a)

        new_positions = dict()
        for payload, time in positions.items():
            state = State(payload, time, floor)
            for npayload, ntime in state.choices_to_take_next(a, b):
                if ntime <= max_acceptable_time:
                    npayload = tuple(sorted(npayload))
                    if new_positions.setdefault(npayload, ntime) > ntime:
                        new_positions[npayload] = ntime

        positions = new_positions
        floor = a

    return min(t + time_to_get_free(p, floor) for p, t in positions.items()) \
        + 2 * n

print(main())


# python3
import sys
from itertools import chain
from collections import namedtuple

def readline(): return map(int, input().split())

def readlines():
    for line in sys.stdin.readlines():
        yield map(int, line.split())

class Position(namedtuple('Position', 'payload time')):
    # def __eq__(self, other):
    #     return self.time == other.time \
    #            and sorted(self.payload) == sorted(other.payload)

    def is_not_full(self):
        return len(self.payload) < 4

    def take(self, b):
        self.payload.append(b)
        return self

    def free(self, x, y):
        x, y = sorted((x, y))
        return [s for s in self.payload if not x <= s <= y]

    def hook(self, start, pivot, finish):
        time = self.time + abs(start - pivot) + abs(pivot - finish)
        return Position(self.free(pivot, finish), time)

    def possibilities_to_take_next(self, floor, a, b):
        pivots = [x for x in self.payload if x > floor] \
                 if a <= floor else \
                 [x for x in self.payload if x < floor]
        pivots.append(floor)

        for pivot in pivots:
            possibility = self.hook(floor, pivot, a)
            if possibility.is_not_full():
                yield possibility.take(b)

    def get_free(self, floor):
        if self.payload:
            lo, up = min(self.payload), max(self.payload)
            if floor <= (lo + up) // 2:
                return self.hook(floor, lo, up)
            else:
                return self.hook(floor, up, lo)

# assert sorted(Position(payload=[1, 2, 3, 3, 4, 5, 5, 6, 7], time=3)
#               .free(3, 5)) == [1, 2, 6, 7]

# assert Position(payload=[1, 2, 3, 3, 4, 5, 5, 6, 7], time=3)\
#        .hook(4, 2, 6) == Position(payload=[1, 7], time=9)

# assert Position(payload=[1, 5], time=0)\
#        .take(9) == Position(payload=[1, 5, 9], time=0)

# assert list(Position(payload=[1, 2, 5], time=0)
#             .possibilities_to_take_next(4, 2, 9))\
#        == [Position(payload=[1, 9], time=4),
#            Position(payload=[1, 5, 9], time=2)]

# assert list(Position(payload=[1, 2, 5], time=0)
#             .possibilities_to_take_next(4, 5, 1)) \
#        == [Position(payload=[1], time=7),
#            Position(payload=[1, 1], time=5),
#            Position(payload=[1, 1, 2], time=1)]

def main():
    n, = readline()

    floor = 1
    positions = [Position(payload=[], time=0)]
    for (a, b) in readlines():
        positions = list(chain.from_iterable(
            p.possibilities_to_take_next(floor, a, b) for p in positions
        ))
        min_t = min(pos.time for pos in positions)
        positions = (pos for pos in positions if pos.time <= min_t + a + 7)
        floor = a

    return min(pos.get_free(floor).time for pos in positions) + 2 * n

print(main())


# python3
import sys
from itertools import chain
from bisect import bisect_left as lower_bound, bisect_right as upper_bound, \
                   insort

def readline(): return map(int, input().split())

def readlines():
    for line in sys.stdin.readlines():
        yield map(int, line.split())

class Position(object):
    __slots__ = 'floor payload time'.split()

    def __init__(self, floor, payload, time):
        self.floor = floor
        self.payload = payload
        self.time = time

    def copy(self):
        return self.__class__(self.floor, list(self.payload), self.time)

    def is_not_full(self):
        return len(self.payload) < 4

    def take(self, b):
        insort(self.payload, b)
        return self

    def free(self, x, y):
        lo = lower_bound(self.payload, min(x, y))
        up = upper_bound(self.payload, max(x, y))
        del self.payload[lo:up]
        return self

    def hook(self, pivot, finish):
        self.time += abs(self.floor - pivot) + abs(pivot - finish)
        self.floor = finish
        self.free(*sorted([pivot, finish]))
        return self

    def possibilities_to_take_next(self, a, b):
        pivots = self.payload[upper_bound(self.payload, self.floor):] \
                 if a <= self.floor else \
                 self.payload[:lower_bound(self.payload, self.floor)]
        pivots.append(self.floor)

        for pivot in pivots:
            possibility = self.copy().hook(pivot, a)
            if possibility.is_not_full():
                yield possibility.take(b)

    def get_free(self):
        if self.payload:
            lo, up = self.payload[0], self.payload[-1]
            if self.floor <= (lo + up) // 2:
                self.hook(lo, up)
            else:
                self.hook(up, lo)
            assert not self.payload
        return self

#assert Position(floor=2, payload=[1, 2, 3, 3, 4, 5, 5, 6, 7], time=3)\
       #.free(3, 5) == Position(floor=2, payload=[1, 2, 6, 7], time=3)

#assert Position(floor=4, payload=[1, 2, 3, 3, 4, 5, 5, 6, 7], time=3)\
       #.hook(2, 6) == Position(floor=6, payload=[1, 7], time=9)

#assert Position(floor=4, payload=[1, 5], time=0)\
       #.take(9) == Position(floor=4, payload=[1, 5, 9], time=0)

#assert list(Position(floor=4, payload=[1, 2, 5], time=0)
            #.possibilities_to_take_next(2, 9))\
       #== [Position(floor=2, payload=[1, 9], time=4),
           #Position(floor=2, payload=[1, 5, 9], time=2)]

#assert list(Position(floor=4, payload=[1, 2, 5], time=0)
            #.possibilities_to_take_next(5, 1)) \
       #== [Position(floor=5, payload=[1], time=7),
           #Position(floor=5, payload=[1, 1], time=5),
           #Position(floor=5, payload=[1, 1, 2], time=1)]

def main():
    n, = readline()

    positions = [Position(floor=1, payload=[], time=0)]
    for (a, b) in readlines():
        positions = list(chain.from_iterable(p.possibilities_to_take_next(a, b)
                                             for p in positions))

    return min(pos.get_free().time for pos in positions) + 2 * n

print(main())


# python3
import sys
from itertools import chain
from bisect import bisect_left as lower_bound, bisect_right as upper_bound, \
                   insort
from collections import namedtuple

def readline(): return map(int, input().split())

def readlines():
    for line in sys.stdin.readlines():
        yield map(int, line.split())

class Position(namedtuple('Position', 'payload time')):
    def is_not_full(self):
        return len(self.payload) < 4

    def take(self, b):
        insort(self.payload, b)
        return self

    def free(self, x, y):
        x, y = sorted((x, y))
        return [s for s in self.payload if not x <= s <= y]

    def hook(self, start, pivot, finish):
        time = self.time + abs(start - pivot) + abs(pivot - finish)
        return Position(self.free(pivot, finish), time)

    def possibilities_to_take_next(self, floor, a, b):
        pivots = self.payload[upper_bound(self.payload, floor):] \
                 if a <= floor else \
                 self.payload[:lower_bound(self.payload, floor)]
        pivots.append(floor)

        for pivot in pivots:
            possibility = self.hook(floor, pivot, a)
            if possibility.is_not_full():
                yield possibility.take(b)

    def get_free(self, floor):
        if self.payload:
            lo, up = self.payload[0], self.payload[-1]
            if floor <= (lo + up) // 2:
                return self.hook(floor, lo, up)
            else:
                return self.hook(floor, up, lo)

assert Position(payload=[1, 2, 3, 3, 4, 5, 5, 6, 7], time=3)\
       .free(3, 5) == [1, 2, 6, 7]

assert Position(payload=[1, 2, 3, 3, 4, 5, 5, 6, 7], time=3)\
       .hook(4, 2, 6) == Position(payload=[1, 7], time=9)

assert Position(payload=[1, 5], time=0)\
       .take(9) == Position(payload=[1, 5, 9], time=0)

assert list(Position(payload=[1, 2, 5], time=0)
            .possibilities_to_take_next(4, 2, 9))\
       == [Position(payload=[1, 9], time=4),
           Position(payload=[1, 5, 9], time=2)]

assert list(Position(payload=[1, 2, 5], time=0)
            .possibilities_to_take_next(4, 5, 1)) \
       == [Position(payload=[1], time=7),
           Position(payload=[1, 1], time=5),
           Position(payload=[1, 1, 2], time=1)]

def main():
    n, = readline()

    floor = 1
    positions = [Position(payload=[], time=0)]
    for (a, b) in readlines():
        positions = list(chain.from_iterable(
            p.possibilities_to_take_next(floor, a, b) for p in positions
        ))
        # min_t = min(pos.time for pos in positions)
        # positions = pos for pos in positions if pos.time <= min_t + a + 7
        floor = a

    return min(pos.get_free(floor).time for pos in positions) + 2 * n

print(main())