#include <bits/stdc++.h>
using namespace std;
map<int, long long> mp;
int n, m, l, r, x, y, seed, maxVal, op;
vector<pair<long long, int>> v;
int rnd() {
  int s = seed;
  seed = (1LL * seed * 7 + 13) % 1000000007;
  return s;
}
long long pw(long long a, long long b) {
  return b ? b & 1 ? a * pw(a, b - 1) % y : pw(a * a % y, b >> 1) : 1;
}
int main() {
  cin >> n >> m >> seed >> maxVal;
  for (int i = 1; i <= n; i++) mp[i] = rnd() % maxVal + 1;
  mp[n + 1] = 0;
  while (m--) {
    op = rnd() % 4 + 1;
    l = rnd() % n + 1;
    r = rnd() % n + 1;
    if (l > r) swap(l, r);
    r++;
    if (op == 3) {
      x = rnd() % (r - l) + 1;
    } else
      x = rnd() % maxVal + 1;
    if (op == 4) y = rnd() % maxVal + 1;
    auto L = --mp.upper_bound(l);
    if (L->first != l) mp[l] = L->second, L++;
    auto R = --mp.upper_bound(r);
    if (R->first != r) mp[r] = R->second, R++;
    if (op == 1) {
      while (L != R) L++->second += x;
    } else if (op == 2) {
      while (L != R) mp.erase(L++), mp[l] = x;
    } else if (op == 3) {
      v.clear();
      for (int d; L != R;)
        d = R--->first, v.push_back({R->second, d - R->first});
      sort(v.begin(), v.end());
      for (auto i : v)
        if (x <= i.second) {
          printf("%I64d\n", i.first);
          break;
        } else
          x -= i.second;
    } else {
      long long ans = 0;
      for (int d; L != R;)
        d = R--->first, (ans += pw(R->second % y, x) * (d - R->first)) %= y;
      printf("%I64d\n", ans);
    }
  }
}
