#include <bits/stdc++.h>   using namespace std;   const int NMax = 100005;   const int sqrNMax = 330;   int N;   int Nb[NMax][sqrNMax + 5];   int A[NMax], B[sqrNMax + 5][2 * sqrNMax + 5], Start[sqrNMax + 5], Block[NMax],       totalB, Size[sqrNMax + 5];   void Read() {     scanf( %d , &N);     for (int i = 1; i <= N; i++) scanf( %d , &A[i]);   }   void buildB() {     int currentBlock = 1, cnt = 0;     Start[1] = 1;     for (int i = 1; i <= N; i++) {       ++cnt;       if (cnt == sqrNMax) {         ++currentBlock;         Start[currentBlock] = i;         cnt = 1;       }       ++Size[currentBlock];       B[currentBlock][cnt] = A[i];       Nb[A[i]][currentBlock]++;       Block[i] = currentBlock;     }     totalB = currentBlock;   }   int findBlock(int pos) {     int sum = 0;     for (int i = 1; i <= totalB; i++) {       if (sum + Size[i] >= pos) {         Start[i] = sum + 1;         return i;       }       sum += Size[i];     }   }   int deleteElem(int block, int pos) {     int p = pos - Start[block] + 1;     int res = B[block][p];     Nb[res][block]--;     for (int j = p; j < Size[block]; j++) swap(B[block][j], B[block][j + 1]);     --Size[block];     return res;   }   void addElem(int block, int pos, int val) {     int p = pos - Start[block] + 1;     Nb[val][block]++;     B[block][++Size[block]] = val;     for (int j = Size[block] - 1; j >= p; j--) swap(B[block][j], B[block][j + 1]);   }   void makeCircularPerm(int left, int right) {     int b = findBlock(right);     int val = deleteElem(b, right);     b = findBlock(left);     addElem(b, left, val);   }   void buildA() {     int cnt = 0;     for (int i = 1; i <= totalB; i++) {       for (int j = 1; j <= Size[i]; j++) A[++cnt] = B[i][j];     }   }   void initialize() {     for (int i = 1; i <= totalB; i++) {       for (int j = 1; j <= Size[i]; j++) Nb[B[i][j]][i] = 0;       Size[i] = 0;       Start[i] = 0;     }   }   inline int decode(int nb, int lastans) { return (nb + lastans - 1) % N + 1; }   int Query(int left, int right, int val) {     int ans = 0, b = findBlock(left), b2 = findBlock(right);     for (int i = b + 1; i < b2; i++) ans += Nb[val][i];     int l = left - Start[b] + 1, r = right - Start[b2] + 1;     if (b == b2) {       for (int j = l; j <= r; j++)         if (B[b][j] == val) ++ans;       return ans;     }     for (int j = l; j <= Size[b]; j++)       if (B[b][j] == val) ans++;     for (int j = 1; j <= r; j++)       if (B[b2][j] == val) ++ans;     return ans;   }   void Solve() {     int Q;     scanf( %d , &Q);     buildB();     int lastans = 0, cntQ = 0;     for (int i = 1; i <= Q; i++) {       int type, l, r, k;       scanf( %d%d%d , &type, &l, &r);       l = decode(l, lastans);       r = decode(r, lastans);       if (l > r) swap(l, r);       if (type == 1) {         ++cntQ;         makeCircularPerm(l, r);         if (cntQ == sqrNMax) {           cntQ = 0;           buildA();           initialize();           buildB();         }       } else {         scanf( %d , &k);         k = decode(k, lastans);         lastans = Query(l, r, k);         printf( %d n , lastans);       }     }   }   int main() {     Read();     Solve();     return 0;   }   