#include<bits/stdc++.h>
using namespace std;

#define rep(i,l,r) for(int i=(l);i<=(r);i++)
#define per(i,l,r) for(int i=(l);i>=(r);i--)
#define ll long long
#define pii pair<int, int>
#define mset(s,t) memset(s,t,sizeof(t))
#define mcpy(s,t) memcpy(s,t,sizeof(t))
#define fir first
#define pb push_back
#define sec second

inline int read () {
int x = 0, f = 0;
char ch = getchar();
while (!isdigit(ch)) f |= (ch=='-'), ch= getchar();
while (isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
return f?-x:x;
}
template<typename T> void print(T x) {
if (x < 0) putchar('-'), x = -x;
if (x >= 10) print(x/10);
putchar(x % 10 + '0');
}
const int N = 1e5 + 10;

ll n, x, y;

ll get (int x, int y, int z) {
cout << "? " << x << " " << y << ' ' << z << endl;
fflush(stdout);
int k;
cin >> k;
return k;
}
void solve() {
cin >> n;
ll x, y, z;
x = 1, y = 2, z = 3;
int last = get (x, y, z);
for (int i = 4; i<= n; i++)
{
int t = get (x, y, i);
if (t >= last) {
last = t;
z = i;
}
}
for (int i = 1; i<= n; i ++) {
if (i ==x || i == z || i == y) continue;
int t = get (x, i, z);
if (t >= last) {
last = t;
y = i;
}
}
int id = - 1;
for (int i = 1; i <= n; i++)
if (i == x || i == y || i == z) continue;
else {
id = i;
break;
}
int k = get (x, y, id);
if (k == last) {
cout << "!" << " " << x << " " << y << endl;
}
else {
k = get (x, id, z);
if (k == last) {
cout << "!" << " " << x << " " << z << endl;
}
else {
cout << "!" << " " << y << " " << z << endl;
}
}
}
int main () {
int t;
cin >> t;
while (t --) solve();
return 0;
}

这次比赛卡在了B题,没想对方向,之前是是整个数来看,但是太麻烦了,应该设法简单点,正解是按照奇偶性思考,因为题目保证,最终只有一个能到达y,通过考虑最后一位异或操作和加操作是等价的。因为都是改变了奇偶性 找到一个性质,找到最大值最小值,然后再通过一些询问就可以得到答案