#include <cstdio>
#include <cstring>
#include <vector>

typedef unsigned long long ull;
const int MOD = 998244353;
const int INV2 = 499122177;
const int N = 2e6 + 10;
const int S = 75;
const int LIM = 2e7;

ull seed;
ull rd(ull &x) {
	x ^= (x << 13);
	x ^= (x >> 7);
	x ^= (x << 17);
	return x;
}

struct Matrix {
	int p, q;
	ull mat[S][S];
	void init(int p, int q) {
		this->p = p, this->q = q;
		for (int i = 0; i < p; ++i) {
			for (int j = 0; j < q; ++j) {
				mat[i][j] = 0;
			}
		}
		return;
	}
	void operator*=(Matrix &k) {
		static ull x[S][S], y[S][S];
		for (int i = 0; i < p; ++i) {
			for (int j = 0; j < q; ++j) {
				x[i][j] = mat[i][j];
			}
		}
		for (int i = 0; i < k.p; ++i) {
			for (int j = 0; j < k.q; ++j) {
				y[i][j] = k.mat[i][j];
			}
		}
		q = k.q;
		for (int i = 0; i < p; ++i) {
			for (int j = 0; j < q; ++j) {
				mat[i][j] = 0;
			}
		}
		for (int k = 0; k < q; ++k) {
			for (int i = 0; i < p; ++i) {
				for (int j = 0; j < q; ++j) {
					(mat[i][j] += x[i][k] * y[k][j]) %= MOD;
				}
			}
		}
		return;
	}
	void pow(Matrix &res, ull k) {
		static Matrix f;
		f.init(p, q);
		res.init(p, q);
		for (int i = 0; i < p; ++i) {
			res.mat[i][i] = 1;
			for (int j = 0; j < q; ++j) {
				f.mat[i][j] = mat[i][j];
			}
		}
		while (k) {
			if (k & 1) res *= f;
			f *= f;
			k >>= 1;
		}
		return;
	}
} F, val, tmp;

void solve() {
	int n, q, x; ull k_max;
	scanf("%d%d%d%llu", &n, &q, &x, &k_max);
	--x;
	std::vector<int> a(n);
	for (int i = 0; i < n; ++i) {
		scanf("%d", &a[i]);
	}
	ull ans = 0;
	if (k_max <= LIM && n * k_max <= LIM) {
		std::vector<int> f(k_max);
		f[0] = a[x];
		for (int i = 1; i < k_max; ++i) {
			std::vector<int> b(a);
			for (int j = 0; j < n; ++j) {
				a[j] = (ull)(b[j / 2] + b[n - j / 2 - 1]) * INV2 % MOD;
			}
			f[i] = a[x];
		}
		for (int i = 1; i <= q; ++i) {
			ull k = rd(seed) % k_max;
			ans ^= (ull)f[k] * i;
		}
		printf("%llu\n", ans);
		return;
	}
	std::vector<int> f;
	while (~n & 1) {
		f.push_back(a[x]);
		n >>= 1;
		for (int i = 0; i < n; ++i) {
			a[i] = (ull)(a[i] + a[n * 2 - i - 1]) * INV2 % MOD;
		}
		a.resize(n);
		x >>= 1;
	}
	F.init(n, n);
	for (int i = 0; i < n - 1; ++i) {
		F.mat[i / 2][i] = INV2;
		F.mat[n - i / 2 - 1][i] = INV2;
	}
	F.mat[n / 2][n - 1] = 1;
	for (int i = 1; i <= q; ++i) {
		ull k = rd(seed) % k_max;
		if (k < f.size()) ans ^= (ull)f[k] * i;
		else {
			F.pow(tmp, k - f.size());
			val.init(1, n);
			for (int i = 0; i < n; ++i) {
				val.mat[0][i] = a[i];
			}
			val *= tmp;
			ans ^= val.mat[0][x] * i;
		}
	}
	printf("%llu\n", ans);
	return;
}
int main() {
	freopen("noodle.in", "r", stdin);
	freopen("noodle.out", "w", stdout);

	int test, T;
	scanf("%d%d%llu", &test, &T, &seed);
	while (T--) solve();
	return 0;
}