#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp>
#define sz(v)   ((int)(v).size())
#define  all(v)    ((v).begin()),((v).end())
#define  allr(v)    ((v).rbegin()),((v).rend())
#define   pb         push_back
#define   mp         make_pair
#define   mt         make_tuple
//#define   Y            imag()
//#define   X            real()
#define    clr(v,d)      memset( v, d ,sizeof(v))
#define   angle(n)      atan2((n.imag()),(n.real()))
#define   vec(a,b)       ((b)-(a))
//#define   length(a)      hypot( (a.imag()),(a.real()) )
#define   normalize(a)      (a)/(length(a))
//#define    dp(a,b)          (((conj(a))*(b)).real())
//#define    cp(a,b)          (((conj(a))*(b)).imag())
#define    lengthsqrt(a)       dp(a,a)
#define    rotate0( a,ang)    ((a)*exp( point(0,ang) ))
#define    rotateA(about,p,ang)   (rotate0(vec(about,p),ang)+about)
#define    reflection0(m,v)         (conj((v)/(m))*(m))
#define     reflectionA(m,v,p0)     (conj( (vec(p0,v))/(vec(p0,m)) ) * (vec(p0,m)) ) + p0
//#define     same(p1,p2)               ( dp(  vec(p1,p2),vec(p1,p2)) < eps )
#define     PT                    complex<double>
#define outfile freopen("out.out", "w", stdout);
#define infile  freopen("in.in", "r", stdin);
#define PI acos(-1)
typedef  long long     ll ;
typedef  unsigned long long ull;
const double eps= (1e-9);
using namespace std;
using namespace __gnu_pbds;
int dcmp(double a,double b){   return fabs(a-b)<=eps ? 0: (a>b)? 1:-1  ;}
int getBit(int num, int idx) {return ((num >> idx) & 1) == 1;}
ll setBit1(ll num, int idx) {return num | (1ll<<idx);}
ll setBit0(ll num, int idx) {return num & ~(1ll<<idx);}
ll flipBit(int num, int idx) {return num ^ (1<<idx);}
void FS(){ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);}
const int N=200009;
int cnt[N],cnt2[N];
vector<pair<int,int> > v;
void I(int n)
{
    for(int i=0;i<=n;i++)
        cnt[i]=cnt2[i]=0;
}
int main()
{
    int q;
    cin>>q;

    while(q--)
    {
       int n;
       cin>>n;
       int a,b,S=0;
       I(n);
       for(int i=0;i<n;i++)
       {
           cin>>a>>b;
           cnt[a]++;
           if(b==0)
           cnt2[a]++,S++;
       }
       v.clear();
       for(int i=1;i<=n;i++)
       {
           if(cnt[i]==0)
            continue;
           v.pb(mp(cnt[i],-cnt2[i]));
       }

       sort(allr(v));
       int dec=1;
       ll ans1=0,ans2=0;
       ans1=v[0].first;
       for(int i=1;i<sz(v);i++)
       {
           int C=v[i].first;
           int T=-v[i].second;
           if(C==v[i-1].first)
           {
               if(C-dec>=1)
               {
                 ans1+= C-dec;
                 ans2+=min(T,dec);
                 dec++;
               }
               else
               {
                   ans2+=min(dec,T);
                   dec++;
               }
           }
           else
           {
               dec=1;
               ans1+=C;
           }
       }

       cout<<ans1<<" "<<ans1-(S-ans2)<<endl;
    }
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp>
#define sz(v)   ((int)(v).size())
#define  all(v)    ((v).begin()),((v).end())
#define  allr(v)    ((v).rbegin()),((v).rend())
#define   pb         push_back
#define   mp         make_pair
#define   mt         make_tuple
//#define   Y            imag()
//#define   X            real()
#define    clr(v,d)      memset( v, d ,sizeof(v))
#define   angle(n)      atan2((n.imag()),(n.real()))
#define   vec(a,b)       ((b)-(a))
//#define   length(a)      hypot( (a.imag()),(a.real()) )
#define   normalize(a)      (a)/(length(a))
//#define    dp(a,b)          (((conj(a))*(b)).real())
//#define    cp(a,b)          (((conj(a))*(b)).imag())
#define    lengthsqrt(a)       dp(a,a)
#define    rotate0( a,ang)    ((a)*exp( point(0,ang) ))
#define    rotateA(about,p,ang)   (rotate0(vec(about,p),ang)+about)
#define    reflection0(m,v)         (conj((v)/(m))*(m))
#define     reflectionA(m,v,p0)     (conj( (vec(p0,v))/(vec(p0,m)) ) * (vec(p0,m)) ) + p0
//#define     same(p1,p2)               ( dp(  vec(p1,p2),vec(p1,p2)) < eps )
#define     PT                    complex<double>
#define outfile freopen("out.out", "w", stdout);
#define infile  freopen("in.in", "r", stdin);
#define PI acos(-1)
typedef  long long     ll ;
typedef  unsigned long long ull;
const double eps= (1e-9);
using namespace std;
using namespace __gnu_pbds;
int dcmp(double a,double b){   return fabs(a-b)<=eps ? 0: (a>b)? 1:-1  ;}
int getBit(int num, int idx) {return ((num >> idx) & 1) == 1;}
ll setBit1(ll num, int idx) {return num | (1ll<<idx);}
ll setBit0(ll num, int idx) {return num & ~(1ll<<idx);}
ll flipBit(int num, int idx) {return num ^ (1<<idx);}
void FS(){ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);}
const int N=200009;
int cnt[N],cnt2[N];
vector<int > v,v1;
vector< pair<int,int> > v2;
priority_queue<int > pq;
void I(int n)
{
    for(int i=0;i<=n;i++)
        cnt[i]=cnt2[i]=0;
    while(!pq.empty())
        pq.pop();
    v1.clear();
    v2.clear();
    v.clear();
}
int main()
{
    int q;
    cin>>q;

    while(q--)
    {
       int n;
       cin>>n;
       int a,b;
       I(n);
       for(int i=0;i<n;i++)
       {
          cin>>a>>b;
          cnt[a]++;
          if(b==1)
            cnt2[a]++;
       }

       for(int i=1;i<=n;i++)
       {
           if(cnt[i]==0)
            continue;
           v.pb(cnt[i]);
           v2.pb(mp(cnt[i],cnt2[i]));
       }
       sort(allr(v2));
       sort(allr(v));
       v1.pb(v[0]);
       ll ans1=v[0],ans2=0;

       for(int i=1;i<n;i++)
       {
           v[i]=max(0,min(v[i],v[i-1]-1));
           ans1+=v[i];
           if(v[i]>0)
           v1.pb(v[i]);
       }
       int id=0;
      // cout<<v[0]<<" "<<v2[id].first<<endl;
       for(int i=0;i<sz(v1);i++)
       {
           while(id<sz(v2)&&v2[id].first>=v1[i])
           {
               pq.push(v2[id].second);
               id++;
           }
           if(sz(pq)>0)
           {
           ans2+=min(v1[i],pq.top());
           pq.pop();
           }
       }
       cout<<ans1<<" "<<ans2<<endl;
    }
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp>
#define sz(v)   ((int)(v).size())
#define  all(v)    ((v).begin()),((v).end())
#define  allr(v)    ((v).rbegin()),((v).rend())
#define   pb         push_back
#define   mp         make_pair
#define   mt         make_tuple
//#define   Y            imag()
//#define   X            real()
#define    clr(v,d)      memset( v, d ,sizeof(v))
#define   angle(n)      atan2((n.imag()),(n.real()))
#define   vec(a,b)       ((b)-(a))
//#define   length(a)      hypot( (a.imag()),(a.real()) )
#define   normalize(a)      (a)/(length(a))
//#define    dp(a,b)          (((conj(a))*(b)).real())
//#define    cp(a,b)          (((conj(a))*(b)).imag())
#define    lengthsqrt(a)       dp(a,a)
#define    rotate0( a,ang)    ((a)*exp( point(0,ang) ))
#define    rotateA(about,p,ang)   (rotate0(vec(about,p),ang)+about)
#define    reflection0(m,v)         (conj((v)/(m))*(m))
#define     reflectionA(m,v,p0)     (conj( (vec(p0,v))/(vec(p0,m)) ) * (vec(p0,m)) ) + p0
//#define     same(p1,p2)               ( dp(  vec(p1,p2),vec(p1,p2)) < eps )
#define     PT                    complex<double>
#define outfile freopen("out.out", "w", stdout);
#define infile  freopen("in.in", "r", stdin);
#define PI acos(-1)
typedef  long long     ll ;
typedef  unsigned long long ull;
const double eps= (1e-9);
using namespace std;
using namespace __gnu_pbds;
int dcmp(double a,double b){   return fabs(a-b)<=eps ? 0: (a>b)? 1:-1  ;}
int getBit(int num, int idx) {return ((num >> idx) & 1) == 1;}
ll setBit1(ll num, int idx) {return num | (1ll<<idx);}
ll setBit0(ll num, int idx) {return num & ~(1ll<<idx);}
ll flipBit(int num, int idx) {return num ^ (1<<idx);}
void FS(){ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);}
const int N=200009;
int cnt[N],cnt2[N];
vector<int > v,v1;
vector< pair<int,int> > v2;
priority_queue<int > pq;
void I(int n)
{
    for(int i=0;i<=n;i++)
        cnt[i]=cnt2[i]=0;
    while(!pq.empty())
        pq.pop();
    v1.clear();
    v2.clear();
    v.clear();
}
int main()
{
    int q;
    cin>>q;

    while(q--)
    {
       int n;
       cin>>n;
       int a,b;
       I(n);
       for(int i=0;i<n;i++)
       {
          cin>>a>>b;
          cnt[a]++;
          if(b==1)
            cnt2[a]++;
       }

       for(int i=1;i<=n;i++)
       {
           if(cnt[i]==0)
            continue;
           v.pb(cnt[i]);
           v2.pb(mp(cnt[i],cnt2[i]));
       }
       sort(allr(v2));
       sort(allr(v));
       v1.pb(v[0]);
       ll ans1=v[0],ans2=0;

       for(int i=1;i<n;i++)
       {
           v[i]=max(0,min(v[i],v[i-1]-1));
           ans1+=v[i];
           if(v[i]>0)
           v1.pb(v[i]);
       }
       int id=0;
      // cout<<v[0]<<" "<<v2[id].first<<endl;
       for(int i=0;i<sz(v1);i++)
       {
           while(id<sz(v2)&&v2[id].first>=v1[i])
           {
               pq.push(v2[id].second);
               id++;
           }
         //  if(sz(pq)>0)
           //{
           ans2+=min(v1[i],pq.top());
           pq.pop();
        //   }
       }
       cout<<ans1<<" "<<ans2<<endl;
    }
}


#include<bits/stdc++.h>
using namespace std;

int sum(map<int, int> &candies) {
	map<int, int>::iterator it;
	set<int> freq;
	int sum = 0;
	for(it = candies.begin(); it != candies.end(); it++) {
		int count = it->second;
		while(freq.find(count) != freq.end())
			count--;
		if(count > 0) {
			freq.insert(count);
			sum += count;
		}
	}
	return sum;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);

	int q;
//	freopen("input/1183G.txt", "r", stdin);
	cin >> q;
	while(q--) {
		int n, candy;
		bool can_give;
		cin >> n;

		map<int, int> candies;
		map<int, int> candies_can_give;

		for(int i=0; i<n; i++) {
			cin >> candy;
			cin >> can_give;
			if(!candies.count(candy))
				candies[candy] = 1;
			else candies[candy]++;

			if(can_give) {
				if(!candies_can_give.count(candy))
					candies_can_give[candy] = 1;
				else candies_can_give[candy]++;
			}
		}
		cout << sum(candies) << ' ' << sum(candies_can_give) << '\n';
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;

int sum(map<int, int> candies) {
	map<int, int>::iterator it;
	set<int> freq;
	int sum = 0;
	for(it = candies.begin(); it != candies.end(); it++) {
		int count = it->second;
		while(freq.find(count) != freq.end())
			count--;
		if(count > 0) {
			freq.insert(count);
			sum += count;
		}
	}
	return sum;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);

	int q;
	//freopen("input/1183G.txt", "r", stdin);
	cin >> q;
	while(q--) {
		int n, candy;
		int can_give;
		cin >> n;

		map<int, int> candies;
		map<int, int> candies_can_give;

		for(int i=0; i<n; i++) {
			cin >> candy;
			cin >> can_give;
			if(!candies.count(candy))
				candies[candy] = 1;
			else candies[candy]++;

			if(can_give) {
				if(!candies_can_give.count(candy))
					candies_can_give[candy] = 1;
				else candies_can_give[candy]++;
			}
		}
		cout << sum(candies) << ' ' << sum(candies_can_give) << '\n';
	}
	return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef pair<int, int> pii;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);

	int q;
	//freopen("input/1183G.txt", "r", stdin);
	cin >> q;
	while(q--) {
		int n, num, f;
		int sumA = 0, sumB = 0;
		cin >> n;
		if(n == 1) {
			cin >> num >> f;
			sumA = num;
			sumB = f;
		}
		else {
			vector<pii> candy(n);

			for(int i = 0; i < n; i++)
				candy[i] = {0, 0};

			for(int i = 0; i < n; i++) {
				cin >> num >> f;
				num--;
				candy[num].first += f;
				candy[num].second++;
			}

			sort(candy.begin(), candy.end());
			set<int> freq;
			set<pii> freqB;

			for(int i = n - 1; i >= 0; i--) {
				if(candy[i].second != 0) {
					int count = candy[i].second;
					while(freq.find(count) != freq.end())
						count--;

					if(count > 0) {
						freq.insert(count);
						candy[i].second = count;
						freqB.insert({candy[i].first, candy[i].second});
						sumA += count;
					}
				}
			}

			for(auto it = freqB.begin(); it != freqB.end(); it++) {
				pii p = *it;
				sumB += min(p.first, p.second);
			}
		}
		cout << sumA << ' ' << sumB << '\n';
	}
	return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef pair<int, int> pii;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);

	int q;
	//freopen("input/1183G.txt", "r", stdin);
	cin >> q;
	while(q--) {
		int n, num, f;
		int sumA = 0, sumB = 0;
		cin >> n;
		vector<pii> candy(n);

		for(int i=0; i<n; i++)
			candy[i] = make_pair(0, 0);

		for(int i=0; i<n; i++) {
			cin >> num >> f;
			num--;
			candy[num].first += f;
			candy[num].second++;
		}

		sort(candy.begin(), candy.end());
		set<int> freq;
		set<pii> freqB;

		for(int i = n - 1; i >= 0; i--) {
			if(candy[i].second != 0) {
				int count = candy[i].second;
				while(freq.find(count) != freq.end())
					count--;
				if(count > 0) {
					freq.insert(count);
					candy[i].second = count;
					freqB.insert(make_pair(candy[i].first, candy[i].second));
					sumA += count;
				}
			}
		}

		set<pii>::iterator it;
		for(it = freqB.begin(); it != freqB.end(); it++) {
			pii p = *it;
			sumB += min(p.first, p.second);
		}

		cout << sumA << ' ' << sumB << '\n';
	}
	return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef pair<int, int> pii;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);

	int q;
	//freopen("input/1183G.txt", "r", stdin);
	cin >> q;
	while(q--) {
		int n, num, f;
		int sumA = 0, sumB = 0;

		cin >> n;
		vector<pii> candy(n);

		for(int i = 0; i < n; i++)
			candy[i] = {0, 0};

		for(int i = 0; i < n; i++) {
			cin >> num >> f;
			num--;
			candy[num].first += f;
			candy[num].second++;
		}

		sort(candy.begin(), candy.end());
		set<int> freq;

		for(int i = n - 1; i >= 0; i--) {
			if(candy[i].second != 0) {
				int count = candy[i].second;
				while(freq.find(count) != freq.end())
					count--;

				if(count > 0) {
					freq.insert(count);
					candy[i].second = count;
					sumA += count;
					sumB += min(candy[i].first, candy[i].second);
				}
			}
		}

		cout << sumA << ' ' << sumB << '\n';
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;

int sum(map<int, int> &candies) {
	map<int, int>::iterator it;
	set<int> freq;
	int sum = 0;
	for(it = candies.begin(); it != candies.end(); it++) {
		int count = it->second;
		while(freq.find(count) != freq.end())
			count--;
		if(count > 0) {
			freq.insert(count);
			sum += count;
		}
	}
	return sum;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);

	int q;
	freopen("input/1183G.txt", "r", stdin);
	cin >> q;
	while(q--) {
		int n, candy;
		bool can_give;
		cin >> n;

		map<int, int> candies;
		map<int, int> candies_can_give;

		for(int i=0; i<n; i++) {
			cin >> candy;
			cin >> can_give;
			if(!candies.count(candy))
				candies[candy] = 1;
			else candies[candy]++;

			if(can_give) {
				if(!candies_can_give.count(candy))
					candies_can_give[candy] = 1;
				else candies_can_give[candy]++;
			}
		}
		cout << sum(candies) << ' ' << sum(candies_can_give) << '\n';
	}
	return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef pair<int, int> pii;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);

	int q;
	//freopen("input/1183G.txt", "r", stdin);
	cin >> q;
	while(q--) {
		int n, num, f;
		int sumA = 0, sumB = 0;

		cin >> n;
		vector<pii> candy(n);

		for(int i = 0; i < n; i++)
			candy[i] = {0, 0};

		for(int i = 0; i < n; i++) {
			cin >> num >> f;
			num--;
			candy[num].first += f;
			candy[num].second++;
		}

		sort(candy.begin(), candy.end());
		set<int> freq;
		set<pii> freqB;
		set<pii>::iterator it;

		for(int i = n - 1; i >= 0; i--) {
			if(candy[i].second != 0) {
				int count = candy[i].second;
				while(freq.find(count) != freq.end())
					count--;

				if(count > 0) {
					freq.insert(count);
					candy[i].second = count;
					freqB.insert({candy[i].first, candy[i].second});
					sumA += count;
				}
			}
		}

		for(it = freqB.begin(); it != freqB.end(); it++) {
			pii p = *it;
			sumB += min(p.first, p.second);
		}
		cout << sumA << ' ' << sumB << '\n';
	}
	return 0;
}


#include<bits/stdc++.h>

using namespace std;
typedef pair<int, int> pii;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);

	int q;
	//freopen("input/1183G.txt", "r", stdin);
	cin >> q;
	while(q--) {
		int n, num, f;
		int sumA = 0, sumB = 0;
		cin >> n;
		vector<pii> candy(n);

		for(int i = 0; i < n; i++)
			candy[i] = {0, 0};

		for(int i = 0; i < n; i++) {
			cin >> num >> f;
			num--;
			candy[num].first += f;
			candy[num].second++;
		}

		sort(candy.begin(), candy.end());
		set<int> freq;
		set<pii> freqB;

		for(int i = n - 1; i >= 0; i--) {
			if(candy[i].second != 0) {
				int count = candy[i].second;
				while(freq.find(count) != freq.end())
					count--;

				if(count > 0) {
					freq.insert(count);
					candy[i].second = count;
					freqB.insert({candy[i].first, candy[i].second});
					sumA += count;
				}
			}
		}

		for(auto it = freqB.begin(); it != freqB.end(); it++) {
			pii p = *it;
			sumB += min(p.first, p.second);
		}

		cout << sumA << ' ' << sumB << '\n';
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <stdlib.h>
#include <map>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <unordered_set>
#include <string>
#include <string.h>
#include <cmath>
#include <time.h>
using namespace std;
typedef long long ll;
#define MOD 998244353

//#include <bits/stdc++.h>

using namespace std;

struct Node
{
    int t;
    int f;
};

bool operator < (const Node& a,const Node& b)
{
    if(a.t == b.t)
        return a.f > b.f;
    return a.t > b.t;
}

int main()
{
    std::ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    int q;
    cin>>q;
    while(q--)
    {
        int n;
        cin>>n;
        map<int,Node> s;
        int i;
        for(i=0;i<n;i++)
        {
            int ta,tb;
            cin>>ta>>tb;
            auto it = s.find(ta);
            if(it == s.end())
            {
                Node tmp;
                tmp.t = 1;
                tmp.f = tb;
                s[ta] = tmp;
            }
            else
            {
                (it->second).t = (it->second).t + 1;
                (it->second).f = (it->second).f + tb;
            }
        }

        map<int,vector<Node>,greater<int>> c;
        int ans1 = 0;
        int ans2 = 0;

        for(auto& it : s)
        {
            auto it2 = c.find((it.second).t);
            if(it2 == c.end())
            {
                vector<Node> tmp;
                tmp.push_back(it.second);
                c[(it.second).t] = tmp;
            }
            else
            {
                (it2->second).push_back(it.second);
            }
        }

        priority_queue<int> pq;
        auto it = c.begin();
        int cur = it->first;
        while(cur > 0)
        {
            if(it != c.end() && cur == it->first)
            {
                for(i=0;i<(it->second).size();i++)
                {
                    pq.push((it->second)[i].f);
                }
                it++;
            }

            ans1 += cur;
            ans2 += min(pq.top(),cur);
            pq.pop();

            if(!pq.empty())
            {
                cur--;
            }
            else if(it != c.end())
            {
                cur = it->first;
            }
            else
            {
                break;
            }
        }

        cout<<ans1<<" "<<ans2<<endl;
    }

    return 0;
}


#include <iostream>
#include <vector>
#include <stdlib.h>
#include <map>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <unordered_set>
#include <string>
#include <string.h>
#include <cmath>
#include <time.h>
using namespace std;
typedef long long ll;
#define MOD 998244353

//#include <bits/stdc++.h>

using namespace std;

struct Node
{
    int t;
    int f;
};

bool operator < (const Node& a,const Node& b)
{
    if(a.t == b.t)
        return a.f > b.f;
    return a.t > b.t;
}

int main()
{
    std::ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    int q;
    cin>>q;
    while(q--)
    {
        int n;
        cin>>n;
        map<int,Node> s;
        int i;
        for(i=0;i<n;i++)
        {
            int ta,tb;
            cin>>ta>>tb;
            auto it = s.find(ta);
            if(it == s.end())
            {
                Node tmp;
                tmp.t = 1;
                tmp.f = tb;
                s[ta] = tmp;
            }
            else
            {
                (it->second).t = (it->second).t + 1;
                (it->second).f = (it->second).f + tb;
            }
        }

        map<int,vector<Node>,greater<int>> c;
        int ans1 = 0;
        int ans2 = 0;

        for(auto& it : s)
        {
            auto it2 = c.find((it.second).t);
            if(it2 == c.end())
            {
                vector<Node> tmp;
                tmp.push_back(it.second);
                c[(it.second).t] = tmp;
            }
            else
            {
                (it2->second).push_back(it.second);
            }
        }

        for(auto& it : c)
        {
            sort((it.second).begin(),(it.second).end());
        }

        priority_queue<int> pq;
        auto it = c.begin();
        int cur = it->first;
        while(cur > 0)
        {
            if(it != c.end() && cur == it->first)
            {
                for(i=0;i<(it->second).size();i++)
                {
                    pq.push((it->second)[i].f);
                }
                it++;
            }

            ans1 += cur;
            ans2 += min(pq.top(),cur);
            pq.pop();

            if(!pq.empty())
            {
                cur--;
            }
            else if(it != c.end())
            {
                cur = it->first;
            }
            else
            {
                break;
            }
        }

        cout<<ans1<<" "<<ans2<<endl;
    }

    return 0;
}


#include <iostream>
#include <vector>
#include <stdlib.h>
#include <map>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <unordered_set>
#include <string>
#include <string.h>
#include <cmath>
#include <time.h>
using namespace std;
typedef long long ll;
#define MOD 998244353

//#include <bits/stdc++.h>

using namespace std;

struct Node
{
    int t;
    int f;
};

bool operator < (const Node& a,const Node& b)
{
    if(a.t == b.t)
        return a.f > b.f;
    return a.t > b.t;
}

int main()
{
    std::ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    int q;
    cin>>q;
    while(q--)
    {
        int n;
        cin>>n;
        map<int,Node> s;
        int i;
        for(i=0;i<n;i++)
        {
            int ta,tb;
            cin>>ta>>tb;
            auto it = s.find(ta);
            if(it == s.end())
            {
                Node tmp;
                tmp.t = 1;
                tmp.f = tb;
                s[ta] = tmp;
            }
            else
            {
                (it->second).t = (it->second).t + 1;
                (it->second).f = (it->second).f + tb;
            }
        }

        map<int,vector<Node>,greater<int>> c;
        int ans1 = 0;
        int ans2 = 0;

        for(auto& it : s)
        {
            auto it2 = c.find((it.second).t);
            if(it2 == c.end())
            {
                vector<Node> tmp;
                tmp.push_back(it.second);
                c[(it.second).t] = tmp;
            }
            else
            {
                (it2->second).push_back(it.second);
            }
        }

        for(auto& it : c)
        {
            sort((it.second).begin(),(it.second).end());
        }

        map<int,int> d;
        for(auto& it : c)
        {
            int cnt = it.first;
            for(i = 0; i < (it.second).size()  && cnt > 0 ; i++ , cnt-- )
            {
                auto it2 = d.find(cnt);
                if(it2 == d.end())
                {
                    d[cnt] = min((it.second)[i].f , cnt);
                    ans1 += cnt;
                    ans2 += min((it.second)[i].f , cnt);
                }
                else
                {
                    if(it2->second < min((it.second)[i].f , cnt) )
                    {
                        ans2 -= it2->second;
                        it2->second = min((it.second)[i].f , cnt);
                        ans2 += it2->second;
                    }
                }
            }
        }

        cout<<ans1<<" "<<ans2<<endl;
    }

    return 0;
}


#include <iostream>
#include <vector>
#include <stdlib.h>
#include <map>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <unordered_set>
#include <string>
#include <string.h>
#include <cmath>
#include <time.h>
using namespace std;
typedef long long ll;
#define MOD 998244353

//#include <bits/stdc++.h>

using namespace std;

struct Node
{
    int t;
    int f;
};

bool operator < (const Node& a,const Node& b)
{
    if(a.t == b.t)
        return a.f > b.f;
    return a.t > b.t;
}

int main()
{
    std::ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    int q;
    cin>>q;
    while(q--)
    {
        int n;
        cin>>n;
        map<int,Node> s;
        int i;
        for(i=0;i<n;i++)
        {
            int ta,tb;
            cin>>ta>>tb;
            auto it = s.find(ta);
            if(it == s.end())
            {
                Node tmp;
                tmp.t = 1;
                tmp.f = tb;
                s[ta] = tmp;
            }
            else
            {
                (it->second).t = (it->second).t + 1;
                (it->second).f = (it->second).f + tb;
            }
        }

        map<int,vector<Node>> c;
        int ans1 = 0;
        int ans2 = 0;

        for(auto& it : s)
        {
            auto it2 = c.find((it.second).t);
            if(it2 == c.end())
            {
                vector<Node> tmp;
                tmp.push_back(it.second);
                c[(it.second).t] = tmp;
            }
            else
            {
                (it2->second).push_back(it.second);
            }
        }

        for(auto& it : c)
        {
            sort((it.second).begin(),(it.second).end());
        }

        int last = 0;

        for(auto& it : c)
        {
            int cnt = it.first;
            for(i = 0; i < (it.second).size() && cnt > last ; i++ , cnt--)
            {
                ans1 += cnt;
                ans2 += min((it.second)[i].f , cnt);
            }

            last = it.first;
        }

        cout<<ans1<<" "<<ans2<<endl;
    }

    return 0;
}


#include <bits/stdc++.h>
using namespace std;
int n;
int x[200009];
int f[200009];
multiset < int > se;
vector < int > v[200009];
struct BAP{int num,sum;};
BAP I[200009];
bool cmp(BAP a,BAP b){
	if(a.num == b.num) return a.sum > b.sum;
	return a.num > b.num;
}
void solve(){
	cin>>n;
	for(int i=1;i<=n;i++) I[i].num = I[i].sum = 0;
	for(int i=1;i<=n;i++){
		cin>>x[i]>>f[i];
		I[x[i]].num++;
		I[x[i]].sum+=f[i];
		v[i].clear();
	}
	se.clear();
	for(int i=1;i<=n;i++){
		v[I[i].num].push_back(I[i].sum);
	}
	int ans1 = 0,ans2 = 0;
	for(int i=n;i>=0;i--){
		for(int j=0;j<v[i].size();j++){
			se.insert(v[i][j]);
		}
		if(se.empty()) continue;
		int tmp = *se.rbegin();
		se.erase(se.find(tmp));
		ans1 += i;
		ans2 += min(i,tmp);
	}
	cout<<ans1<<" "<<ans2<<endl;
}
int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	int t; cin>>t;
	while(t--) solve();
}


#include <bits/stdc++.h>
using namespace std;
int n;
vector < int > v[200009];
struct BAP{int num,sum;};
BAP I[200009];
void solve(){
  	cin>>n;
   	for(int i=1;i<=n;i++) I[i].num = I[i].sum = 0;
   	for(int i=1;i<=n;i++){
   		int x,f;
   		cin>>x>>f;
   		I[x].num++;
   		I[x].sum+=f;
   		v[i].clear();
   	}
   	for(int i=1;i<=n;i++){
   		v[I[i].num].push_back(I[i].sum);
   	}
   	int ans1 = 0,ans2 = 0;
  	multiset < int > se;
   	for(int i=n;i>=1;i--){
   		for(int j=0;j<v[i].size();j++){
   			se.insert(v[i][j]);
   		}
   		if(se.empty()) continue;
   		int tmp = *se.rbegin();
   		se.erase(se.find(tmp));
   		ans2 += min(i,tmp);
   		ans1 += i;
   	}
  	cout<<ans1<<" "<<ans2<<endl;
}
int main(){
   	ios_base::sync_with_stdio(0);
   	cin.tie(0);cout.tie(0);
   	int t; cin>>t;
   	while(t--) solve();
}


#include <bits/stdc++.h>
using namespace std;
int n;
vector < int > v[200009];
struct BAP{int num,sum;};
BAP I[200009];
void solve(){
	cin>>n;
	for(int i=1;i<=n;i++) I[i].num = I[i].sum = 0;
	for(int i=1;i<=n;i++){
		cin>>x>>f;
		I[x].num++;
		I[x].sum+=f;
		v[i].clear();
	}
	for(int i=1;i<=n;i++){
		v[I[i].num].push_back(I[i].sum);
	}
	int ans1 = 0,ans2 = 0;
	multiset < int > se;
	for(int i=n;i>=0;i--){
		for(int j=0;j<v[i].size();j++){
			se.insert(v[i][j]);
		}
		if(se.empty()) continue;
		int tmp = *se.rbegin();
		se.erase(se.find(tmp));
		ans2 += min(i,tmp);
		ans1 += i;
	}
	cout<<ans1<<" "<<ans2<<endl;
}
int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	int t; cin>>t;
	while(t--) solve();
}


#include <bits/stdc++.h>
using namespace std;
int n;
vector < int > v[200009];
struct BAP{int num,sum;};
BAP I[200009];
void solve(){
	cin>>n;
	for(int i=1;i<=n;i++) I[i].num = I[i].sum = 0;
	for(int i=1;i<=n;i++){
		int x,f;
		cin>>x>>f;
		I[x].num++;
		I[x].sum+=f;
		v[i].clear();
	}
	for(int i=1;i<=n;i++){
		v[I[i].num].push_back(I[i].sum);
	}
	int ans1 = 0,ans2 = 0;
	multiset < int > se;
	for(int i=n;i>=0;i--){
		for(int j=0;j<v[i].size();j++){
			se.insert(v[i][j]);
		}
		if(se.empty()) continue;
		int tmp = *se.rbegin();
		se.erase(se.find(tmp));
		ans2 += min(i,tmp);
		ans1 += i;
	}
	cout<<ans1<<" "<<ans2<<endl;
}
int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	int t; cin>>t;
	while(t--) solve();
}


#include<bits/stdc++.h>
// #include<ext/pb_ds/assoc_container.hpp>
// #include<ext/pb_ds/tree_policy.hpp>
using namespace std;
    // using namespace __gnu_pbds;

typedef long long int lli;
typedef unsigned long long int ull;
typedef long double ld;
typedef pair<lli,lli> pll;
typedef std::vector<lli> vll;
typedef std::vector<pll> vpll;
typedef std::vector<bool> vbb;
typedef map<lli,lli>mll;
typedef set<lli> sll;
typedef multiset<lli> msll;
lli MOD=1e9 +7;
lli INF=1e18;

#define forr(i,p,n) for(i=p; i<n; i++)
#define forn(i,p,n) for(i=p; i<=n; i++)
#define forl(i,n,p) for(i=n; i>=p; i--)
#define be(a) a.begin(),a.end()
#define mp make_pair
#define eb emplace_back
#define pb push_back
#define F first
#define S second
#define all(a)     (a).begin(),(a).end()
#define PI 3.14159265358979323846
#define lb lower_bound
#define ub upper_bound
#define endl "\n"
#define bpcl(x) __builtin_popcountll(x)
#define deb(vari) cerr<<#vari<<" = "<<vari<<endl;
            // #define ordered_set tree<lli, null_type,less<lli>, rb_tree_tag,tree_order_statistics_node_update>
lli power(lli base, lli exp) {lli res=1;while(exp>0) {if(exp%2==1) res=(res*base);base=(base*base);exp/=2;}return res;}
lli bitc(lli n,lli x){return ((n>>x)&1);}
lli __gcd(lli a,lli b){return b==0?a:__gcd(b,a%b);}
lli fsub(lli a,lli b,lli p=MOD){return ((a%p)-(b%p)+p)%p;}
lli fmult(lli a,lli b, lli p=MOD) {return ((a%p)*(b%p))%p;}
lli fadd(lli a, lli b, lli p=MOD) {return (a%p + b%p)%p;}
                                    // lli add(lli a,lli b,lli p=MOD){//if(a+b>=p){//return (a+b)-p;//  }//return a+b;// }
lli fpow(lli n, lli k, lli p = MOD) {lli r = 1; while(k > 0) {if (k & 1) r = r * n%p; n = n * n%p; k = k >> 1;} return r;}
lli inv(lli a, lli p = MOD) {return fpow(a, p - 2, p);}
lli fdiv(lli a,lli b,lli p=MOD){lli yinv=inv(b);lli ans=(a*yinv)%p;return ans;}

template<typename T>istream &operator>>(istream &in, vector<T> &a) {for (auto &item : a) {in >> item;}return in;}template<typename T,typename U>ostream &operator<<(ostream &out, pair<T,U> &a) {cout<<a.F<<" "<<a.S;return out;}
template<typename T,typename U>
istream &operator>>(istream &out, pair<T,U> &a) {cin>>a.F>>a.S;return out;}
template<typename T,typename U>
ostream &operator<<(ostream &out, map<T,U> &a) {for (auto &item : a) {out << item << endl;}return out;}
template<typename T>
ostream &operator<<(ostream &out, vector<T> &a) {for (auto &item : a) {out << item << " ";}return out;}
template<typename T>
ostream &operator<<(ostream &out, vector<vector<T>> &a) {for (auto &item : a) {out << item << "\n";}return out;}
template<int D, typename T>
struct Vec : public vector<Vec<D - 1, T>> {
  static_assert(D >= 1, "Vector dimension must be greater than zero!");
                      template<typename... Args>
  Vec(int n = 0, Args... args) : vector<Vec<D - 1, T>>(n, Vec<D - 1, T>(args...)) {
  }
};
template<typename T>
struct Vec<1, T> : public vector<T> {
  Vec(int n = 0, T val = T()) : vector<T>(n, val) {
  }
};
                // Vec<2,lli>mat(n,n,1);
#define print(a) for(auto p:a) cout<<p<<endl; cout<<endl;
#define read(a) for(auto &p:a)cin>>p>>endl;
std::vector<bool> is_prime;
std::vector<lli> primes;
void sieve(lli n){is_prime.resize(n+2,true);primes.clear();lli p;for(p=2;p*p<=n;p++){if(is_prime[p]){lli i;for(i=p*p;i<=n;i+=p){is_prime[i]=false;}}}is_prime[0]=is_prime[1]=false;lli i;for(i=2;i<=n;i++){if(is_prime[i]){primes.eb(i);}}}
mll prime_factors(lli n){  mll s;lli i;lli tc=0;while(n%2==0){tc++;n/=2;}if(tc>0){s[2]=tc;}for(i=3;i<=sqrt(n);i+=2){tc=0;while(n%i==0){tc++;n/=i;}if(tc>0){s[i]=tc;}}if(n>2){s[n]+=1;}return s;}
std::vector<lli> fact_vec;
void fact_fun(lli n){fact_vec.resize(n+10);lli i;fact_vec[0]=1;for(i=1;i<=n+2;i++){fact_vec[i]=(fact_vec[i-1]*i)%MOD;}}
vll p2;
void power_2(lli n,lli m=MOD){ lli i;MOD=m;p2.eb(1);forr(i,0,n){p2.eb(fmult(p2.back(),2));}}
lli ncr(lli n,lli r){if(r>n)return 0;return fdiv(fact_vec[n],fmult(fact_vec[r],fact_vec[n-r]));}
vll spf;void sieve2(lli MAXN) { MAXN+=10;spf.resize(MAXN,0);spf[1] = 1; for (lli i=2; i<MAXN; i++) spf[i] = i;     for (lli i=4; i<MAXN; i+=2) spf[i] = 2; for (lli i=3; i*i<MAXN; i++) {         if (spf[i] == i) { for (lli j=i*i; j<MAXN; j+=i) {if (spf[j]==j) spf[j] = i; }} } }

vll getFactorization(lli x)
{
    vll ret;
    while (x != 1){
        ret.eb(spf[x]);
        x = x / spf[x];
    } return ret;
}

// class Sol{
// public:
//     Sol(){
//         lli  i,j;
//     }
// };

int main(){
    lli i,j;

        #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt",  "w", stdout);
        #endif

    ios::sync_with_stdio(false);
    cin.tie(0);

    lli ti;

    ti=1;
    cin>>ti;
    while(ti--){
        lli n ;
        cin>>n;
        vll cnt(n),cnt1(n);
        forr(i,0,n){
            lli a,b;
            cin>>a>>b;
            a--;
            cnt[a]++;
            if(b){
                cnt1[a]++;
            }
        }
        vector<vll>types(n+1);
        forr(i,0,n){
            types[cnt[i]].eb(cnt1[i]);
        }
        lli ans1=0;
        lli ans2=0;
        multiset<lli,greater<lli>>ms;
        forl(i,n,1){
            for(auto p:types[i]){
                ms.insert(p);
            }
            if(!ms.empty()){
                ans1+= i;
                ans2+= min(i,*ms.begin());
                ms.erase(ms.begin());
            }
        }
        cout<<ans1<<" "<<ans2<<endl;

    }

}


#include<bits/stdc++.h>
// #include<ext/pb_ds/assoc_container.hpp>
// #include<ext/pb_ds/tree_policy.hpp>
using namespace std;
    // using namespace __gnu_pbds;

typedef long long int lli;
typedef unsigned long long int ull;
typedef long double ld;
typedef pair<lli,lli> pll;
typedef std::vector<lli> vll;
typedef std::vector<pll> vpll;
typedef std::vector<bool> vbb;
typedef map<lli,lli>mll;
typedef set<lli> sll;
typedef multiset<lli> msll;
lli MOD=1e9 +7;
lli INF=1e18;

#define forr(i,p,n) for(i=p; i<n; i++)
#define forn(i,p,n) for(i=p; i<=n; i++)
#define forl(i,n,p) for(i=n; i>=p; i--)
#define be(a) a.begin(),a.end()
#define mp make_pair
#define eb emplace_back
#define pb push_back
#define F first
#define S second
#define all(a)     (a).begin(),(a).end()
#define PI 3.14159265358979323846
#define lb lower_bound
#define ub upper_bound
#define endl "\n"
#define bpcl(x) __builtin_popcountll(x)
#define deb(vari) cerr<<#vari<<" = "<<vari<<endl;
            // #define ordered_set tree<lli, null_type,less<lli>, rb_tree_tag,tree_order_statistics_node_update>
lli power(lli base, lli exp) {lli res=1;while(exp>0) {if(exp%2==1) res=(res*base);base=(base*base);exp/=2;}return res;}
lli bitc(lli n,lli x){return ((n>>x)&1);}
lli __gcd(lli a,lli b){return b==0?a:__gcd(b,a%b);}
lli fsub(lli a,lli b,lli p=MOD){return ((a%p)-(b%p)+p)%p;}
lli fmult(lli a,lli b, lli p=MOD) {return ((a%p)*(b%p))%p;}
lli fadd(lli a, lli b, lli p=MOD) {return (a%p + b%p)%p;}
                                    // lli add(lli a,lli b,lli p=MOD){//if(a+b>=p){//return (a+b)-p;//  }//return a+b;// }
lli fpow(lli n, lli k, lli p = MOD) {lli r = 1; while(k > 0) {if (k & 1) r = r * n%p; n = n * n%p; k = k >> 1;} return r;}
lli inv(lli a, lli p = MOD) {return fpow(a, p - 2, p);}
lli fdiv(lli a,lli b,lli p=MOD){lli yinv=inv(b);lli ans=(a*yinv)%p;return ans;}

template<typename T>istream &operator>>(istream &in, vector<T> &a) {for (auto &item : a) {in >> item;}return in;}template<typename T,typename U>ostream &operator<<(ostream &out, pair<T,U> &a) {cout<<a.F<<" "<<a.S;return out;}
template<typename T,typename U>
istream &operator>>(istream &out, pair<T,U> &a) {cin>>a.F>>a.S;return out;}
template<typename T,typename U>
ostream &operator<<(ostream &out, map<T,U> &a) {for (auto &item : a) {out << item << endl;}return out;}
template<typename T>
ostream &operator<<(ostream &out, vector<T> &a) {for (auto &item : a) {out << item << " ";}return out;}
template<typename T>
ostream &operator<<(ostream &out, vector<vector<T>> &a) {for (auto &item : a) {out << item << "\n";}return out;}
template<int D, typename T>
struct Vec : public vector<Vec<D - 1, T>> {
  static_assert(D >= 1, "Vector dimension must be greater than zero!");
                      template<typename... Args>
  Vec(int n = 0, Args... args) : vector<Vec<D - 1, T>>(n, Vec<D - 1, T>(args...)) {
  }
};
template<typename T>
struct Vec<1, T> : public vector<T> {
  Vec(int n = 0, T val = T()) : vector<T>(n, val) {
  }
};
                // Vec<2,lli>mat(n,n,1);
#define print(a) for(auto p:a) cout<<p<<endl; cout<<endl;
#define read(a) for(auto &p:a)cin>>p>>endl;
std::vector<bool> is_prime;
std::vector<lli> primes;
void sieve(lli n){is_prime.resize(n+2,true);primes.clear();lli p;for(p=2;p*p<=n;p++){if(is_prime[p]){lli i;for(i=p*p;i<=n;i+=p){is_prime[i]=false;}}}is_prime[0]=is_prime[1]=false;lli i;for(i=2;i<=n;i++){if(is_prime[i]){primes.eb(i);}}}
mll prime_factors(lli n){  mll s;lli i;lli tc=0;while(n%2==0){tc++;n/=2;}if(tc>0){s[2]=tc;}for(i=3;i<=sqrt(n);i+=2){tc=0;while(n%i==0){tc++;n/=i;}if(tc>0){s[i]=tc;}}if(n>2){s[n]+=1;}return s;}
std::vector<lli> fact_vec;
void fact_fun(lli n){fact_vec.resize(n+10);lli i;fact_vec[0]=1;for(i=1;i<=n+2;i++){fact_vec[i]=(fact_vec[i-1]*i)%MOD;}}
vll p2;
void power_2(lli n,lli m=MOD){ lli i;MOD=m;p2.eb(1);forr(i,0,n){p2.eb(fmult(p2.back(),2));}}
lli ncr(lli n,lli r){if(r>n)return 0;return fdiv(fact_vec[n],fmult(fact_vec[r],fact_vec[n-r]));}
vll spf;void sieve2(lli MAXN) { MAXN+=10;spf.resize(MAXN,0);spf[1] = 1; for (lli i=2; i<MAXN; i++) spf[i] = i;     for (lli i=4; i<MAXN; i+=2) spf[i] = 2; for (lli i=3; i*i<MAXN; i++) {         if (spf[i] == i) { for (lli j=i*i; j<MAXN; j+=i) {if (spf[j]==j) spf[j] = i; }} } }

vll getFactorization(lli x)
{
    vll ret;
    while (x != 1){
        ret.eb(spf[x]);
        x = x / spf[x];
    } return ret;
}

// class Sol{
// public:
//     Sol(){
//         lli  i,j;
//     }
// };
lli n;
vll cnt,ocnt;
pll ans;
bool check(lli tar){
    lli i;
    lli can=INF;
    lli otar=tar;
    for(auto p:cnt){
        if(tar==0){
            break;
        }
        lli take=min({tar,can,p});
        if(take==0){
            break;
        }
        tar-=take;
        can=take-1;

    }
    if(tar>0){
        return 0;
    }
    lli s=0;
    can=INF;
    tar=otar;
    for(auto p:ocnt){
        if(tar==0){
            break;
        }
        lli take=min({tar,p,can});
        if(take==0){
            break;
        }
        tar-=take;
        s+=take;
    }
    if(otar>ans.F){
        ans=mp(otar,s);
    }
    return  1;

}
int main(){
    lli i,j;

        #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt",  "w", stdout);
        #endif

    ios::sync_with_stdio(false);
    cin.tie(0);

    lli ti;

    ti=1;
    cin>>ti;
    while(ti--){
        cin>>n;
        cnt.assign(n+5,0);
        ocnt=cnt;
        forr(i,0,n){
            lli a ,b;
            cin>>a>>b;
            cnt[a]++;
            if(b){
                ocnt[a]++;
            }
        }
        sort(all(cnt),greater<lli>());
        sort(all(ocnt),greater<lli>());
        ans=mp(0,0);
        lli l=0,r=1e13;
        lli tans=0;
        while(l<=r){
            lli mid=(l+r)/2;
            bool res=check(mid);
            if(res){
                tans=mid;
                l=mid+1;
            }else{
                r=mid-1;
            }

        }
        cout<<ans<<endl;

    }

}


#include<bits/stdc++.h>
// #include<ext/pb_ds/assoc_container.hpp>
// #include<ext/pb_ds/tree_policy.hpp>
using namespace std;
    // using namespace __gnu_pbds;

typedef long long int lli;
typedef unsigned long long int ull;
typedef long double ld;
typedef pair<lli,lli> pll;
typedef std::vector<lli> vll;
typedef std::vector<pll> vpll;
typedef std::vector<bool> vbb;
typedef map<lli,lli>mll;
typedef set<lli> sll;
typedef multiset<lli> msll;
lli MOD=1e9 +7;
lli INF=1e18;

#define forr(i,p,n) for(i=p; i<n; i++)
#define forn(i,p,n) for(i=p; i<=n; i++)
#define forl(i,n,p) for(i=n; i>=p; i--)
#define be(a) a.begin(),a.end()
#define mp make_pair
#define eb emplace_back
#define pb push_back
#define F first
#define S second
#define all(a)     (a).begin(),(a).end()
#define PI 3.14159265358979323846
#define lb lower_bound
#define ub upper_bound
#define endl "\n"
#define bpcl(x) __builtin_popcountll(x)
#define deb(vari) cerr<<#vari<<" = "<<vari<<endl;
            // #define ordered_set tree<lli, null_type,less<lli>, rb_tree_tag,tree_order_statistics_node_update>
lli power(lli base, lli exp) {lli res=1;while(exp>0) {if(exp%2==1) res=(res*base);base=(base*base);exp/=2;}return res;}
lli bitc(lli n,lli x){return ((n>>x)&1);}
lli __gcd(lli a,lli b){return b==0?a:__gcd(b,a%b);}
lli fsub(lli a,lli b,lli p=MOD){return ((a%p)-(b%p)+p)%p;}
lli fmult(lli a,lli b, lli p=MOD) {return ((a%p)*(b%p))%p;}
lli fadd(lli a, lli b, lli p=MOD) {return (a%p + b%p)%p;}
                                    // lli add(lli a,lli b,lli p=MOD){//if(a+b>=p){//return (a+b)-p;//  }//return a+b;// }
lli fpow(lli n, lli k, lli p = MOD) {lli r = 1; while(k > 0) {if (k & 1) r = r * n%p; n = n * n%p; k = k >> 1;} return r;}
lli inv(lli a, lli p = MOD) {return fpow(a, p - 2, p);}
lli fdiv(lli a,lli b,lli p=MOD){lli yinv=inv(b);lli ans=(a*yinv)%p;return ans;}

template<typename T>istream &operator>>(istream &in, vector<T> &a) {for (auto &item : a) {in >> item;}return in;}template<typename T,typename U>ostream &operator<<(ostream &out, pair<T,U> &a) {cout<<a.F<<" "<<a.S;return out;}
template<typename T,typename U>
istream &operator>>(istream &out, pair<T,U> &a) {cin>>a.F>>a.S;return out;}
template<typename T,typename U>
ostream &operator<<(ostream &out, map<T,U> &a) {for (auto &item : a) {out << item << endl;}return out;}
template<typename T>
ostream &operator<<(ostream &out, vector<T> &a) {for (auto &item : a) {out << item << " ";}return out;}
template<typename T>
ostream &operator<<(ostream &out, vector<vector<T>> &a) {for (auto &item : a) {out << item << "\n";}return out;}
template<int D, typename T>
struct Vec : public vector<Vec<D - 1, T>> {
  static_assert(D >= 1, "Vector dimension must be greater than zero!");
                      template<typename... Args>
  Vec(int n = 0, Args... args) : vector<Vec<D - 1, T>>(n, Vec<D - 1, T>(args...)) {
  }
};
template<typename T>
struct Vec<1, T> : public vector<T> {
  Vec(int n = 0, T val = T()) : vector<T>(n, val) {
  }
};
                // Vec<2,lli>mat(n,n,1);
#define print(a) for(auto p:a) cout<<p<<endl; cout<<endl;
#define read(a) for(auto &p:a)cin>>p>>endl;
std::vector<bool> is_prime;
std::vector<lli> primes;
void sieve(lli n){is_prime.resize(n+2,true);primes.clear();lli p;for(p=2;p*p<=n;p++){if(is_prime[p]){lli i;for(i=p*p;i<=n;i+=p){is_prime[i]=false;}}}is_prime[0]=is_prime[1]=false;lli i;for(i=2;i<=n;i++){if(is_prime[i]){primes.eb(i);}}}
mll prime_factors(lli n){  mll s;lli i;lli tc=0;while(n%2==0){tc++;n/=2;}if(tc>0){s[2]=tc;}for(i=3;i<=sqrt(n);i+=2){tc=0;while(n%i==0){tc++;n/=i;}if(tc>0){s[i]=tc;}}if(n>2){s[n]+=1;}return s;}
std::vector<lli> fact_vec;
void fact_fun(lli n){fact_vec.resize(n+10);lli i;fact_vec[0]=1;for(i=1;i<=n+2;i++){fact_vec[i]=(fact_vec[i-1]*i)%MOD;}}
vll p2;
void power_2(lli n,lli m=MOD){ lli i;MOD=m;p2.eb(1);forr(i,0,n){p2.eb(fmult(p2.back(),2));}}
lli ncr(lli n,lli r){if(r>n)return 0;return fdiv(fact_vec[n],fmult(fact_vec[r],fact_vec[n-r]));}
vll spf;void sieve2(lli MAXN) { MAXN+=10;spf.resize(MAXN,0);spf[1] = 1; for (lli i=2; i<MAXN; i++) spf[i] = i;     for (lli i=4; i<MAXN; i+=2) spf[i] = 2; for (lli i=3; i*i<MAXN; i++) {         if (spf[i] == i) { for (lli j=i*i; j<MAXN; j+=i) {if (spf[j]==j) spf[j] = i; }} } }

vll getFactorization(lli x)
{
    vll ret;
    while (x != 1){
        ret.eb(spf[x]);
        x = x / spf[x];
    } return ret;
}

// class Sol{
// public:
//     Sol(){
//         lli  i,j;
//     }
// };
lli n;
vll cnt,ocnt;
pll ans;
bool check(lli tar){
    lli i;
    lli can=INF;
    lli otar=tar;
    for(auto p:cnt){
        if(tar==0){
            break;
        }
        lli take=min({tar,can,p});
        if(take==0){
            break;
        }
        tar-=take;
        can=take-1;

    }
    if(tar>0){
        return 0;
    }
    lli s=0;
    can=INF;
    tar=otar;
    for(auto p:ocnt){
        if(tar==0){
            break;
        }

        lli take=min({tar,p,can});
        if(take==0){
            break;
        }
        tar-=take;
        can=take-1;
        s+=take;
    }
    if(otar>ans.F){
        ans=mp(otar,s);
    }
    return  1;

}
int main(){
    lli i,j;

        #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt",  "w", stdout);
        #endif

    ios::sync_with_stdio(false);
    cin.tie(0);

    lli ti;

    ti=1;
    cin>>ti;
    while(ti--){
        cin>>n;
        cnt.assign(n+5,0);
        ocnt=cnt;
        forr(i,0,n){
            lli a ,b;
            cin>>a>>b;
            cnt[a]++;
            if(b){
                ocnt[a]++;
            }
        }
        sort(all(cnt),greater<lli>());
        sort(all(ocnt),greater<lli>());
        ans=mp(0,0);
        lli l=0,r=1e13;
        lli tans=0;
        while(l<=r){
            lli mid=(l+r)/2;
            bool res=check(mid);
            if(res){
                tans=mid;
                l=mid+1;
            }else{
                r=mid-1;
            }

        }
        cout<<ans<<endl;

    }

}


#include <bits/stdc++.h>

using namespace std;

typedef long long int ll;

const int N = (int) 1e5 + 10;

int n;
vector<pair<int, int>> candies;

struct cmp {
    bool operator()(const pair<int, int> &a, const pair<int, int> &b) const {
        if(a.second == b.second) return a.first < b.second;
        return a.second < b.second;
    }
};

void solve() {
    int m; cin >> m;
    while(m--) {
        cin >> n;
        candies.clear();
        candies.resize(n);
        int max_tot = 0;
        for(int i = 0; i < n; ++i) {
            int a, f;
            cin >> a >> f, --a;
            candies[a].second++;
            candies[a].first += f;
            max_tot = max(max_tot, candies[a].second);
        }
        sort(candies.begin(), candies.end(), cmp());
        multiset<pair<int, int>> st;
        int tot = 0, want = 0;
        int idx = n - 1;
        for(int cnt = max_tot; cnt >= 1; --cnt) {
            while(idx >= 0 && candies[idx].second >= cnt) {
                st.insert(candies[idx]);
                --idx;
            }
            if(!st.size()) continue;
            auto it = prev(st.end());
            st.erase(it);
            auto cur = *it;
            tot += cnt;
            want += min(cnt, cur.first);
        }
        cout << tot << " " << want << endl;
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.precision(20);
    cout << fixed;
    solve();
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long int ll;

const int N = (int) 1e5 + 10;

int n;
vector<pair<int, int>> candies;
multiset<pair<int, int>> st;

struct cmp {
    bool operator()(const pair<int, int> &a, const pair<int, int> &b) const {
        if(a.second == b.second) return a.first < b.second;
        return a.second < b.second;
    }
};

void solve() {
    int m; cin >> m;
    while(m--) {
        cin >> n;
        candies.clear();
        st.clear();
        candies.resize(n);
        int max_tot = 0;
        for(int i = 0; i < n; ++i) {
            int a, f;
            cin >> a >> f, --a;
            candies[a].second++;
            candies[a].first += f;
            max_tot = max(max_tot, candies[a].second);
        }
        sort(candies.begin(), candies.end(), cmp());
        int tot = 0, want = 0;
        int idx = n - 1;
        for(int cnt = max_tot; cnt >= 1; --cnt) {
            while(idx >= 0 && candies[idx].second >= cnt) {
                st.insert(candies[idx]);
                --idx;
            }
            if(!st.size()) continue;
            auto it = prev(st.end());
            st.erase(it);
            auto cur = *it;
            tot += cnt;
            want += min(cnt, cur.first);
        }
        cout << tot << " " << want << endl;
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.precision(20);
    cout << fixed;
    solve();
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long int ll;

const int N = (int) 1e5 + 10;

int n;
vector<pair<int, int>> candies;
multiset<int> st;

void solve() {
    int m; cin >> m;
    while(m--) {
        cin >> n;
        candies.clear();
        st.clear();
        candies.resize(n);
        int max_tot = 0;
        for(int i = 0; i < n; ++i) {
            int a, f;
            cin >> a >> f, --a;
            candies[a].first++, candies[a].second += f;
            max_tot = max(max_tot, candies[a].first);
        }
        sort(candies.begin(), candies.end());
        int tot = 0, want = 0;
        int idx = n - 1;
        for(int cnt = max_tot; cnt >= 1; --cnt) {
            while(idx >= 0 && candies[idx].first >= cnt) {
                st.insert(candies[idx].second);
                --idx;
            }
            if(!st.size()) continue;
            auto it = prev(st.end());
            auto cur = *it;
            st.erase(it);
            tot += cnt;
            want += min(cnt, cur);
        }
        cout << tot << " " << want << endl;
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.precision(20);
    cout << fixed;
    solve();
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long int ll;

const int N = (int) 1e5 + 10;

int n;
vector<pair<int, int>> candies;
multiset<pair<int, int>> st;

struct cmp {
    bool operator()(const pair<int, int> &a, const pair<int, int> &b) const {
        if(a.second == b.second) return a.first < b.second;
        return a.second < b.second;
    }
};

void solve() {
    int m; cin >> m;
    while(m--) {
        cin >> n;
        candies.clear();
        st.clear();
        candies.resize(n);
        int max_tot = 0;
        for(int i = 0; i < n; ++i) {
            int a, f;
            cin >> a >> f, --a;
            candies[a].second++;
            candies[a].first += f;
            max_tot = max(max_tot, candies[a].second);
        }
        sort(candies.begin(), candies.end(), cmp());
        int tot = 0, want = 0;
        int idx = n - 1;
        for(int cnt = max_tot; cnt >= 1; --cnt) {
            while(idx >= 0 && candies[idx].second >= cnt) {
                st.insert(candies[idx]);
                --idx;
            }
            if(!st.size()) continue;
            auto it = prev(st.end());
            auto cur = *it;
            st.erase(it);
            tot += cnt;
            want += min(cnt, cur.first);
        }
        cout << tot << " " << want << endl;
    }
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.precision(20);
    cout << fixed;
    solve();
    return 0;
}


#include <cstdio>
#include <iostream>
#include <string>
#include <sstream>
#include <stack>
#include <algorithm>
#include <cmath>
#include <queue>
#include <map>
#include <set>
#include <cstdlib>
#include <bitset>
#include <tuple>
#include <assert.h>
#include <deque>
#include <bitset>
#include <iomanip>
#include <limits>
#include <chrono>
#include <random>
#include <array>
#include <unordered_map>
#include <functional>
#include <complex>

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

constexpr long long MAX = 5100000;
constexpr long long INF = 1LL << 60;
constexpr int inf = 1 << 28;
//constexpr long long mod = 1000000007LL;
//constexpr long long mod = 998244353LL;

using namespace std;
typedef unsigned long long ull;
typedef long long ll;

int main()
{
	/*
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	*/
	int kkt; scanf("%d", &kkt);
	while (kkt--) {
		int n; scanf("%d", &n);
		vector<vector<int>> g(n + 1);
		vector<int> all(n), cnt1(n);
		for (int i = 0; i < n; i++) {
			int a, b; scanf("%d %d", &a, &b);
			a--;
			all[a]++;
			if (b) cnt1[a]++;
		}
		for (int i = 0; i < n; i++) {
			if (all[i]) {
				g[all[i]].push_back(cnt1[i]);
			}
		}
		int res = 0, res1 = 0;
		priority_queue<int> pq;
		for (int i = n; i >= 1; i--) {
			for (auto e : g[i]) {
				pq.push(e);
			}
			if (!pq.empty()) {
				res += i;
				res1 += min(pq.top(), i);
				pq.pop();
			}
		}
		printf("%d %d\n", res, res1);
	}
	return 0;

}


#include <cstdio>
#include <iostream>
#include <string>
#include <sstream>
#include <stack>
#include <algorithm>
#include <cmath>
#include <queue>
#include <map>
#include <set>
#include <cstdlib>
#include <bitset>
#include <tuple>
#include <assert.h>
#include <deque>
#include <bitset>
#include <iomanip>
#include <limits>
#include <chrono>
#include <random>
#include <array>
#include <unordered_map>
#include <functional>
#include <complex>

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

const long long MAX = 5100000;
const long long INF = 1LL << 60;
const int inf = 1 << 28;
const long long mod = 1000000007LL;
//const long long mod = 998244353LL;

using namespace std;
typedef unsigned long long ull;
typedef long long ll;

vector<int> g[200010];
int cnt1[200010];
int cnt2[200010];
int main()
{
	/*
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	*/
	int q; scanf("%d", &q);
	while (q--) {
		int n; scanf("%d", &n);
		for (int i = 0; i <= n; i++) cnt1[i] = 0, cnt2[i] = 0, g[i].clear();
		for (int i = 0; i < n; i++) {
			int a, f; scanf("%d %d", &a, &f);
			cnt1[a]++;
			if (f) cnt2[a]++;
		}
		for (int i = 0; i <= n; i++) if(cnt1[i] > 0) g[cnt1[i]].push_back(cnt2[i]);
		priority_queue<int> pq;
		int res1 = 0, res2 = 0;
		for (int i = n; i >= 1; i--) {
			for (int e : g[i]) pq.push(e);
			if (!pq.empty()) {
				res1 += i;
				res2 += min(i, pq.top());
				pq.pop();
			}
		}
		printf("%d %d\n", res1, res2);
	}

	return 0;

	/*
		おまじないを使ったらscanfとprintf関連注意！！！！！！！！！！！！
	*/
}


#include <cstdio>
#include <iostream>
#include <string>
#include <sstream>
#include <stack>
#include <algorithm>
#include <cmath>
#include <queue>
#include <map>
#include <set>
#include <cstdlib>
#include <bitset>
#include <tuple>
#include <assert.h>
#include <deque>
#include <bitset>
#include <iomanip>
#include <limits>
#include <chrono>
#include <random>
#include <array>
#include <unordered_map>
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

const long long MAX = 5100000;
const long long INF = 1LL << 60;
const long long MOD = 1'000'000'007LL;
const long long mod = 998244353LL;

using namespace std;
typedef unsigned long long ull;
typedef long long ll;

int main()
{
	/*
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	*/
	ll q; scanf("%lld", &q);
	while (q--) {
		ll n; scanf("%lld", &n);
		vector<ll> cnt1(n), cnt2(n);
		for (ll i = 0; i < n; i++) {
			ll x, t; scanf("%lld %lld", &x, &t);
			x--;
			cnt1[x]++;
			if (t == 1) cnt2[x]++;
		}
		vector<vector<ll>> g(n + 1);
		for (ll i = 0; i < n; i++) {
			g[cnt1[i]].push_back(cnt2[i]);
		}
		priority_queue<ll> pq;
		ll res1 = 0;
		ll res2 = 0;
		for (ll i = n; i >= 0; i--) {
			for (ll e : g[i]) pq.push(e);
			if (!pq.empty()) {
				res1 += i;
				res2 += min(pq.top(), i);
				pq.pop();
			}
		}
		printf("%lld %lld\n", res1, res2);
	}

	return 0;
}


#include <cstdio>
#include <iostream>
#include <string>
#include <sstream>
#include <stack>
#include <algorithm>
#include <cmath>
#include <queue>
#include <map>
#include <set>
#include <cstdlib>
#include <bitset>
#include <tuple>
#include <assert.h>
#include <deque>
#include <bitset>
#include <iomanip>
#include <limits>
#include <chrono>
#include <random>
#include <array>
#include <unordered_map>
#include <functional>
#include <complex>

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

constexpr long long MAX = 5100000;
constexpr long long INF = 1LL << 60;
constexpr int inf = 1 << 28;
//constexpr long long mod = 1000000007LL;
//constexpr long long mod = 998244353LL;

using namespace std;
typedef unsigned long long ull;
typedef long long ll;

int main()
{
	/*
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	*/

	int q; scanf("%d", &q);
	while (q--) {
		int n; scanf("%d", &n);
		vector<pair<int, int>> cnt(n);
		for (int i = 0; i < n; i++) {
			int a, f; scanf("%d %d", &a, &f);
			a--;
			cnt[a].first++;
			if(f) cnt[a].second++;
		}
		sort(cnt.rbegin(), cnt.rend());
		queue<pair<int, int>> q;
		for (int i = 0; i < n; i++) q.push(cnt[i]);
		priority_queue<int> pq;
		int res1 = 0, res2 = 0;
		for (int i = n; i > 0; i--) {
			while (!q.empty() && q.front().first == i) {
				pq.push(q.front().second);
				q.pop();
			}
			if (!pq.empty()) {
				res1 += i;
				res2 += min(i, pq.top());
				pq.pop();
			}
		}
		printf("%d %d\n", res1, res2);
	}
	return 0;
	/*
		おまじないを使ったらscanfとprintf関連注意！！！！！！！！！！！！
	*/
}


#include <cstdio>
#include <iostream>
#include <string>
#include <sstream>
#include <stack>
#include <algorithm>
#include <cmath>
#include <queue>
#include <map>
#include <set>
#include <cstdlib>
#include <bitset>
#include <tuple>
#include <assert.h>
#include <deque>
#include <bitset>
#include <iomanip>
#include <limits>
#include <chrono>
#include <random>
#include <array>
#include <unordered_map>
#include <functional>
#include <complex>

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

const long long MAX = 5100000;
const long long INF = 1LL << 60;
const int inf = 1 << 28;
const long long mod = 1000000007LL;
//const long long mod = 998244353LL;

using namespace std;
typedef unsigned long long ull;
typedef long long ll;

vector<int> g[200010];
int cnt1[200010];
int cnt2[200010];
int main()
{
	/*
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	*/
	int q; scanf("%d", &q);
	while (q--) {
		int n; scanf("%d", &n);
		for (int i = 0; i <= 200000; i++) cnt1[i] = 0, cnt2[i] = 0, g[i].clear();
		for (int i = 0; i < n; i++) {
			int a, f; scanf("%d %d", &a, &f);
			cnt1[a]++;
			if (f) cnt2[a]++;
		}
		for (int i = 0; i <= 200000; i++) if(cnt1[i] > 0) g[cnt1[i]].push_back(cnt2[i]);
		priority_queue<int> pq;
		int res1 = 0, res2 = 0;
		for (int i = 200000; i >= 1; i--) {
			for (int e : g[i]) pq.push(e);
			if (!pq.empty()) {
				res1 += i;
				res2 += min(i, pq.top());
				pq.pop();
			}
		}
		printf("%d %d\n", res1, res2);
	}

	return 0;

	/*
		おまじないを使ったらscanfとprintf関連注意！！！！！！！！！！！！
	*/
}


#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef pair<int,int> pii;
#define NN 200100
int a[NN],f[NN];
pii p[NN];
multiset <int> st;
int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in","r",stdin);
	freopen("out.out","w",stdout);
#endif
	int t;cin>>t;
	while(t--){
		int n;cin>>n;
		for(int i=1;i<=n;i++) {scanf("%d%d",a+i,f+i),p[a[i]].x++;if(f[i]) p[a[i]].y++;}
		sort(p+1,p+n+1);
		int ans=0,o=0,ed=p[n].x+1;
		for(int i=n;i>=1;i--){
			int it=lower_bound(p+1,p+n+1,pii(p[i].x,0))-p;
			for(int j=i;j>=it;j--) st.insert(p[j].y);
			while(!st.empty() and ed-1>p[it-1].x){
				ed--;
				int dds=*(--st.end());st.erase(--st.end());
				ans+=ed;
				o+=min(ed,dds);
			}
			ed=p[it-1].x+1;
			if(ed<=1) break;
			i=it;
		}
		cout<<ans<<' '<<o<<endl;
		for(int i=1;i<=n;i++) p[i].x=p[i].y=0;st.clear();
	}
	return 0;
}


#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back

using namespace std;
template<typename T, typename U> inline void smin(T &a, const U &b) {if (a>b) a=b;}
template<typename T, typename U> inline void smax(T &a, const U &b) {if (a<b) a=b;}

using DO = double;
using LL = long long;
using VI = vector<int>;
using pii = pair<int, int>;

const int mod=1000000007;
const int inf=0x3f3f3f3f;
const DO pi = acosl(-1.);
const DO eps = 1e-9;

int power(int a, LL b, int m=mod, int ans=1) {
  for(; b; b>>=1, a=(LL)a*a%m) if (b&1) ans=(LL)ans*a%m;
  return ans;
}
const int NN =2e5+10;
pii t[NN];

void solve() {
  int n, m=0;
  cin>>n;
  for(int i=1; i<=n; i++) {
    scanf("%d %d", &t[i].x, &t[i].y);
  }
  sort(t+1, t+n+1);
  multiset<pii> st;
  for(int i=1, j; i<=n; i=j) {
    int sz=0;
    for(j=i; j<=n && t[j].x == t[i].x; ) {
      sz+=t[j].y;
      j++;
    }
    st.insert({-(j-i), sz});
  }
  multiset<int> ov;
  int cur=-(st.begin()->x);
  int ans=0, res=0;
  while(cur>0) {
    if(st.empty() && ov.empty()) break;
    while(!st.empty() && -(st.begin()->x) <=cur) {
      ov.insert(-(st.begin()->y));
      st.erase(st.begin());
    }
    if(ov.empty()) {
      cur=-(st.begin()->x);
    }else {
      ans+=cur;
      res+=min(-(*ov.begin()), cur);
      ov.erase(ov.begin());
      cur--;
    }
  }
  printf("%d %d\n", ans, res);
}

int main() {
#ifndef ONLINE_JUDGE
  freopen("in.in", "r", stdin);
  freopen("out.out", "w", stdout);
#endif

  int q;
  cin>>q;
  while(q--) solve();

  return 0;
}


#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef pair<int,int> pii;
#define NN 200100
int a[NN],f[NN];
pii p[NN];
multiset <int> st;
int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in","r",stdin);
	freopen("out.out","w",stdout);
#endif
	int t;cin>>t;
	while(t--){
		int n;cin>>n;
		for(int i=1;i<=n;i++) {scanf("%d%d",a+i,f+i),p[a[i]].x++;if(f[i]) p[a[i]].y++;}
		sort(p+1,p+n+1);
		int ans=0,o=0,ed=p[n].x+1;
		for(int i=n;i>=1;i--){
			int it=lower_bound(p+1,p+n+1,pii(p[i].x,0))-p;
			for(int j=i;j>=it;j--) st.insert(p[j].y);
			while(!st.empty() and ed-1>p[it-1].x){
				ed--;
				int dds=*(--st.end());st.erase(--st.end());
				ans+=ed;
				o+=min(ed,dds);
			}
			if(!ed) break;
			ed=p[it-1].x+1;
			i=it;
		}
		cout<<ans<<' '<<o<<endl;
		for(int i=1;i<=n;i++) p[i].x=p[i].y=0;st.clear();
	}
	return 0;
}


#include<bits/stdc++.h>

#define NN 200010
#define inf 1e6

using namespace std;

typedef long long INT;
typedef pair<int,int>pii;

int cnt[NN],a[NN],mp[NN];
multiset<pii>ss;
multiset<int>s;
multiset<pii>:: iterator it;

int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in","r",stdin);
	freopen("out.out","w",stdout);
#endif
	int q;
	cin>>q;
	while(q--){
		int n;
		cin>>n;
		for(int i=1;i<=n;i++){
			int f;
			scanf("%d%d",&a[i],&f);
			if(f)mp[a[i]]++;
			cnt[a[i]]++;
		}
		for(int i=1;i<=n;i++){
			if(cnt[a[i]]){
				ss.insert({cnt[a[i]],mp[a[i]]});
			}
			cnt[a[i]]=0;
		}
		int ans=0,res=0,k=inf;
		while(k){
			if(s.empty() && ss.empty()) break;
			if(!ss.empty() && (*--ss.end()).first >= k){
				it=ss.lower_bound({k, 0});
				while(1){
					s.insert((*--ss.end()).second);
					if(it==--ss.end())break;
					ss.erase(--ss.end());
				}
				ss.erase(it);
			}
			if(s.size()==0)	k=(*--ss.end()).first;
			else {
				ans+=k;
				res+=min(k,*--s.end());
				k--;
				s.erase(--s.end());
			}
		}
		printf("%d %d\n",ans,res);
		for(int i=1;i<=n;i++)mp[a[i]]=0;
		for(int i=1;i<=n;i++)cnt[a[i]]=0;
		s.clear();
		ss.clear();
	}

	return 0;
}


#include<bits/stdc++.h>

#define NN 200010
#define inf 1e6

using namespace std;

typedef long long INT;
typedef pair<int,int>pii;

int cnt[NN],a[NN];
multiset<pii>ss;
multiset<int>s;
map<pii,int>mp;
multiset<pii>:: iterator it;

int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in","r",stdin);
	freopen("out.out","w",stdout);
#endif
	int q;
	cin>>q;
	while(q--){
		s.clear();
		mp.clear();
		ss.clear();
		int n;
		cin>>n;
		for(int i=1;i<=n;i++){
			int f;
			scanf("%d%d",&a[i],&f);
			if(f)mp[{a[i],f}]++;
			cnt[a[i]]++;
		}
		for(int i=1;i<=n;i++){
			if(cnt[a[i]]){
				s.insert(cnt[a[i]]);
				ss.insert({cnt[a[i]],mp[{a[i],1}]});
			}
			cnt[a[i]]=0;
			mp[{a[i],1}]=0;
		}
		int ans=0,ansf=0,k=inf;
		while(s.size()){
			int mx=*--s.end();
			k=min(k,mx);
			ans+=k;
			it=ss.lower_bound({k,inf});
			ansf+=min(k,(*--it).second);
			int l=(*it).first;
			ss.erase(it);
			s.erase(s.lower_bound(l));
			k--;
			if(k==0)break;
		}
		printf("%d %d\n",ans,ansf);
	}

	return 0;
}


#include<bits/stdc++.h>

#define NN 200010
#define inf 1e6

using namespace std;

typedef long long INT;
typedef pair<int,int>pii;

int cnt[NN],a[NN],mp[NN];
multiset<pii>ss;
multiset<int>s;
multiset<pii>:: iterator it;

int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in","r",stdin);
	freopen("out.out","w",stdout);
#endif
	int q;
	cin>>q;
	while(q--){
		s.clear();
		ss.clear();
		int n;
		cin>>n;
		for(int i=1;i<=n;i++){
			int f;
			scanf("%d%d",&a[i],&f);
			if(f)mp[a[i]]++;
			cnt[a[i]]++;
		}
		for(int i=1;i<=n;i++){
			if(cnt[a[i]]){
				s.insert(cnt[a[i]]);
				ss.insert({cnt[a[i]],mp[a[i]]});
			}
			cnt[a[i]]=0;
		}
		for(int i=1;i<=n;i++)mp[a[i]]=0;
		int ans=0,res=0,k=inf;
		while(s.size()){
			int mx=*--s.end();
			k=min(k,mx);
			ans+=k;
			it=ss.lower_bound({k,inf});
			res+=min(k,(*--it).second);
			int l=(*it).first;
			ss.erase(it);
			s.erase(s.lower_bound(l));
			k--;
			if(k==0)break;
		}
		printf("%d %d\n",ans,res);
	}

	return 0;
}


#include<bits/stdc++.h>

#define NN 200010
#define inf 1e6

using namespace std;

typedef long long INT;
typedef pair<int,int>pii;

int cnt[NN],a[NN],mp[NN];
multiset<pii>ss;
multiset<int>s;
multiset<pii>:: iterator it;

int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in","r",stdin);
	freopen("out.out","w",stdout);
#endif
	int q;
	cin>>q;
	while(q--){
		int n;
		cin>>n;
		for(int i=1;i<=n;i++){
			int f;
			scanf("%d%d",&a[i],&f);
			if(f)mp[a[i]]++;
			cnt[a[i]]++;
		}
		for(int i=1;i<=n;i++){
			if(cnt[a[i]]){
				s.insert(cnt[a[i]]);
				ss.insert({cnt[a[i]],mp[a[i]]});
			}
			cnt[a[i]]=0;
		}
		int ans=0,res=0,k=inf;
		while(s.size()){
			int mx=*--s.end();
			k=min(k,mx);
			ans+=k;
			it=ss.lower_bound({k,inf});
			res+=min(k,(*--it).second);
			int l=(*it).first;
			ss.erase(it);
			s.erase(s.lower_bound(l));
			k--;
			if(k==0)break;
		}
		printf("%d %d\n",ans,res);
		for(int i=1;i<=n;i++)mp[a[i]]=0;
		for(int i=1;i<=n;i++)cnt[a[i]]=0;
		s.clear();
		ss.clear();
	}

	return 0;
}


#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back

using namespace std;
template<typename T, typename U> inline void smin(T &a, const U &b) {if (a>b) a=b;}
template<typename T, typename U> inline void smax(T &a, const U &b) {if (a<b) a=b;}

using DO = double;
using LL = long long;
using VI = vector<int>;
using pii = pair<int, int>;

const int mod=1000000007;
const int inf=0x3f3f3f3f;
const DO pi = acosl(-1.);
const DO eps = 1e-9;

int power(int a, LL b, int m=mod, int ans=1) {
  for(; b; b>>=1, a=(LL)a*a%m) if (b&1) ans=(LL)ans*a%m;
  return ans;
}
const int NN =2e5+10;
pii t[NN];
multiset<pii> st;
multiset<int> ov;

void solve() {
  st.clear();
  ov.clear();
  int n, m=0;
  cin>>n;
  for(int i=1; i<=n; i++) {
    scanf("%d %d", &t[i].x, &t[i].y);
  }
  sort(t+1, t+n+1);
  for(int i=1, j; i<=n; i=j) {
    int sz=0;
    for(j=i; j<=n && t[j].x == t[i].x; ) {
      sz+=t[j].y;
      j++;
    }
    st.insert({-(j-i), sz});
  }
  int cur=-(st.begin()->x);
  int ans=0, res=0;
  while(cur>0) {
    if(st.empty() && ov.empty()) break;
    while(!st.empty() && -(st.begin()->x) >=cur) {
      ov.insert(-(st.begin()->y));
      st.erase(st.begin());
    }
    if(ov.empty()) {
      cur=-(st.begin()->x);
    }else {
      ans+=cur;
      res+=min(-(*ov.begin()), cur);
      ov.erase(ov.begin());
      cur--;
    }
  }
  printf("%d %d\n", ans, res);
}

int main() {
#ifndef ONLINE_JUDGE
  freopen("in.in", "r", stdin);
  freopen("out.out", "w", stdout);
#endif

  int q;
  cin>>q;
  while(q--) solve();

  return 0;
}


#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back

using namespace std;
template<typename T, typename U> inline void smin(T &a, const U &b) {if (a>b) a=b;}
template<typename T, typename U> inline void smax(T &a, const U &b) {if (a<b) a=b;}

using DO = double;
using LL = long long;
using VI = vector<int>;
using pii = pair<int, int>;

const int mod=1000000007;
const int inf=0x3f3f3f3f;
const DO pi = acosl(-1.);
const DO eps = 1e-9;

int power(int a, LL b, int m=mod, int ans=1) {
  for(; b; b>>=1, a=(LL)a*a%m) if (b&1) ans=(LL)ans*a%m;
  return ans;
}
const int NN =2e5+10;
pii t[NN];

void solve() {
  int n, m=0;
  cin>>n;
  for(int i=1; i<=n; i++) {
    scanf("%d %d", &t[i].x, &t[i].y);
  }
  sort(t+1, t+n+1);
  multiset<pii> st;
  for(int i=1, j; i<=n; i=j) {
    int sz=0;
    for(j=i; j<=n && t[j].x == t[i].x; ) {
      sz+=t[j].y;
      j++;
    }
    st.insert({-(j-i), sz});
  }
  multiset<int> ov;
  int cur=-(st.begin()->x);
  int ans=0, res=0;
  while(cur>0) {
    if(st.empty() && ov.empty()) break;
    while(!st.empty() && st.begin()->x<=cur) {
      ov.insert(-(st.begin()->y));
      st.erase(st.begin());
    }
    if(ov.empty()) {
      cur=-(st.begin()->x);
    }else {
      ans+=cur;
      res+=min(-(*ov.begin()), cur);
      ov.erase(ov.begin());
      cur--;
    }
  }
  printf("%d %d\n", ans, res);
}

int main() {
#ifndef ONLINE_JUDGE
  freopen("in.in", "r", stdin);
  freopen("out.out", "w", stdout);
#endif

  int q;
  cin>>q;
  while(q--) solve();

  return 0;
}


#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef pair<int,int> pii;
#define NN 200100
int a[NN],f[NN],d[NN];
pii p[NN];
int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in","r",stdin);
	freopen("out.out","w",stdout);
#endif
	int t;cin>>t;
	while(t--){
		int n;cin>>n;
		for(int i=1;i<=n;i++) {scanf("%d%d",a+i,f+i),p[a[i]].x++;if(f[i]) p[a[i]].y++;}
		sort(p+1,p+n+1);
		int ans=0,o=0,ed=1e9;
		for(int i=n;i>=1;i--){
			ans+=p[i].x;o+=p[i].y;
			ed=p[i].x;
			int it=lower_bound(p+1,p+n+1,pii(p[i].x,0))-p;
			int num=i-it;
			if(ed-num>p[it-1].x){
				for(int j=i-1;j>=it;j--) {if(ed==0) break;ed--,ans+=ed,o+=min(ed,p[i].y);}
			}
			else {
				for(int j=i-1;j>=it;j--) {if(ed-1==p[it-1].x or ed==0) break;ed--;ans+=ed;o+=min(ed,p[i].y);}
			}
			i=it;
		}
		cout<<ans<<' '<<o<<endl;
		for(int i=1;i<=n;i++) p[i].x=p[i].y=0,d[i]=0;
	}
	return 0;
}


#include<bits/stdc++.h>

#define NN 210000
#define inf 1e6

using namespace std;

typedef long long INT;
typedef pair<int,int>pii;

int cnt[NN],a[NN],f[NN];
multiset<pii>ss;
multiset<int>s;
map<pii,int>mp;
multiset<pii>:: iterator it;

int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in","r",stdin);
	freopen("out.out","w",stdout);
#endif
	int q;
	cin>>q;
	while(q--){
		s.clear();
		mp.clear();
		ss.clear();
		int n;
		cin>>n;
		for(int i=1;i<=n;i++){
			scanf("%d%d",&a[i],&f[i]);
			mp[{a[i],f[i]}]++;
			cnt[a[i]]++;
		}
		for(int i=1;i<=n;i++){
			if(cnt[a[i]]){
				s.insert(cnt[a[i]]);
				ss.insert({cnt[a[i]],mp[{a[i],1}]});
			}
			cnt[a[i]]=0;
			mp[{a[i],1}]=0;
		}
		int ans=0,ansf=0,k=inf;
		while(s.size()){
			int mx=*--s.end();
			k=min(k,mx);
			ans+=k;
			it=ss.lower_bound({k,inf});
			ansf+=min(k,(*--it).second);
			int l=(*it).first;
			ss.erase(it);
			s.erase(s.lower_bound(l));
			k--;
			if(k==0)break;
		}
		printf("%d %d\n",ans,ansf);
	}

	return 0;
}


#include <bits/stdc++.h>
#define NN 200100
using namespace std;
typedef long long INT;
int n, sum1 = 0, sum2 = 0;
int a[NN], b[NN];
int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif
	int test;
	scanf("%d", &test);
	while(test--){
		sum1 = 0, sum2 = 0;
		for(int i = n; i > 0; i--){
			if(a[i] == 0) break;
			a[i] = 0;
		}
		for(int i = n; i > 0; i--){
			if(b[i] == 0) break;
			b[i] = 0;
		}
		scanf("%d", &n);
		for(int i = 0; i < n; i++){
			int u, f;
			scanf("%d%d", &u, &f);
			a[u]++;
			if(f) b[u]++;
		}
		sort(a + 1, a + n + 1);
		int ct = max(a[n] - 1, 0);
		sum1 += a[n];
		for(int i = n - 1; i > 0; i--){
			if(ct == 0 || a[i] == 0) break;
			if(a[i] >= ct) {
				sum1 += ct;
				ct--;
			}
			else {
				sum1 += a[i];
				ct = a[i] - 1;
			}
		}
		sort(b + 1, b + n + 1);
		ct = max(0, b[n] - 1);
		sum2 += b[n];
		for(int i = n - 1; i > 0; i--){
			if(ct == 0 || b[i] == 0) break;
			if(b[i] >= ct) {
				sum2 += ct;
				ct--;
			}
			else {
				sum2 += b[i];
				ct = b[i] - 1;
			}
		}
		cout<<sum1<<" "<<sum2<<endl;
	}
	return 0;
}


#include <bits/stdc++.h>
#define x first
#define y second
#define NN 200100
using namespace std;
typedef long long INT;
typedef pair<int, int> pii;
multiset <pii> F;
multiset <int> S;
pii p[NN];
int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif
	int test;
	scanf("%d", &test);
	while(test--){
		F.clear();
		S.clear();
		int n;
		scanf("%d", &n);
		for(int i = 1; i <= n; i++)
			scanf("%d%d", &p[i].x, &p[i].y);
		sort(p + 1, p + n + 1);
		for(int i = 1, j; i <= n;){
			int ct = 0;
			for(j = i; j <= n; j++){
				if(p[i].x == p[j].x) ct += p[j].y;
				else break;
			}
			F.insert({i - j, ct});
			i = j;
		}
		int cur = -F.begin()->x;
		int ans = 0, res = 0;
		while(cur){
			if(F.empty() && S.empty()) break;
			if(!F.empty() && -(F.begin()->x) >= cur){
				S.insert(-(F.begin()->y));
				F.erase(F.begin());
			}
			else if(S.empty()){
				cur = -F.begin()->x;
			}
			else {
				ans += cur;
				res += min(-*S.begin(), cur);
				S.erase(S.begin());
				cur--;
			}
		}
		cout<<ans<<" "<<res<<endl;
	}
	return 0;
}


#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef pair<int,int> pii;
#define NN 200100
int a[NN],f[NN],d[NN];
pii p[NN];
int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in","r",stdin);
	freopen("out.out","w",stdout);
#endif
	int t;cin>>t;
	while(t--){
		int n;cin>>n;
		for(int i=1;i<=n;i++) scanf("%d%d",a+i,f+i),d[i]=a[i];
		sort(d+1,d+n+1);
		int m=unique(d+1,d+n+1)-d-1;
		for(int i=1;i<=n;i++) a[i]=lower_bound(d+1,d+m+1,a[i])-d;
		for(int i=1;i<=n;i++) {p[a[i]].x++;if(f[i]) p[a[i]].y++;}
		sort(p+1,p+m+1);
		int ans=0,o=0,ed=1e9;
		for(int i=m;i>=1;i--){
//			cerr<<p[i].x<<endl;
			ans+=p[i].x;o+=p[i].y;
			ed=p[i].x;
			int it=lower_bound(p+1,p+m+1,pii(p[i].x,0))-p;
			int num=i-it;
//			cerr<<num<<endl;
			if(ed-num>p[it].x){
				for(int j=i-1;j>=it;j--) {if(ed==0) break;ed--,ans+=ed,o+=min(ed,p[i].y);}
			}
			else {
				for(int j=i-1;j>=it;j--) {if(ed-1==p[it-1].x or ed==0) break;ed--;ans+=ed;o+=min(ed,p[i].y);}
			}
			i=it;
		}
		cout<<ans<<' '<<o<<endl;
		for(int i=1;i<=m;i++) p[i].x=p[i].y=0;
	}
	return 0;
}


#include <bits/stdc++.h>
#define NN 200100
using namespace std;
typedef long long INT;
int n, sum1 = 0, sum2 = 0;
int a[NN], b[NN];
int main(){
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif
	int test;
	scanf("%d", &test);
	while(test--){
		sum1 = 0, sum2 = 0;
		for(int i = n; i > 0; i--){
			if(a[i] == 0) break;
			a[i] = 0;
		}
		for(int i = n; i > 0; i--){
			if(b[i] == 0) break;
			b[i] = 0;
		}
		scanf("%d", &n);
		for(int i = 0; i < n; i++){
			int u, f;
			scanf("%d%d", &u, &f);
			a[u]++;
			if(f) b[u]++;
		}
		sort(a + 1, a + n + 1);
		int ct = a[n] - 1;
		sum1 += a[n];
		for(int i = n - 1; i > 0; i--){
			if(ct == 0 || a[i] == 0) break;
			if(a[i] >= ct) {
				sum1 += ct;
				ct--;
			}
			else {
				sum1 += a[i];
				ct = a[i] - 1;
			}
		}
		sort(b + 1, b + n + 1);
		ct = b[n] - 1;
		sum2 += b[n];
		for(int i = n - 1; i > 0; i--){
			if(ct == 0 || b[i] == 0) break;
			if(b[i] >= ct) {
				sum2 += ct;
				ct--;
			}
			else {
				sum2 += b[i];
				ct = b[i] - 1;
			}
		}
		cout<<sum1<<" "<<sum2<<endl;
	}
	return 0;
}


#include <iostream>
#include <cstdio>
#include <deque>
#include <cmath>

using namespace std;

const int inf = (int)19;
int _y[3] = {-1, 0, 1};
int d[4][110], n, k, t;
char a[4][110];

deque <pair<int, int> > deq;

void write(){
	for (int i=1; i<=3; i++) {
	for (int j=1; j<=n; j++)
		if (a[i][j] != '.' ) cout << a[i][j] << ' '; else
		cout << d[i][j] << ' ';
		cout << endl;
	}
}
string bfs(int x, int y) {
	deq.push_back(make_pair(x, y));
	d[x][y] = 1;
	for (int tt = 1; tt <= n; tt++) {
		int s = deq.size();
		cout << s << '\n';
		for(int j=0; j<s; j++) {
	    	x = deq.front().first;
		    y = deq.front().second;
		    deq.pop_front();

	//	    cout << x << ' ' <<  y << endl;

			for (int i=0; i<3; i++)
				if (a[x][y] == '.' and a[x][y+1] =='.' and a[x+_y[i]][y+1] == '.')
					deq.push_back(make_pair(x+_y[i], y+1)),
					d[ x + _y[i] ][ y + 1 ] = min( d[ x+_y[i] ][ y+1 ], d[ x ][ y ] + 1);
		}

		//write(); cout << '\n';

		for (int i=1; i<=3; i++)
			if (d[i][n] != inf) { return "YES"; }

		for (int i=1; i<=3; i++)
		for (int j=1; j<=n-2; j++)
			if (a[i][j+2] != '.') a[i][j] = a[i][j+2], a[i][j+2] = '.';

	}
	return "NO";
}

int main(){
//	freopen("a.in", "r", stdin);
//	freopen("a.out", "w", stdout);
	cin >> t;

	int x, y;

	while (t--) {
		cin >> n >> k;
		for (int i=1; i<=3; i++)
		for (int j=1; j<=n; j++) {
			cin >> a[i][j];
			if (a[i][j] == 's')
				x = i, y = j, a[i][j] = '.';
			d[i][j] = inf;
		}

		cerr << bfs(x,y) << '\n';
	}

}


#include <iostream>
#include <cstdio>
#include <deque>
#include <cmath>

using namespace std;

const int inf = (int)19;
int _y[3] = {-1, 0, 1};
int d[4][110], n, k, t;
char a[4][110];

deque <pair<int, int> > deq;

void write(){
	for (int i=1; i<=3; i++) {
	for (int j=1; j<=n; j++)
		if (a[i][j] != '.' ) cout << a[i][j] << ' '; else
		cout << d[i][j] << ' ';
		cout << endl;
	}
}
string bfs(int x, int y) {
	deq.push_back(make_pair(x, y));
	d[x][y] = 1;
	for (int tt = 1; tt <= n; tt++) {
		int s = deq.size();
		//cout << s << '\n';
		for(int j=0; j<s; j++) {
	    	x = deq.front().first;
		    y = deq.front().second;
		    deq.pop_front();

	//	    cout << x << ' ' <<  y << endl;

			for (int i=0; i<3; i++)
				if (a[x][y] == '.' and a[x][y+1] =='.' and a[x+_y[i]][y+1] == '.')
					deq.push_back(make_pair(x+_y[i], y+1)),
					d[ x + _y[i] ][ y + 1 ] = min( d[ x+_y[i] ][ y+1 ], d[ x ][ y ] + 1);
		}

		//write(); cout << '\n';

		for (int i=1; i<=3; i++)
			if (d[i][n] != inf) { return "YES"; }

		for (int i=1; i<=3; i++)
		for (int j=1; j<=n-2; j++)
			if (a[i][j+2] != '.') a[i][j] = a[i][j+2], a[i][j+2] = '.';

	}
	return "NO";
}

int main(){
//	freopen("a.in", "r", stdin);
//	freopen("a.out", "w", stdout);
	cin >> t;

	int x, y;

	while (t--) {
		cin >> n >> k;
		for (int i=1; i<=3; i++)
		for (int j=1; j<=n; j++) {
			cin >> a[i][j];
			if (a[i][j] == 's')
				x = i, y = j, a[i][j] = '.';
			d[i][j] = inf;
		}

		cout << bfs(x,y) << '\n';
	}

}


#include<iostream>
using namespace std;
bool a[3][100];
bool vis[3][100];
int n,k,x,y,flag;
void dfs(int p,int q,int c)
{
	vis[p][q]=1;
	if(p<0||p>2)
		return;
	if(q==n){
		flag=1;
		return;
	}
	if(a[p][q]==1)
		return;
	if(c%4==1){
		dfs(p,q,c+1);
		if(vis[p+1][q]==0)
			dfs(p+1,q,c+1);
		if(vis[p-1][q]==0)
			dfs(p-1,q,c+1);
	}
	else
		dfs(p,q+1,c+1);
}
int main()
{
	int num;
	cin>>num;
	while(num--){
		flag=0;
		char c;
		cin>>n>>k;
		for(int j=0;j<3;j++)
			for(int i=0;i<n;i++){
				vis[j][i]=0;
				cin>>c;
				if(c=='.')
					a[j][i]=0;
				else if(c=='s'){
					x=j;
					y=i;
					a[j][i]=0;
				}
				else
					a[j][i]=1;
			}
		dfs(x,y,0);
		if(flag)
			cout<<"YES"<<endl;
		else
			cout<<"NO"<<endl;
	}
}


#include<iostream>
#include<cstring>
using namespace std;
bool a[3][100];
bool vis[3][100];
int n,k,x,y,flag;
void dfs(int p,int q,int c)
{
	if(p<0||p>2)
		return;
	if(q==n){
		flag=1;
		return;
	}
	if(a[p][q]==1)
		return;
	vis[p][q]=1;
	if(c%4==1){
		dfs(p,q,c+1);
		if(vis[p+1][q]==0)
			dfs(p+1,q,c+1);
		if(vis[p-1][q]==0)
			dfs(p-1,q,c+1);
	}
	else
		if(vis[p][q+1]==0)
			dfs(p,q+1,c+1);
	return;
}
int main()
{
	int num;
	cin>>num;
	while(num--){
		flag=0;
		char c;
		cin>>n>>k;
		memset(vis,0,sizeof(vis));
		for(int j=0;j<3;j++)
			for(int i=0;i<n;i++){
				cin>>c;
				if(c=='.')
					a[j][i]=0;
				else if(c=='s'){
					x=j;
					y=i;
					a[j][i]=0;
				}
				else
					a[j][i]=1;
			}
		dfs(x,y,0);
		if(flag)
			cout<<"YES"<<endl;
		else
			cout<<"NO"<<endl;
	}
}


#include<iostream>
using namespace std;
bool a[3][100];
int n,k,x,y,flag;
void dfs(int p,int q,int c)
{
	if(p<0||p>2)
		return;
	if(q==n){
		flag=1;
		return;
	}
	if(a[p][q]==1)
		return;
	if(c%4==1){
		dfs(p,q,c+1);
		dfs(p+1,q,c+1);
		dfs(p-1,q,c+1);
	}
	else
		dfs(p,q+1,c+1);
}
int main()
{
	int num;
	cin>>num;
	while(num--){
		flag=0;
		char c;
		cin>>n>>k;
		for(int j=0;j<3;j++)
			for(int i=0;i<n;i++){
				cin>>c;
				if(c=='.')
					a[j][i]=0;
				else if(c=='s'){
					x=j;
					y=i;
					a[j][i]=0;
				}
				else
					a[j][i]=1;
			}
		dfs(x,y,0);
		if(flag)
			cout<<"YES"<<endl;
		else
			cout<<"NO"<<endl;
	}
}


#include<iostream>
#include<cstring>
using namespace std;
bool a[3][100];
bool vis[3][100];
int n,k,x,y,flag;
void dfs(int p,int q,int c)
{
	if(p<0||p>2)
		return;
	if(q==n){
		flag=1;
		return;
	}
	if(a[p][q]==1)
		return;
	if(vis[p][q]==1)
		return;
	if(c%4==1){
		dfs(p,q,c+1);
		dfs(p+1,q,c+1);
		dfs(p-1,q,c+1);
	}
	else
		dfs(p,q+1,c+1);
	vis[p][q]=1;
	return;
}
int main()
{
	int num;
	cin>>num;
	while(num--){
		flag=0;
		char c;
		cin>>n>>k;
		memset(vis,0,sizeof(vis));
		for(int j=0;j<3;j++)
			for(int i=0;i<n;i++){
				cin>>c;
				if(c=='.')
					a[j][i]=0;
				else if(c=='s'){
					x=j;
					y=i;
					a[j][i]=0;
				}
				else
					a[j][i]=1;
			}
		dfs(x,y,0);
		if(flag)
			cout<<"YES"<<endl;
		else
			cout<<"NO"<<endl;
	}
}


#include<iostream>
using namespace std;
bool a[3][100];
bool vis[3][100];
int n,k,x,y,flag;
void dfs(int p,int q,int c)
{
	vis[p][q]=1;
	if(p<0||p>2)
		return;
	if(q==n){
		flag=1;
		return;
	}
	if(a[p][q]==1)
		return;
	if(c%4==1){
		dfs(p,q,c+1);
		if(vis[p+1][q]==0)
			dfs(p+1,q,c+1);
		if(vis[p-1][q]==0)
			dfs(p-1,q,c+1);
	}
	else
		dfs(p,q+1,c+1);
}
int main()
{
	int num;
	cin>>num;
	while(num--){
		flag=0;
		char c;
		cin>>n>>k;
		for(int j=0;j<3;j++)
			for(int i=0;i<n;i++){
				vis[j][i]=0;
				cin>>c;
				if(c=='.')
					a[j][i]=0;
				else if(c=='s'){
					x=j;
					y=i;
					a[j][i]=0;
				}
				else
					a[j][i]=1;
			}
		dfs(x,y,0);
		if(flag)
			cout<<"YES"<<endl;
		else
			cout<<"NO"<<endl;
	}
	return 0;
}


#include<iostream>
#include<cstring>
using namespace std;
bool a[3][100];
bool vis[3][100];
int n,k,x,y,flag;
void dfs(int p,int q,int c)
{
	if(p<0||p>2)
		return;
	if(q==n){
		flag=1;
		return;
	}
	if(a[p][q]==1)
		return ;
	if(vis[p][q]==1)
		return;
	if(c%4==1){
		dfs(p,q,c+1);
		dfs(p+1,q,c+1);
		dfs(p-1,q,c+1);
	}
	else
		dfs(p,q+1,c+1);
	vis[p][q]=1;
	return;
}
int main()
{
	int num;
	cin>>num;
	while(num--){
		flag=0;
		char c;
		cin>>n>>k;
		memset(vis,0,sizeof(vis));
		for(int j=0;j<3;j++)
			for(int i=0;i<n;i++){
				cin>>c;
				if(c=='.')
					a[j][i]=0;
				else if(c=='s'){
					x=j;
					y=i;
					a[j][i]=0;
				}
				else
					a[j][i]=1;
			}
		dfs(x,y,0);
		if(flag)
			cout<<"YES"<<endl;
		else
			cout<<"NO"<<endl;
	}
}


#include<iostream>
#include<cstring>
using namespace std;
bool a[3][100];
bool vis[3][100][4];
int n,k,x,y,flag;
void dfs(int p,int q,int c)
{
	if(p<0||p>2)
		return;
	if(q==n){
		flag=1;
		return;
	}
	if(a[p][q]==1)
		return;
	if(vis[p][q][c]==1)
		return;
	vis[p][q][c]=1;
	if(c%4==1){
		dfs(p,q,c+1);
		dfs(p+1,q,c+1);
		dfs(p-1,q,c+1);
	}
	else
		dfs(p,q+1,c+1);
	return;
}
int main()
{
	int num;
	cin>>num;
	while(num--){
		flag=0;
		char c;
		cin>>n>>k;
		memset(vis,0,sizeof(vis));
		for(int j=0;j<3;j++)
			for(int i=0;i<n;i++){
				cin>>c;
				if(c=='.')
					a[j][i]=0;
				else if(c=='s'){
					x=j;
					y=i;
					a[j][i]=0;
				}
				else
					a[j][i]=1;
			}
		dfs(x,y,0);
		if(flag)
			cout<<"YES"<<endl;
		else
			cout<<"NO"<<endl;
	}
}


#include<iostream>
#include<cstring>
using namespace std;
bool a[3][100];
bool vis[3][100][4];
int n,k,x,y,flag;
void dfs(int p,int q,int c)
{
	if(p<0||p>2)
		return;
	if(q==n){
		flag=1;
		return;
	}
	if(a[p][q]==1)
		return;
	if(vis[p][q][c]==1)
		return;
	if(c%4==1){
		dfs(p,q,c+1);
		dfs(p+1,q,c+1);
		dfs(p-1,q,c+1);
	}
	else
		dfs(p,q+1,c+1);
	vis[p][q][c]=1;
	return;
}
int main()
{
	int num;
	cin>>num;
	while(num--){
		flag=0;
		char c;
		cin>>n>>k;
		memset(vis,0,sizeof(vis));
		for(int j=0;j<3;j++)
			for(int i=0;i<n;i++){
				cin>>c;
				if(c=='.')
					a[j][i]=0;
				else if(c=='s'){
					x=j;
					y=i;
					a[j][i]=0;
				}
				else
					a[j][i]=1;
			}
		dfs(x,y,0);
		if(flag)
			cout<<"YES"<<endl;
		else
			cout<<"NO"<<endl;
	}
}


#include<iostream>
#include<cstring>
using namespace std;
bool a[3][100];
bool vis[3][100];
int n,k,x,y,flag;
void dfs(int p,int q,int c)
{
	vis[p][q]=1;
	if(p<0||p>2)
		return;
	if(q==n){
		flag=1;
		return;
	}
	if(a[p][q]==1)
		return;
	if(c%4==1){
		dfs(p,q,c+1);
		if(vis[p+1][q]==0)
			dfs(p+1,q,c+1);
		if(vis[p-1][q]==0)
			dfs(p-1,q,c+1);
	}
	else
		if(vis[p][q+1]==0)
			dfs(p,q+1,c+1);
	return;
}
int main()
{
	int num;
	cin>>num;
	while(num--){
		flag=0;
		char c;
		cin>>n>>k;
		memset(vis,0,sizeof(vis));
		for(int j=0;j<3;j++)
			for(int i=0;i<n;i++){
				cin>>c;
				if(c=='.')
					a[j][i]=0;
				else if(c=='s'){
					x=j;
					y=i;
					a[j][i]=0;
				}
				else
					a[j][i]=1;
			}
		dfs(x,y,0);
		if(flag)
			cout<<"YES"<<endl;
		else
			cout<<"NO"<<endl;
	}
}


#include<iostream>
#include<cstring>
using namespace std;
bool a[3][100];
bool vis[3][100][4];
int n,k,x,y,flag;
void dfs(int p,int q,int c)
{
	if(q==n){
		flag=1;
		return;
	}
	if(a[p][q]==1)
		return ;
	if(vis[p][q][c]==1)
		return;
	if(c%4==1){
		dfs(p,q,c+1);
		if(p!=2)
			dfs(p+1,q,c+1);
		if(p!=0)
			dfs(p-1,q,c+1);
	}
	else
		dfs(p,q+1,c+1);
	vis[p][q][c]=1;
	return;
}
int main()
{
	int num;
	cin>>num;
	while(num--){
		flag=0;
		char c;
		cin>>n>>k;
		memset(vis,0,sizeof(vis));
		for(int j=0;j<3;j++)
			for(int i=0;i<n;i++){
				cin>>c;
				if(c=='.')
					a[j][i]=0;
				else if(c=='s'){
					x=j;
					y=i;
					a[j][i]=0;
				}
				else
					a[j][i]=1;
			}
		dfs(x,y,0);
		if(flag)
			cout<<"YES"<<endl;
		else
			cout<<"NO"<<endl;
	}
}


#include<iostream>
#include<cstring>
using namespace std;
bool a[3][100];
bool vis[3][100][4];
int n,k,x,y,flag;
void dfs(int p,int q,int c)
{
	if(p<0||p>2)
		return;
	if(q==n){
		flag=1;
		return;
	}
	if(a[p][q]==1)
		return ;
	if(vis[p][q][c]==1)
		return;
	if(c%4==1){
		dfs(p,q,c+1);
		dfs(p+1,q,c+1);
		dfs(p-1,q,c+1);
	}
	else
		dfs(p,q+1,c+1);
	vis[p][q][c]=1;
	return;
}
int main()
{
	int num;
	cin>>num;
	while(num--){
		flag=0;
		char c;
		cin>>n>>k;
		memset(vis,0,sizeof(vis));
		for(int j=0;j<3;j++)
			for(int i=0;i<n;i++){
				cin>>c;
				if(c=='.')
					a[j][i]=0;
				else if(c=='s'){
					x=j;
					y=i;
					a[j][i]=0;
				}
				else
					a[j][i]=1;
			}
		dfs(x,y,0);
		if(flag)
			cout<<"YES"<<endl;
		else
			cout<<"NO"<<endl;
	}
}


#include<iostream>
#include<cstring>
using namespace std;
bool a[3][100];
bool vis[3][100];
int n,k,x,y,flag;
void dfs(int p,int q,int c)
{
	if(p<0||p>2)
		return;
	if(q==n){
		flag=1;
		return;
	}
	if(a[p][q]==1)
		return ;
	if(vis[p][q]==1&&c==2)
		return;
	if(c%4==1){
		dfs(p,q,c+1);
		dfs(p+1,q,c+1);
		dfs(p-1,q,c+1);
	}
	else
		dfs(p,q+1,c+1);
	vis[p][q]=1;
	return;
}
int main()
{
	int num;
	cin>>num;
	while(num--){
		flag=0;
		char c;
		cin>>n>>k;
		memset(vis,0,sizeof(vis));
		for(int j=0;j<3;j++)
			for(int i=0;i<n;i++){
				cin>>c;
				if(c=='.')
					a[j][i]=0;
				else if(c=='s'){
					x=j;
					y=i;
					a[j][i]=0;
				}
				else
					a[j][i]=1;
			}
		dfs(x,y,0);
		if(flag)
			cout<<"YES"<<endl;
		else
			cout<<"NO"<<endl;
	}
}


#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i = (a); i <= (b); i++)
#define red(i, a, b) for(int i = (a); i >= (b); i--)
#define ll long long
#define PII pair<int, int>

inline int read() {
    char c = getchar(); int x = 0;
    while(!isdigit(c)) c = getchar();
    while(isdigit(c)) {
        x = x * 10 + c - '0';
        c = getchar();
    }
    return x;
}

const int N = 500;
char str[N];
queue<PII> q;
int T, len, K;
int a[10][N];
int vis[10][N];

int main() {
    scanf("%d", &T);
    while(T--) {
        scanf("%d%d", &len, &K);
        int OK = 0;
        while(!q.empty()) q.pop();
        memset(a, 0, sizeof(a));
        memset(vis, 0, sizeof(vis));
        rep(col, 1, 3) {
            scanf("%s", str);
            rep(i, 0, len - 1) {
                if (str[i] == 's') {
                    q.push(make_pair(col, i + 1));
                    a[col][i + 1] = 0;
                    vis[col][i + 1] = 1;
                }
                else if (str[i] == '.') a[col][i + 1] = 0;
                else a[col][i + 1] = 1;
            }
        }
        while(!q.empty()) {
            PII now = q.front();
            q.pop();
            int inow = now.first, jnow =now.second;
            if (jnow >= len * 3 - 2) { OK = 1; break; }
            if (a[inow][jnow + 1]) continue;
            rep(i, 1, 3) {
                if (fabs(i - inow) >= 2) continue;
                if (a[i][jnow + 1]) continue;
                if (a[i][jnow + 2]) continue;
                if (a[i][jnow + 3]) continue;
                if (vis[i][jnow + 3]) continue; //不能转移到已经在队列中的点
                vis[i][jnow + 3] = 1;
                q.push(make_pair(i, jnow + 3));
            }
        }
        if (OK) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}


#include <iostream>
#include <cstring>
using namespace std;

int n, k;
char bd[5][100];
int dp[100][5][110];

bool isOK(const int t, const int x, const int y) {
	if(x >= 0 && x < 3 && y >=0 && y < n) {
		if(y + 2 * t >= n)
			return true;
		else if('.' == bd[x][y + 2 * t])
			return true;
	}

	return false;
}

bool DFS(const int t, const int x, const int y) {
	if(-1 != dp[t][x][y])
		return dp[t][x][y];

	bool flag = true;
	for(int j = y + 1; j + 2 * t < n; j++) {
		if('.' != bd[x][j + 2 * t]) {
			flag = false;
			break;
		}
	}

	if(flag) {
		dp[t][x][y] = 1;
		return dp[t][x][y];
	}

	if(isOK(t, x, y + 1) && isOK(t + 1, x, y + 1)) {
		bool res = DFS(t + 1, x, y + 1);
		if(res) {
			dp[t][x][y] = 1;
#ifdef LOCAL
cerr << t << " " << x << " " << y << " : " << 0 << endl;
#endif
			return dp[t][x][y];
		}
	}

	if(isOK(t, x, y + 1) && isOK(t, x + 1, y + 1) && isOK(t + 1, x + 1, y + 1)) {
		bool res = DFS(t + 1, x + 1, y + 1);
		if(res) {
			dp[t][x][y] = 1;
#ifdef LOCAL
cerr << t << " " << x << " " << y << " : " << 1 << endl;
#endif
			return dp[t][x][y];
		}
	}

	if(isOK(t, x, y + 1) && isOK(t, x - 1, y + 1) && isOK(t + 1, x - 1, y + 1)) {
		bool res = DFS(t + 1, x - 1, y + 1);
		if(res) {
			dp[t][x][y] = 1;
#ifdef LOCAL
cerr << t << " " << x << " " << y << " : " << 2 << endl;
#endif
			return dp[t][x][y];
		}
	}

	dp[t][x][y] = 0;
	return dp[t][x][y];
}

void print(const int t) {
	for(int i = 0; i < 3; i++) {
		for(int j = 0; j < n; ++j) {
			if(j + 2 * t < n)
				cout << bd[i][j + 2 * t];
			else
				cout << '.';
		}
		cout << endl;
	}
	cout << endl;
}

int main() {
	int t;
	cin >> t;
	while(t--) {
		cin >> n >> k;
		for(int i = 0; i < 3; i++) {
			cin >> bd[i];
		}

		for(int t = 0; t < 60; t++) {
			for(int i = 0; i < 3; i++)
				memset(dp[t][i], -1, sizeof(int) * (n + 5));
		}

		int x, y = 0;
		for(int i = 0; i < 3; ++i) {
			if('s' == bd[i][0]) {
				x = i;
				break;
			}
		}

		if(DFS(0, x, y))
			cout << "YES\n";
		else
			cout << "NO\n";
#ifdef LOCAL
for(int i = 0; i <= 5; i++)
	print(i);
	}
#endif
	return 0;
}


#include <iostream>
#include <cstring>
using namespace std;

int n, k;
char bd[5][100];
int dp[100][5][110];

bool isOK(const int t, const int x, const int y) {
	if(x >= 0 && x < 3 && y >=0 && y < n) {
		if(y + 2 * t >= n)
			return true;
		else if('.' == bd[x][y + 2 * t])
			return true;
	}

	return false;
}

bool DFS(const int t, const int x, const int y) {
	if(-1 != dp[t][x][y])
		return dp[t][x][y];
	bool flag = true;
	for(int j = y + 1; j + 2 * t < n; j++) {
		if('.' != bd[x][j + 2 * t]) {
			flag = false;
			break;
		}
	}

	if(flag) {
		dp[t][x][y] = 1;
		return dp[t][x][y];
	}

	if(isOK(t + 1, x, y + 1)) {
		bool res = DFS(t + 1, x, y + 1);
		if(res) {
			dp[t][x][y] = 1;
//cerr << t << " " << x << " " << y << " : " << 0 << endl;
			return dp[t][x][y];
		}
	}

	if(isOK(t, x, y + 1) && isOK(t, x + 1, y + 1) && isOK(t + 1, x + 1, y + 1)) {
		bool res = DFS(t + 1, x + 1, y + 1);
		if(res) {
			dp[t][x][y] = 1;
//cerr << t << " " << x << " " << y << " : " << 1 << endl;
			return dp[t][x][y];
		}
	}

	if(isOK(t, x, y + 1) && isOK(t, x - 1, y + 1) && isOK(t + 1, x - 1, y + 1)) {
		bool res = DFS(t + 1, x - 1, y + 1);
		if(res) {
			dp[t][x][y] = 1;
//cerr << t << " " << x << " " << y << " : " << 2 << endl;
			return dp[t][x][y];
		}
	}

	dp[t][x][y] = 0;
	return dp[t][x][y];
}

void print(const int t) {
	for(int i = 0; i < 3; i++) {
		for(int j = 0; j < n; ++j) {
			if(j + 2 * t < n)
				cout << bd[i][j + 2 * t];
			else
				cout << '.';
		}
		cout << endl;
	}
	cout << endl;
}

int main() {
	int t;
	cin >> t;
	while(t--) {
		cin >> n >> k;
		for(int i = 0; i < 3; i++) {
			cin >> bd[i];
			memset(dp[i], -1, sizeof(int) * (n + 5));
		}

		int x, y = 0;
		for(int i = 0; i < 3; ++i)
			if('s' == bd[i][0]) {
				x = i;
				break;
			}
		if(DFS(0, x, y))
			cout << "YES\n";
		else
			cout << "NO\n";
//for(int i = 0; i <= 3; i++)
//	print(i);
	}

	return 0;
}


#include <iostream>
#include <cstring>
using namespace std;

#define LOCAL

int n, k;
char bd[5][100];
int dp[100][5][110];

bool isOK(const int t, const int x, const int y) {
	if(x >= 0 && x < 3 && y >=0 && y < n) {
		if(y + 2 * t >= n)
			return true;
		else if('.' == bd[x][y + 2 * t])
			return true;
	}

	return false;
}

bool DFS(const int t, const int x, const int y) {
	if(-1 != dp[t][x][y])
		return dp[t][x][y];

	bool flag = true;
	for(int j = y + 1; j + 2 * t < n; j++) {
		if('.' != bd[x][j + 2 * t]) {
			flag = false;
			break;
		}
	}

	if(flag) {
		dp[t][x][y] = 1;
		return dp[t][x][y];
	}

	if(isOK(t, x, y + 1) && isOK(t + 1, x, y + 1)) {
		bool res = DFS(t + 1, x, y + 1);
		if(res) {
			dp[t][x][y] = 1;
#ifdef LOCAL
cerr << t << " " << x << " " << y << " : " << 0 << endl;
#endif
			return dp[t][x][y];
		}
	}

	if(isOK(t, x, y + 1) && isOK(t, x + 1, y + 1) && isOK(t + 1, x + 1, y + 1)) {
		bool res = DFS(t + 1, x + 1, y + 1);
		if(res) {
			dp[t][x][y] = 1;
#ifdef LOCAL
cerr << t << " " << x << " " << y << " : " << 1 << endl;
#endif
			return dp[t][x][y];
		}
	}

	if(isOK(t, x, y + 1) && isOK(t, x - 1, y + 1) && isOK(t + 1, x - 1, y + 1)) {
		bool res = DFS(t + 1, x - 1, y + 1);
		if(res) {
			dp[t][x][y] = 1;
#ifdef LOCAL
cerr << t << " " << x << " " << y << " : " << 2 << endl;
#endif
			return dp[t][x][y];
		}
	}

	dp[t][x][y] = 0;
	return dp[t][x][y];
}

void print(const int t) {
	for(int i = 0; i < 3; i++) {
		for(int j = 0; j < n; ++j) {
			if(j + 2 * t < n)
				cout << bd[i][j + 2 * t];
			else
				cout << '.';
		}
		cout << endl;
	}
	cout << endl;
}

int main() {
	int t;
	cin >> t;
	while(t--) {
		cin >> n >> k;
		for(int i = 0; i < 3; i++) {
			cin >> bd[i];
		}

		for(int t = 0; t < 60; t++) {
			for(int i = 0; i < 3; i++)
				memset(dp[t][i], -1, sizeof(int) * (n + 5));
		}

		int x, y = 0;
		for(int i = 0; i < 3; ++i) {
			if('s' == bd[i][0]) {
				x = i;
				break;
			}
		}

		if(DFS(0, x, y))
			cout << "YES\n";
		else
			cout << "NO\n";
#ifdef LOCAL
for(int i = 0; i <= 5; i++)
	print(i);
	}
#endif
	return 0;
}


#include <iostream>
#include <cstring>
using namespace std;

int n, k;
char bd[5][100];
int dp[100][5][110];

bool isOK(const int t, const int x, const int y) {
	if(x >= 0 && x < 3 && y >=0 && y < n) {
		if(y + 2 * t >= n)
			return true;
		else if('.' == bd[x][y + 2 * t])
			return true;
	}

	return false;
}

bool DFS(const int t, const int x, const int y) {
	if(-1 != dp[t][x][y])
		return dp[t][x][y];

	bool flag = true;
	for(int j = y + 1; j + 2 * t < n; j++) {
		if('.' != bd[x][j + 2 * t]) {
			flag = false;
			break;
		}
	}

	if(flag) {
		dp[t][x][y] = 1;
		return dp[t][x][y];
	}

	if(isOK(t + 1, x, y + 1)) {
		bool res = DFS(t + 1, x, y + 1);
		if(res) {
			dp[t][x][y] = 1;
//cerr << t << " " << x << " " << y << " : " << 0 << endl;
			return dp[t][x][y];
		}
	}

	if(isOK(t, x, y + 1) && isOK(t, x + 1, y + 1) && isOK(t + 1, x + 1, y + 1)) {
		bool res = DFS(t + 1, x + 1, y + 1);
		if(res) {
			dp[t][x][y] = 1;
//cerr << t << " " << x << " " << y << " : " << 1 << endl;
			return dp[t][x][y];
		}
	}

	if(isOK(t, x, y + 1) && isOK(t, x - 1, y + 1) && isOK(t + 1, x - 1, y + 1)) {
		bool res = DFS(t + 1, x - 1, y + 1);
		if(res) {
			dp[t][x][y] = 1;
//cerr << t << " " << x << " " << y << " : " << 2 << endl;
			return dp[t][x][y];
		}
	}

	dp[t][x][y] = 0;
	return dp[t][x][y];
}

void print(const int t) {
	for(int i = 0; i < 3; i++) {
		for(int j = 0; j < n; ++j) {
			if(j + 2 * t < n)
				cout << bd[i][j + 2 * t];
			else
				cout << '.';
		}
		cout << endl;
	}
	cout << endl;
}

int main() {
	int t;
	cin >> t;
	while(t--) {
		cin >> n >> k;
		for(int i = 0; i < 3; i++) {
			cin >> bd[i];
		}

		for(int t = 0; t < 60; t++) {
			for(int i = 0; i < 3; i++)
				memset(dp[t][i], -1, sizeof(int) * (n + 5));
		}

		int x, y = 0;
		for(int i = 0; i < 3; ++i) {
			if('s' == bd[i][0]) {
				x = i;
				break;
			}
		}

		if(DFS(0, x, y))
			cout << "YES\n";
		else
			cout << "NO\n";
//for(int i = 0; i <= 3; i++)
//	print(i);
	}

	return 0;
}