#include <bits/stdc++.h>
using namespace std;
const long long MOD = 1000000007;
int n, m, t;
long long seed, valmax;
struct p {
  int l, r;
  mutable long long val;
  p(int L, int R = -1, long long V = 0) : l(L), r(R), val(V) {}
  bool operator<(const p &o) const { return l < o.l; }
};
set<p> S;
vector<pair<long long, int> > G;
inline long long rnd() {
  long long ret = seed;
  seed = (seed * 7 + 13) % MOD;
  return ret;
}
inline long long quickpow(long long a, long long b, long long mod) {
  long long ans = 1;
  a %= mod;
  while (b) {
    if (b & 1) ans = ans * a % mod;
    a = a * a % mod;
    b >>= 1;
  }
  return ans % mod;
}
inline set<p>::iterator split(int pos) {
  set<p>::iterator it = S.lower_bound(p(pos));
  if (it != S.end() && it->l == pos) return it;
  it--;
  if (pos > it->r) return S.end();
  int L = it->l, R = it->r;
  long long V = it->val;
  S.erase(it);
  S.insert(p(L, pos - 1, V));
  return S.insert(p(pos, R, V)).first;
}
inline void add(int l, int r, long long val = 1) {
  set<p>::iterator itr = split(r + 1), itl = split(l);
  for (; itl != itr; itl++) itl->val += val;
}
inline void Assign(int l, int r, long long val = 0) {
  set<p>::iterator itr = split(r + 1), itl = split(l);
  S.erase(itl, itr);
  S.insert(p(l, r, val));
}
inline long long Rank(int l, int r, int k, bool reversed = 0) {
  if (reversed) k = r - l + 2 - k;
  set<p>::iterator itr = split(r + 1), itl = split(l);
  G.clear();
  for (; itl != itr; itl++) G.push_back({itl->val, itl->r - itl->l + 1});
  sort(G.begin(), G.end());
  int len = G.size();
  for (int i = 0; i < len; i++) {
    k -= G[i].second;
    if (k <= 0) return G[i].first;
  }
  return -1;
}
inline long long Sum(int l, int r, int ex, int mod) {
  set<p>::iterator itr = split(r + 1), itl = split(l);
  long long res = 0;
  for (; itl != itr; itl++)
    res =
        (res + (long long)(itl->r - itl->l + 1) * quickpow(itl->val, ex, mod)) %
        mod;
  return res;
}
int main() {
  cin >> n >> m >> seed >> valmax;
  for (int i = 1; i <= n; i++) S.insert(p(i, i, (rnd() % valmax + 1)));
  int op, l, r, x, y;
  for (int 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() % valmax + 1;
    if (op == 4) y = rnd() % valmax + 1;
    if (op == 1)
      add(l, r, x);
    else if (op == 2)
      Assign(l, r, x);
    else if (op == 3) {
      cout << Rank(l, r, x) << endl;
    } else {
      cout << Sum(l, r, x, y) << endl;
    }
  }
  return 0;
}
