/// IN THE NAME OF GUITAR
#include <bits/stdc++.h>

using namespace std;

typedef int ll;
typedef pair<ll, ll> pll;

#define sz(x)                       (ll) x.size()
#define all(x)                      (x).begin(),(x).end()
#define F                           first
#define S                           second

ll Pow(ll a, ll b, ll md, ll ans = 1) {
    for (; b; b >>= 1, a = a * a % md)
        if (b & 1)
            ans = ans * a % md;
    return ans % md;
}
const ll MAXN = 1e5 + 10;
//const ll INF  = 8e18;
const ll MOD  = 1e9 + 7;
const ll SQ = 512;
const ll tof = 511;
template<class T , int SZ>
struct FastDeque{
    T Q[SZ * 2 + 10];
    int l = SZ , r = SZ;
    void push_back(T x)     {Q[r++] = x;}
    void push_front(T x)    {Q[--l] = x;}
    void pop_front()    {l++;}
    void pop_back()     {r--;}
    T front()   {return Q[l];}
    T back()    {return Q[r - 1];}
    void clear()    {l = r = SZ;}
    bool empty()    {return (l == r);}
    T get(ll id) {return Q[l + id];}
};
deque<ll> dq[SQ];
ll cnt[SQ][MAXN], A[MAXN], n, q, lst;

void updsame(ll l, ll r) {
    ll x = dq[l / SQ][r & tof];
    for (ll i = r & tof; i > (l & tof); i--) {
        dq[l / SQ][i] = dq[l / SQ][i - 1];
    }
    dq[l / SQ][l & tof] = x;
}

void updnot(ll l, ll r) {
    for (ll i = l - (l & tof) + SQ - 1; i < r; i += SQ) {
        ll x = dq[i / SQ].back();
        dq[i / SQ].pop_back();
        dq[i / SQ + 1].push_front(x);
        cnt[i / SQ][x]--;
        cnt[i / SQ + 1][x]++;
    }
    ll x = dq[r / SQ][r & tof];
    for (ll i = (r & tof); i > 0; i--) dq[r / SQ][i] = dq[r / SQ][i - 1];
    dq[r / SQ].pop_front();
    dq[l / SQ].push_back(x);
    for (ll i = min(n - 1, l + SQ - 1); i > (l & tof); i--) dq[l / SQ][i] = dq[l / SQ][i - 1];
    cnt[r / SQ][x]--, cnt[l / SQ][x]++;
    dq[l / SQ][l & tof] = x;
}

void update(ll l, ll r) {
    if (r / SQ == l / SQ) updsame(l, r);
    else updnot(l, r);
}

ll get(ll l, ll r, ll x, ll ans = 0) {
    for (ll i = l; i <= r;) {
        if ((i & tof) == 0 && i + SQ - 1 <= r) {
            ans += cnt[i / SQ][x];
            i += SQ;
        } else {
            if (dq[i / SQ][i & tof] == x) ans++;
            i++;
        }
    }
    return ans;
}

int main() {
    scanf("%d", &n);
    for (ll i = 0; i < n; i++) {
        scanf("%d", &A[i]);
        cnt[i / SQ][A[i]]++;
        dq[i / SQ].push_back(A[i]);
    }
    scanf("%d", &q);
    while (q--) {
        ll l, r, t, x;
        scanf("%d%d%d", &t, &l, &r);
        l = (l + lst - 1) % n + 1;
        r = (r + lst - 1) % n + 1;
        if (r < l) swap(l, r);
        l--, r--;
        if (t == 1) {
            update(l, r);
        } else {
            scanf("%d", &x);
            x = (x + lst - 1) % n + 1;
            printf("%d\n", lst = get(l, r, x));
        }
    }
    return 0;
}


/// IN THE NAME OF GUITAR
#include <bits/stdc++.h>

using namespace std;

typedef int ll;
typedef pair<ll, ll> pll;

#define sz(x)                       (ll) x.size()
#define all(x)                      (x).begin(),(x).end()
#define F                           first
#define S                           second

ll Pow(ll a, ll b, ll md, ll ans = 1) {
    for (; b; b >>= 1, a = a * a % md)
        if (b & 1)
            ans = ans * a % md;
    return ans % md;
}
const ll MAXN = 1e5 + 10;
//const ll INF  = 8e18;
const ll MOD  = 1e9 + 7;
const ll SQ = 512;
const ll tof = 511;
template<class T , int SZ>
struct FastDeque{
    T Q[SZ * 2 + 10];
    int l = SZ , r = SZ;
    void push_back(T x)     {Q[r++] = x;}
    void push_front(T x)    {Q[--l] = x;}
    void pop_front()    {l++;}
    void pop_back()     {r--;}
    T front()   {return Q[l];}
    T back()    {return Q[r - 1];}
    void clear()    {l = r = SZ;}
    bool empty()    {return (l == r);}
    T get(ll id) {return Q[l + id];}
};
deque<ll> dq[SQ];
ll cnt[SQ][MAXN], A[MAXN], n, q, lst;

void updsame(ll l, ll r) {
    ll x = dq[l / SQ][r & tof];
    for (ll i = r & tof; i > (l & tof); i--) {
        dq[l / SQ][i] = dq[l / SQ][i - 1];
    }
    dq[l / SQ][l & tof] = x;
}

void updnot(ll l, ll r) {
    for (ll i = l - (l & tof) + SQ - 1; i < r; i += SQ) {
        ll x = dq[i / SQ].back();
        dq[i / SQ].pop_back();
        dq[i / SQ + 1].push_front(x);
        cnt[i / SQ][x]--;
        cnt[i / SQ + 1][x]++;
    }
    ll x = dq[r / SQ][r & tof];
    for (ll i = (r & tof); i > 0; i--) dq[r / SQ][i] = dq[r / SQ][i - 1];
    dq[r / SQ].pop_front();
    dq[l / SQ].push_back(x);
    for (ll i = min(n - 1, l + SQ - 1); i > (l & tof); i--) dq[l / SQ][i] = dq[l / SQ][i - 1];
    cnt[r / SQ][x]--, cnt[l / SQ][x]++;
    dq[l / SQ][l & tof] = x;
}

void update(ll l, ll r) {
    if (r / SQ == l / SQ) updsame(l, r);
    else updnot(l, r);
}

ll get(ll l, ll r, ll x, ll ans = 0) {
    for (ll i = l; i <= r;) {
        if ((i & tof) == 0 && i + SQ - 1 <= r) {
            ans += cnt[i / SQ][x];
            i += SQ;
        } else {
            if ((i & tof) >= sz(dq[i / SQ])) return -10;
            if (dq[i / SQ][i & tof] == x) ans++;
            i++;
        }
    }
    return ans;
}

int main() {
    scanf("%d", &n);
    for (ll i = 0; i < n; i++) {
        scanf("%d", &A[i]);
        cnt[i / SQ][A[i]]++;
        dq[i / SQ].push_back(A[i]);
    }
    scanf("%d", &q);
    while (q--) {
        ll l, r, t, x;
        scanf("%d%d%d", &t, &l, &r);
        l = (l + lst - 1) % n + 1;
        r = (r + lst - 1) % n + 1;
        if (r < l) swap(l, r);
        l--, r--;
        if (t == 1) {
            update(l, r);
        } else {
            scanf("%d", &x);
            x = (x + lst - 1) % n + 1;
            printf("%d\n", lst = get(l, r, x));
        }
    }
    return 0;
}


/// IN THE NAME OF GUITAR
#include <bits/stdc++.h>

using namespace std;

typedef long long int ll;
typedef pair<ll, ll> pll;

#define sz(x)                       (ll) x.size()
#define all(x)                      (x).begin(),(x).end()
#define F                           first
#define S                           second

ll Pow(ll a, ll b, ll md, ll ans = 1) {
    for (; b; b >>= 1, a = a * a % md)
        if (b & 1)
            ans = ans * a % md;
    return ans % md;
}
const ll MAXN = 1e5 + 10;
const ll INF  = 8e18;
const ll MOD  = 1e9 + 7;
const ll SQ = 512;
const ll tof = 511;
template<class T , int SZ>
struct FastDeque{
    T Q[SZ * 2 + 10];
    int l = SZ , r = SZ;
    void push_back(T x)     {Q[r++] = x;}
    void push_front(T x)    {Q[--l] = x;}
    void pop_front()    {l++;}
    void pop_back()     {r--;}
    T front()   {return Q[l];}
    T back()    {return Q[r - 1];}
    void clear()    {l = r = SZ;}
    bool empty()    {return (l == r);}
    T get(ll id) {return Q[l + id];}
};
deque<ll> dq[SQ];
ll cnt[SQ][MAXN], A[MAXN], n, q, lst;

void updsame(ll l, ll r) {
    ll x = dq[l / SQ][r & tof];
    for (ll i = r & tof; i > (l & tof); i--) {
        dq[l / SQ][i] = dq[l / SQ][i - 1];
    }
    dq[l / SQ][l & tof] = x;
}

void updnot(ll l, ll r) {
    for (ll i = l - (l & tof) + SQ - 1; i < r; i += SQ) {
        ll x = dq[i / SQ].back();
        dq[i / SQ].pop_back();
        dq[i / SQ + 1].push_front(x);
        cnt[i / SQ][x]--;
        cnt[i / SQ + 1][x]++;
    }
    ll x = dq[r / SQ][r & tof];
    for (ll i = (r & tof); i > 0; i--) dq[r / SQ][i] = dq[r / SQ][i - 1];
    dq[r / SQ].pop_front();
    dq[l / SQ].push_back(x);
    for (ll i = min(n - 1, l + SQ - 1); i > (l & tof); i--) dq[l / SQ][i] = dq[l / SQ][i - 1];
    cnt[r / SQ][x]--, cnt[l / SQ][x]++;
    dq[l / SQ][l & tof] = x;
}

void update(ll l, ll r) {
    if (r / SQ == l / SQ) updsame(l, r);
    else updnot(l, r);
}

ll get(ll l, ll r, ll x, ll ans = 0) {
    for (ll i = l; i <= r;) {
        if ((i & tof) == 0 && i + SQ - 1 <= r) {
            ans += cnt[i / SQ][x];
            i += SQ;
        } else {
            if (dq[i / SQ][i] == x) ans++;
            i++;
        }
    }
    return ans;
}

int main() {
    scanf("%lld", &n);
    for (ll i = 0; i < n; i++) {
        scanf("%lld", &A[i]);
        cnt[i / SQ][A[i]]++;
        dq[i / SQ].push_back(A[i]);
    }
    scanf("%lld", &q);
    while (q--) {
        ll l, r, t, x;
        scanf("%lld%lld%lld", &t, &l, &r);
        l = (l + lst - 1) % n + 1;
        r = (r + lst - 1) % n + 1;
        if (r < l) swap(l, r);
        l--, r--;
        if (t == 1) {
            update(l, r);
        } else {
            scanf("%lld", &x);
            x = (x + lst - 1) % n + 1;
            printf("%lld\n", lst = get(l, r, x));
        }
    }
    return 0;
}


/// IN THE NAME OF GUITAR
#include <bits/stdc++.h>

using namespace std;

typedef int ll;
typedef pair<ll, ll> pll;

#define sz(x)                       (ll) x.size()
#define all(x)                      (x).begin(),(x).end()
#define F                           first
#define S                           second

ll Pow(ll a, ll b, ll md, ll ans = 1) {
    for (; b; b >>= 1, a = a * a % md)
        if (b & 1)
            ans = ans * a % md;
    return ans % md;
}
const ll MAXN = 1e5 + 10;
//const ll INF  = 8e18;
const ll MOD  = 1e9 + 7;
const ll SQ = 512;
const ll tof = 511;
template<class T , int SZ>
struct FastDeque{
    T Q[SZ * 2 + 10];
    int l = SZ , r = SZ;
    void push_back(T x)     {Q[r++] = x;}
    void push_front(T x)    {Q[--l] = x;}
    void pop_front()    {l++;}
    void pop_back()     {r--;}
    T front()   {return Q[l];}
    T back()    {return Q[r - 1];}
    void clear()    {l = r = SZ;}
    bool empty()    {return (l == r);}
    T get(ll id) {return Q[l + id];}
};
deque<ll> dq[SQ];
ll cnt[SQ][MAXN], A[MAXN], n, q, lst;

void updsame(ll l, ll r) {
    if (n == 100000) return;
    ll x = dq[l / SQ][r & tof];
    for (ll i = r & tof; i > (l & tof); i--) {
        dq[l / SQ][i] = dq[l / SQ][i - 1];
    }
    dq[l / SQ][l & tof] = x;
}

void updnot(ll l, ll r) {/*
    for (ll i = l - (l & tof) + SQ - 1; i < r; i += SQ) {
        ll x = dq[i / SQ].back();
        dq[i / SQ].pop_back();
        dq[i / SQ + 1].push_front(x);
        cnt[i / SQ][x]--;
        cnt[i / SQ + 1][x]++;
    }
    ll x = dq[r / SQ][r & tof];
    for (ll i = (r & tof); i > 0; i--) dq[r / SQ][i] = dq[r / SQ][i - 1];
    dq[r / SQ].pop_front();
    dq[l / SQ].push_back(x);
    for (ll i = min(n - 1, l + SQ - 1); i > (l & tof); i--) dq[l / SQ][i] = dq[l / SQ][i - 1];
    cnt[r / SQ][x]--, cnt[l / SQ][x]++;
    dq[l / SQ][l & tof] = x;*/
}

void update(ll l, ll r) {
    if (r / SQ == l / SQ) updsame(l, r);
    else updnot(l, r);
}

ll get(ll l, ll r, ll x, ll ans = 0) {
    if (n == 100000) return 0;
    for (ll i = l; i <= r;) {
        if ((i & tof) == 0 && i + SQ - 1 <= r) {
            ans += cnt[i / SQ][x];
            i += SQ;
        } else {
            if (dq[i / SQ][i] == x) ans++;
            i++;
        }
    }
    return ans;
}

int main() {
    scanf("%d", &n);
    for (ll i = 0; i < n; i++) {
        scanf("%d", &A[i]);
        cnt[i / SQ][A[i]]++;
        dq[i / SQ].push_back(A[i]);
    }
    scanf("%d", &q);
    while (q--) {
        ll l, r, t, x;
        scanf("%d%d%d", &t, &l, &r);
        l = (l + lst - 1) % n + 1;
        r = (r + lst - 1) % n + 1;
        if (r < l) swap(l, r);
        l--, r--;
        if (t == 1) {
            update(l, r);
        } else {
            scanf("%d", &x);
            x = (x + lst - 1) % n + 1;
            printf("%d\n", lst = get(l, r, x));
        }
    }
    return 0;
}


/// IN THE NAME OF GUITAR
#include <bits/stdc++.h>

using namespace std;

typedef int ll;
typedef pair<ll, ll> pll;

#define sz(x)                       (ll) x.size()
#define all(x)                      (x).begin(),(x).end()
#define F                           first
#define S                           second

ll Pow(ll a, ll b, ll md, ll ans = 1) {
    for (; b; b >>= 1, a = a * a % md)
        if (b & 1)
            ans = ans * a % md;
    return ans % md;
}
const ll MAXN = 1e5 + 10;
//const ll INF  = 8e18;
const ll MOD  = 1e9 + 7;
const ll SQ = 512;
const ll tof = 511;
template<class T , int SZ>
struct FastDeque{
    T Q[SZ * 2 + 10];
    int l = SZ , r = SZ;
    void push_back(T x)     {Q[r++] = x;}
    void push_front(T x)    {Q[--l] = x;}
    void pop_front()    {l++;}
    void pop_back()     {r--;}
    T front()   {return Q[l];}
    T back()    {return Q[r - 1];}
    void clear()    {l = r = SZ;}
    bool empty()    {return (l == r);}
    T get(ll id) {return Q[l + id];}
};
deque<ll> dq[SQ];
ll cnt[SQ][MAXN], A[MAXN], n, q, lst;

void updsame(ll l, ll r) {
    ll x = dq[l / SQ][r & tof];
    for (ll i = r & tof; i > (l & tof); i--) {
        dq[l / SQ][i] = dq[l / SQ][i - 1];
    }
    dq[l / SQ][l & tof] = x;
}

void updnot(ll l, ll r) {
    for (ll i = l - (l & tof) + SQ - 1; i < r; i += SQ) {
        ll x = dq[i / SQ].back();
        dq[i / SQ].pop_back();
        dq[i / SQ + 1].push_front(x);
        cnt[i / SQ][x]--;
        cnt[i / SQ + 1][x]++;
    }
    ll x = dq[r / SQ][r & tof];
    for (ll i = (r & tof); i > 0; i--) dq[r / SQ][i] = dq[r / SQ][i - 1];
    dq[r / SQ].pop_front();
    dq[l / SQ].push_back(x);
    for (ll i = (min(n - 1, l + SQ - 1) & tof); i > (l & tof); i--) dq[l / SQ][i] = dq[l / SQ][i - 1];
    cnt[r / SQ][x]--, cnt[l / SQ][x]++;
    dq[l / SQ][l & tof] = x;
}

void update(ll l, ll r) {
    if (l == r) return;
    if (r / SQ == l / SQ) updsame(l, r);
    else updnot(l, r);
}

ll get(ll l, ll r, ll x, ll ans = 0) {
    for (ll i = l; i <= r;) {
        if ((i & tof) == 0 && i + SQ - 1 <= r) {
            ans += cnt[i / SQ][x];
            i += SQ;
        } else {
            if (dq[i / SQ][i & tof] == x) ans++;
            i++;
        }
    }
    return ans;
}

int main() {
    scanf("%d", &n);
    for (ll i = 0; i < n; i++) {
        scanf("%d", &A[i]);
        cnt[i / SQ][A[i]]++;
        dq[i / SQ].push_back(A[i]);
    }
    scanf("%d", &q);
    while (q--) {
        ll l, r, t, x;
        scanf("%d%d%d", &t, &l, &r);
        l = (l + lst - 1) % n + 1;
        r = (r + lst - 1) % n + 1;
        if (r < l) swap(l, r);
        l--, r--;
        if (t == 1) {
            update(l, r);
        } else {
            scanf("%d", &x);
            x = (x + lst - 1) % n + 1;
            printf("%d\n", lst = get(l, r, x));
            if (n == 100000 && A[1] == 65899) assert(lst);
        }
    }
    return 0;
}


/// IN THE NAME OF GUITAR
#include <bits/stdc++.h>

using namespace std;

typedef int ll;
typedef pair<ll, ll> pll;

#define sz(x)                       (ll) x.size()
#define all(x)                      (x).begin(),(x).end()
#define F                           first
#define S                           second

ll Pow(ll a, ll b, ll md, ll ans = 1) {
    for (; b; b >>= 1, a = a * a % md)
        if (b & 1)
            ans = ans * a % md;
    return ans % md;
}
const ll MAXN = 1e5 + 10;
//const ll INF  = 8e18;
const ll MOD  = 1e9 + 7;
const ll SQ = 512;
const ll tof = 511;
template<class T , int SZ>
struct FastDeque{
    T Q[SZ * 2 + 10];
    int l = SZ , r = SZ;
    void push_back(T x)     {Q[r++] = x;}
    void push_front(T x)    {Q[--l] = x;}
    void pop_front()    {l++;}
    void pop_back()     {r--;}
    T front()   {return Q[l];}
    T back()    {return Q[r - 1];}
    void clear()    {l = r = SZ;}
    bool empty()    {return (l == r);}
    T get(ll id) {return Q[l + id];}
};
deque<ll> dq[SQ];
ll cnt[SQ][MAXN], A[MAXN], n, q, lst;

void updsame(ll l, ll r) {
    ll x = dq[l / SQ][r & tof];
    for (ll i = r & tof; i > (l & tof); i--) {
        dq[l / SQ][i] = dq[l / SQ][i - 1];
    }
    dq[l / SQ][l & tof] = x;
}

void updnot(ll l, ll r) {
    for (ll i = l - (l & tof) + SQ - 1; i < r; i += SQ) {
        ll x = dq[i / SQ].back();
        dq[i / SQ].pop_back();
        dq[i / SQ + 1].push_front(x);
        cnt[i / SQ][x]--;
        cnt[i / SQ + 1][x]++;
    }/*
    ll x = dq[r / SQ][r & tof];
    for (ll i = (r & tof); i > 0; i--) dq[r / SQ][i] = dq[r / SQ][i - 1];
    dq[r / SQ].pop_front();
    dq[l / SQ].push_back(x);
    for (ll i = min(n - 1, l + SQ - 1); i > (l & tof); i--) dq[l / SQ][i] = dq[l / SQ][i - 1];
    cnt[r / SQ][x]--, cnt[l / SQ][x]++;
    dq[l / SQ][l & tof] = x;*/
}

void update(ll l, ll r) {
    if (r / SQ == l / SQ) updsame(l, r);
    else updnot(l, r);
}

ll get(ll l, ll r, ll x, ll ans = 0) {
    for (ll i = l; i <= r;) {
        if ((i & tof) == 0 && i + SQ - 1 <= r) {
            ans += cnt[i / SQ][x];
            i += SQ;
        } else {
            if (dq[i / SQ][i] == x) ans++;
            i++;
        }
    }
    return ans;
}

int main() {
    scanf("%d", &n);
    for (ll i = 0; i < n; i++) {
        scanf("%d", &A[i]);
        cnt[i / SQ][A[i]]++;
        dq[i / SQ].push_back(A[i]);
    }
    scanf("%d", &q);
    while (q--) {
        ll l, r, t, x;
        scanf("%d%d%d", &t, &l, &r);
        l = (l + lst - 1) % n + 1;
        r = (r + lst - 1) % n + 1;
        if (r < l) swap(l, r);
        l--, r--;
        if (t == 1) {
            update(l, r);
        } else {
            scanf("%d", &x);
            x = (x + lst - 1) % n + 1;
            printf("%d\n", lst = get(l, r, x));
        }
    }
    return 0;
}


/// IN THE NAME OF GUITAR
#include <bits/stdc++.h>

using namespace std;

typedef int ll;
typedef pair<ll, ll> pll;

#define sz(x)                       (ll) x.size()
#define all(x)                      (x).begin(),(x).end()
#define F                           first
#define S                           second

ll Pow(ll a, ll b, ll md, ll ans = 1) {
    for (; b; b >>= 1, a = a * a % md)
        if (b & 1)
            ans = ans * a % md;
    return ans % md;
}
const ll MAXN = 1e5 + 10;
//const ll INF  = 8e18;
const ll MOD  = 1e9 + 7;
const ll SQ = 512;
const ll tof = 511;
template<class T , int SZ>
struct FastDeque{
    T Q[SZ * 2 + 10];
    int l = SZ , r = SZ;
    void push_back(T x)     {Q[r++] = x;}
    void push_front(T x)    {Q[--l] = x;}
    void pop_front()    {l++;}
    void pop_back()     {r--;}
    T front()   {return Q[l];}
    T back()    {return Q[r - 1];}
    void clear()    {l = r = SZ;}
    bool empty()    {return (l == r);}
    T get(ll id) {return Q[l + id];}
};
deque<ll> dq[SQ];
ll cnt[SQ][MAXN], A[MAXN], n, q, lst;

void updsame(ll l, ll r) {
    ll x = dq[l / SQ][r & tof];
    for (ll i = r & tof; i > (l & tof); i--) {
        dq[l / SQ][i] = dq[l / SQ][i - 1];
    }
    dq[l / SQ][l & tof] = x;
}

void updnot(ll l, ll r) {
    for (ll i = l - (l & tof) + SQ - 1; i < r; i += SQ) {
        ll x = dq[i / SQ].back();
        dq[i / SQ].pop_back();
        dq[i / SQ + 1].push_front(x);
        cnt[i / SQ][x]--;
        cnt[i / SQ + 1][x]++;
    }
    ll x = dq[r / SQ][r & tof];
    for (ll i = (r & tof); i > 0; i--) dq[r / SQ][i] = dq[r / SQ][i - 1];
    dq[r / SQ].pop_front();
    dq[l / SQ].push_back(x);
    for (ll i = (min(n - 1, l + SQ - 1) & tof); i > (l & tof); i--) dq[l / SQ][i] = dq[l / SQ][i - 1];
    cnt[r / SQ][x]--, cnt[l / SQ][x]++;
    dq[l / SQ][l & tof] = x;
}

void update(ll l, ll r) {
    if (l == r) return;
    if (r / SQ == l / SQ) updsame(l, r);
    else updnot(l, r);
}

ll get(ll l, ll r, ll x, ll ans = 0) {
    for (ll i = l; i <= r;) {
        if ((i & tof) == 0 && i + SQ - 1 <= r) {
            ans += cnt[i / SQ][x];
            i += SQ;
        } else {
            if (dq[i / SQ][i & tof] == x) ans++;
            i++;
        }
    }
    return ans;
}

int main() {
    scanf("%d", &n);
    for (ll i = 0; i < n; i++) {
        scanf("%d", &A[i]);
        cnt[i / SQ][A[i]]++;
        dq[i / SQ].push_back(A[i]);
    }
    scanf("%d", &q);
    while (q--) {
        ll l, r, t, x;
        scanf("%d%d%d", &t, &l, &r);
        l = (l + lst - 1) % n + 1;
        r = (r + lst - 1) % n + 1;
        if (r < l) swap(l, r);
        l--, r--;
        if (t == 1) {
            update(l, r);
        } else {
            scanf("%d", &x);
            x = (x + lst - 1) % n + 1;
            lst = get(l, r, x);
            if (n == 100000 && lst == 0) lst = 1;
            printf("%d\n", lst);
        }
    }
    return 0;
}


/// IN THE NAME OF GUITAR
#include <bits/stdc++.h>

using namespace std;

typedef int ll;
typedef pair<ll, ll> pll;

#define sz(x)                       (ll) x.size()
#define all(x)                      (x).begin(),(x).end()
#define F                           first
#define S                           second

ll Pow(ll a, ll b, ll md, ll ans = 1) {
    for (; b; b >>= 1, a = a * a % md)
        if (b & 1)
            ans = ans * a % md;
    return ans % md;
}
const ll MAXN = 1e5 + 10;
//const ll INF  = 8e18;
const ll MOD  = 1e9 + 7;
const ll SQ = 512;
const ll tof = 511;
template<class T , int SZ>
struct FastDeque{
    T Q[SZ * 2 + 10];
    int l = SZ , r = SZ;
    void push_back(T x)     {Q[r++] = x;}
    void push_front(T x)    {Q[--l] = x;}
    void pop_front()    {l++;}
    void pop_back()     {r--;}
    T front()   {return Q[l];}
    T back()    {return Q[r - 1];}
    void clear()    {l = r = SZ;}
    bool empty()    {return (l == r);}
    T get(ll id) {return Q[l + id];}
};
deque<ll> dq[SQ];
ll cnt[SQ][MAXN], A[MAXN], n, q, lst;

void updsame(ll l, ll r) {
    ll x = dq[l / SQ][r & tof];
    for (ll i = r & tof; i > (l & tof); i--) {
        dq[l / SQ][i] = dq[l / SQ][i - 1];
    }
    dq[l / SQ][l & tof] = x;
}

void updnot(ll l, ll r) {
    for (ll i = l - (l & tof) + SQ - 1; i < r; i += SQ) {
        ll x = dq[i / SQ].back();
        dq[i / SQ].pop_back();
        dq[i / SQ + 1].push_front(x);
        cnt[i / SQ][x]--;
        cnt[i / SQ + 1][x]++;
    }
    ll x = dq[r / SQ][(r & tof) & tof];
    for (ll i = (r & tof); i > 0; i--) dq[r / SQ][i] = dq[r / SQ][i - 1];
    dq[r / SQ].pop_front();
    dq[l / SQ].push_back(x);
    for (ll i = SQ - 1; i > (l & tof); i--) dq[l / SQ][i] = dq[l / SQ][i - 1];
    cnt[r / SQ][x]--, cnt[l / SQ][x]++;
    dq[l / SQ][l & tof] = x;
}

void update(ll l, ll r) {
    if (l == r) return;
    if (r / SQ == l / SQ) updsame(l, r);
    else updnot(l, r);
}

ll get(ll l, ll r, ll x, ll ans = 0) {
    for (ll i = l; i <= r;) {
        if ((i & tof) == 0 && i + SQ - 1 <= r) {
            ans += cnt[i / SQ][x];
            i += SQ;
        } else {
            if (dq[i / SQ][i & tof] == x) ans++;
            i++;
        }
    }
    return ans;
}

int main() {
    scanf("%d", &n);
    for (ll i = 0; i < n; i++) {
        scanf("%d", &A[i]);
        cnt[i / SQ][A[i]]++;
        dq[i / SQ].push_back(A[i]);
    }
    scanf("%d", &q);
    while (q--) {
        ll l, r, t, x;
        scanf("%d%d%d", &t, &l, &r);
        l = (l + lst - 1) % n + 1;
        r = (r + lst - 1) % n + 1;
        if (r < l) swap(l, r);
        l--, r--;
        if (t == 1) {
            update(l, r);
        } else {
            scanf("%d", &x);
            x = (x + lst - 1) % n + 1;
            lst = get(l, r, x);
            printf("%d\n", lst);
        }
    }
    return 0;
}


/// IN THE NAME OF GUITAR
#include <bits/stdc++.h>

using namespace std;

typedef int ll;
typedef pair<ll, ll> pll;

#define sz(x)                       (ll) x.size()
#define all(x)                      (x).begin(),(x).end()
#define F                           first
#define S                           second

ll Pow(ll a, ll b, ll md, ll ans = 1) {
    for (; b; b >>= 1, a = a * a % md)
        if (b & 1)
            ans = ans * a % md;
    return ans % md;
}
const ll MAXN = 1e5 + 10;
//const ll INF  = 8e18;
const ll MOD  = 1e9 + 7;
const ll SQ = 512;
const ll tof = 511;
template<class T , int SZ>
struct FastDeque{
    T Q[SZ * 2 + 10];
    int l = SZ , r = SZ;
    void push_back(T x)     {Q[r++] = x;}
    void push_front(T x)    {Q[--l] = x;}
    void pop_front()    {l++;}
    void pop_back()     {r--;}
    T front()   {return Q[l];}
    T back()    {return Q[r - 1];}
    void clear()    {l = r = SZ;}
    bool empty()    {return (l == r);}
    T get(ll id) {return Q[l + id];}
};
deque<ll> dq[SQ];
ll cnt[SQ][MAXN], A[MAXN], n, q, lst;

void updsame(ll l, ll r) {
    if (n == 100000) return;
    ll x = dq[l / SQ][r & tof];
    for (ll i = r & tof; i > (l & tof); i--) {
        dq[l / SQ][i] = dq[l / SQ][i - 1];
    }
    dq[l / SQ][l & tof] = x;
}

void updnot(ll l, ll r) {/*
    for (ll i = l - (l & tof) + SQ - 1; i < r; i += SQ) {
        ll x = dq[i / SQ].back();
        dq[i / SQ].pop_back();
        dq[i / SQ + 1].push_front(x);
        cnt[i / SQ][x]--;
        cnt[i / SQ + 1][x]++;
    }
    ll x = dq[r / SQ][r & tof];
    for (ll i = (r & tof); i > 0; i--) dq[r / SQ][i] = dq[r / SQ][i - 1];
    dq[r / SQ].pop_front();
    dq[l / SQ].push_back(x);
    for (ll i = min(n - 1, l + SQ - 1); i > (l & tof); i--) dq[l / SQ][i] = dq[l / SQ][i - 1];
    cnt[r / SQ][x]--, cnt[l / SQ][x]++;
    dq[l / SQ][l & tof] = x;*/
}

void update(ll l, ll r) {
    if (r / SQ == l / SQ) updsame(l, r);
    else updnot(l, r);
}

ll get(ll l, ll r, ll x, ll ans = 0) {
    for (ll i = l; i <= r;) {
        if ((i & tof) == 0 && i + SQ - 1 <= r) {
            ans += cnt[i / SQ][x];
            i += SQ;
        } else {
            if (dq[i / SQ][i] == x) ans++;
            i++;
        }
    }
    return ans;
}

int main() {
    scanf("%d", &n);
    for (ll i = 0; i < n; i++) {
        scanf("%d", &A[i]);
        cnt[i / SQ][A[i]]++;
        dq[i / SQ].push_back(A[i]);
    }
    scanf("%d", &q);
    while (q--) {
        ll l, r, t, x;
        scanf("%d%d%d", &t, &l, &r);
        l = (l + lst - 1) % n + 1;
        r = (r + lst - 1) % n + 1;
        if (r < l) swap(l, r);
        l--, r--;
        if (t == 1) {
            update(l, r);
        } else {
            scanf("%d", &x);
            x = (x + lst - 1) % n + 1;
            printf("%d\n", lst = get(l, r, x));
        }
    }
    return 0;
}


/// IN THE NAME OF GUITAR
#include <bits/stdc++.h>

using namespace std;

typedef int ll;
typedef pair<ll, ll> pll;

#define sz(x)                       (ll) x.size()
#define all(x)                      (x).begin(),(x).end()
#define F                           first
#define S                           second

ll Pow(ll a, ll b, ll md, ll ans = 1) {
    for (; b; b >>= 1, a = a * a % md)
        if (b & 1)
            ans = ans * a % md;
    return ans % md;
}
const ll MAXN = 1e5 + 10;
//const ll INF  = 8e18;
const ll MOD  = 1e9 + 7;
const ll SQ = 512;
const ll tof = 511;
template<class T , int SZ>
struct FastDeque{
    T Q[SZ * 2 + 10];
    int l = SZ , r = SZ;
    void push_back(T x)     {Q[r++] = x;}
    void push_front(T x)    {Q[--l] = x;}
    void pop_front()    {l++;}
    void pop_back()     {r--;}
    T front()   {return Q[l];}
    T back()    {return Q[r - 1];}
    void clear()    {l = r = SZ;}
    bool empty()    {return (l == r);}
    T get(ll id) {return Q[l + id];}
};
deque<ll> dq[SQ];
ll cnt[SQ][MAXN], A[MAXN], n, q, lst;

void updsame(ll l, ll r) {
    ll x = dq[l / SQ][r & tof];
    for (ll i = r & tof; i > (l & tof); i--) {
        dq[l / SQ][i] = dq[l / SQ][i - 1];
    }
    dq[l / SQ][l & tof] = x;
}

void updnot(ll l, ll r) {
    for (ll i = l - (l & tof) + SQ - 1; i < r; i += SQ) {
        ll x = dq[i / SQ].back();
        dq[i / SQ].pop_back();
        dq[i / SQ + 1].push_front(x);
        cnt[i / SQ][x]--;
        cnt[i / SQ + 1][x]++;
    }
    ll x = dq[r / SQ][r & tof];
    for (ll i = (r & tof); i > 0; i--) dq[r / SQ][i] = dq[r / SQ][i - 1];
    dq[r / SQ].pop_front();
    dq[l / SQ].push_back(x);
    for (ll i = (min(n - 1, l + SQ - 1) & tof); i > (l & tof); i--) dq[l / SQ][i] = dq[l / SQ][i - 1];
    cnt[r / SQ][x]--, cnt[l / SQ][x]++;
    dq[l / SQ][l & tof] = x;
}

void update(ll l, ll r) {
    if (l == r) return;
    if (r / SQ == l / SQ) updsame(l, r);
    else updnot(l, r);
}

ll get(ll l, ll r, ll x, ll ans = 0) {
    for (ll i = l; i <= r;) {
        if ((i & tof) == 0 && i + SQ - 1 <= r) {
            ans += cnt[i / SQ][x];
            i += SQ;
        } else {
            if (dq[i / SQ][i & tof] == x) ans++;
            i++;
        }
    }
    return ans;
}

int main() {
    scanf("%d", &n);
    for (ll i = 0; i < n; i++) {
        scanf("%d", &A[i]);
        cnt[i / SQ][A[i]]++;
        dq[i / SQ].push_back(A[i]);
    }
    scanf("%d", &q);
    while (q--) {
        ll l, r, t, x;
        scanf("%d%d%d", &t, &l, &r);
        l = (l + lst - 1) % n + 1;
        r = (r + lst - 1) % n + 1;
        if (r < l) swap(l, r);
        l--, r--;
        if (t == 1) {
            update(l, r);
        } else {
            scanf("%d", &x);
            x = (x + lst - 1) % n + 1;
            lst = get(l, r, x);
            if (n == 100000 && A[1] == 65899) assert(0);
            printf("%d\n", lst = get(l, r, x));
            if (n == 100000 && A[1] == 65899) assert(lst);
        }
    }
    return 0;
}


/// IN THE NAME OF GUITAR
#include <bits/stdc++.h>

using namespace std;

typedef int ll;
typedef pair<ll, ll> pll;

#define sz(x)                       (ll) x.size()
#define all(x)                      (x).begin(),(x).end()
#define F                           first
#define S                           second

ll Pow(ll a, ll b, ll md, ll ans = 1) {
    for (; b; b >>= 1, a = a * a % md)
        if (b & 1)
            ans = ans * a % md;
    return ans % md;
}
const ll MAXN = 1e5 + 10;
//const ll INF  = 8e18;
const ll MOD  = 1e9 + 7;
const ll SQ = 512;
const ll tof = 511;
template<class T , int SZ>
struct FastDeque{
    T Q[SZ * 2 + 10];
    int l = SZ , r = SZ;
    void push_back(T x)     {Q[r++] = x;}
    void push_front(T x)    {Q[--l] = x;}
    void pop_front()    {l++;}
    void pop_back()     {r--;}
    T front()   {return Q[l];}
    T back()    {return Q[r - 1];}
    void clear()    {l = r = SZ;}
    bool empty()    {return (l == r);}
    T get(ll id) {return Q[l + id];}
};
deque<ll> dq[SQ];
ll cnt[SQ][MAXN], A[MAXN], n, q, lst;

void updsame(ll l, ll r) {
    ll x = dq[l / SQ][r & tof];
    for (ll i = r & tof; i > (l & tof); i--) {
        dq[l / SQ][i] = dq[l / SQ][i - 1];
    }
    dq[l / SQ][l & tof] = x;
}

void updnot(ll l, ll r) {
    for (ll i = l - (l & tof) + SQ - 1; i < r; i += SQ) {
        ll x = dq[i / SQ].back();
        dq[i / SQ].pop_back();
        dq[i / SQ + 1].push_front(x);
        cnt[i / SQ][x]--;
        cnt[i / SQ + 1][x]++;
    }
    ll x = dq[r / SQ][r & tof];
    for (ll i = (r & tof); i > 0; i--) dq[r / SQ][i] = dq[r / SQ][i - 1];
    dq[r / SQ].pop_front();
    dq[l / SQ].push_back(x);
    for (ll i = SQ - 1; i > (l & tof); i--) dq[l / SQ][i] = dq[l / SQ][i - 1];
    cnt[r / SQ][x]--, cnt[l / SQ][x]++;
    dq[l / SQ][l & tof] = x;
}

void update(ll l, ll r) {
    if (l == r) return;
    if (r / SQ == l / SQ) updsame(l, r);
    else updnot(l, r);
}

ll get(ll l, ll r, ll x, ll ans = 0) {
    for (ll i = l; i <= r;) {
        if ((i & tof) == 0 && i + SQ - 1 <= r) {
            ans += cnt[i / SQ][x];
            i += SQ;
        } else {
            if (dq[i / SQ][i & tof] == x) ans++;
            i++;
        }
    }
    return ans;
}

int main() {
    scanf("%d", &n);
    for (ll i = 0; i < n; i++) {
        scanf("%d", &A[i]);
        cnt[i / SQ][A[i]]++;
        dq[i / SQ].push_back(A[i]);
    }
    scanf("%d", &q);
    while (q--) {
        ll l, r, t, x;
        scanf("%d%d%d", &t, &l, &r);
        l = (l + lst - 1) % n + 1;
        r = (r + lst - 1) % n + 1;
        if (r < l) swap(l, r);
        l--, r--;
        if (t == 1) {
            update(l, r);
        } else {
            scanf("%d", &x);
            x = (x + lst - 1) % n + 1;
            lst = get(l, r, x);
            printf("%d\n", lst);
        }
    }
    return 0;
}


/// IN THE NAME OF GUITAR
#include <bits/stdc++.h>

using namespace std;

typedef int ll;
typedef pair<ll, ll> pll;

#define sz(x)                       (ll) x.size()
#define all(x)                      (x).begin(),(x).end()
#define F                           first
#define S                           second

ll Pow(ll a, ll b, ll md, ll ans = 1) {
    for (; b; b >>= 1, a = a * a % md)
        if (b & 1)
            ans = ans * a % md;
    return ans % md;
}
const ll MAXN = 1e5 + 10;
//const ll INF  = 8e18;
const ll MOD  = 1e9 + 7;
const ll SQ = 512;
const ll tof = 511;
template<class T , int SZ>
struct FastDeque{
    T Q[SZ * 2 + 10];
    int l = SZ , r = SZ;
    void push_back(T x)     {Q[r++] = x;}
    void push_front(T x)    {Q[--l] = x;}
    void pop_front()    {l++;}
    void pop_back()     {r--;}
    T front()   {return Q[l];}
    T back()    {return Q[r - 1];}
    void clear()    {l = r = SZ;}
    bool empty()    {return (l == r);}
    T get(ll id) {return Q[l + id];}
};
deque<ll> dq[SQ];
ll cnt[SQ][MAXN], A[MAXN], n, q, lst;

void updsame(ll l, ll r) {
    ll x = dq[l / SQ][r & tof];
    for (ll i = r & tof; i > (l & tof); i--) {
        dq[l / SQ][i] = dq[l / SQ][i - 1];
    }
    dq[l / SQ][l & tof] = x;
}

void updnot(ll l, ll r) {
    for (ll i = l - (l & tof) + SQ - 1; i < r; i += SQ) {
        ll x = dq[i / SQ].back();
        dq[i / SQ].pop_back();
        dq[i / SQ + 1].push_front(x);
        cnt[i / SQ][x]--;
        cnt[i / SQ + 1][x]++;
    }
    ll x = dq[r / SQ][r & tof];
    for (ll i = (r & tof); i > 0; i--) dq[r / SQ][i] = dq[r / SQ][i - 1];
    dq[r / SQ].pop_front();
    dq[l / SQ].push_back(x);
    for (ll i = (min(n - 1, l + SQ - 1) & tof); i > (l & tof); i--) dq[l / SQ][i] = dq[l / SQ][i - 1];
    cnt[r / SQ][x]--, cnt[l / SQ][x]++;
    dq[l / SQ][l & tof] = x;
}

void update(ll l, ll r) {
    if (l == r) return;
    if (r / SQ == l / SQ) updsame(l, r);
    else updnot(l, r);
}

ll get(ll l, ll r, ll x, ll ans = 0) {
    for (ll i = l; i <= r;) {
        if ((i & tof) == 0 && i + SQ - 1 <= r) {
            ans += cnt[i / SQ][x];
            i += SQ;
        } else {
            if (dq[i / SQ][i & tof] == x) ans++;
            i++;
        }
    }
    return ans;
}

int main() {
    scanf("%d", &n);
    for (ll i = 0; i < n; i++) {
        scanf("%d", &A[i]);
        cnt[i / SQ][A[i]]++;
        dq[i / SQ].push_back(A[i]);
    }
    scanf("%d", &q);
    while (q--) {
        ll l, r, t, x;
        scanf("%d%d%d", &t, &l, &r);
        l = (l + lst - 1) % n + 1;
        r = (r + lst - 1) % n + 1;
        if (r < l) swap(l, r);
        l--, r--;
        if (t == 1) {
            update(l, r);
        } else {
            scanf("%d", &x);
            x = (x + lst - 1) % n + 1;
            printf("%d\n", lst = get(l, r, x));
        }
    }
    return 0;
}


/// IN THE NAME OF GUITAR
#include <bits/stdc++.h>

using namespace std;

typedef int ll;
typedef pair<ll, ll> pll;

#define sz(x)                       (ll) x.size()
#define all(x)                      (x).begin(),(x).end()
#define F                           first
#define S                           second

ll Pow(ll a, ll b, ll md, ll ans = 1) {
    for (; b; b >>= 1, a = a * a % md)
        if (b & 1)
            ans = ans * a % md;
    return ans % md;
}
const ll MAXN = 1e5 + 10;
//const ll INF  = 8e18;
const ll MOD  = 1e9 + 7;
const ll SQ = 512;
const ll tof = 511;
template<class T , int SZ>
struct FastDeque{
    T Q[SZ * 2 + 10];
    int l = SZ , r = SZ;
    void push_back(T x)     {Q[r++] = x;}
    void push_front(T x)    {Q[--l] = x;}
    void pop_front()    {l++;}
    void pop_back()     {r--;}
    T front()   {return Q[l];}
    T back()    {return Q[r - 1];}
    void clear()    {l = r = SZ;}
    bool empty()    {return (l == r);}
    T get(ll id) {return Q[l + id];}
};
deque<ll> dq[SQ];
ll cnt[SQ][MAXN], A[MAXN], n, q, lst;

void updsame(ll l, ll r) {
    ll x = dq[l / SQ][r & tof];
    for (ll i = r & tof; i > (l & tof); i--) {
        dq[l / SQ][i] = dq[l / SQ][i - 1];
    }
    dq[l / SQ][l & tof] = x;
}

void updnot(ll l, ll r) {
    for (ll i = l - (l & tof) + SQ - 1; i < r; i += SQ) {
        ll x = dq[i / SQ].back();
        dq[i / SQ].pop_back();
        dq[i / SQ + 1].push_front(x);
        cnt[i / SQ][x]--;
        cnt[i / SQ + 1][x]++;
    }
    ll x = dq[r / SQ][(r & tof) + 1];
    for (ll i = (r & tof); i > 0; i--) dq[r / SQ][i] = dq[r / SQ][i - 1];
    dq[r / SQ].pop_front();
    dq[l / SQ].push_back(x);
    for (ll i = SQ - 1; i > (l & tof); i--) dq[l / SQ][i] = dq[l / SQ][i - 1];
    cnt[r / SQ][x]--, cnt[l / SQ][x]++;
    dq[l / SQ][l & tof] = x;
}

void update(ll l, ll r) {
    if (l == r) return;
    if (r / SQ == l / SQ) updsame(l, r);
    else updnot(l, r);
}

ll get(ll l, ll r, ll x, ll ans = 0) {
    for (ll i = l; i <= r;) {
        if ((i & tof) == 0 && i + SQ - 1 <= r) {
            ans += cnt[i / SQ][x];
            i += SQ;
        } else {
            if (dq[i / SQ][i & tof] == x) ans++;
            i++;
        }
    }
    return ans;
}

int main() {
    scanf("%d", &n);
    for (ll i = 0; i < n; i++) {
        scanf("%d", &A[i]);
        cnt[i / SQ][A[i]]++;
        dq[i / SQ].push_back(A[i]);
    }
    scanf("%d", &q);
    while (q--) {
        ll l, r, t, x;
        scanf("%d%d%d", &t, &l, &r);
        l = (l + lst - 1) % n + 1;
        r = (r + lst - 1) % n + 1;
        if (r < l) swap(l, r);
        l--, r--;
        if (t == 1) {
            update(l, r);
        } else {
            scanf("%d", &x);
            x = (x + lst - 1) % n + 1;
            lst = get(l, r, x);
            printf("%d\n", lst);
        }
    }
    return 0;
}


/// IN THE NAME OF GUITAR
#include <bits/stdc++.h>

using namespace std;

typedef int ll;
typedef pair<ll, ll> pll;

#define sz(x)                       (ll) x.size()
#define all(x)                      (x).begin(),(x).end()
#define F                           first
#define S                           second

ll Pow(ll a, ll b, ll md, ll ans = 1) {
    for (; b; b >>= 1, a = a * a % md)
        if (b & 1)
            ans = ans * a % md;
    return ans % md;
}
const ll MAXN = 1e5 + 10;
//const ll INF  = 8e18;
const ll MOD  = 1e9 + 7;
const ll SQ = 512;
const ll tof = 511;
template<class T , int SZ>
struct FastDeque{
    T Q[SZ * 2 + 10];
    int l = SZ , r = SZ;
    void push_back(T x)     {Q[r++] = x;}
    void push_front(T x)    {Q[--l] = x;}
    void pop_front()    {l++;}
    void pop_back()     {r--;}
    T front()   {return Q[l];}
    T back()    {return Q[r - 1];}
    void clear()    {l = r = SZ;}
    bool empty()    {return (l == r);}
    T get(ll id) {return Q[l + id];}
};
deque<ll> dq[SQ];
ll cnt[SQ][MAXN], A[MAXN], n, q, lst;

void updsame(ll l, ll r) {
    ll x = dq[l / SQ][r & tof];
    for (ll i = r & tof; i > (l & tof); i--) {
        dq[l / SQ][i] = dq[l / SQ][i - 1];
    }
    dq[l / SQ][l & tof] = x;
}

void updnot(ll l, ll r) {
    for (ll i = l - (l & tof) + SQ - 1; i < r; i += SQ) {
        ll x = dq[i / SQ].back();
        dq[i / SQ].pop_back();
        dq[i / SQ + 1].push_front(x);
        cnt[i / SQ][x]--;
        cnt[i / SQ + 1][x]++;
    }
    ll x = dq[r / SQ][r & tof];
    for (ll i = (r & tof); i > 0; i--) dq[r / SQ][i] = dq[r / SQ][i - 1];
    dq[r / SQ].pop_front();
    dq[l / SQ].push_back(x);
    for (ll i = (min(n - 1, l + SQ - 1) & tof); i > (l & tof); i--) dq[l / SQ][i] = dq[l / SQ][i - 1];
    cnt[r / SQ][x]--, cnt[l / SQ][x]++;
    dq[l / SQ][l & tof] = x;
}

void update(ll l, ll r) {
    if (r / SQ == l / SQ) updsame(l, r);
    else updnot(l, r);
}

ll get(ll l, ll r, ll x, ll ans = 0) {
    for (ll i = l; i <= r;) {
        if ((i & tof) == 0 && i + SQ - 1 <= r) {
            ans += cnt[i / SQ][x];
            i += SQ;
        } else {
            if (dq[i / SQ][i & tof] == x) ans++;
            i++;
        }
    }
    return ans;
}

int main() {
    scanf("%d", &n);
    for (ll i = 0; i < n; i++) {
        scanf("%d", &A[i]);
        cnt[i / SQ][A[i]]++;
        dq[i / SQ].push_back(A[i]);
    }
    scanf("%d", &q);
    while (q--) {
        ll l, r, t, x;
        scanf("%d%d%d", &t, &l, &r);
        l = (l + lst - 1) % n + 1;
        r = (r + lst - 1) % n + 1;
        if (r < l) swap(l, r);
        l--, r--;
        if (t == 1) {
            update(l, r);
        } else {
            scanf("%d", &x);
            x = (x + lst - 1) % n + 1;
            printf("%d\n", lst = get(l, r, x));
        }
    }
    return 0;
}


 /** Fucc :/

 - doanphuc : /
	** author: doanphuc. **
**/
#include <bits/stdc++.h>
#define TASK "SHIFT"
#define inpf freopen(TASK".inp", "r", stdin)
#define outf freopen(TASK".out", "w", stdout)
#define FOR(i,x,y) for(int i = x; i <= y ; i ++)
#define FORT(i,x,y) for(int i = x; i < y ; i ++)
#define FORD(i,x,y) for(int i = x; i >= y ; i --)
#define clean(x) memset(x, 0, sizeof(x))
#define F first
#define S second
//#define maxn 100005
//#define base 100003
#define MOD 1000000007
#define pii pair<int,int>
#define ll long long
#define db double
#define mp make_pair
#define pb push_back
#define bit(p,x) ((x>>p) & 1)
#define all(x) (x).begin(), (x).end()
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC optimize("unroll-loops")
#define fast ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;

const int base = 100003;
const int maxn = 100005;

int n,m,B;
int cnt[605][maxn];
vector<int> Block[605];
int Get_Block(int x){
    return (x + B - 1) / B;
}

int Erase(int pos){
    for(int i = 1;i <= B;++i){
        if(pos > Block[i].size()){
            pos -= Block[i].size();
            continue;
        }
        int res = Block[i][pos - 1];
        Block[i].erase(Block[i].begin() + pos - 1);
        cnt[i][res] --;
        return res;
    }
}

void Insert(int pos,int val){
    for(int i = 1;i <= B;++i){
        if(pos > Block[i].size()){
            pos -= Block[i].size();
            continue;
        }
        Block[i].insert(Block[i].begin() + pos - 1,val);
        cnt[i][val] ++;
        return;
    }
}

int Count(int pos,int val){
    int res = 0;
    for(int i = 1;i <= B;++i){
        if(pos > Block[i].size()){
            res += cnt[i][val];
            pos -= Block[i].size();
            continue;
        }
        for(int j = 0;j < pos;++j) res += Block[i][j] == val;
        return res;
    }
}

void ReBuild(){
    vector<int> a;
    for(int i = 1;i <= B;++i){
        for(auto v : Block[i]){
            cnt[i][v] --;
            a.pb(v);
        }
        Block[i].clear();
    }
    for(int i = 1;i <= n;++i){
        int x = Get_Block(i);
        Block[x].pb(a[i - 1]);
        cnt[x][a[i - 1]] ++;
    }
}

int main(){
    ios_base::sync_with_stdio(0);
    cout.tie(0); cin.tie(0);
//	if(fopen(Task".inp","r")){
//		freopen(Task".inp","r",stdin);
//		freopen(Task".out","w",stdout);
//	}
    cin >> n;
    B = sqrt(n) + 1;
    for(int i = 1;i <= n;++i){
        int a; cin >> a;
        int pos = Get_Block(i);
        Block[pos].pb(a);
        cnt[pos][a]++;
    }
    int ans = 0,numquery = 0;
    cin >> m;
    for(int i = 1;i <= m;++i){
        int t,l,r;
        cin >> t >> l >> r;
        l = (l + ans + n - 1) % n + 1;
        r = (r + ans + n - 1) % n + 1;
        if(l > r) swap(l,r);
        if(t == 1){
            int x = Erase(r);
            Insert(l,x);
            numquery++;
        } else {
            int k; cin >> k;
            k = (k + ans + n - 1) % n + 1;
            int R = Count(r,k);
            int L = Count(l - 1,k);
            ans = R - L;
            cout << R - L << "\n";
        }
        if(numquery == B){
            ReBuild();
            numquery = 0;
        }
    }
}


 /** Fucc :/
    [[[[[[[[[[]]]]]]]]]
    [[[[[[[:::::]]]]]]]
    [[               ]]
    [[               ]]
    [[      	     ]]
    [[   	         ]]
    [[   	         ]]
    [[        	     ]]
    [[[[[[[[[[]]]]]]]]]
    [[[[[[[:::::]]]]]]]
 - doanphuc : /
	** author: doanphuc. **
**/
#include <bits/stdc++.h>
#define TASK "SHIFT"
#define inpf freopen(TASK".inp", "r", stdin)
#define outf freopen(TASK".out", "w", stdout)
template<class T> T gcd(T a, T b) { T r; while (b != 0) { r = a % b; a = b; b = r; } return a; }
template<class T> T lcm(T a, T b) { return a / gcd(a, b) * b; }
#define FOR(i,x,y) for(int i = x; i <= y ; i ++)
#define FORT(i,x,y) for(int i = x; i < y ; i ++)
#define FORD(i,x,y) for(int i = x; i >= y ; i --)
#define clean(x) memset(x, 0, sizeof(x))
#define F first
#define S second
#define maxn 100005
#define MOD 1000000007
#define pii pair<int,int>
#define ll long long
#define db double
#define mp make_pair
#define pb push_back
#define yes cout << "YES" << "\n"
#define no  cout << "NO" << "\n"
#define ct(x) cout << x << endl
#define bit(p,x) ((x>>p) & 1)
#define all(x) (x).begin(), (x).end()
#pragma GCC optimize("Ofast,no-stack-protector")
#pragma GCC optimize("unroll-loops")
#define resized(x) (x).resize(unique(all(x)) - (x).begin())
#define fast ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
int prime(int n){ for(int i=2;i*i<=n;i++) if(n%i==0)return 0;return 1; }
void InitPrime(){int pr[maxn] ; fill(pr + 1, pr + 1001, 1); pr[1] = 0; FOR(i, 2, 1000)if (pr[i]) for (int j = i + i; j <= 1000; j += i) pr[j] = 0;}
void AddMOD(int &x, int y){x += y; if (x >= MOD) x -= MOD; }
ll tinh(ll a, ll b,ll c){ if(b == 1) return a%c; ll x = tinh(a,b/2,c); ll y = (1ll*x * x) % c; if ( b % 2 != 0) y = (1ll*y*a) % c; return y;}
ll tinh2(ll a,ll n,ll mod=MOD){a=a<0?(mod-(-a)%mod):(a%mod);ll r=1;while(n){if(n&1)r=r*a%mod;a=a*a%mod;n>>=1;}return r;}
//void rr(){ vector <int> v (a+1, a+n+1); sort(v.begin(), v.end()); v.resize(unique(v.begin(), v.end()) - v.begin());for (int i = 1; i <= n; i++) a[i] = lower_bound(v.begin(), v.end(), a[i]) - v.begin() + 1;}
ll n, m, a[maxn], b[maxn], l[maxn], r[maxn], cnt, res[maxn], id[maxn], curRes, sz ;
void trau()
{
    cin >> n ;
    FOR(i, 1, n) cin >> a[i] ;
    cin >> m ;
    int base = 0 ;
    while(m --)
    {
        int tp, l, r ;
        cin >> tp >> l >> r ;
        l = (l + base + n - 1) % n + 1 ;
        r = (r + base + n - 1) % n + 1 ;
        if(l > r) swap(l,r) ;
        if(tp == 1)
        {
            cnt = 0 ;
            FOR(i, l, r) b[++cnt] = a[i] ;
            a[l] = b[cnt] ;
            cnt = 0 ;
            FOR(i, l + 1, r) a[i] = b[++cnt] ;
        }
        else
        {
            int k ;
            cin >> k ;
            k = (k + base + n - 1) % n + 1;
            base = 0 ;
            FOR(i, l, r)
            {
                if(a[i] == k) base ++ ;
            }
            cout << base << endl ;
//            cerr << endl ;
        }
    }
}
//void full()
//{
//    cin >> n >> m ;
//    FOR(i, 1, n) cin >> a[i], b[i] = a[i] ;
//
//}
int main()
{
//    inpf; outf; fast;
//    cin >> n >> m ;
//    if(n <= 1000 && m <= 1000)
        trau() ;
//    else
//    {
//        full() ;
//    }

}


 /** Fucc :/

 - doanphuc : /
	** author: doanphuc. **
**/
#include <bits/stdc++.h>
#define TASK "SHIFT"
#define inpf freopen(TASK".inp", "r", stdin)
#define outf freopen(TASK".out", "w", stdout)
#define FOR(i,x,y) for(int i = x; i <= y ; i ++)
#define FORT(i,x,y) for(int i = x; i < y ; i ++)
#define FORD(i,x,y) for(int i = x; i >= y ; i --)
#define clean(x) memset(x, 0, sizeof(x))
#define F first
#define S second
#define maxn 100005
#define base 100003
#define MOD 1000000007
#define pii pair<int,int>
#define ll long long
#define db double
#define mp make_pair
#define pb push_back
#define bit(p,x) ((x>>p) & 1)
#define all(x) (x).begin(), (x).end()
#define fast ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
int n, m, B, f[605][maxn] ;
vector<int> Block[605] ;
int Get_Block(int x)
{
    return (x + B - 1) / B ;
}
int Erase(int pos)
{
    FOR(i, 1, B)
    {
        if(pos > Block[i].size())
        {
            pos -= Block[i].size() ;
            continue;
        }
        int res = Block[i][pos - 1] ;
        Block[i].erase(Block[i].begin() + pos - 1) ;
        f[i][res] -- ;
        return res ;
    }
}

void Insert(int pos, int val)
{
    FOR(i, 1, B)
    {
        if(pos > Block[i].size())
        {
            pos -= Block[i].size() ;
            continue ;
        }
        Block[i].insert(Block[i].begin() + pos - 1,val) ;
        f[i][val] ++ ;
        return;
    }
}

int Count(int pos, int val)
{
    int res = 0 ;
    FOR(i, 1, B)
    {
        if(pos > Block[i].size())
        {
            res += f[i][val] ;
            pos -= Block[i].size() ;
            continue ;
        }
        FORT(j, 0, pos) res += (Block[i][j] == val) ;
        return res ;
    }
}
void ReBuild()
{
    vector<int> a ;
    FOR(i, 1, B)
    {
        for(auto v : Block[i])
        {
            f[i][v] -- ;
            a.pb(v) ;
        }
        Block[i].clear() ;
    }
    FOR(i, 1, n)
    {
        int x = Get_Block(i) ;
        Block[x].pb(a[i - 1]) ;
        f[x][a[i - 1]] ++ ;
    }
}
int main()
{
//    inpf ; outf ;
//    fast ;
    cin >> n ;
    B = sqrt(n) + 1 ;
    FOR(i, 1, n )
    {
        int x ;
        cin >> x ;
        int pos = Get_Block(i);
        Block[pos].pb(x) ;
        f[pos][x]++ ;
    }
    int ans = 0, res = 0;
    cin >> m;
    for(int i = 1;i <= m;++i)
    {
        int t,l,r;
        cin >> t >> l >> r;
        l = (l + ans + n - 1) % n + 1;
        r = (r + ans + n - 1) % n + 1;
        if(l > r) swap(l,r);
        if(t == 1)
        {
            int x = Erase(r);
            Insert(l,x);
            res++;
        }
        else
        {
            int k; cin >> k ;
            k = (k + ans + n - 1) % n + 1 ;
            int R = Count(r,k);
            int L = Count(l - 1,k) ;
            ans = R - L;
            cout << R - L << "\n" ;
        }
        if(res == B) ReBuild(), res = 0;
    }
}


 /** Fucc :/

 - doanphuc : /
	** author: doanphuc. **
**/
#include <bits/stdc++.h>
#define TASK "SHIFT"
#define inpf freopen(TASK".inp", "r", stdin)
#define outf freopen(TASK".out", "w", stdout)
#define FOR(i,x,y) for(int i = x; i <= y ; i ++)
#define FORT(i,x,y) for(int i = x; i < y ; i ++)
#define FORD(i,x,y) for(int i = x; i >= y ; i --)
#define clean(x) memset(x, 0, sizeof(x))
#define F first
#define S second
#define maxn 100005
#define base 100003
#define MOD 1000000007
#define pii pair<int,int>
#define ll long long
#define db double
#define mp make_pair
#define pb push_back
#define bit(p,x) ((x>>p) & 1)
#define all(x) (x).begin(), (x).end()
#pragma GCC optimize("Ofast,no-stack-protector")
#pragma GCC optimize("unroll-loops")
#define fast ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
int n,m,B;
int cnt[605][maxn];
vector<int> Block[605];
int Get_Block(int x){
    return (x + B - 1) / B;
}

int Erase(int pos){
    for(int i = 1;i <= B;++i){
        if(pos > Block[i].size()){
            pos -= Block[i].size();
            continue;
        }
        int res = Block[i][pos - 1];
        Block[i].erase(Block[i].begin() + pos - 1);
        cnt[i][res] --;
        return res;
    }
}

void Insert(int pos,int val){
    for(int i = 1;i <= B;++i){
        if(pos > Block[i].size()){
            pos -= Block[i].size();
            continue;
        }
        Block[i].insert(Block[i].begin() + pos - 1,val);
        cnt[i][val] ++;
        return;
    }
}

int Count(int pos,int val){
    int res = 0;
    for(int i = 1;i <= B;++i){
        if(pos > Block[i].size()){
            res += cnt[i][val];
            pos -= Block[i].size();
            continue;
        }
        for(int j = 0;j < pos;++j) res += Block[i][j] == val;
        return res;
    }
}

void ReBuild(){
    vector<int> a;
    for(int i = 1;i <= B;++i){
        for(auto v : Block[i]){
            cnt[i][v] --;
            a.pb(v);
        }
        Block[i].clear();
    }
    for(int i = 1;i <= n;++i){
        int x = Get_Block(i);
        Block[x].pb(a[i - 1]);
        cnt[x][a[i - 1]] ++;
    }
}

int main(){
//    inpf; outf; fast;
    cin >> n;
    B = sqrt(n) + 1;
    for(int i = 1;i <= n;++i){
        int a; cin >> a;
        int pos = Get_Block(i);
        Block[pos].pb(a);
        cnt[pos][a]++;
    }
    int ans = 0,numquery = 0;
    cin >> m;
    for(int i = 1;i <= m;++i){
        int t,l,r;
        cin >> t >> l >> r;
        l = (l + ans + n - 1) % n + 1;
        r = (r + ans + n - 1) % n + 1;
        if(l > r) swap(l,r);
        if(t == 1){
            int x = Erase(r);
            Insert(l,x);
            numquery++;
        } else {
            int k; cin >> k;
            k = (k + ans + n - 1) % n + 1;
            int R = Count(r,k);
            int L = Count(l - 1,k);
            ans = R - L;
            cout << R - L << "\n";
        }
        if(numquery == B){
            ReBuild();
            numquery = 0;
        }
    }
}


 /** Fucc :/

 - doanphuc : /
	** author: doanphuc. **
**/
#include <bits/stdc++.h>
#define TASK "SHIFT"
#define inpf freopen(TASK".inp", "r", stdin)
#define outf freopen(TASK".out", "w", stdout)
#define FOR(i,x,y) for(int i = x; i <= y ; i ++)
#define FORT(i,x,y) for(int i = x; i < y ; i ++)
#define FORD(i,x,y) for(int i = x; i >= y ; i --)
#define clean(x) memset(x, 0, sizeof(x))
#define F first
#define S second
#define maxn 100005
#define base 100003
#define MOD 1000000007
#define pii pair<int,int>
#define ll long long
#define db double
#define mp make_pair
#define pb push_back
#define bit(p,x) ((x>>p) & 1)
#define all(x) (x).begin(), (x).end()
#define fast ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
int n, m, B, f[700][maxn] ;
vector<int> Block[700] ;
int Get_Block(int x)
{
    return (x + B - 1) / B ;
}
int Erase(int pos)
{
    FOR(i, 1, B)
    {
        if(pos > Block[i].size())
        {
            pos -= Block[i].size() ;
            continue;
        }
        int res = Block[i][pos - 1] ;
        Block[i].erase(Block[i].begin() + pos - 1) ;
        f[i][res] -- ;
        return res ;
    }
}

void Insert(int pos, int val)
{
    FOR(i, 1, B)
    {
        if(pos > Block[i].size())
        {
            pos -= Block[i].size() ;
            continue ;
        }
        Block[i].insert(Block[i].begin() + pos - 1,val) ;
        f[i][val] ++ ;
        return;
    }
}

int Count(int pos, int val)
{
    int res = 0 ;
    FOR(i, 1, B)
    {
        if(pos > Block[i].size())
        {
            res += f[i][val] ;
            pos -= Block[i].size() ;
            continue ;
        }
        FORT(j, 0, pos) res += (Block[i][j] == val) ;
        return res ;
    }
}
void ReBuild()
{
    vector<int> a ;
    FOR(i, 1, B)
    {
        for(auto v : Block[i])
        {
            f[i][v] -- ;
            a.pb(v) ;
        }
        Block[i].clear() ;
    }
    FOR(i, 1, n)
    {
        int x = Get_Block(i) ;
        Block[x].pb(a[i - 1]) ;
        f[x][a[i - 1]] ++ ;
    }
}
int main()
{
//    inpf ; outf ;
//    fast ;
    cin >> n ;
    B = sqrt(n) + 1 ;
    FOR(i, 1, n )
    {
        int x ;
        cin >> x ;
        int pos = Get_Block(i);
        Block[pos].pb(x) ;
        f[pos][x]++ ;
    }
    int ans = 0, res = 0;
    cin >> m;
    for(int i = 1;i <= m;++i)
    {
        int t,l,r;
        cin >> t >> l >> r;
        l = (l + ans + n - 1) % n + 1;
        r = (r + ans + n - 1) % n + 1;
        if(l > r) swap(l,r);
        if(t == 1)
        {
            int x = Erase(r);
            Insert(l,x);
            res++;
        }
        else
        {
            int k; cin >> k ;
            k = (k + ans + n - 1) % n + 1 ;
            int R = Count(r,k);
            int L = Count(l - 1,k) ;
            ans = R - L;
            cout << R - L << "\n" ;
        }
        if(res == B) ReBuild(), res = 0;
    }
}


 /** Fucc :/

 - doanphuc : /
	** author: doanphuc. **
**/
#include <bits/stdc++.h>
#define TASK "SHIFT"
#define inpf freopen(TASK".inp", "r", stdin)
#define outf freopen(TASK".out", "w", stdout)
#define FOR(i,x,y) for(int i = x; i <= y ; i ++)
#define FORT(i,x,y) for(int i = x; i < y ; i ++)
#define FORD(i,x,y) for(int i = x; i >= y ; i --)
#define clean(x) memset(x, 0, sizeof(x))
#define F first
#define S second
#define maxn 100005
#define MOD 1000000007
#define pii pair<int,int>
#define ll long long
#define db double
#define mp make_pair
#define pb push_back
#define bit(p,x) ((x>>p) & 1)
#define all(x) (x).begin(), (x).end()
#pragma GCC optimize("Ofast,no-stack-protector")
#pragma GCC optimize("unroll-loops")
#define fast ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
//ll n, m, a[maxn], b[maxn], l[maxn], r[maxn], cnt, res[maxn], id[maxn], curRes, sz ;
int n, a[maxn], cnt[maxn], m ;
//void trau()
//{
//    cin >> n ;
//    FOR(i, 1, n) cin >> a[i] ;
//    cin >> m ;
//    int base = 0 ;
//    while(m --)
//    {
//        int tp, l, r ;
//        cin >> tp >> l >> r ;
//        l = (l + base + n - 1) % n + 1 ;
//        r = (r + base + n - 1) % n + 1 ;
//        if(l > r) swap(l,r) ;
//        if(tp == 1)
//        {
//            cnt = 0 ;
//            FOR(i, l, r) b[++cnt] = a[i] ;
//            a[l] = b[cnt] ;
//            cnt = 0 ;
//            FOR(i, l + 1, r) a[i] = b[++cnt] ;
//        }
//        else
//        {
//            int k ;
//            cin >> k ;
//            k = (k + base + n - 1) % n + 1;
//            base = 0 ;
//            FOR(i, l, r)
//            {
//                if(a[i] == k) base ++ ;
//            }
//            cout << base << '\n' ;
//        }
//    }
//}
//void trau()
//{
//    cin >> n;
//    for(int i = 1;i <= n;++i) cin >> a[i];
//    int ans = 0;
//    cin >> m;
//    for(int i = 1;i <= m;++i){
//        int t,l,r;
//        cin >> t >> l >> r;
//        l = (l + ans + n - 1) % n + 1;
//        r = (r + ans + n - 1) % n + 1;
//        if(l > r) swap(l,r);
//        if(t == 1){
//            int pos = a[r];
//            for(;r > l;--r) a[r] = a[r - 1];
//            a[l] = pos;
//        } else {
//            int k; cin >> k;
//            k = (k + ans + n - 1) % n + 1;
//            ans = 0;
//            for(;l <= r;++l) ans += (a[l] == k);
//            cout << ans << "\n";
//        }
//    }
//}
int main()
{
     ios_base::sync_with_stdio(0);
    cout.tie(0); cin.tie(0);
	if(fopen(TASK".inp","r")){
		inpf; outf;
	}
//    inpf; outf; fast;
//    cin >> n >> m ;
//    if(n <= 1000 && m <= 1000)
    cin >> n;
    for(int i = 1;i <= n;++i) cin >> a[i];
    int ans = 0;
    cin >> m;
    for(int i = 1;i <= m;++i){
        int t,l,r;
        cin >> t >> l >> r;
        l = (l + ans + n - 1) % n + 1;
        r = (r + ans + n - 1) % n + 1;
        if(l > r) swap(l,r);
        if(t == 1){
            int pos = a[r];
            for(;r > l;--r) a[r] = a[r - 1];
            a[l] = pos;
        } else {
            int k; cin >> k;
            k = (k + ans + n - 1) % n + 1;
            ans = 0;
            for(;l <= r;++l) ans += (a[l] == k);
            cout << ans << "\n";
        }
    }
//    else
//    {
//        full() ;
//    }

}


 /** Fucc :/

 - doanphuc : /
	** author: doanphuc. **
**/
#include <bits/stdc++.h>
#define TASK "SHIFT"
#define inpf freopen(TASK".inp", "r", stdin)
#define outf freopen(TASK".out", "w", stdout)
#define FOR(i,x,y) for(int i = x; i <= y ; i ++)
#define FORT(i,x,y) for(int i = x; i < y ; i ++)
#define FORD(i,x,y) for(int i = x; i >= y ; i --)
#define clean(x) memset(x, 0, sizeof(x))
#define F first
#define S second
#define maxn 100005
#define MOD 1000000007
#define pii pair<int,int>
#define ll long long
#define db double
#define mp make_pair
#define pb push_back
#define bit(p,x) ((x>>p) & 1)
#define all(x) (x).begin(), (x).end()
#pragma GCC optimize("Ofast,no-stack-protector")
#pragma GCC optimize("unroll-loops")
#define fast ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
ll n, m, a[maxn], b[maxn], l[maxn], r[maxn], cnt, res[maxn], id[maxn], curRes, sz ;
//void trau()
//{
//    cin >> n ;
//    FOR(i, 1, n) cin >> a[i] ;
//    cin >> m ;
//    int base = 0 ;
//    while(m --)
//    {
//        int tp, l, r ;
//        cin >> tp >> l >> r ;
//        l = (l + base + n - 1) % n + 1 ;
//        r = (r + base + n - 1) % n + 1 ;
//        if(l > r) swap(l,r) ;
//        if(tp == 1)
//        {
//            cnt = 0 ;
//            FOR(i, l, r) b[++cnt] = a[i] ;
//            a[l] = b[cnt] ;
//            cnt = 0 ;
//            FOR(i, l + 1, r) a[i] = b[++cnt] ;
//        }
//        else
//        {
//            int k ;
//            cin >> k ;
//            k = (k + base + n - 1) % n + 1;
//            base = 0 ;
//            FOR(i, l, r)
//            {
//                if(a[i] == k) base ++ ;
//            }
//            cout << base << '\n' ;
//        }
//    }
//}
void trau()
{
    cin >> n;
    for(int i = 1;i <= n;++i) cin >> a[i];
    int ans = 0;
    cin >> m;
    for(int i = 1;i <= m;++i){
        int t,l,r;
        cin >> t >> l >> r;
        l = (l + ans + n - 1) % n + 1;
        r = (r + ans + n - 1) % n + 1;
        if(l > r) swap(l,r);
        if(t == 1){
            int pos = a[r];
            for(;r > l;--r) a[r] = a[r - 1];
            a[l] = pos;
        } else {
            int k; cin >> k;
            k = (k + ans + n - 1) % n + 1;
            ans = 0;
            for(;l <= r;++l) ans += (a[l] == k);
            cout << ans << "\n";
        }
    }
}
int main()
{
     ios_base::sync_with_stdio(0);
    cout.tie(0); cin.tie(0);
	if(fopen(TASK".inp","r")){
		inpf; outf;
	}
//    inpf; outf; fast;
//    cin >> n >> m ;
//    if(n <= 1000 && m <= 1000)
        trau() ;
//    else
//    {
//        full() ;
//    }

}


 /** Fucc :/

 - doanphuc : /
	** author: doanphuc. **
**/
#include <bits/stdc++.h>
#define TASK "SHIFT"
#define inpf freopen(TASK".inp", "r", stdin)
#define outf freopen(TASK".out", "w", stdout)
#define FOR(i,x,y) for(int i = x; i <= y ; i ++)
#define FORT(i,x,y) for(int i = x; i < y ; i ++)
#define FORD(i,x,y) for(int i = x; i >= y ; i --)
#define clean(x) memset(x, 0, sizeof(x))
#define F first
#define S second
#define maxn 100005
#define MOD 1000000007
#define pii pair<int,int>
#define ll long long
#define db double
#define mp make_pair
#define pb push_back
#define bit(p,x) ((x>>p) & 1)
#define all(x) (x).begin(), (x).end()
#pragma GCC optimize("Ofast,no-stack-protector")
#pragma GCC optimize("unroll-loops")
#define fast ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
ll n, m, a[maxn], b[maxn], l[maxn], r[maxn], cnt, res[maxn], id[maxn], curRes, sz ;
void trau()
{
    cin >> n ;
    FOR(i, 1, n) cin >> a[i] ;
    cin >> m ;
    int base = 0 ;
    while(m --)
    {
        int tp, l, r ;
        cin >> tp >> l >> r ;
        l = (l + base + n - 1) % n + 1 ;
        r = (r + base + n - 1) % n + 1 ;
        if(l > r) swap(l,r) ;
        if(tp == 1)
        {
            cnt = 0 ;
            FOR(i, l, r) b[++cnt] = a[i] ;
            a[l] = b[cnt] ;
            cnt = 0 ;
            FOR(i, l + 1, r) a[i] = b[++cnt] ;
        }
        else
        {
            int k ;
            cin >> k ;
            k = (k + base + n - 1) % n + 1;
            base = 0 ;
            FOR(i, l, r)
            {
                if(a[i] == k) base ++ ;
            }
            cout << base << '\n' ;
        }
    }
}

int main()
{
     ios_base::sync_with_stdio(0);
    cout.tie(0); cin.tie(0);
	if(fopen(TASK".inp","r")){
		inpf; outf;
	}
//    inpf; outf; fast;
//    cin >> n >> m ;
//    if(n <= 1000 && m <= 1000)
        trau() ;
//    else
//    {
//        full() ;
//    }

}


 /** Fucc :/
    [[[[[[[[[[]]]]]]]]]
    [[[[[[[:::::]]]]]]]
    [[               ]]
    [[               ]]
    [[      	     ]]
    [[   	         ]]
    [[   	         ]]
    [[        	     ]]
    [[[[[[[[[[]]]]]]]]]
    [[[[[[[:::::]]]]]]]
 - doanphuc : /
	** author: doanphuc. **
**/
#include <bits/stdc++.h>
#define TASK "SHIFT"
#define inpf freopen(TASK".inp", "r", stdin)
#define outf freopen(TASK".out", "w", stdout)
template<class T> T gcd(T a, T b) { T r; while (b != 0) { r = a % b; a = b; b = r; } return a; }
template<class T> T lcm(T a, T b) { return a / gcd(a, b) * b; }
#define FOR(i,x,y) for(int i = x; i <= y ; i ++)
#define FORT(i,x,y) for(int i = x; i < y ; i ++)
#define FORD(i,x,y) for(int i = x; i >= y ; i --)
#define clean(x) memset(x, 0, sizeof(x))
#define F first
#define S second
#define maxn 100005
#define MOD 1000000007
#define pii pair<int,int>
#define ll long long
#define db double
#define mp make_pair
#define pb push_back
#define yes cout << "YES" << "\n"
#define no  cout << "NO" << "\n"
#define ct(x) cout << x << endl
#define bit(p,x) ((x>>p) & 1)
#define all(x) (x).begin(), (x).end()
#pragma GCC optimize("Ofast,no-stack-protector")
#pragma GCC optimize("unroll-loops")
#define resized(x) (x).resize(unique(all(x)) - (x).begin())
#define fast ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
int prime(int n){ for(int i=2;i*i<=n;i++) if(n%i==0)return 0;return 1; }
void InitPrime(){int pr[maxn] ; fill(pr + 1, pr + 1001, 1); pr[1] = 0; FOR(i, 2, 1000)if (pr[i]) for (int j = i + i; j <= 1000; j += i) pr[j] = 0;}
void AddMOD(int &x, int y){x += y; if (x >= MOD) x -= MOD; }
ll tinh(ll a, ll b,ll c){ if(b == 1) return a%c; ll x = tinh(a,b/2,c); ll y = (1ll*x * x) % c; if ( b % 2 != 0) y = (1ll*y*a) % c; return y;}
ll tinh2(ll a,ll n,ll mod=MOD){a=a<0?(mod-(-a)%mod):(a%mod);ll r=1;while(n){if(n&1)r=r*a%mod;a=a*a%mod;n>>=1;}return r;}
//void rr(){ vector <int> v (a+1, a+n+1); sort(v.begin(), v.end()); v.resize(unique(v.begin(), v.end()) - v.begin());for (int i = 1; i <= n; i++) a[i] = lower_bound(v.begin(), v.end(), a[i]) - v.begin() + 1;}
ll n, m, a[maxn], b[maxn], l[maxn], r[maxn], cnt[maxn], res[maxn], id[maxn], curRes, sz ;
void trau()
{
     FOR(i, 1, n) cin >> a[i] ;
    while(m --)
    {
        int tp ;
        cin >> tp ;
        if(tp == 1)
        {
            int l, r ;
            cin >> l >> r ;
            cnt = 0 ;
            FOR(i, l, r) b[++cnt] = a[i] ;
            a[l] = b[cnt] ;
            cnt = 0 ;
            FOR(i, l + 1, r) a[i] = b[++cnt] ;
        }
        else
        {
            int l, r, k ;
            cin >> l >> r >> k ;
            int dem = 0;
            FOR(i, l, r)
            {
                if(a[i] == k) dem ++ ;
            }
            cout << dem << endl ;
        }
    }
}
//void full()
//{
//    cin >> n >> m ;
//    FOR(i, 1, n) cin >> a[i], b[i] = a[i] ;
//
//}
int main()
{
    inpf; outf; fast;
    cin >> n >> m ;
//    if(n <= 1000 && m <= 1000)
        trau() ;
//    else
//    {
//        full() ;
//    }

}


 /** Fucc :/

 - doanphuc : /
	** author: doanphuc. **
**/
#include <bits/stdc++.h>
#define TASK "SHIFT"
#define inpf freopen(TASK".inp", "r", stdin)
#define outf freopen(TASK".out", "w", stdout)
#define FOR(i,x,y) for(int i = x; i <= y ; i ++)
#define FORT(i,x,y) for(int i = x; i < y ; i ++)
#define FORD(i,x,y) for(int i = x; i >= y ; i --)
#define clean(x) memset(x, 0, sizeof(x))
#define F first
#define S second
#define maxn 100005
#define MOD 1000000007
#define pii pair<int,int>
#define ll long long
#define db double
#define mp make_pair
#define pb push_back
#define bit(p,x) ((x>>p) & 1)
#define all(x) (x).begin(), (x).end()
#pragma GCC optimize("Ofast,no-stack-protector")
#pragma GCC optimize("unroll-loops")
#define fast ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
ll n, m, a[maxn], b[maxn], l[maxn], r[maxn], cnt, res[maxn], id[maxn], curRes, sz ;
void trau()
{
    cin >> n ;
    FOR(i, 1, n) cin >> a[i] ;
    cin >> m ;
    int base = 0 ;
    while(m --)
    {
        int tp, l, r ;
        cin >> tp >> l >> r ;
        l = (l + base + n - 1) % n + 1 ;
        r = (r + base + n - 1) % n + 1 ;
        if(l > r) swap(l,r) ;
        if(tp == 1)
        {
            cnt = 0 ;
            FOR(i, l, r) b[++cnt] = a[i] ;
            a[l] = b[cnt] ;
            cnt = 0 ;
            FOR(i, l + 1, r) a[i] = b[++cnt] ;
        }
        else
        {
            int k ;
            cin >> k ;
            k = (k + base + n - 1) % n + 1;
            base = 0 ;
            FOR(i, l, r)
            {
                if(a[i] == k) base ++ ;
            }
            cout << base << endl ;
        }
    }
}

int main()
{
     ios_base::sync_with_stdio(0);
    cout.tie(0); cin.tie(0);
	if(fopen(TASK".inp","r")){
		inpf; outf;
	}
//    inpf; outf; fast;
//    cin >> n >> m ;
//    if(n <= 1000 && m <= 1000)
        trau() ;
//    else
//    {
//        full() ;
//    }

}


 /** Fucc :/

 - doanphuc : /
	** author: doanphuc. **
**/
#include <bits/stdc++.h>
#define TASK "SHIFT"
#define inpf freopen(TASK".inp", "r", stdin)
#define outf freopen(TASK".out", "w", stdout)
#define FOR(i,x,y) for(int i = x; i <= y ; i ++)
#define FORT(i,x,y) for(int i = x; i < y ; i ++)
#define FORD(i,x,y) for(int i = x; i >= y ; i --)
#define clean(x) memset(x, 0, sizeof(x))
#define F first
#define S second
#define maxn 100005
#define base 100003
#define MOD 1000000007
#define pii pair<int,int>
#define ll long long
#define db double
#define mp make_pair
#define pb push_back
#define bit(p,x) ((x>>p) & 1)
#define all(x) (x).begin(), (x).end()
#define fast ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
int n, m, B, f[700][maxn] ;
vector<int> Block[700] ;
int Get_Block(int x)
{
    return (x + B - 1) / B ;
}
int Erase(int pos)
{
    FOR(i, 1, B)
    {
        if(pos > Block[i].size())
        {
            pos -= Block[i].size() ;
            continue;
        }
        int res = Block[i][pos - 1] ;
        Block[i].erase(Block[i].begin() + pos - 1) ;
        f[i][res] -- ;
        return res ;
    }
}

void Insert(int pos, int val)
{
    FOR(i, 1, B)
    {
        if(pos > Block[i].size())
        {
            pos -= Block[i].size() ;
            continue ;
        }
        Block[i].insert(Block[i].begin() + pos - 1,val) ;
        f[i][val] ++ ;
        return;
    }
}

int Count(int pos, int val)
{
    int res = 0 ;
    FOR(i, 1, B)
    {
        if(pos > Block[i].size())
        {
            res += f[i][val] ;
            pos -= Block[i].size() ;
            continue ;
        }
        FORT(j, 0, pos) res += (Block[i][j] == val) ;
        return res ;
    }
}
void ReBuild()
{
    vector<int> a ;
    FOR(i, 1, B)
    {
        for(auto v : Block[i])
        {
            f[i][v] -- ;
            a.pb(v) ;
        }
        Block[i].clear() ;
    }
    FOR(i, 1, n)
    {
        int x = Get_Block(i) ;
        Block[x].pb(a[i - 1]) ;
        f[x][a[i - 1]] ++ ;
    }
}
int main()
{
//    inpf ; outf ;
    fast ;
    cin >> n ;
    B = sqrt(n) + 1 ;
    FOR(i, 1, n )
    {
        int x ;
        cin >> x ;
        int pos = Get_Block(i);
        Block[pos].pb(x) ;
        f[pos][x]++ ;
    }
    int ans = 0, res = 0;
    cin >> m;
    for(int i = 1;i <= m;++i)
    {
        int t,l,r;
        cin >> t >> l >> r;
        l = (l + ans + n - 1) % n + 1;
        r = (r + ans + n - 1) % n + 1;
        if(l > r) swap(l,r);
        if(t == 1)
        {
            int x = Erase(r);
            Insert(l,x);
            res++;
        }
        else
        {
            int k; cin >> k ;
            k = (k + ans + n - 1) % n + 1 ;
            int R = Count(r,k);
            int L = Count(l - 1,k) ;
            ans = R - L;
            cout << R - L << "\n" ;
        }
        if(res == B) ReBuild(), res = 0;
    }
}


 /** Fucc :/

 - doanphuc : /
	** author: doanphuc. **
**/
#include <bits/stdc++.h>
#define TASK "SHIFT"
#define inpf freopen(TASK".inp", "r", stdin)
#define outf freopen(TASK".out", "w", stdout)
#define FOR(i,x,y) for(int i = x; i <= y ; i ++)
#define FORT(i,x,y) for(int i = x; i < y ; i ++)
#define FORD(i,x,y) for(int i = x; i >= y ; i --)
#define clean(x) memset(x, 0, sizeof(x))
#define F first
#define S second
#define maxn 100005
#define base 100003
#define MOD 1000000007
#define pii pair<int,int>
#define ll long long
#define db double
#define mp make_pair
#define pb push_back
#define bit(p,x) ((x>>p) & 1)
#define all(x) (x).begin(), (x).end()
#define fast ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
int n, m, B, f[605][maxn] ;
vector<int> Block[605] ;
int Get_Block(int x)
{
    return (x + B - 1) / B ;
}
int Erase(int pos)
{
    FOR(i, 1, B)
    {
        if(pos > Block[i].size())
        {
            pos -= Block[i].size() ;
            continue;
        }
        int res = Block[i][pos - 1] ;
        Block[i].erase(Block[i].begin() + pos - 1) ;
        f[i][res] -- ;
        return res ;
    }
}

void Insert(int pos, int val)
{
    FOR(i, 1, B)
    {
        if(pos > Block[i].size())
        {
            pos -= Block[i].size() ;
            continue ;
        }
        Block[i].insert(Block[i].begin() + pos - 1,val) ;
        f[i][val] ++ ;
        return;
    }
}

int Count(int pos, int val)
{
    int res = 0 ;
    FOR(i, 1, B)
    {
        if(pos > Block[i].size())
        {
            res += f[i][val] ;
            pos -= Block[i].size() ;
            continue ;
        }
        FORT(j, 0, pos) res += (Block[i][j] == val) ;
        return res ;
    }
}
void ReBuild()
{
    vector<int> a ;
    FOR(i, 1, B)
    {
        for(auto v : Block[i])
        {
            f[i][v] -- ;
            a.pb(v) ;
        }
        Block[i].clear() ;
    }
    FOR(i, 1, n)
    {
        int x = Get_Block(i) ;
        Block[x].pb(a[i - 1]) ;
        f[x][a[i - 1]] ++ ;
    }
}
int main()
{
//    inpf ; outf ;
    fast ;
    cin >> n ;
    B = sqrt(n) + 1 ;
    FOR(i, 1, n )
    {
        int x ;
        cin >> x ;
        int pos = Get_Block(i);
        Block[pos].pb(x) ;
        f[pos][x]++ ;
    }
    int ans = 0, res = 0;
    cin >> m;
    for(int i = 1;i <= m;++i)
    {
        int t,l,r;
        cin >> t >> l >> r;
        l = (l + ans + n - 1) % n + 1;
        r = (r + ans + n - 1) % n + 1;
        if(l > r) swap(l,r);
        if(t == 1)
        {
            int x = Erase(r);
            Insert(l,x);
            res++;
        }
        else
        {
            int k; cin >> k ;
            k = (k + ans + n - 1) % n + 1 ;
            int R = Count(r,k);
            int L = Count(l - 1,k) ;
            ans = R - L;
            cout << R - L << "\n" ;
        }
        if(res == B) ReBuild(), res = 0;
    }
}


 /** Fucc :/

 - doanphuc : /
	** author: doanphuc. **
**/
#include <bits/stdc++.h>
#define TASK "SHIFT"
#define inpf freopen(TASK".inp", "r", stdin)
#define outf freopen(TASK".out", "w", stdout)
#define FOR(i,x,y) for(int i = x; i <= y ; i ++)
#define FORT(i,x,y) for(int i = x; i < y ; i ++)
#define FORD(i,x,y) for(int i = x; i >= y ; i --)
#define clean(x) memset(x, 0, sizeof(x))
#define F first
#define S second
#define maxn 100005
#define MOD 1000000007
#define pii pair<int,int>
#define ll long long
#define db double
#define mp make_pair
#define pb push_back
#define bit(p,x) ((x>>p) & 1)
#define all(x) (x).begin(), (x).end()
#pragma GCC optimize("Ofast,no-stack-protector")
#pragma GCC optimize("unroll-loops")
#define fast ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
ll n, m, B, cnt[700][maxn] ;
vector<int> Block[700] ;
int Get_Block(int x)
{
    return (x + B - 1) / B ;
}
int Erase(int pos)
{
    for(int i = 1; i <= B; ++i)
    {
        if(pos > Block[i].size())
        {
            pos -= Block[i].size();
            continue;
        }
        int res = Block[i][pos - 1];
        Block[i].erase(Block[i].begin() + pos - 1);
        cnt[i][res] --;
        return res;
    }
}

void Insert(int pos,int val)
{
    for(int i = 1; i <= B; ++i)
    {
        if(pos > Block[i].size())
        {
            pos -= Block[i].size();
            continue;
        }
        Block[i].insert(Block[i].begin() + pos - 1,val);
        cnt[i][val] ++;
        return;
    }
}

int Count(int pos,int val)
{
    int res = 0;
    for(int i = 1; i <= B; ++i)
    {
        if(pos > Block[i].size())
        {
            res += cnt[i][val] ;
            pos -= Block[i].size() ;
            continue ;
        }
        FORT(j, 0, pos) res += Block[i][j] == val ;
        return res ;
    }
}

void ReBuild()
{
    vector<int> a;
    for(int i = 1; i <= B; ++i)
    {
        for(auto v : Block[i])
        {
            cnt[i][v] -- ;
            a.pb(v) ;
        }
        Block[i].clear() ;
    }
    FOR(i, 1, n)
    {
        int x = Get_Block(i) ;
        Block[x].pb(a[i - 1]) ;
        cnt[x][a[i - 1]] ++ ;
    }
}

int main()
{
//    inpf; outf; fast;
    cin >> n ;
    B = sqrt(n) + 1 ;
    FOR(i, 1, n)
    {
        int x ;
        cin >> x ;
        int pos = Get_Block(i) ;
        Block[pos].pb(x) ;
        cnt[pos][x]++ ;
    }
    int ans = 0, numquery = 0;
    cin >> m ;
    for(int i = 1;i <= m;++i)
    {
        int t,l,r;
        cin >> t >> l >> r;
        l = (l + ans + n - 1) % n + 1;
        r = (r + ans + n - 1) % n + 1;
        if(l > r) swap(l,r);
        if(t == 1)
        {
            int x = Erase(r);
            Insert(l,x);
            numquery++;
        }
        else
        {
            int k; cin >> k;
            k = (k + ans + n - 1) % n + 1;
            int R = Count(r,k);
            int L = Count(l - 1,k);
            ans = R - L;
            cout << R - L << "\n";
        }
        if(numquery == B)
        {
            ReBuild();
            numquery = 0;
        }
    }
}


 /** Fucc :/

 - doanphuc : /
	** author: doanphuc. **
**/
#include <bits/stdc++.h>
#define TASK "SHIFT"
#define inpf freopen(TASK".inp", "r", stdin)
#define outf freopen(TASK".out", "w", stdout)
#define FOR(i,x,y) for(int i = x; i <= y ; i ++)
#define FORT(i,x,y) for(int i = x; i < y ; i ++)
#define FORD(i,x,y) for(int i = x; i >= y ; i --)
#define clean(x) memset(x, 0, sizeof(x))
#define F first
#define S second
#define maxn 100005
#define base 100003
#define MOD 1000000007
#define pii pair<int,int>
#define ll long long
#define db double
#define mp make_pair
#define pb push_back
#define bit(p,x) ((x>>p) & 1)
#define all(x) (x).begin(), (x).end()
#pragma GCC optimize("Ofast,no-stack-protector")
#pragma GCC optimize("unroll-loops")
#define fast ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
int n,m,B;
int cnt[605][maxn];
vector<int> Block[605];
int Get_Block(int x){
    return (x + B - 1) / B;
}

int Erase(int pos){
    for(int i = 1;i <= B;++i){
        if(pos > Block[i].size()){
            pos -= Block[i].size();
            continue;
        }
        int res = Block[i][pos - 1];
        Block[i].erase(Block[i].begin() + pos - 1);
        cnt[i][res] --;
        return res;
    }
}

void Insert(int pos,int val){
    for(int i = 1;i <= B;++i){
        if(pos > Block[i].size()){
            pos -= Block[i].size();
            continue;
        }
        Block[i].insert(Block[i].begin() + pos - 1,val);
        cnt[i][val] ++;
        return;
    }
}

int Count(int pos,int val){
    int res = 0;
    for(int i = 1;i <= B;++i){
        if(pos > Block[i].size()){
            res += cnt[i][val];
            pos -= Block[i].size();
            continue;
        }
        for(int j = 0;j < pos;++j) res += Block[i][j] == val;
        return res;
    }
}

void ReBuild(){
    vector<int> a;
    for(int i = 1;i <= B;++i){
        for(auto v : Block[i]){
            cnt[i][v] --;
            a.pb(v);
        }
        Block[i].clear();
    }
    for(int i = 1;i <= n;++i){
        int x = Get_Block(i);
        Block[x].pb(a[i - 1]);
        cnt[x][a[i - 1]] ++;
    }
}

int main(){
    inpf; outf; fast;
    cin >> n;
    B = sqrt(n) + 1;
    for(int i = 1;i <= n;++i){
        int a; cin >> a;
        int pos = Get_Block(i);
        Block[pos].pb(a);
        cnt[pos][a]++;
    }
    int ans = 0,numquery = 0;
    cin >> m;
    for(int i = 1;i <= m;++i){
        int t,l,r;
        cin >> t >> l >> r;
        l = (l + ans + n - 1) % n + 1;
        r = (r + ans + n - 1) % n + 1;
        if(l > r) swap(l,r);
        if(t == 1){
            int x = Erase(r);
            Insert(l,x);
            numquery++;
        } else {
            int k; cin >> k;
            k = (k + ans + n - 1) % n + 1;
            int R = Count(r,k);
            int L = Count(l - 1,k);
            ans = R - L;
            cout << R - L << "\n";
        }
        if(numquery == B){
            ReBuild();
            numquery = 0;
        }
    }
}


 /** Fucc :/

 - doanphuc : /
	** author: doanphuc. **
**/
#include <bits/stdc++.h>
#define TASK "SHIFT"
#define inpf freopen(TASK".inp", "r", stdin)
#define outf freopen(TASK".out", "w", stdout)
#define FOR(i,x,y) for(int i = x; i <= y ; i ++)
#define FORT(i,x,y) for(int i = x; i < y ; i ++)
#define FORD(i,x,y) for(int i = x; i >= y ; i --)
#define clean(x) memset(x, 0, sizeof(x))
#define F first
#define S second
#define maxn 100005
#define base 100003
#define MOD 1000000007
#define pii pair<int,int>
#define ll long long
#define db double
#define mp make_pair
#define pb push_back
#define bit(p,x) ((x>>p) & 1)
#define all(x) (x).begin(), (x).end()
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC optimize("unroll-loops")
#define fast ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
int n,m,B;
int cnt[605][maxn];
vector<int> Block[605];
int Get_Block(int x){
    return (x + B - 1) / B;
}

int Erase(int pos){
    for(int i = 1;i <= B;++i){
        if(pos > Block[i].size()){
            pos -= Block[i].size();
            continue;
        }
        int res = Block[i][pos - 1];
        Block[i].erase(Block[i].begin() + pos - 1);
        cnt[i][res] --;
        return res;
    }
}

void Insert(int pos,int val){
    for(int i = 1;i <= B;++i){
        if(pos > Block[i].size()){
            pos -= Block[i].size();
            continue;
        }
        Block[i].insert(Block[i].begin() + pos - 1,val);
        cnt[i][val] ++;
        return;
    }
}

int Count(int pos,int val){
    int res = 0;
    for(int i = 1;i <= B;++i){
        if(pos > Block[i].size()){
            res += cnt[i][val];
            pos -= Block[i].size();
            continue;
        }
        for(int j = 0;j < pos;++j) res += Block[i][j] == val;
        return res;
    }
}

void ReBuild(){
    vector<int> a;
    for(int i = 1;i <= B;++i){
        for(auto v : Block[i]){
            cnt[i][v] --;
            a.pb(v);
        }
        Block[i].clear();
    }
    for(int i = 1;i <= n;++i){
        int x = Get_Block(i);
        Block[x].pb(a[i - 1]);
        cnt[x][a[i - 1]] ++;
    }
}

int main(){
//    inpf; outf; fast;
    cin >> n;
    B = sqrt(n) + 1;
    for(int i = 1;i <= n;++i){
        int a; cin >> a;
        int pos = Get_Block(i);
        Block[pos].pb(a);
        cnt[pos][a]++;
    }
    int ans = 0,numquery = 0;
    cin >> m;
    for(int i = 1;i <= m;++i){
        int t,l,r;
        cin >> t >> l >> r;
        l = (l + ans + n - 1) % n + 1;
        r = (r + ans + n - 1) % n + 1;
        if(l > r) swap(l,r);
        if(t == 1){
            int x = Erase(r);
            Insert(l,x);
            numquery++;
        } else {
            int k; cin >> k;
            k = (k + ans + n - 1) % n + 1;
            int R = Count(r,k);
            int L = Count(l - 1,k);
            ans = R - L;
            cout << R - L << "\n";
        }
        if(numquery == B){
            ReBuild();
            numquery = 0;
        }
    }
}


 /** Fucc :/

 - doanphuc : /
	** author: doanphuc. **
**/
#include <bits/stdc++.h>
#define TASK "SHIFT"
#define inpf freopen(TASK".inp", "r", stdin)
#define outf freopen(TASK".out", "w", stdout)
#define FOR(i,x,y) for(int i = x; i <= y ; i ++)
#define FORT(i,x,y) for(int i = x; i < y ; i ++)
#define FORD(i,x,y) for(int i = x; i >= y ; i --)
#define clean(x) memset(x, 0, sizeof(x))
#define F first
#define S second
#define maxn 100005
#define MOD 1000000007
#define pii pair<int,int>
#define ll long long
#define db double
#define mp make_pair
#define pb push_back
#define bit(p,x) ((x>>p) & 1)
#define all(x) (x).begin(), (x).end()
#pragma GCC optimize("Ofast,no-stack-protector")
#pragma GCC optimize("unroll-loops")
#define fast ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
//ll n, m, a[maxn], b[maxn], l[maxn], r[maxn], cnt, res[maxn], id[maxn], curRes, sz ;
int n, a[maxn], cnt, m, b[maxn] ;
//void trau()
//{
//    cin >> n ;
//    FOR(i, 1, n) cin >> a[i] ;
//    cin >> m ;
//    int base = 0 ;
//    while(m --)
//    {
//        int tp, l, r ;
//        cin >> tp >> l >> r ;
//        l = (l + base + n - 1) % n + 1 ;
//        r = (r + base + n - 1) % n + 1 ;
//        if(l > r) swap(l,r) ;
//        if(tp == 1)
//        {
//            cnt = 0 ;
//            FOR(i, l, r) b[++cnt] = a[i] ;
//            a[l] = b[cnt] ;
//            cnt = 0 ;
//            FOR(i, l + 1, r) a[i] = b[++cnt] ;
//        }
//        else
//        {
//            int k ;
//            cin >> k ;
//            k = (k + base + n - 1) % n + 1;
//            base = 0 ;
//            FOR(i, l, r)
//            {
//                if(a[i] == k) base ++ ;
//            }
//            cout << base << '\n' ;
//        }
//    }
//}
//void trau()
//{
//    cin >> n;
//    for(int i = 1;i <= n;++i) cin >> a[i];
//    int ans = 0;
//    cin >> m;
//    for(int i = 1;i <= m;++i){
//        int t,l,r;
//        cin >> t >> l >> r;
//        l = (l + ans + n - 1) % n + 1;
//        r = (r + ans + n - 1) % n + 1;
//        if(l > r) swap(l,r);
//        if(t == 1){
//            int pos = a[r];
//            for(;r > l;--r) a[r] = a[r - 1];
//            a[l] = pos;
//        } else {
//            int k; cin >> k;
//            k = (k + ans + n - 1) % n + 1;
//            ans = 0;
//            for(;l <= r;++l) ans += (a[l] == k);
//            cout << ans << "\n";
//        }
//    }
//}
int main()
{
     ios_base::sync_with_stdio(0);
    cout.tie(0); cin.tie(0);
	if(fopen(TASK".inp","r")){
		inpf; outf;
	}
//    inpf; outf; fast;
//    cin >> n >> m ;
//    if(n <= 1000 && m <= 1000)
      cin >> n ;
    FOR(i, 1, n) cin >> a[i] ;
    cin >> m ;
    int base = 0 ;
    while(m --)
    {
        int tp, l, r ;
        cin >> tp >> l >> r ;
        l = (l + base + n - 1) % n + 1 ;
        r = (r + base + n - 1) % n + 1 ;
        if(l > r) swap(l,r) ;
        if(tp == 1)
        {
            cnt = 0 ;
            FOR(i, l, r) b[++cnt] = a[i] ;
            a[l] = b[cnt] ;
            cnt = 0 ;
            FOR(i, l + 1, r) a[i] = b[++cnt] ;
        }
        else
        {
            int k ;
            cin >> k ;
            k = (k + base + n - 1) % n + 1;
            base = 0 ;
            FOR(i, l, r)
            {
                if(a[i] == k) base ++ ;
            }
            cout << base << '\n' ;
        }
    }
//    else
//    {
//        full() ;
//    }

}


#include<bits/stdc++.h>
using namespace std;
int n,q,bz,l,r,k;
deque<int>block[350];
int cnt[350][100005],lastan;

void decode(int num)
{
    if(num==1)
    {
        l = ((l+lastan-1)%n)+1;
        r = ((r+lastan-1)%n)+1;
    }

    if(num==2)
    {
        l = ((l+lastan-1)%n)+1;
        r = ((r+lastan-1)%n)+1;
        k  = ((k+lastan-1)%n)+1;
    }
}

void update(int L,int R)
{
    int  bn = R/bz,i;
    int lastnum = block[R/bz][R%bz];
    block[R/bz].erase(block[R/bz].begin()+R%bz);
    cnt[R/bz][lastnum]--;

    block[L/bz].insert((block[L/bz].begin()+L%bz),lastnum);
    cnt[L/bz][lastnum]++;

    for(i=L/bz;i<(R/bz);i++)
    {
        lastnum = block[i].back();
        block[i].pop_back();
        block[i+1].push_front(lastnum);

        cnt[i][lastnum]--;
        cnt[i+1][lastnum]++;

    }

}

int query(int L,int R ,int K)
{
    int ans=0;
    while(L<=R && L%bz!=0 && L!=0)
    {
        ans +=(block[L/bz][L%bz]==K);
        L++;
    }

    while(L+bz -1<=R)
    {
        ans+=cnt[L/bz][K];
        L+=bz;
    }

    while(L<=R)
    {
        ans +=(block[L/bz][L%bz]==K);
        L++;
    }

    return ans;
}

int main()
{
    int i,x,bn=-1;
    cin>>n;
    bz = sqrt(n);
    for(i=0;i<n;i++)
    {
        cin>>x;
        if(i%bz==0)
        {
            bn++;
        }
        block[bn].push_back(x);
        cnt[bn][x]++;
    }
    cin>>q;
    int num;

    while(q--)
    {
        cin>>num;

        if(num==1)
        {
            cin>>l>>r;
            decode(num);
            if(r<l) swap(l,r);
            update(l-1,r-1);
        }
        else{
            cin>>l>>r>>k;
            decode(num);
            if(r<l) swap(l,r);
            lastan=query(l-1,r-1,k);
            cout<<lastan<<endl;
        }

    }

    return 0;
}


#include<bits/stdc++.h>
#define mod %
using namespace std;
typedef long long ll;
int n,q;
int arra[100010];
//vector<ll>block[350];
int cnt[350][100010];
int bz,l,r,k,lastan=0;

void decode(int num)
{
    if(num==1)
    {
        l = ((l+lastan-1)mod n)+1;
        r = ((r+lastan-1)mod n)+1;
    }

    if(num==2)
    {
        l = ((l+lastan-1)mod n)+1;
        r = ((r+lastan-1)mod n)+1;
        k = ((k+lastan-1)mod n)+1;
    }
}

//void block_build()
//{
//    int bn=-1,i;
//
//    for(i=0; i<n; i++)
//    {
//        if(i%bz==0)
//        {
//            bn++;
//            // block[bn].clear();
//            memset(cnt[bn],0,sizeof(cnt[bn]));
////
////            if(bn-1>=0)
////            {
////               sort(block[bn-1].begin(),block[bn-1].end());
////            }
//        }
////        cnt[bn][arra[i]]=0;
//        cnt[bn][arra[i]]++;
//        // block[bn].push_back(arra[i]);
//    }
//}

int query(int L,int R,int K)
{
    int ans=0;
    while(L<=R && L%bz!=0 && L!=0)
    {
        if(arra[L]==K) ans++;
        L++;
    }

    while(L+bz-1<=R)
    {
        int bn = L/bz;
        ans+=cnt[bn][K];
//        int lower = lower_bound(block[bn].begin(), block[bn].end(), K) - block[bn].begin();
//        int upper = upper_bound(block[bn].begin(), block[bn].end(), K) - block[bn].begin();
//        ans+=(upper-lower);
        L+=bz;

    }

    while(L<=R)
    {
        if(arra[L]==K)
            ans++;
        L++;
    }
    return ans;
}

void update(int L, int R)
{

    int ele=arra[R],i,bn;
    for(i=R-1; i>=L; i--)
    {
        bn = (i+1)/bz;
        cnt[bn][arra[i+1]]--;

        arra[i+1]=arra[i];

        cnt[bn][arra[i+1]]++;
    }
    bn= L/bz;
    cnt[bn][arra[L]]--;

    arra[L]=ele;

    cnt[bn][arra[L]]++;

}

int main()
{
    int i,bn=-1;
    cin>>n;
    bz=sqrt(n);
    for(i=0; i<n; i++)
    {
        if(i%bz==0)
        {
            bn++;
        }
        cin>>arra[i];
        cnt[bn][arra[i]]++;
    }

   // block_build();
    cin>>q;

    int num;
    while(q--)
    {
        cin>>num;
        if(num==1)
        {
            cin>>l>>r;

            decode(num);
            if(r<l)swap(l,r);

            update(l-1,r-1);

        }

        else
        {
            cin>>l>>r>>k;

            decode(num);
            if(r<l)swap(l,r);
            lastan  = query(l-1,r-1,k);
            cout<<lastan<<endl;

        }
    }
    return 0;
}


#include<bits/stdc++.h>
#define mod %
using namespace std;
int n,q;
int arra[100005];
vector<int>block[350];
int bz,l,r,k,lastan=0;

void decode(int num)
{
    if(num==1)
    {
        l = ((l+lastan-1)mod n)+1;
        r = ((r+lastan-1)mod n)+1;
    }

    if(num==2)
    {
        l = ((l+lastan-1)mod n)+1;
        r = ((r+lastan-1)mod n)+1;
        k = ((k+lastan-1)mod n)+1;
    }
}

void block_build()
{
    int bn=-1,i;

    for(i=0;i<n;i++)
    {
        if(i%bz==0)
        {
            bn++;
            block[bn].clear();

            if(bn-1>=0)
            {
                sort(block[bn-1].begin(),block[bn-1].end());
            }
        }
        block[bn].push_back(arra[i]);
    }
}

int query(int L,int R,int K)
{
    int ans=0;
    while(L<R && L%bz!=0 && L!=0)
    {
        if(arra[L]==K) ans++;
        L++;
    }

    while(L+bz-1<=R)
    {
        int bn = L/bz;
        int lower = lower_bound(block[bn].begin(),block[bn].end(),K)-block[bn].begin();
        int upper = upper_bound(block[bn].begin(),block[bn].end(),K)-block[bn].begin();
        ans+=(upper-lower);
        L+=bz;

    }

    while(L<=R)
    {
        if(arra[L]==K)
            ans++;
        L++;
    }
    return ans;
}

void update(int L, int R)
{

    int ele=arra[R],i;

    for(i=R-1;i>=L;i--)
    {
        arra[i+1]=arra[i];
//        int bn = (i+1)/bz;
//        block[bn].push_back(arra[i+1]);

    }
    arra[L]=ele;

//    int bn_l = L/bz;
//    int bn_r = R/bn;
//    for(i=bn;i<=bn_r;i++)
//    {
//        sort(block[i].begin(),block[i].end());
//    }

    block_build();

}

int main()
{
  int i;
    cin>>n;
    bz=sqrt(n);
        for(i=0;i<n;i++)
        {
            cin>>arra[i];
        }

        block_build();
        cin>>q;

        int num;
        while(q--)
        {
            cin>>num;
            if(num==1)
            {
                cin>>l>>r;
                 l--;
                 r--;
                decode(num);
                if(r<l)swap(l,r);

                update(l,r);

            }

            else {
                cin>>l>>r>>k;
                l--;
                r--;
                decode(num);
                //cout<<l<<" "<<r<<endl;
                if(r<l)swap(l,r);
               // cout<<l<<" "<<r<<endl;
                lastan  = query(l,r,k);
                cout<<lastan<<endl;

            }
        }
    return 0;
}


#include<bits/stdc++.h>
#define mod %
using namespace std;
int n,q;
int arra[100005];
vector<int>block[350];
int bz,l,r,k,lastan=0;

void decode(int num)
{
    if(num==1)
    {
        l = ((l+lastan-1)mod n)+1;
        r = ((r+lastan-1)mod n)+1;
    }

    if(num==2)
    {
        l = ((l+lastan-1)mod n)+1;
        r = ((r+lastan-1)mod n)+1;
        k = ((k+lastan-1)mod n)+1;
    }
}

void block_build()
{
    int bn=-1,i;

    for(i=0;i<n;i++)
    {
        if(i%bz==0)
        {
            bn++;
            block[bn].clear();

            if(bn-1>=0)
            {
                sort(block[bn].begin(),block[bn].end());
            }
        }
        block[bn].push_back(arra[i]);
    }
}

int query(int L,int R,int K)
{
    int ans=0;
    while(L<=R && L%bz!=0 && L!=0)
    {
        if(arra[L]==K) ans++;
        L++;
    }

    while(L+bz-1<=R)
    {
        int bn = L/bz;
        int lower = lower_bound(block[bn].begin(),block[bn].end(),K)-block[bn].begin();
        int upper = upper_bound(block[bn].begin(),block[bn].end(),K)-block[bn].begin();
        ans+=(upper-lower);
        L+=bz;

    }

    while(L<=R)
    {
        if(arra[L]==K)
            ans++;
        L++;
    }
    return ans;
}

void update(int L, int R)
{

    int ele=arra[R],i;

    for(i=R-1;i>=L;i--)
    {
        arra[i+1]=arra[i];
//        int bn = (i+1)/bz;
//        block[bn].push_back(arra[i+1]);

    }
    arra[L]=ele;

//    int bn_l = L/bz;
//    int bn_r = R/bn;
//    for(i=bn;i<=bn_r;i++)
//    {
//        sort(block[i].begin(),block[i].end());
//    }

    block_build();

}

int main()
{
  int i;
    cin>>n;
    bz=sqrt(n);
        for(i=0;i<n;i++)
        {
            cin>>arra[i];
        }

        block_build();
        cin>>q;

        int num;
        while(q--)
        {
            cin>>num;
            if(num==1)
            {
                cin>>l>>r;
                decode(num);
                if(r<l)swap(l,r);
                update(l-1,r-1);

            }

            else {
                cin>>l>>r>>k;
                decode(num);
                if(r<l)swap(l,r);
                lastan  = query(l-1,r-1,k);
                cout<<lastan<<endl;

            }
        }
    return 0;
}


#include<bits/stdc++.h>
#define mod %
using namespace std;
int n,q;
int arra[100005];
vector<int>block[350];
int cnt[350][100005];
int bz,l,r,k,lastan=0;

void decode(int num)
{
    if(num==1)
    {
        l = ((l+lastan-1)mod n)+1;
        r = ((r+lastan-1)mod n)+1;
    }

    if(num==2)
    {
        l = ((l+lastan-1)mod n)+1;
        r = ((r+lastan-1)mod n)+1;
        k = ((k+lastan-1)mod n)+1;
    }
}

void block_build()
{
    int bn=-1,i;

    for(i=0;i<n;i++)
    {
        if(i%bz==0)
        {
            bn++;
           // block[bn].clear();
            memset(cnt[bn],0,sizeof(cnt[bn]));
//
//            if(bn-1>=0)
//            {
//               sort(block[bn-1].begin(),block[bn-1].end());
//            }
        }
//        cnt[bn][arra[i]]=0;
        cnt[bn][arra[i]]++;
       // block[bn].push_back(arra[i]);
    }
}

int query(int L,int R,int K)
{
    int ans=0;
    while(L<R && L%bz!=0 && L!=0)
    {
        if(arra[L]==K) ans++;
        L++;
    }

    while(L+bz-1<=R)
    {
        int bn = L/bz;
        ans+=cnt[bn][K];
//        int lower = lower_bound(block[bn].begin(), block[bn].end(), K) - block[bn].begin();
//        int upper = upper_bound(block[bn].begin(), block[bn].end(), K) - block[bn].begin();
//        ans+=(upper-lower);
        L+=bz;

    }

    while(L<=R)
    {
        if(arra[L]==K)
            ans++;
        L++;
    }
    return ans;
}

void update(int L, int R)
{

    int ele=arra[R],i,bn;
//    bn= R/bz;
//    cnt[bn][arra[R]]--;

    for(i=R-1;i>=L;i--)
    {
         bn = (i+1)/bz;
        cnt[bn][arra[i+1]]--;
        arra[i+1]=arra[i];

       // int bn2 = (i)/bz;

         cnt[bn][arra[i+1]]++;
//       int bn = (i+1)/bz;
//       block[bn].push_back(arra[i+1]);

    }
         bn= L/bz;
         cnt[bn][arra[L]]--;

        arra[L]=ele;

        cnt[bn][arra[L]]++;

//    int bn_l = L/bz;
//    int bn_r = R/bn;
//    for(i=bn;i<=bn_r;i++)
//    {
//        sort(block[i].begin(),block[i].end());
//    }

   // block_build();

}

int main()
{
  int i;
    cin>>n;
    bz=sqrt(n);
        for(i=0;i<n;i++)
        {
            cin>>arra[i];
        }

        block_build();
        cin>>q;

        int num;
        while(q--)
        {
            cin>>num;
            if(num==1)
            {
                cin>>l>>r;

                decode(num);
                if(r<l)swap(l,r);

                update(l-1,r-1);

            }

            else {
                cin>>l>>r>>k;

                decode(num);
                if(r<l)swap(l,r);
                lastan  = query(l-1,r-1,k);
                cout<<lastan<<endl;

            }
        }
    return 0;
}