#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/rope>
using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;
#define ll long long
#define ii pair<ll,ll>
#define iii pair<ii,ll>
#define fi first
#define se second
#define pub push_back
#define pob pop_back
#define puf push_front
#define pof pop_front
#define lb lower_bound
#define up upper_bound
#define rep(x,start,end) for(auto x=(start)-((start)>(end));x!=(end)-((start)>(end));((start)<(end)?x++:x--))
#define all(x) (x).begin(),(x).end()
#define sz(x) (int)(x).size()
#define indexed_set tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>
mt19937 rng(177013);
// 交互查询函数
int query(int a,int b,int c){
cout<<"? "<<a<<" "<<b<<" "<<c<<endl;
int temp;
cin>>temp;
return temp;
}
// 三个元素排序函数,避免和 std::sort 冲突
void sort3(int &a,int &b,int &c){
if (a>b) swap(a,b);
if (b>c) swap(b,c);
if (a>b) swap(a,b);
}
// 每个测试点的解题逻辑
void solve(){
int n;
cin>>n;
vector<int> ans(n+5,0);
// 预选三个元素 a,b,c
int a=0,b=0,c=0;
bool found=false;
rep(x,1,14) rep(y,x+1,14) rep(z,y+1,14){
if (query(x,y,z)<=(n-4)/6){
a=x,b=y,c=z;
found=true;
break;
}
}
// map 按 key 降序排列
map<int,vector<int>,greater<int> > m;
rep(x,1,n+1) if (x!=a && x!=b){
m[query(a,b,x)].push_back(x);
}
int hv = (*m.begin()).fi; // 最大 key
if (sz(m[hv-1])>=2){ // 必有恰好两个
if (query(m[hv][0], m[hv-1][0], a) >
query(m[hv][0], m[hv-1][1], a))
swap(m[hv-1][0], m[hv-1][1]);
}
int hi = m[hv][0], hi2 = m[hv-1][0];
ans[hi] = 1;
ans[hi2] = 2;
rep(x,1,n+1) if (x!=hi && x!=hi2){
ans[x] = query(hi, hi2, x) + 2;
}
if (ans[1] > ans[2])
rep(x,1,n+1) ans[x] = n - ans[x] + 1;
cout<<"! ";
rep(x,1,n+1) cout<<ans[x]<<" ";
cout<<endl;
cin>>n; // 读入比赛中固定的“无用”值
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin.exceptions(ios::badbit | ios::failbit);
int TC;
cin>>TC;
while (TC--){
solve();
}
}