#include <bits/stdc++.h>   using namespace std;   void read(long long &x) {     x = 0;     char c = getchar();     int f = 1;     while (!(c >=  0  && c <=  9 )) {       if (c ==  - ) f = -1;       c = getchar();     }     while ((c >=  0  && c <=  9 )) {       x = (x << 1) + (x << 3) + (c ^ 48);       c = getchar();     }     x *= f;   }   void output(long long x) {     if (x < 0) {       x = -x;       putchar( - );     }     if (x > 9) output(x / 10);     putchar(x % 10 +  0 );   }   struct node {     long long l, r;     mutable long long val;     node(long long L) : l(L) {}     node(long long L, long long R, long long VAL) : l(L), r(R), val(VAL) {}   };   bool operator<(node x, node y) { return x.l < y.l; }   set<node> s;   set<node>::iterator split(long long pos) {     set<node>::iterator it = s.lower_bound(node(pos));     if (it != s.end() && it->l == pos) return it;     it--;     long long l = it->l, r = it->r, val = it->val;     s.erase(it);     s.insert(node(l, pos - 1, val));     return s.insert(node(pos, r, val)).first;   }   void add(long long l, long long r, long long x) {     set<node>::iterator it2 = split(r + 1), it1 = split(l);     for (set<node>::iterator it = it1; it != it2; ++it) {       it->val += x;     }   }   long long kth(long long l, long long r, long long x) {     set<node>::iterator it2 = split(r + 1), it1 = split(l);     vector<pair<long long, long long> > v;     v.clear();     for (set<node>::iterator it = it1; it != it2; ++it) {       v.push_back(pair<long long, long long>(it->val, it->r - it->l + 1));     }     sort(v.begin(), v.end());     for (long long i = 0; i < v.size(); ++i) {       x -= v[i].second;       if (x <= 0) return v[i].first;     }   }   long long ksm(long long a, long long b, long long c) {     a %= c;     long long ans = 1;     while (b) {       if (b & 1) ans = (ans * a) % c;       a = (a * a) % c;       b >>= 1;     }     return ans;   }   long long query(long long l, long long r, long long x, long long y) {     long long ans = 0;     set<node>::iterator it2 = split(r + 1), it1 = split(l);     for (set<node>::iterator it = it1; it != it2; ++it) {       ans = (ans + (it->r - it->l + 1) * ksm(it->val, x, y) % y) % y;     }     return ans;   }   void assign(long long l, long long r, long long k) {     set<node>::iterator it2 = split(r + 1), it1 = split(l);     s.erase(it1, it2);     s.insert(node(l, r, k));   }   long long n, m, seed, vmax;   long long op, l, r, x, y;   long long rnd() {     long long ret = seed;     seed = (seed * 7 + 13) % 1000000007;     return ret;   }   void SWAP(long long &x, long long &y) {     x ^= y;     y ^= x;     x ^= y;   }   int main() {     read(n), read(m), read(seed), read(vmax);     for (long long i = 1; i <= n; ++i) {       x = (rnd() % vmax) + 1;       s.insert(node(i, i, x));     }     for (long long 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 == 1) {         x = (rnd() % vmax) + 1;         add(l, r, x);       } else if (op == 2) {         x = (rnd() % vmax) + 1;         assign(l, r, x);       } else if (op == 3) {         x = (rnd() % (r - l + 1)) + 1;         output(kth(l, r, x));         putchar(  n );       } else {         x = (rnd() % vmax) + 1;         y = (rnd() % vmax) + 1;         output(query(l, r, x, y));         putchar(  n );       }     }     return 0;   }