def test_all(f):
for i, data in enumerate(eval(f'test_data{f.__name__}')):
exp = data["out"]
ans = f(*data["in"])
result = "AC" if exp == ans else "WA"
print(f"{i+1} {result}: expected: {exp}, output: {ans}")
def B(*S):
def get_range(S):
row = ["#" in s for s in S]
return row.index(True) + 1, 9 - row[::-1].index(True) + 1
A, B = get_range(S)
C, D = get_range(zip(*S))
return f"{A} {B}\n{C} {D}"
test_all(B)
# 提出用
# print(B(*[input() for _ in range(10)]))
from itertools import product
def C(N):
ones = [i for i, f in enumerate(bin(N)[2:][::-1]) if f == "1"][::-1]
for c in product([0, 1], repeat=len(ones)):
n = sum([2**exp for exp, f in zip(ones, c) if f == 1])
print(n)
return
test_all(C)
from itertools import product
def C(N):
p2 = [2**i for i in range(61) if N & 2**i][::-1]
ret = [sum(f for f, c in zip(p2, com) if c) for com in product([0, 1], repeat=len(p2))]
return "\n".join(map(str, ret))
test_all(C)
# 提出用
# print(C(int(input())))
def D(N, XY):
dsu = [-1] * N
def leader(i):
if dsu[i] < 0: return i
dsu[i] = leader(dsu[i])
return dsu[i]
def merge(i, j):
'''サイズの大きい方(x)に小さい方(y)をマージ'''
if i == j: return
x = leader(i)
y = leader(j)
if x == y: return
if dsu[x] > dsu[y]: x, y = y, x
dsu[x] += dsu[y]
dsu[y] = x
def is_neighbor(p1, p2):
i1, j1 = p1
i2, j2 = p2
return (
i1 == i2 and j1 - 1 <= j2 <= j1 + 1 or
j1 == j2 and i1 - 1 <= i2 <= i1 + 1 or
i1 + 1 == i2 and j1 + 1 == j2 or
i1 - 1 == i2 and j1 - 1 == j2
)
for s, now in enumerate(XY):
for t in range(s):
if is_neighbor(now, XY[t]):
merge(s, t)
return sum(1 for n in dsu if n < 0)
# 提出用
# N = int(input())
# XY = [list(map(int, input().split())) for _ in range(N)]
# print(D(N, XY))test_all(D)
def D(N, XY):
contain = [[-1] * 20010 for _ in range(2010)]
for i, (x, y) in enumerate(XY):
contain[x+1005][y+1005] = i
dsu = [-1] * N
def leader(i):
if dsu[i] < 0: return i
dsu[i] = leader(dsu[i])
return dsu[i]
def merge(i, j):
'''サイズの大きい方(x)に小さい方(y)をマージ'''
if i == j: return
x = leader(i)
y = leader(j)
if x == y: return
if dsu[x] > dsu[y]: x, y = y, x
dsu[x] += dsu[y]
dsu[y] = x
def get_neighbors(i, j):
return (
[i-1,j-1],
[i-1,j],
[i,j-1],
[i,j+1],
[i+1,j],
[i+1,j+1],
)
for i, (x, y) in enumerate(XY):
for s, t in get_neighbors(x, y):
idx = contain[s+1005][t+1005]
if idx > -1:
merge(i, idx)
return sum(1 for n in dsu if n < 0)
# 提出用
# N = int(input())
# XY = [list(map(int, input().split())) for _ in range(N)]
# print(D(N, XY))test_all(D)
N = int(input())
def main(N):
for i in range(2):
s = 1
e = N + 1
while e - s > 0:
# print(s, e)
m = (s + e) // 2
if i == 0:
print(f"? {s} {m} {1} {N}")
else:
print(f"? {1} {N} {s} {m}")
ans = int(input())
if ans == -1: return
elif ans == m - s + 1:
s = m + 1
else:
e = m
else:
if i == 0:
x = s
else:
y = s
print(f"! {x} {y}")
main(N)
N = int(input())
def main(N):
def bs(f):
def is_ok(m):
f(ok, m)
ans = int(input())
return ans == m - ok
ok = 1
ng = N + 1
while abs(ok - ng) > 1:
m = (ok + ng) // 2 - 1
if is_ok(m):
ng = m + 1
else:
ok = m + 1
return ok
x = bs(lambda s, m: print(f"? {s} {m} {1} {N}"))
y = bs(lambda s, m: print(f"? {1} {N} {s} {m}"))
print(f"! {x} {y}")
main(N)
N = int(input())
def main(N):
def bs(f):
def is_ok(m):
f(m, ok)
ans = int(input())
return ans == ok - m
ng = 0
ok = N
while abs(ok - ng) > 1:
m = (ok + ng) // 2 + 1
if is_ok(m):
ng = m - 1
else:
ok = m - 1
return ok
x = bs(lambda s, m: print(f"? {s} {m} {1} {N}"))
y = bs(lambda s, m: print(f"? {1} {N} {s} {m}"))
print(f"! {x} {y}")
main(N)
N = int(input())
def main(N):
def bs(f):
def is_ok(m):
f(ok, m)
ans = int(input())
return ans == m - ok
ok = 1
ng = N
while abs(ok - ng) > 0:
m = (ok + ng) // 2
if is_ok(m):
ng = m
else:
ok = m + 1
return ok
x = bs(lambda s, m: print(f"? {s} {m} {1} {N}"))
y = bs(lambda s, m: print(f"? {1} {N} {s} {m}"))
print(f"! {x} {y}")
main(N)