#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5, blockSize = 350;
int n, a[N], cnt[400][N], q, type;
deque<int> dq[400];
void Shift(int L, int R) {
  int blockL = L / blockSize, blockR = R / blockSize;
  int posR = R % blockSize, posL = L % blockSize;
  deque<int>::iterator it;
  it = (dq[blockR].begin() + posR);
  int val = *it;
  dq[blockR].erase(it);
  cnt[blockR][val]--;
  it = (dq[blockL].begin() + posL);
  dq[blockL].insert(it, val);
  cnt[blockL][val]++;
  int curBlock = blockL;
  while (curBlock < blockR) {
    int Back = dq[curBlock].back();
    dq[curBlock + 1].push_front(Back);
    ++cnt[curBlock + 1][Back];
    dq[curBlock].pop_back();
    --cnt[curBlock][Back];
    ++curBlock;
  }
}
int Solve(int L, int R, int K) {
  int blockL = L / blockSize, blockR = R / blockSize;
  int posR = R % blockSize, posL = L % blockSize, res = 0;
  for (int i = blockL + 1; i <= blockR - 1; ++i) res += cnt[i][K];
  if (blockL != blockR) {
    for (auto it = (dq[blockL].begin() + posL); it != dq[blockL].end(); ++it)
      res += ((*it) == K);
    for (auto it = dq[blockR].begin(); it != (dq[blockR].begin() + posR + 1);
         ++it)
      res += ((*it) == K);
  } else
    for (auto it = (dq[blockL].begin() + posL);
         it != (dq[blockR].begin() + posR + 1); ++it)
      res += ((*it) == K);
  return res;
}
int main() {
  int lastans = 0, li, ri, ki, k, l, r;
  cin >> n;
  for (int i = 0; i < n; ++i) {
    cin >> a[i];
    ++cnt[i / blockSize][a[i]];
    dq[i / blockSize].push_back(a[i]);
  }
  cin >> q;
  while (q--) {
    cin >> type >> li >> ri;
    l = (li + lastans - 1) % n;
    r = (ri + lastans - 1) % n;
    if (l > r) swap(l, r);
    if (type == 1)
      Shift(l, r);
    else {
      cin >> ki;
      k = (ki + lastans - 1) % n + 1;
      lastans = Solve(l, r, k);
      cout << lastans << '\n';
    }
  }
}
