#include <bits/stdc++.h>
using namespace std;
long long n, m, seed, vmax, op, x, y;
long long a[1000001];
struct node {
  long long l, r;
  mutable long long v;
  node(long long ll, long long rr = -1, long long vv = 0)
      : l(ll), r(rr), v(vv) {}
  bool operator<(const node &u) const { return l < u.l; }
};
set<node> se;
long long poww(long long p, long long q, long long r) {
  long long res = 1, ans = p % r;
  while (q) {
    if (q & 1) res = res * ans % r;
    ans = ans * ans % r;
    q >>= 1;
  }
  return res;
}
set<node>::iterator sp(long long op) {
  set<node>::iterator it = se.lower_bound(node(op));
  if (it != se.end() && it->l == op) return it;
  it--;
  long long ll = it->l, rr = it->r, vv = it->v;
  se.erase(it);
  se.insert(node(ll, op - 1, vv));
  return se.insert(node(op, rr, vv)).first;
}
void ass(long long ll, long long rr, long long vv) {
  set<node>::iterator ir = sp(rr + 1), il = sp(ll);
  se.erase(il, ir);
  se.insert(node(ll, rr, vv));
}
void add(long long ll, long long rr, long long vv) {
  set<node>::iterator itr = sp(rr + 1), itl = sp(ll);
  for (; itl != itr; ++itl) {
    itl->v += vv;
  }
}
long long kth(long long ll, long long rr, long long k) {
  vector<pair<long long, long long> > ve;
  set<node>::iterator itr = sp(rr + 1), itl = sp(ll);
  for (; itl != itr; ++itl) {
    ve.push_back(pair<long long, long long>(itl->v, itl->r - itl->l + 1));
  }
  sort(ve.begin(), ve.end());
  for (vector<pair<long long, long long> >::iterator it = ve.begin();
       it != ve.end(); ++it) {
    k -= it->second;
    if (k <= 0) return it->first;
  }
  return 0;
}
long long rnd() {
  long long ret = seed;
  seed = (seed * 7 + 13) % 1000000007;
  return ret;
}
long long mcf(long long l, long long r, long long x, long long y) {
  set<node>::iterator itr = sp(r + 1), itl = sp(l);
  long long res = 0;
  for (; itl != itr; ++itl) {
    res = (res + (itl->r - itl->l + 1) * poww(itl->v, x, y) % y) % y;
  }
  return res;
}
signed main() {
  scanf("%lld%lld%lld%lld", &n, &m, &seed, &vmax);
  for (long long i = 1; i <= n; ++i) {
    a[i] = rnd() % vmax + 1;
    se.insert(node(i, i, a[i]));
  }
  for (long long i = 1; i <= m; ++i) {
    long long 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);
    }
    if (op == 2) {
      ass(l, r, x);
    }
    if (op == 3) {
      printf("%lld\n", kth(l, r, x));
    }
    if (op == 4) {
      printf("%lld\n", mcf(l, r, x, y));
    }
  }
  return 0;
}
