rt
#include <bits/stdc++.h>
#define int long long
#define sort stable_sort
using namespace std;
int n, m, seed, vmax;
int rnd(){
int ret = seed;
seed = (seed * 7 + 13) % 1000000007;
return ret;
}
int a[100010];
struct Node{
int l, r;
mutable int v;
Node(int l, int r = 0, int v = 0) : l(l), r(r), v(v) {};
bool operator<(Node y) const{
return l < y.l;
}
};
set<Node> s;
set<Node>::iterator split(int x){
set<Node>::iterator it = s.lower_bound(Node(x));
if (it -> l == x) return it;
it--;
if (it -> r < x) return s.end();
int l = it -> l, r = it -> r, v = it -> v;
s.erase(it);
s.insert(Node(l, x - 1, v));
return s.insert(Node(x, r, v)).first;
}
void assign(int l, int r, int v){
set<Node>::iterator itr = split(r + 1), itl = split(l);
for (set<Node>::iterator it = itl; it != itr; it++){
it -> v = v;
}
}
void add(int l, int r, int x){
set<Node>::iterator itr = split(r + 1), itl = split(l);
for (set<Node>::iterator it = itl; it != itr; it++){
it -> v += x;
}
}
struct Rk{
int cnt, v;
bool operator<(Rk y) const{
return v < y.v;
}
};
int getKMin(int l, int r, int k){
set<Node>::iterator itr = split(r + 1), itl = split(l);
vector<Rk> b;
for (set<Node>::iterator it = itl; it != itr; it++){
b.push_back(Rk{(it -> r) - (it -> l) + 1, it -> v});
}
sort(b.begin(), b.end());
int kk = k;
for (int i = 0; i < b.size(); i++){
if (kk > b[i].cnt){
kk -= b[i].cnt;
}
else{
return b[i].v;
}
}
}
int qpow(int a, int b, int p){
if (b == 1){
return a % p;
}
int c = qpow(a, b / 2, p);
c = c * c % p;
if (b & 1){
c = c * a % p;
}
return c;
}
int getSum(int l, int r, int x, int y){
int ans = 0;
set<Node>::iterator itr = split(r + 1), itl = split(l);
for (set<Node>::iterator it = itl; it != itr; it++){
ans = (ans + qpow(it -> v, x, y) * ((it -> r) - (it -> l) + 1) % y) % y;
}
return ans;
}
signed main(){
ios::sync_with_stdio(false);
cin >> n >> m >> seed >> vmax;
for (int i = 1; i <= n; i++){
a[i] = rnd() % vmax + 1;
s.insert(Node(i, i, a[i]));
}
for (int i = 1; i <= m; i++){
int op = rnd() % 4 + 1, l = rnd() % n + 1, r = rnd() % n + 1, x, y;
if (l > r){
swap(l, r);
}
if (op == 3){
x = rnd() % (r - l + 1) + 1;
}
else{
x = rnd() % vmax + 1;
}
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){
cout << getKMin(l, r, x) << endl;
}
else{
cout << getSum(l, r, x, y) << endl;
}
}
return 0;
}