//#4测试点WA,第175个数字,要求10368000,结果0
#include<iostream>
#include<set>
#include<functional>
#include<vector>
#include<algorithm>
#include<numeric>
using namespace std;
using LL = long long;
LL n, m, seed, vmax;
template<typename T>
class Chtholly{
public:
struct node { LL l, r;mutable T v;bool operator<(const node& bb)const { return l < bb.l; }
node(LL il,LL ir,T iv):l(il),r(ir),v(iv){}
};
set<node>tree;
using IT = decltype(tree.begin());
//把区间[l,r]切分为[l,pos-1]和[pos,r]
//返回以pos开头的那个节点的迭代器
auto split(LL pos){
auto it = tree.lower_bound(node(pos, 0, T()));
if (it == tree.end()) { return it; }
if (it->l == pos) { return it; }
--it;
LL tl = it->l, tr = it->r;
T tv = it->v;
tree.erase(it);
tree.insert(node(tl, pos - 1, tv));
return tree.insert(node(pos, tr, tv)).first;
}
//合并整个区间
void unite() {
LL tl, tr; T tv; auto tofin = tree.end(), temp = tofin; tofin--;
for (auto it = tree.begin();it != tofin;) {
temp = it; temp++;
if (it->v == temp->v) {
tl = it->l; tr = temp->r; tv = it->v;
temp = tree.erase(temp);
it=tree.erase(it);
tree.insert(node(tl, tr, tv));
}
else { ++it; }
}
}
//区间赋值
inline void assign(LL il, LL ir, T iv) {
auto fin = split(ir+1), init = split(il);
tree.erase(init, fin);
tree.insert(node(il, ir, iv));
}
//对某个区间进行变换
inline void cast(LL il, LL ir, function<void(T&)> func) {
auto fin = split(ir + 1),it = split(il);
for (;it != fin;++it) { func(it->v); }
}
//输入数据
inline void insert(LL il, LL ir, T iv) { tree.insert(node(il, ir, iv)); }
//查错用函数,打印整个树
void print() {
for (node i : tree) {
cout << i.l << "-" << i.v <<"-" << i.r << "\t";
}
cout << '\n';
}
//在切割之后弥合断点
inline void repair(decltype(tree.begin()) it) {
auto temp = it; --temp;
if (it!=tree.end()&&it!=tree.begin()&&it->v == temp->v) {
node to_insert(temp->l, it->r, it->v);
tree.erase(it);
tree.erase(temp);
tree.insert(to_insert);
}
}
T operator[](int pos) {
auto it=tree.lower_bound(node(pos, 0, T()));
if (pos < it->l) { --it; }
return it->v;
}
};
//生成随机数
inline LL rnd() {
LL ret = seed;
seed = (seed * 7 + 13) % 1000000007;
return ret;
}
//找到第K个数
LL kth(Chtholly<LL>& ch, LL il, LL ir, LL k) {
vector<pair<LL,LL> >te;
auto fin = ch.split(ir + 1),init= ch.split(il);
for (auto it = init;it != fin;++it) {te.push_back(pair<LL,LL>(it->v, it->r - it->l + 1));}
sort(te.begin(), te.end());
for (auto it = te.begin(), fin2 = te.end();it != fin2;++it) {
k -= it->second;
if (k <= 0){ return it->first; }
}
ch.repair(init); ch.repair(fin);
return -1;
}
//快速幂
LL fm(LL x, LL y, LL mod) {
LL ans = 1;
x = x % mod;
while (y) {
if (y & 1)
ans *= x, ans %= mod;
x *= x, x %= mod;
y >>= 1;
}
return ans % mod;
}
//求区间的次方和在取模
LL bemod(Chtholly<LL>& ch, LL il, LL ir, LL x, LL y) {
auto fin = ch.split(ir + 1),init= ch.split(il);
LL temp = 0;
for (auto it = init;it != fin;++it) {
temp += (it->r - it->l + 1) * fm(it->v, x, y);
temp %= y;
}
ch.repair(init); ch.repair(fin);
return temp;
}
int main(){
cin >> n>> m>> seed>> vmax;
LL N, L, R,X,Y=0;Chtholly<LL> ch;
for (int i = 1; i <= n; ++i) { Y = (rnd() % vmax) + 1; ch.insert(i, i, Y); }
for (int i = 1;i <= m;++i) {
N = (rnd() % 4) + 1;L = (rnd() % n) + 1;R = (rnd() % n) + 1;
if (L > R) { swap(L,R); }
if (N == 3) { X = (rnd() % (R - L + 1)) + 1; }else{ X = (rnd() % vmax) + 1; }
if(N==4){Y= (rnd() % vmax) + 1;}
function<void(LL&)> add([X](LL& a)->void { a += X; });
switch (N) {
case 1:
ch.cast(L, R, add);break;
case 2:
ch.assign(L, R, X);break;
case 3:
cout << kth(ch, L, R, X) << "\n";
break;
case 4:
cout << bemod(ch, L, R, X, Y) << "\n";
}
}
return 0;
}