record
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
struct node_t{
int l,r; mutable ll v;
node_t(int l):l(l){}
node_t(int l,int r,int v):l(l),r(r),v(v){}
friend bool operator<(const node_t&a,const node_t&b){
return a.l<b.l;
}
};
set<node_t> odt;
auto split(int x){
auto it=--odt.upper_bound(node_t(x));
if(it->l==x) return it;
auto[l,r,v]=*it;
odt.erase(it),odt.emplace(l,x-1,v);
return odt.emplace(x,r,v).first;
}
auto get(int l,int r){
auto itr=split(r+1),itl=split(l);
return make_pair(itl,itr);
}
void insert(int l,int r,int v){
odt.emplace(l,r,v);
}
void assign(int l,int r,int v){
auto [itl,itr]=get(l,r);
odt.erase(itl,itr);
odt.emplace(l,r,v);
}
void add(int l,int r,ll v){
auto[itl,itr]=get(l,r);
for(;itl!=itr;++itl) itl->v+=v;
}
ll rank_k(int l,int r,int k){
vector<pair<ll,int>>bucket;
auto[itl,itr]=get(l,r);
for(;itl!=itr;++itl) bucket.push_back({itl->v,itl->r-itl->l+1});
sort(bucket.begin(),bucket.end());
for(auto i:bucket) if((k-=i.second)<=0) return i.first;
return -1;
}
ll pow_mod(ll a,ll b,ll p){
ll res=1%p;
for(a%=p;b;b>>=1,a=a*a%p)
if(b&1) res=res*a%p;
return res;
}
void modify(int l,int r,ll v){
auto[itl,itr]=get(l,r);
for(;itl!=itr;++itl) itl->v=v;
}
ll sumpow(int l,int r,int x,int y){
ll res=0;
auto[itl,itr]=get(l,r);
for(;itl!=itr;++itl){
auto[ll,rr,vv]=*itl;
(res+=(rr-ll+1)*pow_mod(vv,x,y))%=y;
}
return res;
}
const int N=1e5+1;
ll seed,op,l,r,x,y;
ll rnd(){
ll ret=seed;
(seed=seed*7+13)%=1000000007;
return ret;
}
main(){
cin.tie(0)->sync_with_stdio(0);
int n,m,vmax;
cin>>n>>m>>seed>>vmax;
for(int i=1;i<=n;++i) insert(i,i,1+(rnd()%vmax));
insert(n+1,n+1,0);
for(int i=1;i<=m;++i){
op=rnd()%4+1,l=rnd()%n+1,r=rnd()%n+1,x;
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) modify(l,r,x);
else if(op==3) cout<<rank_k(l,r,x)<<'\n';
else cout<<sumpow(l,r,x,y)<<'\n';
}
}