#include<bits/stdc++.h>
#define ll long long
using namespace std;
namespace IO{
const int SIZE=1<<21;
static char ibuf[SIZE],obuf[SIZE],*iS,*iT,*oS=obuf,*oT=oS+SIZE-1;
int qr;
char qu[55],c;
bool f;
#define getchar() (IO::iS==IO::iT?(IO::iT=(IO::iS=IO::ibuf)+fread(IO::ibuf,1,IO::SIZE,stdin),(IO::iS==IO::iT?EOF:*IO::iS++)):*IO::iS++)
#define putchar(x) *IO::oS++=x,IO::oS==IO::oT?flush():0
#define flush() fwrite(IO::obuf,1,IO::oS-IO::obuf,stdout),IO::oS=IO::obuf
#define puts(x) IO::Puts(x)
template<typename T>
inline void read(T&x){
for(f=1,c=getchar();c<48||c>57;c=getchar())f^=c=='-';
for(x=0;c<=57&&c>=48;c=getchar()) x=(x<<1)+(x<<3)+(c&15);
x=f?x:-x;
}
template<typename T>
inline void write(T x){
if(!x) putchar(48); if(x<0) putchar('-'),x=-x;
while(x) qu[++qr]=x%10^48,x/=10;
while(qr) putchar(qu[qr--]);
}
struct Flusher_{~Flusher_(){flush();}}io_flusher_;
}
using IO::read;
using IO::write;
struct Node{
int l,r;
mutable ll v;
inline bool operator<(const Node &x)const{return l<x.l;}
};
set<Node>odt;
inline auto split(int x){
auto it=odt.lower_bound(Node{x,0,0});
if(it!=odt.end()&&it->l==x)return it;
--it;
int l=it->l,r=it->r,v=it->v;
odt.erase(it),odt.insert(Node{l,x-1,v});
return odt.insert(Node{x,r,v}).first;
}
inline void ass(int l,int r,int x){
auto itr=split(r+1),itl=split(l);
odt.erase(itl,itr),odt.insert(Node{l,r,x});
}
inline void add(int l,int r,int x) {
auto itr=split(r+1),it=split(l);
for(;it!=itr;++it)
it->v+=x;
}
inline ll qpow(ll n,int p,int m){
ll ans=1;
while(p>0){
if(p&1) ans=ans*n%m;
p>>=1,n*=n,n%=m;
}
return ans;
}
inline ll askpow(int l,int r,int x,int y) {
auto itr=split(r+1),it=split(l);
ll ans(0);
for(;it!=itr;++it)
ans+=((it->r-it->l+1)%y)*qpow((it->v),x,y),ans%=y;
return ans;
}
vector<pair<ll,int> >a;
inline ll Rank(int l,int r,int x){
auto itr=split(r+1),it=split(l);
a.clear();
for(;it!=itr;++it)
a.push_back(make_pair(it->v,(it->r-it->l+1)));
sort(a.begin(),a.end());
for(auto IT=a.begin();IT!=a.end();++IT){
x-=IT->second;
if(x<=0)return IT->first;
}
return 1145141919;
}
ll seed;
ll rnd(){
ll ret=seed;
seed=(seed*7+13)%1000000007;
return ret;
}
int main(){
int n,q,vmax;
read(n),read(q),read(seed),read(vmax);
for(int i=1;i<=n;i++)
odt.insert(Node{i,i,(rnd()%vmax)+1});
while(q--){
int op(rnd()%4+1),l(rnd()%n+1),r(rnd()%n+1),x,y;
if(l>r)l^=r,r^=l,l^=r;
if(op==1){
x=(rnd()%vmax)+1;
add(l,r,x);
}else
if(op==2){
x=(rnd()%vmax)+1;
ass(l,r,x);
}else
if(op==3){
x=(rnd()%(r-l+1))+1;
write(Rank(l,r,x)),putchar(10);
}else{
x=(rnd()%vmax)+1,y=(rnd()%vmax)+1;
write(askpow(l,r,x,y)),putchar(10);
}
}
return 0;
}
记录