%:pragma GCC optimize(3)
%:pragma GCC optimize("Ofast")
%:pragma GCC optimize("inline")
%:pragma GCC optimize("-fgcse")
%:pragma GCC optimize("-fgcse-lm")
%:pragma GCC optimize("-fipa-sra")
%:pragma GCC optimize("-ftree-pre")
%:pragma GCC optimize("-ftree-vrp")
%:pragma GCC optimize("-fpeephole2")
%:pragma GCC optimize("-ffast-math")
%:pragma GCC optimize("-fsched-spec")
%:pragma GCC optimize("unroll-loops")
%:pragma GCC optimize("-falign-jumps")
%:pragma GCC optimize("-falign-loops")
%:pragma GCC optimize("-falign-labels")
%:pragma GCC optimize("-fdevirtualize")
%:pragma GCC optimize("-fcaller-saves")
%:pragma GCC optimize("-fcrossjumping")
%:pragma GCC optimize("-fthread-jumps")
%:pragma GCC optimize("-funroll-loops")
%:pragma GCC optimize("-fwhole-program")
%:pragma GCC optimize("-freorder-blocks")
%:pragma GCC optimize("-fschedule-insns")
%:pragma GCC optimize("inline-functions")
%:pragma GCC optimize("-ftree-tail-merge")
%:pragma GCC optimize("-fschedule-insns2")
%:pragma GCC optimize("-fstrict-aliasing")
%:pragma GCC optimize("-fstrict-overflow")
%:pragma GCC optimize("-falign-functions")
%:pragma GCC optimize("-fcse-skip-blocks")
%:pragma GCC optimize("-fcse-follow-jumps")
%:pragma GCC optimize("-fsched-interblock")
%:pragma GCC optimize("-fpartial-inlining")
%:pragma GCC optimize("no-stack-protector")
%:pragma GCC optimize("-freorder-functions")
%:pragma GCC optimize("-findirect-inlining")
%:pragma GCC optimize("-fhoist-adjacent-loads")
%:pragma GCC optimize("-frerun-cse-after-loop")
%:pragma GCC optimize("inline-small-functions")
%:pragma GCC optimize("-finline-small-functions")
%:pragma GCC optimize("-ftree-switch-conversion")
%:pragma GCC optimize("-foptimize-sibling-calls")
%:pragma GCC optimize("-fexpensive-optimizations")
%:pragma GCC optimize("-funsafe-loop-optimizations")
%:pragma GCC optimize("inline-functions-called-once")
%:pragma GCC optimize("-fdelete-null-pointer-checks")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
typedef pair <int, int> pin;
#ifndef ONLINE_JUDGE
bool MEMORY_ST;
#endif
const int N = 1e5 + 5;
const int M = 600;
const ll P = 998244353LL;
int n, qn, a[N], ln[N], rn[N], bel[N];
struct Node {
queue <int> q;
int cnt[N];
inline void build(int l, int r) {
assert(q.empty());
for (int i = r; i >= l; i--) {
q.push(a[i]);
++cnt[a[i]];
}
}
inline void flatten(int l, int r) {
assert(r - l + 1 == q.size());
for (int p = r; !q.empty(); q.pop(), p--) {
a[p] = q.front();
--cnt[a[p]];
}
}
inline int popBack() {
int res = q.front();
q.pop();
--cnt[res];
return res;
}
inline void pushFront(int v) {
q.push(v);
++cnt[v];
}
} s[M];
namespace Fread {
const int L = 1 << 15;
char buffer[L], *S, *T;
inline char Getchar() {
if(S == T) {
T = (S = buffer) + fread(buffer, 1, L, stdin);
if(S == T) return EOF;
}
return *S++;
}
template <class T>
inline void read(T &X) {
char ch; T op = 1;
for(ch = Getchar(); ch > '9' || ch < '0'; ch = Getchar())
if(ch == '-') op = -1;
for(X = 0; ch >= '0' && ch <= '9'; ch = Getchar())
X = (X << 1) + (X << 3) + ch - '0';
X *= op;
}
} using Fread::read;
inline void modify(int l, int r) {
if (bel[l] == bel[r]) {
int id = bel[l];
s[id].flatten(ln[id], rn[id]);
int t = a[r];
for (int i = r; i > l; i--) a[i] = a[i - 1];
a[l] = t;
s[id].build(ln[id], rn[id]);
} else {
int id1 = bel[l], id2 = bel[r];
s[id1].flatten(ln[id1], rn[id1]);
s[id2].flatten(ln[id2], rn[id2]);
int t = a[r], cur = a[rn[bel[l]]];
for (int i = rn[bel[l]]; i > l; i--) a[i] = a[i - 1];
a[l] = t;
for (int i = bel[l] + 1; i <= bel[r] - 1; i++) {
s[i].pushFront(cur);
cur = s[i].popBack();
}
for (int i = r; i > ln[bel[r]]; i--) a[i] = a[i - 1];
a[ln[bel[r]]] = cur;
s[id1].build(ln[id1], rn[id1]);
s[id2].build(ln[id2], rn[id2]);
}
}
inline int solve(int l, int r, int k) {
int res = 0;
if (bel[l] == bel[r]) {
int id = bel[l];
s[id].flatten(ln[id], rn[id]);
for (int i = l; i <= r; i++)
if (a[i] == k)
++res;
s[id].build(ln[id], rn[id]);
} else {
int id = bel[l];
s[id].flatten(ln[id], rn[id]);
for (int i = l; i <= rn[bel[l]]; i++)
if (a[i] == k)
++res;
s[id].build(ln[id], rn[id]);
for (int i = bel[l] + 1; i <= bel[r] - 1; i++) {
res += s[i].cnt[k];
}
id = bel[r];
s[id].flatten(ln[id], rn[id]);
for (int i = ln[bel[r]]; i <= r; i++)
if (a[i] == k)
++res;
s[id].build(ln[id], rn[id]);
}
return res;
}
#ifndef ONLINE_JUDGE
bool MEMORY_ED;
#endif
int main() {
#ifndef ONLINE_JUDGE
freopen("sample.in", "r", stdin);
freopen("sample.out", "w", stdout);
clock_t st_clock = clock();
#endif
read(n);
for (int i = 1; i <= n; i++) read(a[i]);
int block = sqrt(n);
// fprintf(stderr, "%d\n", block);
block *= 1.5;
// fprintf(stderr, "%d\n", block);
if (block == 0) ++block;
int m = n / block;
for (int i = 1; i <= m; i++) {
ln[i] = rn[i - 1] + 1;
rn[i] = i * block;
}
if (n % block != 0) {
++m;
ln[m] = rn[m - 1] + 1;
rn[m] = n;
}
for (int i = 1; i <= m; i++) {
// printf("%d %d\n", ln[i], rn[i]);
for (int j = ln[i]; j <= rn[i]; j++) bel[j] = i;
s[i].build(ln[i], rn[i]);
}
read(qn);
for (int ans = 0, op, l, r; qn--; ) {
read(op), read(l), read(r);
l = (l + ans - 1) % n + 1;
r = (r + ans - 1) % n + 1;
if (l > r) swap(l, r);
if (op == 1) {
modify(l, r);
} else {
int k;
read(k);
k = (k + ans - 1) % n + 1;
ans = solve(l, r, k);
printf("%d\n", ans);
}
}
#ifndef ONLINE_JUDGE
clock_t ed_clock = clock();
printf("time = %f ms\n", (double)(ed_clock - st_clock) / CLOCKS_PER_SEC * 1000);
printf("memory = %.2f MB\n", (&MEMORY_ED - &MEMORY_ST) / 1024.0 / 1024.0);
#endif
return 0;
}