#include<bits/stdc++.h>
#define int long long
#define double long double
#define INF INT_MAX
using namespace std;
const int maxn=1e5+5,mod=1e9+7;
int n,m,seed,cnm;
int a[maxn];
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> ODT;
set<node>::iterator spilit(int pos) {
set<node>::iterator it=ODT.lower_bound(node(pos,-1,0));
if(it!=ODT.end() && it->l==pos) return it;
int V=it->v;
int L=it->l,R=it->r;
ODT.erase(it);
ODT.insert(node(L,pos-1,V));
return ODT.insert(node(pos,R,V)).first;
}
void bulldoze(int l,int r,int x) {
set<node>::iterator itl=spilit(l),itr=spilit(r+1);
ODT.erase(itl,itr);
ODT.insert(node(l,r,x));
}
void add(int l,int r,int x) {
set<node>::iterator itl=spilit(l),itr=spilit(r+1);
for(; itl!=itr; itl++) itl->v+=x;
}
int ksmall(int l,int r,int x) {
vector<pair<int,int> > h;
set<node>::iterator itl=spilit(l),itr=spilit(r+1);
for(; itl!=itr; itl++) h.push_back(pair<int,int>(itl->v,itl->r-itl->l+1));
sort(h.begin(),h.end());
for(vector<pair<int,int> >::iterator it=h.begin(); it!=h.end(); it++) {
x-=it->second;
if(x<=0) return it->first;
}
}
int ksm(int a,int b,int p) {
int res=1;
while(b) {
if(b%2) res=(res*a)%p;
b/=2;
a=(a*a)%p;
}
return res;
}
int section(int l,int r,int sum,int p){
set<node>::iterator itl=spilit(l),itr=spilit(r+1);
int res=0;
for(;itl!=itr;itl++) res=(res+(itl->r-itl->l+1)*ksm(itl->v,sum,p))%p;
}
int randd() {
int ret=seed;
seed=(seed*7+13)%mod;
return ret;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin>>n>>m>>seed>>cnm;
for(int i=1;i<=n;i++){
a[i]=(randd()%cnm)+1;
ODT.insert(node(i,i,a[i]));
}
ODT.insert(node(n+1,n+1,0));
for(int i=1;i<=m;i++){
int op=randd()%4+1;
int l=randd()%n+1;
int r=randd()%n+1,x=0,y=0;
if(l>r) swap(l,r);
if(op==3) x=randd()%(r-l+1)+1;
else x=randd()%cnm+1;
if(op==4) y=rand()%cnm+1;
if(op==1) add(l,r,x);
if(op==2) bulldoze(l,r,x);
if(op==3) cout<<ksmall(l,r,x)<<endl;
if(op==4) cout<<section(l,r,x,y)<<endl;
}
return 0;
}