Problem: This problem is actually a subproblem of problem G from the same contest.

There are n candies in a candy box. The type of the i-th candy is a_i (1 ≤ a_i ≤ n).

You have to prepare a gift using some of these candies with the following restriction: the numbers of candies of each type presented in a gift should be all distinct (i. e. for example, a gift having two candies of type 1 and two candies of type 2 is bad). 

It is possible that multiple types of candies are completely absent from the gift. It is also possible that not all candies of some types will be taken to a gift.

Your task is to find out the maximum possible size of the single gift you can prepare using the candies you have.

You have to answer q independent queries.

If you are Python programmer, consider using PyPy instead of Python when you submit your code.

Input

The first line of the input contains one integer q (1 ≤ q ≤ 2 ⋅ 10^5) — the number of queries. Each query is represented by two lines.

The first line of each query contains one integer n (1 ≤ n ≤ 2 ⋅ 10^5) — the number of candies.

The second line of each query contains n integers a_1, a_2, ..., a_n (1 ≤ a_i ≤ n), where a_i is the type of the i-th candy in the box.

It is guaranteed that the sum of n over all queries does not exceed 2 ⋅ 10^5.

Output

For each query print one integer — the maximum possible size of the single gift you can compose using candies you got in this query with the restriction described in the problem statement.

Example

Input


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


Output


3
10
9

Note

In the first query, you can prepare a gift with two candies of type 8 and one candy of type 5, totalling to 3 candies.

Note that this is not the only possible solution — taking two candies of type 4 and one candy of type 6 is also valid.

Solution (in JAVA):

Solution:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;
import java.util.Map.Entry;


public class  zz{
	static long[][]memo;
	static long mod=(long)(1e9)+7;
	static long dp(int nottaken,int val) {
		if(nottaken==0 && val!=0)return 1l;
		if(nottaken==0)return 0l;
		if(memo[nottaken][val]!=-1)return memo[nottaken][val];
		long sum=0;
		for(int j=1;j<=nottaken;j++) {
			sum=(sum+dp(nottaken-j,val^j))%mod;
		}
		return memo[nottaken][val]=sum;
	}
	static int o=0;
		static class ft {
			int[][]tree;
			int max_x;int max_y;
			ft(int x,int y){
				tree=new int[x+1][y+1];
				max_x=x;max_y=y;
			}
			void update(int x , int y , int val){
				int y1;
			    while (x <= max_x){
			        y1 = y;
			        while (y1 <= max_y){
			            tree[x][y1] += val;
			            y1 += (y1 & -y1); 
			        }
			        x += (x & -x); 
			    }
			}
			int read(int x,int y){
				int sum = 0; 
				  
				int y1;
			    while (x >0){
			        y1 = y;
			        while (y1 >0){
			            sum+=tree[x][y1];
			            y1 -= (y1 & -y1); 
			        }
			        x -= (x & -x); 
			    }
			    return sum;
			}
			
			int sum(int lx,int rx,int ly,int ry) {
				return read(rx,ry)-read(rx,ly-1)-read(lx-1,ry)+read(lx-1,ly-1);
			}
			
			
	}
		static boolean []v;
		static int dfs(int i) {
			v[i]=true;
			int sum=0;int prev=0;
			for(pair j:adj[i]) {
				if(!v[j.num]) {
					int x=dfs(j.num)+j.idx;
					sum+=x+Math.min(x,prev);
					prev=x;
				}
			}
			return sum;
		}
		static int max=-1;
		static boolean sum(int n) {
			int x=0;
			while(n>0) {
        		x+=n%10;
        		n/=10;
        	}
			if(x%4==0)return true;
			return false;
		}
    public static void main(String[] args) throws IOException{
        MScanner sc = new MScanner(System.in);
        PrintWriter pw=new PrintWriter(System.out);
        	int t=sc.nextInt();
        	while(t-->0) {
        		int n=sc.nextInt();
        		TreeMap<Integer,Integer>m=new TreeMap<Integer, Integer>();
        		for(int i=0;i<n;i++) {
        			int x=sc.nextInt();
        			m.put(x,m.getOrDefault(x,0)+1);
        		}
        		//System.out.println(m);
        		HashSet<Integer>taken=new HashSet<Integer>();int ans=0;
        		Integer[]occ=new Integer[m.size()];int c=0;
        		for(Entry<Integer,Integer>i:m.entrySet()) {
        				occ[c++]=i.getValue();
        			
        			
        		}
        		Arrays.sort(occ);int prev=-1;int poss=occ[c-1];
        		
        		for(int i=c-1;i>=0;i--) {
        			//System.out.println(occ[i]+" "+prev+" "+poss);
        			if(poss<=0)break;
        			if(prev==occ[i]) {
        				
        				ans+=poss;poss--;
        			}
        			else {
        				if(occ[i]>poss) {
        					
        					ans+=poss;poss--;
        				}
        				else {
        					ans+=occ[i];poss=occ[i]-1;prev=occ[i];
        				}
        			}
        		}
        		pw.println(ans);
        	}
        pw.flush();
    }
    static LinkedList<pair>adj[];
    static LinkedList<Integer>lang[];
    static long fastpow(long n,long ti) {
		 if (ti == 0) 
		        return 1l;
		if(ti%2==0) {
			long y=fastpow(n, ti/2);
			long k=y*y;
			k%=mod;
			return k;
		}
		else {
			long y=fastpow(n, ti/2);
			long k=n*y*y;
			k%=mod;
			return k;
		}
	}
    static long gcd(long a, long b) {

		if (b == 0)
			return a;
		return gcd(b, a % b);
	}
    static int[]primes;
    static int sizeofp=0;
	static int[] isComposite;

	static void sieve(int N)	// O(N log log N) 
	{
		isComposite = new int[N+1];					
		isComposite[0] = isComposite[1] = 1;			
		primes = new int[N];

		for (int i = 2; i <= N; ++i) 					
			if (isComposite[i] == 0) 					
			{
				primes[sizeofp++]=i;;
				if(1l * i * i <= N)
					for (int j = i * i; j <= N; j += i)	
						isComposite[j] = 1;
			}   
	}
    static class pair implements Comparable<pair>{
    	int num;int idx;
    	pair(int x,int y){
    		num=x;idx=y;
    	}
		@Override
		public int compareTo(pair o) {
			if(num!=o.num) {
				return num-o.num;
			}
			return idx-o.idx;
		}
		public boolean equals(pair o) {
			if(this.compareTo(o)==0)return true;
			return false;
		}
		public String toString() {
			return "("+0+" "+0+")";
		}
    }
	static class MScanner 
	{
	    StringTokenizer st;
	    BufferedReader br;

	    public MScanner(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 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 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 boolean ready() throws IOException {return br.ready();}


	}
}