#include <bits/stdc++.h>
using namespace std;
template<typename T>
inline void read(T &x) {
	x = 0;
	char ch = getchar();
	while (!isdigit(ch))
		ch = getchar();
	while (isdigit(ch))
		x = x * 10 + ch - 48, ch = getchar();
}
const int P = 998244353, inv2 = (P + 1) / 2;
inline void add(int &x, int y) {
	(x += y) >= P && (x -= P);
}
inline void sub(int &x, int y) {
	(x -= y) < 0 && (x += P);
}
inline void mul(int &x, int y) {
	x = 1ull * x * y % P;
}
inline int Add(int x, int y) {
	return add(x, y), x;
}
inline int Sub(int x, int y) {
	return sub(x, y), x;
}
inline int Mul(int x, int y) {
	return mul(x, y), x;
}

const int N = 2000005;
int n, q, x, a[N], b[N], res[505];
long long k_max;
	unsigned long long seed;
	struct matrix {
	int a[155][155];
	matrix() {
		memset(a, 0, sizeof a);
	}
	void init() {
		for (int i = 1; i <= n; ++i)
			a[i][i] = 1;
	}
	inline matrix operator*(const matrix &rhs) {
		matrix res;
		for (int i = 1; i <= n; ++i)
			for (int j = 1; j <= n; ++j)
				for (int k = 1; k <= n; ++k)
					add(res.a[i][j], Mul(a[i][k], rhs.a[k][j]));
		return res;
	}
};
unsigned long long rd(unsigned long long &x) {
	x ^= (x << 13);
	x ^= (x >> 7);
	x ^= (x << 17);
	return x;
}
namespace brute {
	void solve() {
		for (int t = 0; t <= k_max; ++t) {
			res[t] = a[x];
			for (int i = 1; i <= n / 2; ++i)
				b[i] = Add(a[i], a[n - i + 1]);
			for (int i = 1; i <= n / 2; ++i)
				a[2 * i - 1] = a[2 * i] = Mul(b[i], inv2);
		}
		long long ans = 0;
		for(int i = 1; i <= q; ++i) {
			long long k = rd(seed) % k_max;
			ans ^= 1ll * i * res[k];
		}
		printf("%lld\n", ans);
	}
}
matrix power(matrix a, int t) {
	matrix res;
	res.init();
	while (t) {
		if (t & 1) res = res * a;
		a = a * a;
	}
	return res;
}
int main() {
	freopen("noodle.in", "r", stdin);
	freopen("noodle.out", "w", stdout);
	int test, T;
	read(test), read(T), read(seed);
	for(int Case = 1; Case <= T; ++Case) {
		read(n), read(q), read(x), read(k_max);
		for(int i = 1; i <= n; ++i) 
			read(a[i]);
		if (test <= 2) {
			brute::solve();
		} else {
			int k = 0;
			while (n % (1 << k) == 0)
				++k;
			if (n == (1 << k)) {
				res[0] = a[x];
				for (int t = 0; t <= k + 5; ++t) {
					res[t] = a[x];
					for (int i = 1; i <= n / 2; ++i)
						b[i] = Add(a[i], a[n - i + 1]);
					for (int i = 1; i <= n / 2; ++i)
						a[2 * i - 1] = a[2 * i] = Mul(b[i], inv2);
				}
				long long ans = 0;
				for(int i = 1; i <= q; ++i) {
					long long x = rd(seed) % k_max;
					ans ^= 1ll * i * res[min(k + 5ll, x)];
				}
				printf("%lld\n", ans);
			} else {
				matrix b;
				vector<int> a(n + 1);
				for (int i = 1; i <= n; ++i)
					a[i] = ::a[i];
				for (int i = 1; i <= n; ++i) {
					int x = min(i, n - i + 1);
					b.a[i][2 * x - 1] = b.a[i][2 * x] = inv2; 
				}
				vector<pair<long long, int>> qry;
				for(int i = 1; i <= q; ++i) {
					long long k = rd(seed) % k_max;
					qry.emplace_back(k, i);
				}
				sort(qry.begin(), qry.end());
				long long ans = 0, last = 0;
				for (auto it : qry) {
					long long cur = it.first;
					vector<int> c(n + 1);
					auto q = power(b, cur - last);
					for (int i = 1; i <= n; ++i)
						for (int j = 1; j <= n; ++j)
							add(c[j], Mul(a[i], q.a[i][j]));
					a = c;
					ans ^= 1ll * it.second * a[x];
					last = cur;
				}
				printf("%lld\n", ans);
			}
		}
	}
}
