#include <bits/stdc++.h>
using namespace std;
#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <ext/pb_ds/assoc_container.hpp> 
#include <ext/pb_ds/tree_policy.hpp> 
using namespace __gnu_pbds; 
#define indexed_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update> 
//find_by_order = returns pointer to element at that pos
//order_of_key = returns pos of the given element
#define indexed_multiset tree<int, null_type,less_equal<int>, rb_tree_tag,tree_order_statistics_node_update>
#define all(x)  (x).begin(),(x).end() 
#define mem1(a)  memset(a,-1,sizeof(a))
#define mem0(a)  memset(a,0,sizeof(a))  
#define int long long
#define endl "\n"
typedef vector<int> vi;
typedef pair<int,int> pi;
#define F first
#define S second
#define PB push_back
#define MP make_pair
#define rep(i,a,b) for (int i = a; i <b; i++)
#define MOD 1000000007
#define boost
#define printv(x, size) for (size_t tk = 0; tk < size; tk++) {cout << x[tk] << " ";} cout<<endl;
#define debug1(x) cout<<#x<<" "<<x<<endl;
#define debug2(x,y) cout<<#x<<" "<<x<<" "<<#y<<" "<<y<<endl;
#define debug3(x,y,z) cout<<#x<<" "<<x<<" "<<#y<<" "<<y<<" "<<#z<<" "<<z<<endl;
template<typename T1,typename T2>istream& operator>>(istream& in,pair<T1,T2> &a){in>>a.F>>a.S;return in;}
template<typename T1,typename T2>ostream& operator<<(ostream& out,pair<T1,T2> a){out<<a.F<<" "<<a.S;return out;}
template<class _T>inline void read(_T &_a)
{
    bool f=0; char _c=getchar(); _a=0;
    while(_c<'0'||_c>'9'){ if(_c=='-') f=1; _c=getchar(); }
    while(_c>='0'&&_c<='9'){ _a=(_a<<3)+(_a<<1)-'0'+_c; _c=getchar(); }
    if(f) _a=-_a;
}
int pw(int a,int b,int p){
    if(b==0)return 1;
    int t=pw(a,b/2,p);
    if(b%2)return (((a*t)%p)*t)%p;
    else return ((t*t)%p);
}

const long long INF=1e18;
int T=1;

int32_t main()
{ 
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin>>T;
      while(T--)
   {
    
       map<int,int> mp;
       int n;
       cin>>n;
       vi a(n);
       rep(i,0,n)
       {
           cin>>a[i];
           mp[a[i]]++;
       }
       if(n/2<3)
       {
           cout<<0<<" "<<0<<" "<<0<<endl;
           continue;
       }

       set<int> st;
       rep(i,0,n/2)
       {
           st.insert(a[i]);
       }
       if(st.size()<3)
       {
           cout<<0<<" "<<0<<" "<<0<<endl;
           continue;
       }
       vi nw(all(st));
       reverse(all(nw));
    /*    printv(nw,nw.size()); */
       int g = mp[nw[0]];
       int j =1;
       int s = 0;
       while(j<nw.size() && g>=s)
       {
           s+=mp[nw[j]];
           j++;
       }
       int b =0;
       rep(i,j,nw.size())
       {
            b += mp[nw[i]];
            if(g+s+b>n/2)
            {
                b-=mp[nw[i]];
                break;
            }
       }
       /* debug3(g,s,b) */
       if(g>s || g>b)
       {
           cout<<0<<" "<<0<<" "<<0<<endl;
           continue;
       }
       cout<<g<<" "<<s<<" "<<b<<endl;

       
     



        
   }
   
	// you should actually read the stuff at the bottom
 
/* stuff you should look for
	* int overflow, array bounds
	* special cases (n=1?)
	* do smth instead of nothing and stay organized
	* WRITE STUFF DOWN
	* DON'T GET STUCK ON ONE APPROACH
*/
return 0;
}