Problem: You are given an array a consisting of n integers.

Let min(l, r) be the minimum value among a_l, a_{l + 1}, …, a_r and max(l, r) be the maximum value among a_l, a_{l + 1}, …, a_r.

Your task is to choose three positive (greater than 0) integers x, y and z such that:

  * x + y + z = n; 
  * max(1, x) = min(x + 1, x + y) = max(x + y + 1, n). 



In other words, you have to split the array a into three consecutive non-empty parts that cover the whole array and the maximum in the first part equals the minimum in the second part and equals the maximum in the third part (or determine it is impossible to find such a partition).

Among all such triples (partitions), you can choose any.

You have to answer t independent test cases.

Input

The first line of the input contains one integer t (1 ≤ t ≤ 2 ⋅ 10^4) — the number of test cases. Then t test cases follow.

The first line of the test case contains one integer n (3 ≤ n ≤ 2 ⋅ 10^5) — the length of a.

The second line of the test case contains n integers a_1, a_2, …, a_n (1 ≤ a_i ≤ 10^9), where a_i is the i-th element of a.

It is guaranteed that the sum of n does not exceed 2 ⋅ 10^5 (∑ n ≤ 2 ⋅ 10^5).

Output

For each test case, print the answer: NO in the only line if there is no such partition of a that satisfies the conditions from the problem statement. Otherwise, print YES in the first line and three integers x, y and z (x + y + z = n) in the second line.

If there are several answers, you can print any.

Example

Input


6
11
1 2 3 3 3 4 4 3 4 2 1
8
2 9 1 7 3 9 4 1
9
2 1 4 2 4 3 3 1 2
7
4 2 1 1 4 1 4
5
1 1 1 1 1
7
4 3 4 3 3 3 4


Output


YES
6 1 4
NO
YES
2 5 2
YES
4 1 2
YES
1 1 3
YES
2 1 4

Solution (in JAVA):

Solution:
import java.util.*;
import java.io.*;

public class Ana {
	static int n, arr[], max[];
	static SparseTable sp;
	static boolean found;
	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);
		int tt = sc.nextInt();
		lp:while (tt-- > 0) {
			n = sc.nextInt();
			arr = sc.nextIntArray(n);
			sp = new SparseTable(arr,n);
			max = new int[n];
			max[n - 1] = arr[n - 1];
			for (int i = n - 2; i >= 0; i--)
				max[i] = Math.max(arr[i], max[i + 1]);
			int cur = arr[0];
			for(int i=0;i<n-2;i++) {
				cur = Math.max(cur, arr[i]);
				int left = lower_bound(i+1,cur);
				int right = upper_bound(i+1,cur);
//				System.out.println(cur+" "+left+" "+right);
				if(left==-1 || left>=n-1)
					continue;
				right = Math.min(right, n-2);
				int find = find(left+1, right+1, cur);
				if(find==-1)
					continue;
//				System.out.println(i+" "+find);
				out.println("YES");
				out.println((i+1)+" "+(find-i-1)+" "+(n-find));
				continue lp;
			}
			out.println("NO");
		}

		out.close();
	}
	
	private static int find(int lo, int hi, int req) {
		while(lo<=hi) {
			int mid=(lo+hi)/2;
			if(max[mid]>req) 
				lo = mid+1;
			else if(max[mid]<req)
				hi = mid-1;
			else 
				return mid;
		}
		return -1;
	}

	private static int lower_bound(int st, int req) {
		int i=-1;
//		found = false;
		int lo=st; int hi=arr.length-1;
		while(lo<=hi) {
			int mid=(lo+hi)/2;
			int res = sp.query(st, mid);
//			System.out.println(st+" "+mid+" "+res);
			if(res>req) {
				lo = mid+1;
			}
			else if(res<req)
				hi=mid-1;
			else {
				i = mid;
				hi = mid-1;
//				found = true;
			}
		}
		return i;
	}
	private static int upper_bound(int st, int req) {
		int i=-1;
//		found = false;
		int lo=st; int hi=arr.length-1;
		while(lo<=hi) {
			int mid=(lo+hi)/2;
			int res = sp.query(st, mid);
			if(res>req) {
				lo = mid+1;
			}
			else if(res<req)
				hi=mid-1;
			else {
				i = mid;
				lo = mid+1;
//				found = true;
			}
		}
		return i;
	}
//	static class SparseTable {                                          
//		  
//			int A[], SpT[][];
//			
//			SparseTable(int[] A) 
//			{
//				int n = A.length;	this.A = A;
//				int k = (int)Math.floor(Math.log(n) / Math.log(2)) + 1;
//				SpT = new int[n][k];
////				System.out.println(Arrays.toString(A));
//				for (int i = 0; i < n; i++) 
//					SpT[i][0] = i; 					// RMQ of sub array starting at index i and of length 2^0=1
//			
//				//overall time complexity = O(n log n)
//				for (int j = 1; (1<<j) <= n; j++) 				
//					for (int i = 0; i + (1<<j) - 1 < n; i++)    
//						if (A[SpT[i][j-1]] < A[SpT[i+(1<<(j-1))][j-1]])
//							SpT[i][j] = SpT[i][j-1];    		// start at index i of length 2^(j-1)
//						else                  					// start at index i+2^(j-1) of length 2^(j-1)
//							SpT[i][j] = SpT[i+(1<<(j-1))][j-1];
//			 }
//
//			  int query(int i, int j) 
//			  {
////				  i++;
////				  j++;
//			    int k = (int)Math.floor(Math.log(j-i+1) / Math.log(2)); // 2^k <= (j-i+1)
//			    
//			    if (A[SpT[i][k]] <= A[SpT[j-(1<<k)+1][k]]) 
//			    	return SpT[i][k];
//			    else
//			    	return SpT[j-(1<<k)+1][k];
//			  } 
//		}
	static class SparseTable {
		int[]log,min[],arr;
		int inf=(int)1e9;
		SparseTable(int[]in,int n) {
			arr=in;
			log = new int[n+1];
			for (int i = 2; i <= n; i++)
				log[i] = log[i / 2] + 1;
			
			min=new int[n][22];
			for(int i=0;i<n;i++) {
				min[i][0]=i;
			}
			for(int i=1,len=2;len<=n;i++,len<<=1) {
				for(int j=0;j<n;j++) {
					int u=min[j][i-1],v=j+(len>>1)>=n?inf:min[j+(len>>1)][i-1];
					if(v==inf) {
						min[j][i]=u;
					}
					else
						min[j][i]=(arr[u]<arr[v]?u:v);
				}
			}
		}
		int query(int l,int r) {
			int len = r - l + 1;
			int lg = log[len];
			int u = min[l][lg];
			int v = min[r - (1 << lg) + 1][lg];
			int bestIdx = arr[u] < arr[v] ? u : v;
			return arr[bestIdx];//or return bestIdx if we want the best index
		}
		
	}
	static class Pair {
		long x, cnt;

		Pair(long a, long b) {
			x = a;
			cnt = b;
		}
	}

	static class Scanner {
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s) {
			br = new BufferedReader(new InputStreamReader(s));
		}

		public Scanner(String s) throws FileNotFoundException {
			br = new BufferedReader(new FileReader(s));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public int[] nextIntArray(int n) throws IOException {
			int[] ans = new int[n];
			for (int i = 0; i < n; i++)
				ans[i] = nextInt();
			return ans;
		}

		public long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public String nextLine() throws IOException {
			return br.readLine();
		}

		public double nextDouble() throws IOException {
			return Double.parseDouble(next());
		}

		public boolean ready() throws IOException {
			return br.ready();
		}

	}
}