This is an interactive problem. You have to use flush operation right after printing each line. For example, in C++ you should use function fflush(stdout), in Java — System.out.flush(), in Pascal — flush(output) and in Python — sys.stdout.flush().

In this problem, you need to find maximal and minimal elements of an array. What could be simpler?

You can imagine that the jury has an array, and initially you know the only number n — array's length.

Array's elements are numbered from 1 to n. You are allowed to compare two elements of the array by using their indices i and j. There are three possible responses to this query: '<' (if ai is less than aj), '=' (if ai is equal to aj) and finally '>' (if ai is greater than aj).

It's known that it's always possible to find both maximal and minimal elements of the array by using no more than <image> comparisons, where ⌈ x⌉ is the result of rounding x up.

Write the program that will find positions of the minimum and the maximum in the jury's array of length n, by using no more than f(n) comparisons.

Interaction

Each test for this problem will contain one or more arrays. You have to find positions of minimal and maximal elements for each of these arrays. The first line of the input contains integer T (1 ≤ T ≤ 1000) — number of arrays in the test.

Thus, at the beginning, you program should read number T, and then it should solve the problem for T jury's arrays one by one.

Then input for each array goes. Firstly, your program has to read the number n (1 ≤ n ≤ 50) — the length of the array. It will be provided in the next line of the input.

Further, your program can perform comparisons or report that the answer is found.

  * To perform a comparison, you have to output string of the following pattern «? i j» (i and j must be integer numbers from 1 to n) — the indices of the elements to compare in the current query. 
  * To report the indices of minimal and maximal elements of the hidden array, your program have to output a line in the form «! i j» (i and j must be integer numbers from 1 to n), where i is an index of the minimal element of array, and j is an index of the maximal element of the array. If there are several possible answers to the problem, you can output any of them. 



There are several possible responses for a comparison:

  * '<' — if ai is less than aj, 
  * '=' — if ai is equal to aj, 
  * '>' — if ai is greater than aj. 



For an array of length n your program can make at most <image> comparisons. Note that the operation of reporting an answer («! i j» ) is not included into the value of f(n).

After the answer is reported, your program has to solve the problem for the next array or it should terminate if all T arrays are processed.

Example

Input

2
2
 
&gt;
 
3
 
=
 
=
 

Output

 
 
? 1 2
 
! 2 1
 
? 3 1
 
? 2 1
 
! 2 3

Source: codeforces | Difficulty: MEDIUM_HARD
Tags: Constructive algorithms


Solutions:
import sys
T = int(input())

def compare(l, r, arr):
	print('?', a[l] + 1, a[r] + 1)
	sys.stdout.flush()
	res = input()
	if res == '>':
		return 1
	else:
		return 0
while T > 0:
	T -= 1
	Max_a = []
	Min_a = []
	n = int(input())
	a = range(n)
	for i in range(int(n / 2)):
		if compare(i * 2, i * 2 + 1, a) > 0:
			Max_a.append(i * 2)
			Min_a.append(i * 2 + 1)
		else:
			Max_a.append(i * 2 + 1)
			Min_a.append(i * 2)
	if n % 2 == 1:
		Max_a.append(n - 1)
		Min_a.append(n - 1)
	Max_index = Max_a[-1]
	Min_index = Min_a[-1]
	for i in range(len(Max_a) - 1):
		if compare(Max_a[i], Max_index, a) > 0:
			Max_index = Max_a[i]
	for i in range(len(Min_a) - 1):
		if compare(Min_a[i], Min_index, a) == 0:
			Min_index = Min_a[i]
	print('!', Min_index + 1, Max_index + 1)
	sys.stdout.flush()


from __future__ import division, print_function
from fractions import Fraction
import sys
import os
from io import BytesIO, IOBase
from functools import cmp_to_key
from heapq import *
from math import gcd, factorial, floor, ceil, sqrt, log2
from copy import deepcopy
from collections import deque
from bisect import bisect_left as bl
from bisect import bisect_right as br
from bisect import bisect
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')

def print(*args, **kwargs):
	(sep, file) = (kwargs.pop('sep', ' '), kwargs.pop('file', sys.stdout))
	at_start = True
	for x in args:
		if not at_start:
			file.write(sep)
		file.write(str(x))
		at_start = False
	file.write(kwargs.pop('end', '\n'))
	if kwargs.pop('flush', False):
		file.flush()
if sys.version_info[0] < 3:
	(sys.stdin, sys.stdout) = (FastIO(sys.stdin), FastIO(sys.stdout))
else:
	(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
from types import GeneratorType

def iterative(f, stack=[]):

	def wrapped_func(*args, **kwargs):
		if stack:
			return f(*args, **kwargs)
		to = f(*args, **kwargs)
		while True:
			if type(to) is GeneratorType:
				stack.append(to)
				to = next(to)
				continue
			stack.pop()
			if not stack:
				break
			to = stack[-1].send(to)
		return to
	return wrapped_func

def inp():
	return sys.stdin.readline().rstrip('\r\n')

def out(var):
	sys.stdout.write(str(var))

def lis():
	return list(map(int, inp().split()))

def stringlis():
	return list(map(str, inp().split()))

def sep():
	return map(int, inp().split())

def strsep():
	return map(str, inp().split())

def testcase(t):
	for pp in range(t):
		solve(pp)

def google(p):
	print('Case #' + str(p) + ': ', end='')

def lcm(a, b):
	return a * b // gcd(a, b)

def modInverse(b):
	g = gcd(b, mod)
	if g != 1:
		return -1
	else:
		return pow(b, mod - 2, mod)

def power(x, y, p):
	y %= p - 1
	res = 1
	x = x % p
	if x == 0:
		return 0
	while y > 0:
		if y & 1 == 1:
			res = res * x % p
		y = y >> 1
		x = x * x % p
	return res

def isPrime(n):
	if n <= 1:
		return False
	if n <= 3:
		return True
	if n % 2 == 0 or n % 3 == 0:
		return False
	i = 5
	while i * i <= n:
		if n % i == 0 or n % (i + 2) == 0:
			return False
		i = i + 6
	return True
inf = pow(10, 20)
mod = 10 ** 9 + 7

def ask(a, b):
	print('?', a + 1, b + 1)
	sys.stdout.flush()
	s = inp()
	return s

def solve(case):
	n = int(inp())
	if n == 1:
		print('!', 1, 1)
		sys.stdout.flush()
		return
	max = []
	min = []
	for i in range(0, n, 2):
		if i == n - 1:
			max.append(i)
			min.append(i)
		else:
			temp = ask(i, i + 1)
			if temp == '<' or temp == '=':
				min.append(i)
				max.append(i + 1)
			if temp == '>':
				min.append(i + 1)
				max.append(i)
	while len(max) > 1:
		new = []
		for i in range(0, len(max), 2):
			if i == len(max) - 1:
				new.append(max[i])
			else:
				temp = ask(max[i], max[i + 1])
				if temp == '<' or temp == '=':
					new.append(max[i + 1])
				else:
					new.append(max[i])
		max = deepcopy(new)
	maxans = max[0]
	while len(min) > 1:
		new = []
		for i in range(0, len(min), 2):
			if i == len(min) - 1:
				new.append(min[i])
			else:
				temp = ask(min[i], min[i + 1])
				if temp == '<' or temp == '=':
					new.append(min[i])
				else:
					new.append(min[i + 1])
		min = deepcopy(new)
	minans = min[0]
	print('!', minans + 1, maxans + 1)
	sys.stdout.flush()
testcase(int(inp()))


from collections import defaultdict
for ik in range(int(input())):
	n = int(input())
	d = defaultdict(str)
	if n == 1:
		print('! 1 1', flush=True)
		continue
	elif n == 2:
		print('? 1 2', flush=True)
		s = input()
		if s == '>':
			print('! 2 1', flush=True)
		else:
			print('! 1 2', flush=True)
		continue
	last = [i for i in range(1, n + 1)]
	res = []
	while len(last) != 1:
		for i in range(len(last) // 2):
			print('?', last[2 * i], last[2 * i + 1], flush=True)
			r = input()
			d[last[2 * i], last[2 * i + 1]] = r
			if r == '>':
				res.append(last[2 * i])
			else:
				res.append(last[2 * i + 1])
		if len(last) % 2 == 1:
			res.append(last[-1])
		last = res + []
		res = []
	max = last[0]
	last = [i for i in range(1, n + 1)]
	res = []
	while len(last) != 1:
		for i in range(len(last) // 2):
			if (last[2 * i], last[2 * i + 1]) in d:
				r1 = d[last[2 * i], last[2 * i + 1]]
			else:
				print('?', last[2 * i], last[2 * i + 1], flush=True)
				r1 = input()
			if r1 == '<':
				res.append(last[2 * i])
			else:
				res.append(last[2 * i + 1])
		if len(last) % 2 == 1:
			res.append(last[-1])
		last = res + []
		res = []
	min = last[0]
	print('!', min, max, flush=True)


import sys

def f(arr):
	(mn, mx) = ([], [])
	for i in range(len(arr) // 2):
		print('?', arr[2 * i], arr[2 * i + 1])
		sys.stdout.flush()
		if input() == '>':
			mn.append(arr[2 * i + 1])
			mx.append(arr[2 * i])
		else:
			mn.append(arr[2 * i])
			mx.append(arr[2 * i + 1])
	if len(arr) % 2 == 1:
		mn.append(arr[-1])
		mx.append(arr[-1])
	return (mn, mx)
for _ in range(int(input())):
	n = int(input())
	arr = range(1, n + 1)
	(mn, mx) = f(arr)
	while len(mn) > 1:
		mn = f(mn)[0]
	while len(mx) > 1:
		mx = f(mx)[1]
	print('!', mn[0], mx[0])
	sys.stdout.flush()


import sys

def obtain_min_max(left, right):
	print('?', left, right)
	sys.stdout.flush()
	k = input()
	if k == '=':
		return (left, left)
	elif k == '<':
		return (left, right)
	else:
		return (right, left)

def solve_aux(left, right):
	if left == right:
		return (left, left)
	if right == left + 1:
		return obtain_min_max(left, right)
	mid = (left + right) // 2
	if (mid - left + 1) % 2 == 1 and (right - mid) % 2 == 1:
		mid -= 1
	(min1, max1) = solve_aux(left, mid)
	(min2, max2) = solve_aux(mid + 1, right)
	(min_min, min_max) = obtain_min_max(min1, min2)
	(max_min, max_max) = obtain_min_max(max1, max2)
	return (min_min, max_max)

def solve(k):
	return solve_aux(1, k)
n = int(input())
for i in range(n):
	k = int(input())
	(min, max) = solve(k)
	print('!', min, max)
	sys.stdout.flush()


from sys import *

def f(t):
	n = len(t)
	k = n >> 1
	(u, v) = ([], [])
	if n & 1:
		(u, v) = ([t[-1]], [t[-1]])
	for i in range(k):
		print('?', t[i], t[k + i])
		stdout.flush()
		q = k * (input() == '<')
		u.append(t[k - q + i])
		v.append(t[q + i])
	return (u, v)
for i in range(int(input())):
	(u, v) = f(range(1, int(input()) + 1))
	while len(u) > 1:
		u = f(u)[0]
	while len(v) > 1:
		v = f(v)[1]
	print('!', u[0], v[0])
	stdout.flush()


from sys import stdin, stdout

def ask(i, j):
	print('?', i + 1, j + 1, flush=True)
	s = input()
	if s == '<':
		return -1
	if s == '=':
		return 0
	return 1

def ans(i, j):
	print('!', i + 1, j + 1, flush=True)

def f(i, j, c):
	if (ask(i, j) > 0) ^ c:
		return j
	return i

def g(i, j):
	if ask(i, j) < 0:
		return [i, j]
	return [j, i]
for _ in range(int(input())):
	n = int(input())
	if n == 1:
		ans(0, 0)
		continue
	a = []
	for i in range(n // 2):
		a.append(g(2 * i, 2 * i + 1))
	(x, y) = (a[0][0], a[0][1])
	for i in range(1, n // 2):
		x = f(x, a[i][0], 0)
		y = f(y, a[i][1], 1)
	if n & 1:
		x = f(x, n - 1, 0)
		y = f(y, n - 1, 1)
	ans(x, y)


import random
import sys

def myprint(s):
	print(s)
	sys.stdout.flush()
t = int(input())
while t > 0:
	t -= 1
	n = int(input())
	A = [i + 1 for i in range(n)]
	allowed = 3 * n // 2 + n % 2 - 2
	random.shuffle(A)

	def cmp(x, y):
		myprint('? ' + str(A[x]) + ' ' + str(A[y]))
		return input()
	mins = []
	maxs = []
	for i in range(0, n - 1, 2):
		cmpres = cmp(i, i + 1)
		allowed -= 1
		if cmpres == '<':
			mins.append(i)
			maxs.append(i + 1)
		else:
			mins.append(i + 1)
			maxs.append(i)
	if n % 2 != 0:
		mins.append(n - 1)
		maxs.append(n - 1)
	while allowed:
		mn = []
		mx = []
		for i in range(0, len(mins) - 1, 2):
			if allowed:
				cmpres = cmp(mins[i], mins[i + 1])
				allowed -= 1
				if cmpres == '<':
					mn.append(mins[i])
				else:
					mn.append(mins[i + 1])
		if len(mins) % 2:
			mn.append(mins[-1])
		for i in range(0, len(maxs) - 1, 2):
			if allowed:
				cmpres = cmp(maxs[i], maxs[i + 1])
				allowed -= 1
				if cmpres == '>':
					mx.append(maxs[i])
				else:
					mx.append(maxs[i + 1])
		if len(maxs) % 2:
			mx.append(maxs[-1])
		mins = mn
		maxs = mx
	myprint('! ' + str(A[mins[0]]) + ' ' + str(A[maxs[0]]))


from sys import stdin, stdout
from math import sin, tan, cos

def ask(i, j):
	stdout.write('? ' + str(i) + ' ' + str(j) + '\n')
	stdout.flush()
	return stdin.readline().strip()
T = int(stdin.readline())
for t in range(T):
	n = int(stdin.readline())
	if n == 1:
		stdout.write('! 1 1\n')
		stdout.flush()
		continue
	(l, r) = (1, 2)
	if ask(l, r) == '>':
		(l, r) = (r, l)
	for i in range(3, n + 1, 2):
		if i == n:
			s = ask(l, i)
			f = ask(r, i)
			if s == '>':
				l = i
			if f == '<':
				r = i
			continue
		(lb, rb) = (i, i + 1)
		if ask(lb, rb) == '>':
			(lb, rb) = (rb, lb)
		if ask(lb, l) == '<':
			l = lb
		if ask(rb, r) == '>':
			r = rb
	stdout.write('! ' + str(l) + ' ' + str(r) + '\n')
	stdout.flush()


import sys

def find_min_max(l, d=None):
	n = len(l)
	if n == 1:
		return (l[0], l[0])
	lesser = []
	greater = []
	for i in range(n // 2):
		first = l[2 * i]
		second = l[2 * i + 1]
		print('? {} {}'.format(first, second))
		sys.stdout.flush()
		answer = input()
		if answer == '<':
			lesser.append(first)
			greater.append(second)
		else:
			lesser.append(second)
			greater.append(first)
	if n % 2 == 1:
		lesser.append(l[-1])
		greater.append(l[-1])
	mn = None
	mx = None
	if d != 'max':
		mn = find_min_max(lesser, 'min')[0]
	if d != 'min':
		mx = find_min_max(greater, 'max')[1]
	return (mn, mx)
t = input()
t = int(t)
for k in range(t):
	n = input()
	n = int(n)
	l = list(range(1, n + 1))
	(mn, mx) = find_min_max(l)
	print('! {} {}'.format(mn, mx))
	sys.stdout.flush()