#include<set>
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
#define int long long
using namespace std;
const int N = 1e6 + 10;
const int MAXN = 2e5 + 10;
inline char readchar() {
static char buf[100000], *p1 = buf, *p2 = buf;
return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++;
}
inline int read() {
#define readchar getchar
int res = 0, f = 0;char ch = readchar();
for(; !isdigit(ch); ch = readchar()) if(ch == '-') f = 1;
for(; isdigit(ch); ch = readchar()) res = (res << 1) + (res << 3) + (ch ^ '0');
return f ? -res : res;
}
inline void print(int x) {
if (x < 0 ) putchar('-'), x = -x;
if (x > 9 ) print(x / 10);
putchar(x % 10 + '0');
}
int Qpow(int a, int b, int mod) {
int base = a, res = 1;
while(b) {
if(b & 1) res = (res * base) % mod;
base = (base * base) % mod, b >>= 1;
}return res % mod;
}
int n, m, seed, vmax;
const int Mod = 1e9 + 7;
int Rand() {
int ret = seed;
seed = (seed * 7 + 13) % Mod;
return ret;
}
namespace Chtholly_Tree {
#define It set<node>::iterator
struct node {
int l, r;
mutable int v;
node (int L, int R = -1, int V = 0) { l = L, r = R, v = V; }
bool operator < (const node &x) const { return l < x.l; }
};
set <node> s;
It Spilt(int pos) {
It it = s.lower_bound(node(pos));
if(it != s.end() && it->l == pos) return it;
--it;
int L = it -> l, R = it -> r, V = it -> v;
s.erase(it);
s.insert(node(L, pos - 1, V));
return s.insert(node(pos, R, V)).first;
}
void Add(int l, int r, int Val) {
It it2 = Spilt(r + 1), it1 = Spilt(l);
for(; it1 != it2; it1++) it1 -> v += Val;
}
void Cover(int l, int r, int Val) {
It it2 = Spilt(r + 1), it1 = Spilt(l);
s.erase(it1, it2); s.insert(node(l, r, Val));
}
int Rank(int l, int r, int k) {
vector <pair<int, int > > vec;
It it2 = Spilt(r + 1), it1 = Spilt(l);
vec.clear();
for(; it1 != it2; it1++) {
vec.push_back(pair <int, int> (it1 -> v, it1 -> r - it1 -> l + 1));
}
sort(vec.begin(), vec.end());
for(vector <pair <int, int>>::iterator it = vec.begin(); it != vec.end(); it++) {
k -= it -> second;
if(k <= 0) return it -> first;
}
return -1ll;
}
int Query(int l, int r, int p, int mod) {
It it2 = Spilt(r + 1), it1 = Spilt(l);
int res = 0;
for(; it1 != it2; it1++) {
res = (res + (it1 -> r - it1 -> l + 1) * Qpow(it1 -> v, p, mod) ) % mod;
}
return res;
}
}
using namespace Chtholly_Tree;
signed main() {
n = read(), m = read(), seed = read(), vmax = read();
for(int i = 1; i <= n; i++) {
int x = Rand() % vmax + 1;
s.insert(node(i, i, x));
}
s.insert(node(n + 1, n + 1, 0));
for(int i = 1, opt, l, r, x, y; i <= m; ++i) {
opt = Rand() % 4 + 1, l = Rand() % n + 1, r = Rand() % n + 1;
if(l > r) swap(l, r);
if(opt == 3) x = Rand() % (r - l + 1) + 1;
else x = Rand() % vmax + 1;
if(opt == 4) y = Rand() % vmax + 1;
if(opt == 1) {
Add(l, r, x);
} else if(opt == 2) {
Cover(l, r, x);
} else if(opt == 3) {
printf("%lld\n", Rank(l, r, x));
} else {
printf("%lld\n", Query(l, r, x, y));
}
}
return 0;
}