rt
#include<bits/stdc++.h>
using namespace std;
#define int long long
struct _ {
int l, r;
mutable long long v;
};
bool operator<(_ a, _ b) {
return a.l < b.l;
}
set<_>odt;
using IT = set<_>::iterator;
IT split(int p) {
IT it = odt.lower_bound({p, 0, 0});
if (it != odt.end() && it->l == p)return it;
it--;
if (it->r < p)
return odt.end();
int l = it->l, r = it->r;
long long v = it->v;
odt.erase(it);
odt.insert({l, p - 1, v});
return odt.insert({p, r, v}).first;
}
void assign(int l, int r, long long v) {
//puts("A");
IT itr = split(r + 1), itl = split(l);
odt.erase(itl, itr);
odt.insert({l, r, v});
}
void add(int l, int r, long long v) {
//puts("B");
IT itr = split(r + 1), itl = split(l);
for (IT it = itl; it != itr; ++it)
it->v += v;
}
long long rnk(int l, int r, int x) {
//puts("C");
vector<_>v;
IT itr = split(r + 1), itl = split(l);
for (IT it = itl; it != itr; ++it) {
int L = it->l, R = it->r, V = it->v;
v.push_back({L, R, V});
}
sort(v.begin(), v.end(), [](_ a, _ b) {
return a.v < b.v;
});
int cnt = 0;
for (int i = 0; i < v.size(); ++i) {
cnt += v[i].l - v[i].r + 1;
if (cnt >= x)return v[i].v;
}
}
long long qpow(long long a, long long b, long long m) {
long long res = 1, base = a % m;
while (b) {
if (b & 1)res = res * base % m;
base = base * base % m;
b >>= 1;
}
return res;
}
long long p_s(int l, int r, int x, int y) {
//puts("D");
IT itr = split(r + 1), itl = split(l);
long long res = 0;
for (IT it = itl; it != itr; ++it)
res = (res + (it->l - it->r + 1) * qpow(it->v, x, y)) % y;
return res % y;
}
long long n, m, seed, vmax;
int rnd() {
long long ret = seed;
seed = (seed * 7 + 13) % 1000000007;
return ret;
}
signed main() {
//puts("1");
scanf("%d%d%d%d", &n, &m, &seed, &vmax);
//puts("2");
for (int i = 1; i <= n; ++i)
odt.insert({i, i, rnd()});
//puts("3");
for (int i = 1; i <= m; ++i) {
int op = (rnd() % 4) + 1;
int l = (rnd() % n) + 1;
int r = (rnd() % n) + 1;
//puts("4");
int x, y;
if (l > r)
swap(l, r);
//cout<<"l r"<<l<<" "<<r<<endl;
if (op == 3)
x = (rnd() % (r - l + 1)) + 1;
else
x = (rnd() % vmax) + 1;
//puts("5");
if (op == 4)
y = (rnd() % vmax) + 1;
if (op == 1)
add(l, r, x);
else if (op == 2)
assign(l, r, x);
else if (op == 3)
printf("%lld\n", rnk(l, r, x));
else
printf("%lld\n", p_s(l, r, x, y));
}
return 0;
}