# いい質問をして絞り込む

def valid(t):
	for i in range(4):
		for j in range(i+1,4):
			if t[i] == t[j]: return False
	return True

a = [31,29,31,30,31,30,31,31,30,31,30,31]
s = []
for i in range(12):
	for j in range(1,a[i]+1):
		t = f"{str(i+1).zfill(2)}{str(j).zfill(2)}"
		if valid(t):
			s.append(t)


T = int(input())
for _ in range(T):
	nokori = s[::]

	while len(nokori) > 1:
		g = 10 ** 18
		v = [[] for i in range(25)]
		tt = ""

		for i in range(10000):
			t = str(i).zfill(4)
			if not valid(t): continue
			tar = [0] * 10
			for i in range(4):
				tar[int(t[i])] += 1

			bunpu = [[] for i in range(25)]
			for x in nokori:
				hit = 0
				blow = 0
				for j in range(4):
					if x[j] == t[j]:
						hit += 1
					if tar[int(x[j])]:
						blow += 1
				blow -= hit
				#if x == "0823" and t == "4156":
				#	print(hit, blow)
				bunpu[hit*5+blow].append(x)

			cmp = max([len(bunpu[y]) for y in range(25)])
			if cmp < g:
				g = cmp
				v = bunpu[::]
				tt = t
		#print(cmp)
		print(f"? {tt}")
		h,b = map(int,input().split())
		#print(v[h*5+b])
		nokori = v[h*5+b][::]
	print(f"! {nokori[0]}")
	a = int(input())