#include <bits/stdc++.h>
#define ll long long
using namespace std;
struct odt
{
ll l,r;
mutable ll v;
odt(ll l, ll r = 0, ll v = 0) : l(l), r(r), v(v) {}
bool operator<(const odt &a) const
{
return l < a.l;
}
};
set<odt> Chtholly;
ll a[10005],n,m,x,y,op,l,r,vmax,seed;
ll rnd()
{
ll ret=seed;
ll seed=(seed*7+13)%1000000007;
return ret;
}
set<odt>::iterator split(int p)
{
set<odt>::iterator it=Chtholly.lower_bound(odt(p));
if (it!=Chtholly.end()&&it->l==p)
{
return it;
}
it--;
if (it->r<p) return Chtholly.end();
ll l = it->l;
ll r = it->r;
ll v = it->v;
Chtholly.erase(it);
Chtholly.insert(odt(l, p-1,v));
return Chtholly.insert(odt(p,r,v)).first;
}
void add(ll l, ll r, ll x)
{
set<odt>::iterator itr=split(r+1),itl=split(l);
for (set<odt>::iterator it = itl;it!=itr;it++)
{
it->v+=x;
}
}
void assign(ll l,ll r,ll x)
{
set<odt>::iterator itr=split(r+1),itl=split(l);
Chtholly.erase(itl,itr);
Chtholly.insert(odt(l,r,x));
}
int find_k(ll l,ll r,ll x)
{
set<odt>::iterator itr=split(r+1),itl=split(l);
int cnt=0;
set<odt>::iterator i=itl;
while(cnt<x)
{
cnt+=(i->r-i->l+1);
i++;
}
return i->v;
}
ll cal(ll l,ll r,ll x,ll y)
{
set<odt>::iterator itr = split(r+1),itl=split(l);
ll ans = 0;
for (set<odt>::iterator i = itl; i!=itr;i++)
{
int sum=1;
int p=x,b=i->v;
while(p>0)
{
if(p%2!=0)
{
sum=sum*b%y;
}
b=b*b%y;
p/=2;
}
sum%=y;
ans+=sum;
ans%=y;
}
return ans;
}
int main()
{
cin>>n>>m>>vmax>>seed;
for (ll i=1;i<=n;i++){a[i]=(rnd()%vmax)+1;}
for (ll i=1;i<=m;i++)
{
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);
}
if (op==2)
{
assign(l,r,x);
}
if (op==3)
{
cout<<find_k(l,r,x)<<endl;
}
if (op==4)
{
cout<<cal(l,r,x,y)<<endl;
}
}
return 0;
}