#include<fstream>
#include<vector>
#include<algorithm>

constexpr unsigned long long mod = 998244353, _2 = 499122177;

using namespace std;

ifstream cin("noodle.in");
ofstream cout("noodle.out");

struct query
{
	int i;
	long long k;
	unsigned long long ans;
};

struct mat
{
	int n, m;
	vector<vector<unsigned long long>> v;
	
	mat(int N, int M) : n(N), m(M), v(N, vector<unsigned long long>(M))
	{
	}
};

mat operator*(const mat& x, const mat& y)
{
	int n = x.n, p = x.m, m = y.m;
	mat res{n, m};
	
	for (int i = 0; i < n; ++i)
	{
		for (int j = 0; j < m; ++j)
		{
			for (int k = 0; k < p; ++k)
			{
				res.v[i][j] = (res.v[i][j] + x.v[i][k] * y.v[k][j] % mod) % mod;
			}
		}
	}
	
	return res;
}

mat power(const mat& a, int x)
{
	if (x == 1)
	{
		return a;
	}
	else
	{
		mat half = power(a, x / 2);
		
		if (x % 2 == 1)
		{
			return half * half * a;
		}
		else
		{
			return half * half;
		}
	}
}

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

void fold(vector<unsigned long long>& a)
{
	int n = a.size(), m = (n + 1) / 2;
	
	for (int i = 0; i < m; ++i)
	{
		a[i] = (a[i] + a[n - 1 - i]) * _2 % mod;
	}
	
	a.resize(m);
}

void put_ans(vector<query>& queries, int& to_do, int q, int folded_count, unsigned long long ans)
{
	while (to_do < q ? queries[to_do].k == folded_count : false)
	{
		queries[to_do].ans = ans;
		++to_do;
	}
}

int main()
{
	int test, T;
	unsigned long long seed;
	cin >> test >> T >> seed;
	
	for (int i = 0; i < T; ++i)
	{
		int n, q, x;
		long long kmax;
		cin >> n >> q >> x >> kmax;
		--x;
		
		vector<unsigned long long> a(n);
		
		for (unsigned long long& v : a)
		{
			cin >> v;
		}
		
		vector<query> queries(q);
		
		for (int i = 0; i < q; ++i)
		{
			queries[i] = {i + 1, rd(seed) % kmax, 0};
		}
		
		sort(queries.begin(), queries.end(), [](const query& x, const query& y)
		{
			return x.k < y. k;
		});
		
		int to_do = 0, folded_count = 0, div = 1;
		put_ans(queries, to_do, q, folded_count, a[x]);
		
		while (a.size() % 2 == 0)
		{
			fold(a);
			++folded_count;
			div *= 2;
			put_ans(queries, to_do, q, folded_count, a[x / div]);
		}
		
		fold(a);
		++folded_count;
		div *= 2;
		put_ans(queries, to_do, q, folded_count, a[x / div]);
		
		n = a.size();
		
		mat factor{n, n};
		
		for (int i = 0; i < n - 1; ++i)
		{
			factor.v[i][i / 2] = _2;
			factor.v[i][n - 1 - (i + 1) / 2] = _2;
		}
		
		factor.v[n - 1][(n - 1) / 2] = 1;
		
		mat aT{n, 1};
		
		for (int i = 0; i < n; ++i)
		{
			aT.v[i][0] = a[i];
		}
		
		while (to_do < q)
		{
			int diff = queries[to_do].k - folded_count;
			folded_count = queries[to_do].k;
			aT = power(factor, diff) * aT;
			put_ans(queries, to_do, q, folded_count, aT.v[x / div][0]);
		}
		
		unsigned long long ans = 0;
		
		for (query& q : queries)
		{
			ans ^= q.i * q.ans;
		}
		
		cout << ans << "\n";
	}
	
	return 0;
}
