#include <bits/stdc++.h>   using namespace std;   inline long long read() {     long long s = 0, w = 1;     char ch = getchar();     while (ch < 48 || ch > 57) {       if (ch ==  - ) w = -1;       ch = getchar();     }     while (ch >= 48 && ch <= 57)       s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();     return s * w;   }   const long long N = 1e5 + 5, P = 1e9 + 7;   struct ChthollyTree {     map<long long, long long> s;     inline long long find(long long p) { return s.lower_bound(p)->second; }     inline void split(long long p) {       long long pos = find(p);       s[p] = pos;     }     inline pair<map<long long, long long>::iterator,                 map<long long, long long>::iterator>     range(long long l, long long r) {       split(l - 1), split(r);       return make_pair(s.find(l - 1), s.find(r));     }   } T;   long long n, m, seed, vmax, a[N], sum[N], len;   struct Node {     long long val, cnt;   } A[N];   inline bool cmp(Node x, Node y) { return x.val < y.val; }   inline long long rnd() {     long long res = seed;     seed = (seed * 7ll + 13ll) % P;     return res;   }   inline long long qpow(long long x, long long y, long long p) {     long long ans = 1, res = x % p;     while (y) {       if (y & 1) ans = (ans * res) % p;       y >>= 1;       res = (res * res) % p;     }     return ans % p;   }   signed main() {     n = read(), m = read(), seed = read(), vmax = read();     for (register long long i = 1; i <= n; ++i) {       a[i] = (rnd() % vmax) + 1;       T.s[i] = a[i];     }     while (m--) {       long long op = (rnd() % 4) + 1, l = (rnd() % n) + 1, r = (rnd() % n) + 1, x,                 y;       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;       map<long long, long long>::iterator st, ed;       if (op == 1) {         pair<map<long long, long long>::iterator,              map<long long, long long>::iterator>             border = T.range(l, r);         st = border.first, ed = border.second;         while (st != ed) ed->second += x, ed--;       } else if (op == 2) {         pair<map<long long, long long>::iterator,              map<long long, long long>::iterator>             border = T.range(l, r);         st = border.first, ed = border.second;         while (st != ed) T.s.erase(ed--);         T.s[r] = x;       } else if (op == 3) {         long long nxt;         len = 0;         for (register long long i = l; i <= r; i = nxt + 1) {           map<long long, long long>::iterator now = T.s.lower_bound(i);           nxt = min(r, now->first);           A[++len] = (Node){now->second, nxt - i + 1};         }         sort(A + 1, A + len + 1, cmp);         for (register long long i = 1; i <= len; ++i)           sum[i] = sum[i - 1] + A[i].cnt;         long long L = 1, R = len, res = -1;         while (L <= R) {           long long mid = (L + R) >> 1;           if (sum[mid] >= x)             res = mid, R = mid - 1;           else             L = mid + 1;         }         printf( %lld n , A[res].val);       } else {         long long Ans = 0;         long long nxt;         for (register long long i = l; i <= r; i = nxt + 1) {           map<long long, long long>::iterator now = T.s.lower_bound(i);           nxt = min(r, now->first);           Ans = (Ans + qpow(now->second, x, y) * (nxt - i + 1) % y) % y;         }         printf( %lld n , Ans % y);       }     }     return 0;   }