#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <map>
#include <unordered_map>
#include <stack>
#include <iomanip>
#include <queue>
#include <set>
#include <bitset>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
 
 
 
#define ll long long
#define uint unsigned int
#define ull unsigned ll
#define mp make_pair
#define pb push_back
#define all(x) x.begin(), x.end()
#define allr(x) x.rbegin(), x.rend()
#define speedhack() ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define do(x) for(int i = 1; i <= x; i++){ solve(); }
#define sz(x) (int)x.size()
#define pii pair < int, int >
using namespace std;
using namespace __gnu_pbds;
#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
 
const ll MAXN = 1e18;
const ll SIZE = 1e5+2; //are u sure?
const ll mod = 1e9+7;
unordered_map<int,int> cnt;


void solve(){
	int n; cin >> n;
	vector<int> v;
	for(int i = 0; i < n; i++){
		int x; cin >> x;
		if(cnt[x] == 0){
			v.push_back(x);
		}
		cnt[x]++;
	}
	int lim = n/2;
	int g = cnt[v[0]];
	lim -= g;
	int s = 0;
	int b = 0;
	int pos = 0;
	for(int i = 1; i < sz(v); i++){
		s += cnt[v[i]];
		if(s > g){
			pos = i+1;
			break;
		}
	}
	lim -= s;
	for(int i = pos; i < sz(v); i++){
		if(b+cnt[v[i]] <= lim){
			b += cnt[v[i]];
		}else{
			break;
		}
	}
	if(g == 0 || s == 0 || b == 0)
		g = s = b = 0;
	cout << g << " " << s << " " << b << endl;
	cnt.clear();
}



int main(){
	speedhack()
	int it; cin >> it;
	// int it = 1;
	do(it);
	return 0;
}