Let's denote a k-step ladder as the following structure: exactly k + 2 wooden planks, of which

  * two planks of length at least k+1 — the base of the ladder; 
  * k planks of length at least 1 — the steps of the ladder; 



Note that neither the base planks, nor the steps planks are required to be equal.

For example, ladders 1 and 3 are correct 2-step ladders and ladder 2 is a correct 1-step ladder. On the first picture the lengths of planks are [3, 3] for the base and [1] for the step. On the second picture lengths are [3, 3] for the base and [2] for the step. On the third picture lengths are [3, 4] for the base and [2, 3] for the steps. 

<image>

You have n planks. The length of the i-th planks is a_i. You don't have a saw, so you can't cut the planks you have. Though you have a hammer and nails, so you can assemble the improvised "ladder" from the planks.

The question is: what is the maximum number k such that you can choose some subset of the given planks and assemble a k-step ladder using them?

Input

The first line contains a single integer T (1 ≤ T ≤ 100) — the number of queries. The queries are independent.

Each query consists of two lines. The first line contains a single integer n (2 ≤ n ≤ 10^5) — the number of planks you have.

The second line contains n integers a_1, a_2, ..., a_n (1 ≤ a_i ≤ 10^5) — the lengths of the corresponding planks.

It's guaranteed that the total number of planks from all queries doesn't exceed 10^5.

Output

Print T integers — one per query. The i-th integer is the maximum number k, such that you can choose some subset of the planks given in the i-th query and assemble a k-step ladder using them.

Print 0 if you can't make even 1-step ladder from the given set of planks.

Example

Input


4
4
1 3 1 3
3
3 3 2
5
2 3 3 4 2
3
1 1 2


Output


2
1
2
0

Note

Examples for the queries 1-3 are shown at the image in the legend section.

The Russian meme to express the quality of the ladders:

<image>


import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.StringTokenizer;
import java.util.TreeSet;

import javax.swing.plaf.synth.SynthSpinnerUI;

public class cf2 {
	static final double EPS = 1e-9;
	static int[] isComposite;
	static ArrayList<Integer> primes;
	static TreeSet<Long> hs = new TreeSet<>();
	static HashMap<Long, Integer> hm = new HashMap<>();
	// static int n;
	static int k;
	static int y[];
	static int x[];
	static long memo[][];
	static long pageSize = 0;
	static long reached = 0;
    static long ans=0; 
	
	public static void main(String[] args) throws IOException {

		Scanner sc = new Scanner(System.in);
	    int n = sc.nextInt();
	    StringBuilder sb = new StringBuilder();
	    while(n-->0) {
	    int m = sc.nextInt();
	    int x [] = new int [m];
	    
	    for(int i=0;i<m;i++) {
	    	x[i]=sc.nextInt();
	    }
	    
	    shuffle(x);
	    Arrays.sort(x);
	    int least = x[m-2]-1;
//	    System.out.println(least);
	    int ans = Math.min(least, m-2);
	    ans= Math.max(0,ans);
	    sb.append(ans+"\n");
//	    System.out.println(ans);
	    
	    }
	System.out.println(sb.toString());
	}
	
	public static long rec( int index, boolean canUpper, boolean canLower) {
		
		if(index==x.length) {
			return 0;
		}
		int valFormem = mapBool(canUpper, canLower);
		
		if(memo[index][valFormem]!=-1) {
			return memo[index][valFormem]; 
		}
		
		long tot=0;
		if(canUpper) {
		 tot=x[index]+rec( index+1, false, true);
		}
	
		if(canLower) {
			 tot=Math.max(tot, y[index]+rec( index+1, true, false));
		}
		tot=Math.max(tot, rec(index+1, true, true));
		
		return memo[index][valFormem]=tot;
		
		
		
	}
	
    public static int mapBool(boolean canUpper, boolean canLower) {
    	if(canUpper&&canLower)
    		return 2;
    	if(canUpper&&!canLower)
    		return 1;
    	
    	if(!canUpper&&canLower)
    		return 0;
    	
    	return 3;
        
    }

	public static int nextPage(int gathered) {
		long nextAt = hs.ceiling((long) reached) - gathered;

		long skipPages = (long) Math.ceil((nextAt * 1.0) / (pageSize * 1.0));

		long nextPage = (skipPages) * pageSize;
		long from = (skipPages - 1) * pageSize;
		long to = (skipPages) * pageSize;
//		System.out.println("from " + from + " to " + to);
		int count = 0;
		long i = nextAt;
		while (true) {

			if (hs.contains(i + gathered)) {
				count++;
				hs.remove(i + gathered);

				if (hs.ceiling((long) reached) != null) {
					nextAt = hs.ceiling((long) reached) - gathered;
					if (nextAt <= to)
						i = nextAt;
					else
						break;

				} else
					break;

			}

		}
		// System.out.println(count);
		reached = to;
		return count;
	}

	public static void printAns() {

	}

	public static class Point implements Comparable<Point> {

		static final double EPS = 1e-9;

		int x, y;
		// String c;

		Point(int a, int b) {
			x = a;
			y = b;
			// c = s;
		}

		public int compareTo(Point p) {
			if (Math.abs(x - p.x) > EPS)
				return x > p.x ? 1 : -1;
			if (Math.abs(y - p.y) > EPS)
				return y > p.y ? 1 : -1;
			return 0;
		}

	}

	static void shuffle(int[] a) {
		int n = a.length;
		for (int i = 0; i < n; i++) {
			int r = i + (int) (Math.random() * (n - i));
			int tmp = a[i];
			a[i] = a[r];
			a[r] = tmp;
		}
	}

	static class Scanner {
		StringTokenizer st;
		BufferedReader br;

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

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

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

		public double nextDouble() throws IOException {
			String x = next();
			StringBuilder sb = new StringBuilder("0");
			double res = 0, f = 1;
			boolean dec = false, neg = false;
			int start = 0;
			if (x.charAt(0) == '-') {
				neg = true;
				start++;
			}
			for (int i = start; i < x.length(); i++)
				if (x.charAt(i) == '.') {
					res = Long.parseLong(sb.toString());
					sb = new StringBuilder("0");
					dec = true;
				} else {
					sb.append(x.charAt(i));
					if (dec)
						f *= 10;
				}
			res += Long.parseLong(sb.toString()) / f;
			return res * (neg ? -1 : 1);
		}

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

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

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

		public long nextlong() throws IOException {
			String x = next();
			StringBuilder sb = new StringBuilder("0");
			long res = 0, f = 1;
			boolean dec = false, neg = false;
			int start = 0;
			if (x.charAt(0) == '-') {
				neg = true;
				start++;
			}
			for (int i = start; i < x.length(); i++)
				if (x.charAt(i) == '.') {
					res = Long.parseLong(sb.toString());
					sb = new StringBuilder("0");
					dec = true;
				} else {
					sb.append(x.charAt(i));
					if (dec)
						f *= 10;
				}
			res += Long.parseLong(sb.toString()) / f;
			return res * (neg ? -1 : 1);
		}

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

	}
	public static class SegmentTree {		// 1-based DS, OOP
		
		int N; 			//the number of elements in the array as a power of 2 (i.e. after padding)
		int[] array, sTree, lazy;
		
		SegmentTree(int[] in)		
		{
			array = in; N = in.length - 1;
			sTree = new int[N<<1];		//no. of nodes = 2*N - 1, we add one to cross out index zero
			lazy = new int[N<<1];
			build(1,1,N);
		}
		
		void build(int node, int b, int e)	// O(n)
		{
			if(b == e)					
				sTree[node] = array[b];
			else						
			{
				int mid = b + e >> 1;
				build(node<<1,b,mid);
				build(node<<1|1,mid+1,e);
				sTree[node] = sTree[node<<1]+sTree[node<<1|1];
			}
		}
		
		
		void update_point(int index, int val)			// O(log n)
		{
			index += N - 1;				
			sTree[index] += val;			
			while(index>1)				
			{
				index >>= 1;
				sTree[index] = sTree[index<<1] + sTree[index<<1|1];		
			}
		}
		
		
		void update_range(int i, int j, int val)		// O(log n) 
		{
			update_range(1,1,N,i,j,val);
		}
		
		void update_range(int node, int b, int e, int i, int j, int val)
		{
			if(i > e || j < b)		
				return;
			if(b >= i && e <= j)		
			{
				sTree[node] += (e-b+1)*val;			
				lazy[node] += val;				
			}							
			else		
			{
				int mid = b + e >> 1;
				propagate(node, b, mid, e);
				update_range(node<<1,b,mid,i,j,val);
				update_range(node<<1|1,mid+1,e,i,j,val);
				sTree[node] = sTree[node<<1] + sTree[node<<1|1];		
			}
			
		}
		void propagate(int node, int b, int mid, int e)		
		{
			lazy[node<<1] += lazy[node];
			lazy[node<<1|1] += lazy[node];
			sTree[node<<1] += (mid-b+1)*lazy[node];		
			sTree[node<<1|1] += (e-mid)*lazy[node];		
			lazy[node] = 0;
		}
		
		int query(int i, int j)
		{
			return query(1,1,N,i,j);
		}
		
		int query(int node, int b, int e, int i, int j)	// O(log n)
		{
			if(i>e || j <b)
				return 0;		
			if(b>= i && e <= j)
				return sTree[node];
			int mid = b + e >> 1;
			propagate(node, b, mid, e);
			int q1 = query(node<<1,b,mid,i,j);
			int q2 = query(node<<1|1,mid+1,e,i,j);
			return q1 + q2;	
					
		}
		}
		
}