The Red Kingdom is attacked by the White King and the Black King!

The Kingdom is guarded by $n$ castles, the $i$-th castle is defended by $a_i$ soldiers. To conquer the Red Kingdom, the Kings have to eliminate all the defenders. 

Each day the White King launches an attack on one of the castles. Then, at night, the forces of the Black King attack a castle (possibly the same one). Then the White King attacks a castle, then the Black King, and so on. The first attack is performed by the White King.

Each attack must target a castle with at least one alive defender in it. There are three types of attacks:

  a mixed attack decreases the number of defenders in the targeted castle by $x$ (or sets it to $0$ if there are already less than $x$ defenders);  an infantry attack decreases the number of defenders in the targeted castle by $y$ (or sets it to $0$ if there are already less than $y$ defenders);  a cavalry attack decreases the number of defenders in the targeted castle by $z$ (or sets it to $0$ if there are already less than $z$ defenders). 

The mixed attack can be launched at any valid target (at any castle with at least one soldier). However, the infantry attack cannot be launched if the previous attack on the targeted castle had the same type, no matter when and by whom it was launched. The same applies to the cavalry attack. A castle that was not attacked at all can be targeted by any type of attack.

The King who launches the last attack will be glorified as the conqueror of the Red Kingdom, so both Kings want to launch the last attack (and they are wise enough to find a strategy that allows them to do it no matter what are the actions of their opponent, if such strategy exists). The White King is leading his first attack, and you are responsible for planning it. Can you calculate the number of possible options for the first attack that allow the White King to launch the last attack? Each option for the first attack is represented by the targeted castle and the type of attack, and two options are different if the targeted castles or the types of attack are different.


-----Input-----

The first line contains one integer $t$ ($1 \le t \le 1000$) — the number of test cases.

Then, the test cases follow. Each test case is represented by two lines. 

The first line contains four integers $n$, $x$, $y$ and $z$ ($1 \le n \le 3 \cdot 10^5$, $1 \le x, y, z \le 5$). 

The second line contains $n$ integers $a_1$, $a_2$, ..., $a_n$ ($1 \le a_i \le 10^{18}$).

It is guaranteed that the sum of values of $n$ over all test cases in the input does not exceed $3 \cdot 10^5$.


-----Output-----

For each test case, print the answer to it: the number of possible options for the first attack of the White King (or $0$, if the Black King can launch the last attack no matter how the White King acts).


-----Examples-----
Input
3
2 1 3 4
7 6
1 1 2 3
1
1 1 2 2
3

Output
2
3
0

Input
10
6 5 4 5
2 3 2 3 1 3
1 5 2 3
10
4 4 2 3
8 10 8 5
2 2 1 4
8 5
3 5 3 5
9 2 10
4 5 5 5
2 10 4 2
2 3 1 4
1 10
3 1 5 3
9 8 7
2 5 4 5
8 8
3 5 1 4
5 5 10

Output
0
2
1
2
5
12
5
0
0
2

Source: codeforces | Difficulty: MEDIUM


Solutions:
def divisors(M):
	d = []
	i = 1
	while M >= i ** 2:
		if M % i == 0:
			d.append(i)
			if i ** 2 != M:
				d.append(M // i)
		i = i + 1
	return d

def popcount(x):
	x = x - (x >> 1 & 1431655765)
	x = (x & 858993459) + (x >> 2 & 858993459)
	x = x + (x >> 4) & 252645135
	x = x + (x >> 8)
	x = x + (x >> 16)
	return x & 127

def eratosthenes(n):
	res = [0 for i in range(n + 1)]
	prime = set([])
	for i in range(2, n + 1):
		if not res[i]:
			prime.add(i)
			for j in range(1, n // i + 1):
				res[i * j] = 1
	return prime

def factorization(n):
	res = []
	for p in prime:
		if n % p == 0:
			while n % p == 0:
				n //= p
			res.append(p)
	if n != 1:
		res.append(n)
	return res

def euler_phi(n):
	res = n
	for x in range(2, n + 1):
		if x ** 2 > n:
			break
		if n % x == 0:
			res = res // x * (x - 1)
			while n % x == 0:
				n //= x
	if n != 1:
		res = res // n * (n - 1)
	return res

def ind(b, n):
	res = 0
	while n % b == 0:
		res += 1
		n //= b
	return res

def isPrimeMR(n):
	if n == 1:
		return 0
	d = n - 1
	d = d // (d & -d)
	L = [2, 3, 5, 7, 11, 13, 17]
	for a in L:
		t = d
		y = pow(a, t, n)
		if y == 1:
			continue
		while y != n - 1:
			y = y * y % n
			if y == 1 or t == n - 1:
				return 0
			t <<= 1
	return 1

def findFactorRho(n):
	from math import gcd
	m = 1 << n.bit_length() // 8
	for c in range(1, 99):
		f = lambda x: (x * x + c) % n
		(y, r, q, g) = (2, 1, 1, 1)
		while g == 1:
			x = y
			for i in range(r):
				y = f(y)
			k = 0
			while k < r and g == 1:
				ys = y
				for i in range(min(m, r - k)):
					y = f(y)
					q = q * abs(x - y) % n
				g = gcd(q, n)
				k += m
			r <<= 1
		if g == n:
			g = 1
			while g == 1:
				ys = f(ys)
				g = gcd(abs(x - ys), n)
		if g < n:
			if isPrimeMR(g):
				return g
			elif isPrimeMR(n // g):
				return n // g
			return findFactorRho(g)

def primeFactor(n):
	i = 2
	ret = {}
	rhoFlg = 0
	while i * i <= n:
		k = 0
		while n % i == 0:
			n //= i
			k += 1
		if k:
			ret[i] = k
		i += 1 + i % 2
		if i == 101 and n >= 2 ** 20:
			while n > 1:
				if isPrimeMR(n):
					(ret[n], n) = (1, 1)
				else:
					rhoFlg = 1
					j = findFactorRho(n)
					k = 0
					while n % j == 0:
						n //= j
						k += 1
					ret[j] = k
	if n > 1:
		ret[n] = 1
	if rhoFlg:
		ret = {x: ret[x] for x in sorted(ret)}
	return ret

def divisors(n):
	res = [1]
	prime = primeFactor(n)
	for p in prime:
		newres = []
		for d in res:
			for j in range(prime[p] + 1):
				newres.append(d * p ** j)
		res = newres
	res.sort()
	return res

def xorfactorial(num):
	if num == 0:
		return 0
	elif num == 1:
		return 1
	elif num == 2:
		return 3
	elif num == 3:
		return 0
	else:
		x = baseorder(num)
		return 2 ** x * ((num - 2 ** x + 1) % 2) + function(num - 2 ** x)

def xorconv(n, X, Y):
	if n == 0:
		res = [X[0] * Y[0] % mod]
		return res
	x = [digit[i] + X[i + 2 ** (n - 1)] for i in range(2 ** (n - 1))]
	y = [Y[i] + Y[i + 2 ** (n - 1)] for i in range(2 ** (n - 1))]
	z = [digit[i] - X[i + 2 ** (n - 1)] for i in range(2 ** (n - 1))]
	w = [Y[i] - Y[i + 2 ** (n - 1)] for i in range(2 ** (n - 1))]
	res1 = xorconv(n - 1, x, y)
	res2 = xorconv(n - 1, z, w)
	former = [(res1[i] + res2[i]) * inv for i in range(2 ** (n - 1))]
	latter = [(res1[i] - res2[i]) * inv for i in range(2 ** (n - 1))]
	former = list(map(lambda x: x % mod, former))
	latter = list(map(lambda x: x % mod, latter))
	return former + latter

def merge_sort(A, B):
	(pos_A, pos_B) = (0, 0)
	(n, m) = (len(A), len(B))
	res = []
	while pos_A < n and pos_B < m:
		(a, b) = (A[pos_A], B[pos_B])
		if a < b:
			res.append(a)
			pos_A += 1
		else:
			res.append(b)
			pos_B += 1
	res += A[pos_A:]
	res += B[pos_B:]
	return res

class UnionFindVerSize:

	def __init__(self, N):
		self._parent = [n for n in range(0, N)]
		self._size = [1] * N
		self.group = N

	def find_root(self, x):
		if self._parent[x] == x:
			return x
		self._parent[x] = self.find_root(self._parent[x])
		stack = [x]
		while self._parent[stack[-1]] != stack[-1]:
			stack.append(self._parent[stack[-1]])
		for v in stack:
			self._parent[v] = stack[-1]
		return self._parent[x]

	def unite(self, x, y):
		gx = self.find_root(x)
		gy = self.find_root(y)
		if gx == gy:
			return
		self.group -= 1
		if self._size[gx] < self._size[gy]:
			self._parent[gx] = gy
			self._size[gy] += self._size[gx]
		else:
			self._parent[gy] = gx
			self._size[gx] += self._size[gy]

	def get_size(self, x):
		return self._size[self.find_root(x)]

	def is_same_group(self, x, y):
		return self.find_root(x) == self.find_root(y)

class WeightedUnionFind:

	def __init__(self, N):
		self.parent = [i for i in range(N)]
		self.size = [1 for i in range(N)]
		self.val = [0 for i in range(N)]
		self.flag = True
		self.edge = [[] for i in range(N)]

	def dfs(self, v, pv):
		stack = [(v, pv)]
		new_parent = self.parent[pv]
		while stack:
			(v, pv) = stack.pop()
			self.parent[v] = new_parent
			for (nv, w) in self.edge[v]:
				if nv != pv:
					self.val[nv] = self.val[v] + w
					stack.append((nv, v))

	def unite(self, x, y, w):
		if not self.flag:
			return
		if self.parent[x] == self.parent[y]:
			self.flag = self.val[x] - self.val[y] == w
			return
		if self.size[self.parent[x]] > self.size[self.parent[y]]:
			self.edge[x].append((y, -w))
			self.edge[y].append((x, w))
			self.size[x] += self.size[y]
			self.val[y] = self.val[x] - w
			self.dfs(y, x)
		else:
			self.edge[x].append((y, -w))
			self.edge[y].append((x, w))
			self.size[y] += self.size[x]
			self.val[x] = self.val[y] + w
			self.dfs(x, y)

class Dijkstra:

	class Edge:

		def __init__(self, _to, _cost):
			self.to = _to
			self.cost = _cost

	def __init__(self, V):
		self.G = [[] for i in range(V)]
		self._E = 0
		self._V = V

	@property
	def E(self):
		return self._E

	@property
	def V(self):
		return self._V

	def add_edge(self, _from, _to, _cost):
		self.G[_from].append(self.Edge(_to, _cost))
		self._E += 1

	def shortest_path(self, s):
		import heapq
		que = []
		d = [10 ** 15] * self.V
		d[s] = 0
		heapq.heappush(que, (0, s))
		while len(que) != 0:
			(cost, v) = heapq.heappop(que)
			if d[v] < cost:
				continue
			for i in range(len(self.G[v])):
				e = self.G[v][i]
				if d[e.to] > d[v] + e.cost:
					d[e.to] = d[v] + e.cost
					heapq.heappush(que, (d[e.to], e.to))
		return d

def Z_algorithm(s):
	N = len(s)
	Z_alg = [0] * N
	Z_alg[0] = N
	i = 1
	j = 0
	while i < N:
		while i + j < N and s[j] == s[i + j]:
			j += 1
		Z_alg[i] = j
		if j == 0:
			i += 1
			continue
		k = 1
		while i + k < N and k + Z_alg[k] < j:
			Z_alg[i + k] = Z_alg[k]
			k += 1
		i += k
		j -= k
	return Z_alg

class BIT:

	def __init__(self, n, mod=0):
		self.BIT = [0] * (n + 1)
		self.num = n
		self.mod = mod

	def query(self, idx):
		res_sum = 0
		mod = self.mod
		while idx > 0:
			res_sum += self.BIT[idx]
			if mod:
				res_sum %= mod
			idx -= idx & -idx
		return res_sum

	def update(self, idx, x):
		mod = self.mod
		while idx <= self.num:
			self.BIT[idx] += x
			if mod:
				self.BIT[idx] %= mod
			idx += idx & -idx
		return

class dancinglink:

	def __init__(self, n, debug=False):
		self.n = n
		self.debug = debug
		self._left = [i - 1 for i in range(n)]
		self._right = [i + 1 for i in range(n)]
		self.exist = [True for i in range(n)]

	def pop(self, k):
		if self.debug:
			assert self.exist[k]
		L = self._left[k]
		R = self._right[k]
		if L != -1:
			if R != self.n:
				(self._right[L], self._left[R]) = (R, L)
			else:
				self._right[L] = self.n
		elif R != self.n:
			self._left[R] = -1
		self.exist[k] = False

	def left(self, idx, k=1):
		if self.debug:
			assert self.exist[idx]
		res = idx
		while k:
			res = self._left[res]
			if res == -1:
				break
			k -= 1
		return res

	def right(self, idx, k=1):
		if self.debug:
			assert self.exist[idx]
		res = idx
		while k:
			res = self._right[res]
			if res == self.n:
				break
			k -= 1
		return res

class SparseTable:

	def __init__(self, A, merge_func, ide_ele):
		N = len(A)
		n = N.bit_length()
		self.table = [[ide_ele for i in range(n)] for i in range(N)]
		self.merge_func = merge_func
		for i in range(N):
			self.table[i][0] = A[i]
		for j in range(1, n):
			for i in range(0, N - 2 ** j + 1):
				f = self.table[i][j - 1]
				s = self.table[i + 2 ** (j - 1)][j - 1]
				self.table[i][j] = self.merge_func(f, s)

	def query(self, s, t):
		b = t - s + 1
		m = b.bit_length() - 1
		return self.merge_func(self.table[s][m], self.table[t - 2 ** m + 1][m])

class BinaryTrie:

	class node:

		def __init__(self, val):
			self.left = None
			self.right = None
			self.max = val

	def __init__(self):
		self.root = self.node(-10 ** 15)

	def append(self, key, val):
		pos = self.root
		for i in range(29, -1, -1):
			pos.max = max(pos.max, val)
			if key >> i & 1:
				if pos.right is None:
					pos.right = self.node(val)
					pos = pos.right
				else:
					pos = pos.right
			elif pos.left is None:
				pos.left = self.node(val)
				pos = pos.left
			else:
				pos = pos.left
		pos.max = max(pos.max, val)

	def search(self, M, xor):
		res = -10 ** 15
		pos = self.root
		for i in range(29, -1, -1):
			if pos is None:
				break
			if M >> i & 1:
				if xor >> i & 1:
					if pos.right:
						res = max(res, pos.right.max)
					pos = pos.left
				else:
					if pos.left:
						res = max(res, pos.left.max)
					pos = pos.right
			elif xor >> i & 1:
				pos = pos.right
			else:
				pos = pos.left
		if pos:
			res = max(res, pos.max)
		return res

def solveequation(edge, ans, n, m):
	x = [0] * m
	used = [False] * n
	for v in range(n):
		if used[v]:
			continue
		y = dfs(v)
		if y != 0:
			return False
	return x

	def dfs(v):
		used[v] = True
		r = ans[v]
		for (to, dire, id) in edge[v]:
			if used[to]:
				continue
			y = dfs(to)
			if dire == -1:
				x[id] = y
			else:
				x[id] = -y
			r += y
		return r

class Matrix:
	mod = 10 ** 9 + 7

	def set_mod(m):
		Matrix.mod = m

	def __init__(self, L):
		self.row = len(L)
		self.column = len(L[0])
		self._matrix = L
		for i in range(self.row):
			for j in range(self.column):
				self._matridigit[i][j] %= Matrix.mod

	def __getitem__(self, item):
		if type(item) == int:
			raise IndexError('you must specific row and column')
		elif len(item) != 2:
			raise IndexError('you must specific row and column')
		(i, j) = item
		return self._matridigit[i][j]

	def __setitem__(self, item, val):
		if type(item) == int:
			raise IndexError('you must specific row and column')
		elif len(item) != 2:
			raise IndexError('you must specific row and column')
		(i, j) = item
		self._matridigit[i][j] = val

	def __add__(self, other):
		if (self.row, self.column) != (other.row, other.column):
			raise SizeError('sizes of matrixes are different')
		res = [[0 for j in range(self.column)] for i in range(self.row)]
		for i in range(self.row):
			for j in range(self.column):
				res[i][j] = self._matridigit[i][j] + other._matridigit[i][j]
				res[i][j] %= Matrix.mod
		return Matrix(res)

	def __sub__(self, other):
		if (self.row, self.column) != (other.row, other.column):
			raise SizeError('sizes of matrixes are different')
		res = [[0 for j in range(self.column)] for i in range(self.row)]
		for i in range(self.row):
			for j in range(self.column):
				res[i][j] = self._matridigit[i][j] - other._matridigit[i][j]
				res[i][j] %= Matrix.mod
		return Matrix(res)

	def __mul__(self, other):
		if type(other) != int:
			if self.column != other.row:
				raise SizeError('sizes of matrixes are different')
			res = [[0 for j in range(other.column)] for i in range(self.row)]
			for i in range(self.row):
				for j in range(other.column):
					temp = 0
					for k in range(self.column):
						temp += self._matridigit[i][k] * other._matrix[k][j]
					res[i][j] = temp % Matrix.mod
			return Matrix(res)
		else:
			n = other
			res = [[n * self._matridigit[i][j] % Matrix.mod for j in range(self.column)] for i in range(self.row)]
			return Matrix(res)

	def __pow__(self, m):
		if self.column != self.row:
			raise MatrixPowError('the size of row must be the same as that of column')
		n = self.row
		res = Matrix([[int(i == j) for i in range(n)] for j in range(n)])
		while m:
			if m % 2 == 1:
				res = res * self
			self = self * self
			m //= 2
		return res

	def __str__(self):
		res = []
		for i in range(self.row):
			for j in range(self.column):
				res.append(str(self._matridigit[i][j]))
				res.append(' ')
			res.append('\n')
		res = res[:len(res) - 1]
		return ''.join(res)
from collections import deque

class Dinic:

	def __init__(self, N):
		self.N = N
		self.G = [[] for i in range(N)]

	def add_edge(self, fr, to, cap):
		forward = [to, cap, None]
		forward[2] = backward = [fr, 0, forward]
		self.G[fr].append(forward)
		self.G[to].append(backward)

	def add_multi_edge(self, v1, v2, cap1, cap2):
		edge1 = [v2, cap1, None]
		edge1[2] = edge2 = [v1, cap2, edge1]
		self.G[v1].append(edge1)
		self.G[v2].append(edge2)

	def bfs(self, s, t):
		self.level = level = [None] * self.N
		deq = deque([s])
		level[s] = 0
		G = self.G
		while deq:
			v = deq.popleft()
			lv = level[v] + 1
			for (w, cap, _) in G[v]:
				if cap and level[w] is None:
					level[w] = lv
					deq.append(w)
		return level[t] is not None

	def dfs(self, v, t, f):
		if v == t:
			return f
		level = self.level
		for e in self.it[v]:
			(w, cap, rev) = e
			if cap and level[v] < level[w]:
				d = self.dfs(w, t, min(f, cap))
				if d:
					e[1] -= d
					rev[1] += d
					return d
		return 0

	def flow(self, s, t):
		flow = 0
		INF = 10 ** 9 + 7
		G = self.G
		while self.bfs(s, t):
			(*self.it,) = map(iter, self.G)
			f = INF
			while f:
				f = self.dfs(s, t, INF)
				flow += f
		return flow
import sys, random, bisect
from collections import deque, defaultdict
from heapq import heapify, heappop, heappush
from itertools import permutations
from math import gcd, log
input = lambda : sys.stdin.buffer.readline()
mi = lambda : map(int, input().split())
li = lambda : list(mi())

def mex(*args):
	tmp = [0 for j in range(4)]
	for a in args:
		tmp[a] += 1
	for i in range(4):
		if not tmp[i]:
			return i
ans = []
for _ in range(int(input())):
	(N, x, y, z) = mi()
	A = li()
	X = [0 for i in range(50 + 1)] + [0 for j in range(10)]
	Y = [0 for i in range(50 + 1)] + [0 for j in range(10)]
	Z = [0 for i in range(50 + 1)] + [0 for j in range(10)]
	memo = [[] for i in range(64)]
	(start, D) = (-1, -1)
	for i in range(1, 50 + 1):
		a = X[i - x]
		b = Y[i - y]
		c = Z[i - z]
		X[i] = mex(a, b, c)
		Y[i] = mex(a, c)
		Z[i] = mex(a, b)
		cond = 16 * X[i] + 4 * Y[i] + Z[i]
		for idx in memo[cond]:
			L = i - idx
			if idx < L or L < max(x, y, z):
				continue
			check_1 = [(X[j], Y[j], Z[j]) for j in range(idx - L + 1, idx + 1)]
			check_2 = [(X[j], Y[j], Z[j]) for j in range(idx + 1, i + 1)]
			if check_1 == check_2:
				D = L
				start = idx - L + 1
				break
		memo[cond].append(i)

	def grundy(t, n):
		if n <= 0:
			return 0
		if t == 1:
			if n < start:
				return X[n]
			else:
				n %= D
				while n < start:
					n += D
				return X[n]
		elif t == 2:
			if n < start:
				return Y[n]
			else:
				n %= D
				while n < start:
					n += D
				return Y[n]
		elif n < start:
			return Z[n]
		else:
			n %= D
			while n < start:
				n += D
			return Z[n]
	G = [grundy(1, a) for a in A]
	LG = [G[i] for i in range(N)] + [0]
	RG = [G[i] for i in range(N)] + [0]
	for i in range(1, N):
		LG[i] ^= LG[i - 1]
	for i in range(N - 2, -1, -1):
		RG[i] ^= RG[i + 1]
	res = 0
	for i in range(N):
		tmp_g = LG[i - 1] ^ RG[i + 1]
		if grundy(1, A[i] - x) == tmp_g:
			res += 1
		if grundy(2, A[i] - y) == tmp_g:
			res += 1
		if grundy(3, A[i] - z) == tmp_g:
			res += 1
	ans.append(res)
print(*ans, sep='\n')


import sys
input = sys.stdin.readline
G0 = [[[[0] * 5500 for i in range(6)] for j in range(6)] for k in range(6)]
G1 = [[[[0] * 5500 for i in range(6)] for j in range(6)] for k in range(6)]
G2 = [[[[0] * 5500 for i in range(6)] for j in range(6)] for k in range(6)]
for x in range(1, 6):
	for y in range(1, 6):
		for z in range(1, 6):
			for i in range(1, 5500):
				s = G0[x][y][z][max(0, i - x)]
				t = G1[x][y][z][max(0, i - y)]
				u = G2[x][y][z][max(0, i - z)]
				for j in range(5):
					if j == s or j == t or j == u:
						continue
					else:
						G0[x][y][z][i] = j
						break
				for j in range(5):
					if j == s or j == u:
						continue
					else:
						G1[x][y][z][i] = j
						break
				for j in range(5):
					if j == s or j == t:
						continue
					else:
						G2[x][y][z][i] = j
						break

def lcm(x, y):
	return x * y // math.gcd(x, y)
t = int(input())
for tests in range(t):
	(n, x, y, z) = list(map(int, input().split()))
	B = list(map(int, input().split()))
	A = []
	for a in B:
		if a <= 5400:
			A.append(a)
		else:
			A.append(a % 2520 + 2520)
	XOR = 0
	for a in A:
		XOR ^= G0[x][y][z][a]
	ANS = 0
	for a in A:
		k = XOR ^ G0[x][y][z][a]
		if G0[x][y][z][max(0, a - x)] == k:
			ANS += 1
		if G1[x][y][z][max(0, a - y)] == k:
			ANS += 1
		if G2[x][y][z][max(0, a - z)] == k:
			ANS += 1
	print(ANS)


T = int(input())

def findPeriod(DP):
	for offset in range(0, len(DP)):
		for period in range(1, 500):
			is_period = True
			for j in range(offset, len(DP) - period):
				if DP[j][0] == DP[j + period][0] and DP[j][1] == DP[j + period][1] and (DP[j][2] == DP[j + period][2]):
					is_period = True
				else:
					is_period = False
					break
			if is_period and period < len(DP) - offset + 1:
				return (period, offset)
	return (0, 0)
WHERE = ''
import random
try:
	for _ in range(T):
		memo = {}
		(n, x, y, z) = list(map(int, input().split()))
		PILES = list(map(int, input().split()))
		DP = [[0 for _ in range(3)] for _ in range(1000)]
		for i in range(1, 1000):
			for j in range(3):
				children = []
				for (ind, attack) in enumerate([x, y, z]):
					if ind != j or ind == 0:
						children.append((max(0, i - attack), ind))
				if len(children) == 0:
					DP[i][j] = 0
				else:
					s = set()
					for child in children:
						s.add(DP[child[0]][child[1]])
					grundy = 0
					while grundy in s:
						grundy += 1
					DP[i][j] = grundy
		WHERE = 'a'
		(period, offset) = findPeriod(DP)
		grundy = 0
		convert = lambda pile: (pile - offset) % period + offset if pile - offset >= 0 else pile
		for pile in PILES:
			grundy ^= DP[convert(pile)][0]
		if grundy == 0:
			print(0)
		else:
			count = 0
			WHERE = 'b'
			for pile in PILES:
				grundy ^= DP[convert(pile)][0]
				if grundy ^ DP[convert(max(0, pile - x))][0] == 0:
					count += 1
				if grundy ^ DP[convert(max(0, pile - y))][1] == 0:
					count += 1
				if grundy ^ DP[convert(max(0, pile - z))][2] == 0:
					count += 1
				grundy ^= DP[convert(pile)][0]
			print(count)
except Exception as e:
	print(e)
	print(WHERE)


import sys
readline = sys.stdin.buffer.readline
T = int(readline())
Ans = [None] * T
for qu in range(T):
	(N, x, y, z) = map(int, readline().split())
	A = list(map(int, readline().split()))
	ts = 200
	dp = [[0] * 3 for _ in range(ts)]
	table = [[[0] * 4 for _ in range(3)] for _ in range(ts + 8)]
	for hp in range(ts):
		if 0 < hp <= x:
			table[hp][0][0] = 1
			table[hp][1][0] = 1
			table[hp][2][0] = 1
		if 0 < hp <= y:
			table[hp][0][0] = 1
			table[hp][2][0] = 1
		if 0 < hp <= z:
			table[hp][0][0] = 1
			table[hp][1][0] = 1
		for ty in range(3):
			dp[hp][ty] = table[hp][ty].index(0)
		val0 = dp[hp][0]
		val1 = dp[hp][1]
		val2 = dp[hp][2]
		table[hp + x][0][val0] = 1
		table[hp + x][1][val0] = 1
		table[hp + x][2][val0] = 1
		table[hp + y][0][val1] = 1
		table[hp + y][2][val1] = 1
		table[hp + z][0][val2] = 1
		table[hp + z][1][val2] = 1
	cl = None
	for loop in range(10, 61):
		for i in range(loop):
			if dp[ts - 1 - i] != dp[ts - 1 - i - loop]:
				break
		else:
			cl = loop
			break
		continue
	A1 = [None] * N
	for i in range(N):
		a = A[i]
		if a < ts:
			A1[i] = a
		else:
			k = 1 + (a - ts) // cl
			A1[i] = a - k * cl
	xx = 0
	for a in A1:
		xx ^= dp[a][0]
	res = 0
	for a in A1:
		da = dp[a][0]
		if dp[max(0, a - x)][0] ^ da == xx:
			res += 1
		if dp[max(0, a - y)][1] ^ da == xx:
			res += 1
		if dp[max(0, a - z)][2] ^ da == xx:
			res += 1
	Ans[qu] = res
print('\n'.join(map(str, Ans)))