#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MOD = 1000000007;
const ll MAXN = 100005;
struct Node
{
ll l,r;
mutable ll v;
Node(ll l, ll r=0, ll v=0):l(l),r(r),v(v) {}
bool operator<(const Node &a) const
{
return l<a.l;
}
};
set<Node> s;
ll n, m, seed, vmax, a[MAXN];
set<Node>::iterator Split(int pos)
{
set<Node>::iterator it=s.lower_bound(Node(pos));
if (it != s.end() && it->l == pos)
return it;
it--;
if (it->r < pos)
return s.end();
s.erase(it);
s.insert(Node(it->l, pos-1, it->v));
return s.insert(Node(pos, it->r, it->v)).first;
}
void Add(ll l, ll r, ll x)
{
set<Node>::iterator itr=Split(r+1), itl=Split(l);
for (set<Node>::iterator it=itl; it!=itr; ++it)
it->v+=x;
}
void Assign(ll l, ll r, ll x)
{
set<Node>::iterator itr=Split(r+1), itl=Split(l);
s.erase(itl, itr);
s.insert(Node(l, r, x));
}
struct Rank
{
ll num, cnt;
bool operator<(const Rank &a) const
{
return num < a.num;
}
Rank(ll num, ll cnt) : num(num), cnt(cnt) {}
};
ll Rnk(ll l, ll r, ll x)
{
set<Node>::iterator itr=Split(r+1), itl=Split(l);
vector<Rank> v;
for (set<Node>::iterator i = itl; i != itr; ++i)
v.push_back(Rank(i->v, i->r-i->l+1));
sort(v.begin(), v.end());
int i;
for (i = 0; i < v.size(); ++i)
if (v[i].cnt < x)
x -= v[i].cnt;
else
break;
return v[i].num;
}
ll QuickPower(ll x, ll y, ll p)
{
ll r = 1;
ll base = x % p;
while (y)
{
if (y & 1)
r = r * base % p;
base = base * base % p;
y >>= 1;
}
return r;
}
ll CalP(ll l, ll r, ll x, ll y)
{
set<Node>::iterator itr=Split(r+1), itl=Split(l);
ll ans=0;
for (set<Node>::iterator i=itl; i!=itr; ++i)
ans=(ans+QuickPower(i->v,x,y)*(i->r-i->l+1)%y)%y;
return ans;
}
ll Rnd()
{
ll ret=seed;
seed=(seed*7+13)%MOD;
return ret;
}
int main()
{
cin>>n>>m>>seed>>vmax;
for (int i = 1; i <= n; ++i)
{
a[i]=(Rnd()%vmax)+1;
s.insert(Node(i, i, a[i]));
}
for (int i=1; i<=m; ++i)
{
ll op, l, r, x, y;
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);
else if (op==2)
Assign(l,r,x);
else if (op==3)
cout<<Rnk(l,r,x)<<endl;
else
cout<<CalP(l,r,x,y)<<endl;
}
return 0;
}