#include<iostream>
#include<set>
#include<vector>
#include<algorithm>
#include<cstdio>
using namespace std;
typedef long long ll;
#define int long long

const ll mod = 1000000007;
const ll maxn = 100005;

struct node {
	ll l, r;
	mutable ll v;
	node(ll L, ll R = 0, ll V = 0) : l(L), r(R), v(V) {}
	bool operator<(const node& a)const {
		return l < a.l;
	}
};

ll n, m, seed, vmax, a[maxn];
set<node>odt;

#define IT set<node>::iterator

IT split(int pos) {
	IT it = odt.lower_bound(node(pos));
	if (it != odt.end() && it->l == pos)return it;
	it--;
	if (it->r < pos)return odt.end();
	ll l = it->l;
	ll r = it->r;
	ll v = it->v;
	odt.erase(it);
	odt.insert(node(l, pos - 1, v));
	return odt.insert(node(pos, r, v)).first;
}
void add(ll l, ll r, ll x) {
	IT itr = split(r + 1), itl = split(l);
	for (IT it = itl; it != itr; it++)it->v += x;
}
void assign(ll l, ll r, ll x) {
	IT itr = split(r + 1), itl = split(l);
	odt.erase(itl, itr);
	odt.insert(node(l, r, x));
}
struct Rank {
	int num, cnt;
	bool operator<(const Rank& a)const {
		return num < a.num;
	}
	Rank(ll num, ll cnt) :num(num), cnt(cnt) {}
};
ll rnk(ll l, ll r, ll x) {
	IT itr = split(r + 1), itl = split(l);
	vector<Rank>v;
	for (IT i = itl; i != itr; i++) {
		v.push_back(Rank(i->v, i->r - i->l + 1));
	}
	sort(v.begin(), v.end());
	int i;
	for (i = 0; i < v.size(); i++) {
		if (v[i].cnt < x) {
			x -= v[i].cnt;
		}
		else break;
	}
	return v[i].num;
}
ll qpow(ll x, ll y, ll p) {
	//pow(x,y) mod p
	ll r = 1;
	ll base = x % p;
	while (y) {
		if (y & 1)r = r * base % p;
		base = base * base % p;
		y >>= 1;
	}
	return r;
}
ll calp(ll l, ll r, ll x, ll y) {
	IT itr = split(r + 1), itl = split(l);
	ll ans = 0;
	for (IT i = itl; i != itr; i++) {
		ans = (ans + qpow(i->v, x, y) * (i->r - i->l + 1) % y) % y;
	}
	ans %= y;
	return ans;
}
ll rnd() {
	ll ret = seed;
	seed = (seed * 7 + 13) % mod;
	return ret;
}
signed main() {
	cin >> n >> m >> seed >> vmax;
	for (int i = 1; i <= n; i++) {
		a[i] = (rnd() % vmax) + 1;
		odt.insert(node(i, i, a[i]));
	}
	for (int i = 1; i <= n; i++) {
		ll op, l, r, x, y;
		op = rnd() % 4 + 1;
		l = rnd() % n + 1;
		r = rnd() % n + 1;
		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 << rnk(l, r, x) << endl;
		else cout << calp(l, r, x, y) << endl;
	}
	return 0;
}
2023/5/3 20:06
575655