首先发现能找到1好人1坏人就可以用这两个人确定所有人好坏。
考虑如何找,发现题目给的条件满足鸽笼原理,即我们三个人三个人划分为一组,那么一定会有一组好人多于坏人,一组坏人多于好人,不妨分别记为good组、bad组(此时花费n/3步)
考虑从bad组拿出2个人固定,去查good组的3个人,分几种情况讨论一下:(花费3步)
1)存在一次好人更多,则说明bad组剩下一个一定是坏人,且good组查出来了一个好人,找到一好一坏。
2)不存在坏人更多,那么当前bad组两个人都是坏人,剩下一个不确定,我们拿出bad组中已经确定是坏人的一个,然后查good组的任两个人:此时若坏人更多,good组剩下一个一定好人,否则当前两个都是好人。故一定找到一好一坏(花费1步)
此时我们剩下(n * 2 / 3 + 2)步,貌似确定所有人不够?但是在第一步中,我们已经知道了每个组3个人中好人多还是坏人多,因此确定一个组3个人只需要任查组内两个人即可,满足步数限制。
//#define LOCAL
#include<bits/stdc++.h>
#define pii pair<int,int>
#define fi first
#define sc second
#define pb push_back
#define ll long long
#define trav(v,x) for(auto v:x)
#define all(x) (x).begin(), (x).end()
#define VI vector<int>
#define VLL vector<ll>
#define pll pair<ll, ll>
#define double long double
//#define int long long
using namespace std;
const int N = 1e6 + 100;
const int inf = 1e9;
//const ll inf = 1e18
const ll mod = 998244353;//1e9 + 7
#ifdef LOCAL
void debug_out(){cerr << endl;}
template<typename Head, typename... Tail>
void debug_out(Head H, Tail... T)
{
cerr << " " << to_string(H);
debug_out(T...);
}
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif
int n;
int sta[N], id[N][3], ans[N][3], res[N];
int chk(int x, int y, int z)
{
cout << '?' << ' ' << x << ' ' << y << ' ' << z << endl;
int res;
cin >> res;
return res;
}
void out()
{
cout << '!' << ' ' ;
int num = 0;
for(int i = 1; i <= n * 3; i++)
if(res[i] == 0)++num;
cout << num << ' ' ;
for(int i = 1; i <= n * 3; i++)
if(res[i] == 0)cout << i << ' ';
cout << endl;
}
void sol()
{
cin >> n;
n /= 3;
for(int i = 1; i <= 3 * n; i += 3)
{
sta[(i + 2) / 3] = chk(i, i + 1, i + 2);
id[(i + 2) / 3][0] = i;
id[(i + 2) / 3][1] = i + 1;
id[(i + 2) / 3][2] = i + 2;
}
int bad = 0, good = 0;
for(int i = 1; i <= n; i++)
{
if(sta[i] == 0 && !bad)
bad = i;
if(sta[i] == 1 && !good)
good = i;
}
{
bool flg = 0;
int y;
for(int i = 0; i <= 2; i++)
{
int nw = chk(id[bad][0], id[bad][1], id[good][i]);
if(nw == 1)
{
flg = 1;
y = i;
break;
}
}
if(flg)
{
swap(id[bad][0], id[bad][2]);
swap(id[bad][1], id[good][y]);
}
else
{
int nw = chk(id[bad][0], id[good][0], id[good][1]);
if(nw == 1)
{
swap(id[bad][1], id[good][0]);
}
else swap(id[bad][1], id[good][2]);
}
for(int i = 0; i < 3; i++)
swap(id[1][i], id[bad][i]);
sta[bad] = chk(id[bad][0], id[bad][1], id[bad][2]);
sta[good] = chk(id[good][0], id[good][1], id[good][2]);
ans[1][0] = 0, ans[1][1] = 1;
ans[1][2] = chk(id[1][0], id[1][1], id[1][2]);
}
for(int i = 2; i <= n; i++)
{
if(sta[i] == 0)
{
int nw = chk(id[1][1], id[i][0], id[i][1]);
if(nw == 0)
{
ans[i][0] = ans[i][1] = 0;
ans[i][2] = chk(id[1][0], id[1][1], id[i][2]);
}
else
{
ans[i][2] = 0;
ans[i][0] = chk(id[1][0], id[1][1], id[i][0]);
ans[i][1] = (1 ^ ans[i][0]);
}
}
else
{
int nw = chk(id[1][0], id[i][0], id[i][1]);
if(nw == 1)
{
ans[i][0] = ans[i][1] = 1;
ans[i][2] = chk(id[1][0], id[1][1], id[i][2]);
}
else
{
ans[i][2] = 1;
ans[i][0] = chk(id[1][0], id[1][1], id[i][0]);
ans[i][1] = (1 ^ ans[i][0]);
}
}
}
//output
for(int i = 1; i <= n; i++)
for(int j = 0; j <= 2; j++)
res[id[i][j]] = ans[i][j];
out();
}
signed main()
{
int tt;
cin >> tt;
while(tt--)
sol();
}