/*
    Author: TheHalfBloodPrince
    From  : JU(46), IIT(08)
    Date  : 23/07/2019
*/

#include<bits/stdc++.h>

using namespace std;

#define    flash           ios_base::sync_with_stdio(false);cin.tie(0);
#define    ff              first
#define    ss              second
#define    pb              push_back
#define    m_p             make_pair
#define    ret             return 0
#define    MAX(a,b)        max({a,b})
#define    MAX(a,b,c)      max({a,b,c})
#define    MAX(a,b,c,d)    max({a,b,c,d})
#define    MIN(a,b)        min({a,b})
#define    MIN(a,b,c)      min({a,b,c})
#define    MIN(a,b,c,d)    min({a,b,c,d})
#define    GCD(a,b)        __gcd(a,b)
#define    LCM(a,b)        (a*b)/GCD(a,b)
#define    MEM(a,b)        memset(a,b,sizeof a)
#define    SC(a)           scanf("%d",&a)
#define    SC2(a,b)        scanf("%d %d",&a,&b)
#define    SC3(a,b,c)      scanf("%d %d %d",&a,&b,&c)
#define    SC4(a,b,c,d)    scanf("%d %d %d %d",&a,&b,&c,&d)
#define    PCs(a)          printf("Case %d: ",a)
#define    WRITE(a)        freopen(a,"w",stdout)
#define    READ(a)         freopen(a,"r",stdin)
#define    LB(a,x)         (lower_bound(a.begin(),a.end(),x) - a.begin())
#define    UB(a,x)         (upper_bound(a.begin(),a.end(),x) - a.begin())
#define    PI              2.0*acos(0.0)
#define    MOD1            1000000007 // prime
#define    MOD2            1000000009 // prime
#define    MOD3            1000000021 // prime
#define    Base1           10000019
#define    Base2           10000079
#define    Base3           10000103
#define    MAX             1000007
typedef    pair<int,int> pii;
typedef    pair<int,pii> ppi;
typedef    pair<pii,int> pip;
typedef    long long int ll;
typedef    unsigned long long int ull;
typedef    pair<ll,ll> pll;
typedef    vector<int> VI;
typedef    vector<pii> Vii;
typedef    vector<VI> VVI; // 2D
//typedef    priority_queue<int> PQ; // MaxHeap
typedef    priority_queue<int,VI,greater<int> > PQ; // MinHeap
/*
inline int StringToInt(string a)
{
    int num;
    stringstream aw(a);
    aw>>num;
    return num;
}*/
/*
inline ll StringToLL(string a)
{
    ll num;
    stringstream aw(a);
    aw>>num;
    return num;
}*/
/*
inline int iPOW(int a,int e)
{
    int num = 1;
    while(e)
    {
        if(e%2)
        {
            num = num * a;
        }
        e/=2;
        a = a * a;
    }
    return num;
}
inline ll LPOW(ll a,ll e)
{
    ll num = 1;
    while(e)
    {
        if(e%2)
        {
            num = num * a;
        }
        e/=2;
        a = a * a;
    }
    return num;
}*/
/*
inline ll BigMod(ll a,ll e,ll mod)
{
    ll num = 1;
    while(e)
    {
        if(e%2)
        {
            a%=mod;
            num%=mod;
            num = num * a;
            num%=mod;
        }
        e/=2;
        a%=mod;
        a = a * a;
        a%=mod;
    }
    return num%mod;
}*/
/*inline ll modInverse(ll A,ll P)
{
    return BigMod(A,P-2,P);
}
ll fac[MAX];
inline void factorial(int n,int mod)
{
    fac[0] = 1;
    fac[1] = 1;
    for(int i=2;i<=MAX;i++) fac[i] = ( (fac[i-1]%mod)*i)%mod;
}
inline int nCr(int n,int r,int mod) // ncr with mod
{
    return ((fac[n] * modInverse(fac[r],mod)%mod)%mod * (modInverse(fac[n-r],mod)%mod) ) %mod;
}
*/
/*
bool isprime[MAX+1000];
int Primes[MAX],id; // for <=10^6
void sieve()
{
    Primes[0] = 2;
    id++;
    for(int i=4;i<=MAX+100;i+=2) isprime[i] = true; // is not a prime
    for(int i=3;i<=MAX+100;i+=2)
    {
        if(isprime[i]==false)
        {
            Primes[id++] = i;
            if(i+i<=MAX)
            for(int j=i+i;j<=100+MAX;j+=i)
                isprime[j] = true;
        }
    }
}*/
//int Dx[]  = {-1,0, 0,1};
//int Dy[]  = { 0,1,-1,0};
//int Dx8[] = {-1,-1,-1,0,1,1, 1, 0};
//int Dy8[] = {-1, 0, 1,1,1,0,-1,-1};
//int Kx[]  = {2,1,-1,-2,-2,-1, 1, 2};
//int Ky[]  = {1,2, 2, 1,-1,-2,-2,-1};
bool ok(vector<int>V,int k,int x)
{
    for(int y:V){
        int df = abs(x-y);
        if(df>k)return 0;
    }
    return 1;
}
int main ()
{
    flash;

    int q;cin >> q;
    while(q--)
    {
        int n;cin >> n;
        vector<int>V,V2;
        vector<pii> Ar;
        unordered_map<int,int>Map,Map2,Map3,Map4;
        for(int i=0;i<n;i++){
            int x,type;
            cin >> x >> type;
            V.pb(x);
            Map[x]++;
            if(type)
            Map4[x]++;
        }
        for(int i=0;i<n;i++) {
            if(Map3[V[i]]==0){
                Map3[V[i]]=1;
                Ar.pb({Map[V[i]],V[i]});
            }
        }
        sort(Ar.rbegin(),Ar.rend());
        int last=1e9;
        for(int i=0;i<Ar.size();i++){
            int x=Ar[i].ss;
            int f=Ar[i].ff;
            //cout<<"Element = "<<x<<endl;
            //cout<<"curr freq = "<<f<<" last taken freq = "<<last<<endl;
            if(!Map2[f]){
                    V2.pb(f);
                    Map2[f]=1;
                    last = f;
                    //cout<<"took = "<<f<<endl;
            }
            else{ // range 1 to f-1
                    if(last>1){
                        last--;
                        V2.pb(last);
                        Map2[last]=1;
                        //cout<<"took = "<<last<<endl;
                    }
            }
        }
        int ans=accumulate(V2.begin(),V2.end(),0);

        vector<pii>Ar2;
        for(int i=0;i<Ar.size();i++){
                int x = Ar[i].ss;
                Ar2.pb({Map4[x],x});
        }
        sort(Ar2.rbegin(),Ar2.rend());
        Map2.clear();
        last=1e9;
        V2.clear();
        for(int i=0;i<Ar2.size();i++){
            int x=Ar2[i].ss;
            int f=Ar2[i].ff;
            //cout<<"Element = "<<x<<endl;
            //cout<<"curr freq = "<<f<<" last taken freq = "<<last<<endl;
            if(!Map2[f]){
                    V2.pb(f);
                    Map2[f]=1;
                    last = f;
                    //cout<<"took = "<<f<<endl;
            }
            else{ // range 1 to f-1
                    if(last>1){
                        last--;
                        V2.pb(last);
                        Map2[last]=1;
                        //cout<<"took = "<<last<<endl;
                    }
            }
        }
        int ans2=accumulate(V2.begin(),V2.end(),0);
        cout<<ans<<" "<<ans2<<"\n";

    }
    return 0;
}


/*
    Author: TheHalfBloodPrince
    From  : JU(46), IIT(08)
    Date  : 23/07/2019
*/

#include<bits/stdc++.h>

using namespace std;

#define    flash           ios_base::sync_with_stdio(false);cin.tie(0);
#define    ff              first
#define    ss              second
#define    pb              push_back
#define    m_p             make_pair
#define    ret             return 0
#define    MAX(a,b)        max({a,b})
#define    MAX(a,b,c)      max({a,b,c})
#define    MAX(a,b,c,d)    max({a,b,c,d})
#define    MIN(a,b)        min({a,b})
#define    MIN(a,b,c)      min({a,b,c})
#define    MIN(a,b,c,d)    min({a,b,c,d})
#define    GCD(a,b)        __gcd(a,b)
#define    LCM(a,b)        (a*b)/GCD(a,b)
#define    MEM(a,b)        memset(a,b,sizeof a)
#define    SC(a)           scanf("%d",&a)
#define    SC2(a,b)        scanf("%d %d",&a,&b)
#define    SC3(a,b,c)      scanf("%d %d %d",&a,&b,&c)
#define    SC4(a,b,c,d)    scanf("%d %d %d %d",&a,&b,&c,&d)
#define    PCs(a)          printf("Case %d: ",a)
#define    WRITE(a)        freopen(a,"w",stdout)
#define    READ(a)         freopen(a,"r",stdin)
#define    LB(a,x)         (lower_bound(a.begin(),a.end(),x) - a.begin())
#define    UB(a,x)         (upper_bound(a.begin(),a.end(),x) - a.begin())
#define    PI              2.0*acos(0.0)
#define    MOD1            1000000007 // prime
#define    MOD2            1000000009 // prime
#define    MOD3            1000000021 // prime
#define    Base1           10000019
#define    Base2           10000079
#define    Base3           10000103
#define    MAX             1000007
typedef    pair<int,int> pii;
typedef    pair<int,pii> ppi;
typedef    pair<pii,int> pip;
typedef    long long int ll;
typedef    unsigned long long int ull;
typedef    pair<ll,ll> pll;
typedef    vector<int> VI;
typedef    vector<pii> Vii;
typedef    vector<VI> VVI; // 2D
//typedef    priority_queue<int> PQ; // MaxHeap
typedef    priority_queue<int,VI,greater<int> > PQ; // MinHeap
/*
inline int StringToInt(string a)
{
    int num;
    stringstream aw(a);
    aw>>num;
    return num;
}*/
/*
inline ll StringToLL(string a)
{
    ll num;
    stringstream aw(a);
    aw>>num;
    return num;
}*/
/*
inline int iPOW(int a,int e)
{
    int num = 1;
    while(e)
    {
        if(e%2)
        {
            num = num * a;
        }
        e/=2;
        a = a * a;
    }
    return num;
}
inline ll LPOW(ll a,ll e)
{
    ll num = 1;
    while(e)
    {
        if(e%2)
        {
            num = num * a;
        }
        e/=2;
        a = a * a;
    }
    return num;
}*/
/*
inline ll BigMod(ll a,ll e,ll mod)
{
    ll num = 1;
    while(e)
    {
        if(e%2)
        {
            a%=mod;
            num%=mod;
            num = num * a;
            num%=mod;
        }
        e/=2;
        a%=mod;
        a = a * a;
        a%=mod;
    }
    return num%mod;
}*/
/*inline ll modInverse(ll A,ll P)
{
    return BigMod(A,P-2,P);
}
ll fac[MAX];
inline void factorial(int n,int mod)
{
    fac[0] = 1;
    fac[1] = 1;
    for(int i=2;i<=MAX;i++) fac[i] = ( (fac[i-1]%mod)*i)%mod;
}
inline int nCr(int n,int r,int mod) // ncr with mod
{
    return ((fac[n] * modInverse(fac[r],mod)%mod)%mod * (modInverse(fac[n-r],mod)%mod) ) %mod;
}
*/
/*
bool isprime[MAX+1000];
int Primes[MAX],id; // for <=10^6
void sieve()
{
    Primes[0] = 2;
    id++;
    for(int i=4;i<=MAX+100;i+=2) isprime[i] = true; // is not a prime
    for(int i=3;i<=MAX+100;i+=2)
    {
        if(isprime[i]==false)
        {
            Primes[id++] = i;
            if(i+i<=MAX)
            for(int j=i+i;j<=100+MAX;j+=i)
                isprime[j] = true;
        }
    }
}*/
//int Dx[]  = {-1,0, 0,1};
//int Dy[]  = { 0,1,-1,0};
//int Dx8[] = {-1,-1,-1,0,1,1, 1, 0};
//int Dy8[] = {-1, 0, 1,1,1,0,-1,-1};
//int Kx[]  = {2,1,-1,-2,-2,-1, 1, 2};
//int Ky[]  = {1,2, 2, 1,-1,-2,-2,-1};
bool ok(vector<int>V,int k,int x)
{
    for(int y:V){
        int df = abs(x-y);
        if(df>k)return 0;
    }
    return 1;
}
int main ()
{
    flash;

    int q;cin >> q;
    while(q--)
    {
        int n;cin >> n;
        vector<int>V,V2;
        vector<pii> Ar;
        unordered_map<int,int>Map,Map2,Map3,Map4;
        for(int i=0;i<n;i++){
            int x,type;
            cin >> x >> type;
            V.pb(x);
            Map[x]++;
            if(type)
            Map4[x]++;
        }
        for(int i=0;i<n;i++) {
            if(Map3[V[i]]==0){
                Map3[V[i]]=1;
                Ar.pb({Map[V[i]],V[i]});
            }
        }
        sort(Ar.rbegin(),Ar.rend());
        int last=1e9;
        for(int i=0;i<Ar.size();i++){
            int x=Ar[i].ss;
            int f=Ar[i].ff;
            //cout<<"Element = "<<x<<endl;
            //cout<<"curr freq = "<<f<<" last taken freq = "<<last<<endl;
            if(!Map2[f]){
                    V2.pb(f);
                    Map2[f]=1;
                    last = f;
                    //cout<<"took = "<<f<<endl;
            }
            else{ // range 1 to f-1
                    if(last>1){
                        last--;
                        V2.pb(last);
                        Map2[last]=1;
                        //cout<<"took = "<<last<<endl;
                    }
            }
        }
        int ans=accumulate(V2.begin(),V2.end(),0);

        vector<pii>Ar2;
        for(int i=0;i<Ar.size();i++){
                int x = Ar[i].ss;
                Ar2.pb({Map4[x],x});
        }
        sort(Ar2.rbegin(),Ar2.rend());
        Map2.clear();
        V2.clear();

        last=1e9;
        for(int i=0;i<Ar2.size();i++){
            int x=Ar2[i].ss;
            int f=Ar2[i].ff;
            //cout<<"Element = "<<x<<endl;
            //cout<<"curr freq = "<<f<<" last taken freq = "<<last<<endl;
            if(!Map2[f]){
                    V2.pb(f);
                    Map2[f]=1;
                    last = f;
                    //cout<<"took = "<<f<<endl;
            }
            else{ // range 1 to f-1
                    int zer = Map[x]-Map4[x];
                    //cout<<"zero = "<<zer<<endl;
                    while(Map2[zer+f]&&zer>0){
                        zer--;
                    }
                    if(Map2[zer+f]==0&&zer){
                        Map2[zer+f]=1;
                        V2.pb(f);
                        //cout<<"took = "<<f<<endl;
                    }
                    else if(last>1){
                        last--;
                        V2.pb(last);
                        Map2[last]=1;
                        //cout<<"took = "<<last<<endl;
                    }
            }
        }
        int ans2=accumulate(V2.begin(),V2.end(),0);
        cout<<ans<<" "<<ans2<<"\n";

    }
    return 0;
}


/*
    Author: TheHalfBloodPrince
    From  : JU(46), IIT(08)
    Date  : 23/07/2019
*/

#include<bits/stdc++.h>

using namespace std;

#define    flash           ios_base::sync_with_stdio(false);cin.tie(0);
#define    ff              first
#define    ss              second
#define    pb              push_back
#define    m_p             make_pair
#define    ret             return 0
#define    MAX(a,b)        max({a,b})
#define    MAX(a,b,c)      max({a,b,c})
#define    MAX(a,b,c,d)    max({a,b,c,d})
#define    MIN(a,b)        min({a,b})
#define    MIN(a,b,c)      min({a,b,c})
#define    MIN(a,b,c,d)    min({a,b,c,d})
#define    GCD(a,b)        __gcd(a,b)
#define    LCM(a,b)        (a*b)/GCD(a,b)
#define    MEM(a,b)        memset(a,b,sizeof a)
#define    SC(a)           scanf("%d",&a)
#define    SC2(a,b)        scanf("%d %d",&a,&b)
#define    SC3(a,b,c)      scanf("%d %d %d",&a,&b,&c)
#define    SC4(a,b,c,d)    scanf("%d %d %d %d",&a,&b,&c,&d)
#define    PCs(a)          printf("Case %d: ",a)
#define    WRITE(a)        freopen(a,"w",stdout)
#define    READ(a)         freopen(a,"r",stdin)
#define    LB(a,x)         (lower_bound(a.begin(),a.end(),x) - a.begin())
#define    UB(a,x)         (upper_bound(a.begin(),a.end(),x) - a.begin())
#define    PI              2.0*acos(0.0)
#define    MOD1            1000000007 // prime
#define    MOD2            1000000009 // prime
#define    MOD3            1000000021 // prime
#define    Base1           10000019
#define    Base2           10000079
#define    Base3           10000103
#define    MAX             1000007
typedef    pair<int,int> pii;
typedef    pair<int,pii> ppi;
typedef    pair<pii,int> pip;
typedef    long long int ll;
typedef    unsigned long long int ull;
typedef    pair<ll,ll> pll;
typedef    vector<int> VI;
typedef    vector<pii> Vii;
typedef    vector<VI> VVI; // 2D
//typedef    priority_queue<int> PQ; // MaxHeap
typedef    priority_queue<int,VI,greater<int> > PQ; // MinHeap
/*
inline int StringToInt(string a)
{
    int num;
    stringstream aw(a);
    aw>>num;
    return num;
}*/
/*
inline ll StringToLL(string a)
{
    ll num;
    stringstream aw(a);
    aw>>num;
    return num;
}*/
/*
inline int iPOW(int a,int e)
{
    int num = 1;
    while(e)
    {
        if(e%2)
        {
            num = num * a;
        }
        e/=2;
        a = a * a;
    }
    return num;
}
inline ll LPOW(ll a,ll e)
{
    ll num = 1;
    while(e)
    {
        if(e%2)
        {
            num = num * a;
        }
        e/=2;
        a = a * a;
    }
    return num;
}*/
/*
inline ll BigMod(ll a,ll e,ll mod)
{
    ll num = 1;
    while(e)
    {
        if(e%2)
        {
            a%=mod;
            num%=mod;
            num = num * a;
            num%=mod;
        }
        e/=2;
        a%=mod;
        a = a * a;
        a%=mod;
    }
    return num%mod;
}*/
/*inline ll modInverse(ll A,ll P)
{
    return BigMod(A,P-2,P);
}
ll fac[MAX];
inline void factorial(int n,int mod)
{
    fac[0] = 1;
    fac[1] = 1;
    for(int i=2;i<=MAX;i++) fac[i] = ( (fac[i-1]%mod)*i)%mod;
}
inline int nCr(int n,int r,int mod) // ncr with mod
{
    return ((fac[n] * modInverse(fac[r],mod)%mod)%mod * (modInverse(fac[n-r],mod)%mod) ) %mod;
}
*/
/*
bool isprime[MAX+1000];
int Primes[MAX],id; // for <=10^6
void sieve()
{
    Primes[0] = 2;
    id++;
    for(int i=4;i<=MAX+100;i+=2) isprime[i] = true; // is not a prime
    for(int i=3;i<=MAX+100;i+=2)
    {
        if(isprime[i]==false)
        {
            Primes[id++] = i;
            if(i+i<=MAX)
            for(int j=i+i;j<=100+MAX;j+=i)
                isprime[j] = true;
        }
    }
}*/
//int Dx[]  = {-1,0, 0,1};
//int Dy[]  = { 0,1,-1,0};
//int Dx8[] = {-1,-1,-1,0,1,1, 1, 0};
//int Dy8[] = {-1, 0, 1,1,1,0,-1,-1};
//int Kx[]  = {2,1,-1,-2,-2,-1, 1, 2};
//int Ky[]  = {1,2, 2, 1,-1,-2,-2,-1};
bool ok(vector<int>V,int k,int x)
{
    for(int y:V){
        int df = abs(x-y);
        if(df>k)return 0;
    }
    return 1;
}
int main ()
{
    flash;

    int q;cin >> q;
    while(q--)
    {
        int n;cin >> n;
        vector<int>V,V2;
        vector<pii> Ar;
        unordered_map<int,int>Map,Map2,Map3,Map4;
        for(int i=0;i<n;i++){
            int x,type;
            cin >> x >> type;
            V.pb(x);
            Map[x]++;
            if(type)
            Map4[x]++;
        }
        for(int i=0;i<n;i++) {
            if(Map3[V[i]]==0){
                Map3[V[i]]=1;
                Ar.pb({Map[V[i]],V[i]});
            }
        }
        sort(Ar.rbegin(),Ar.rend());
        int last=1e9;
        for(int i=0;i<Ar.size();i++){
            int x=Ar[i].ss;
            int f=Ar[i].ff;
            //cout<<"Element = "<<x<<endl;
            //cout<<"curr freq = "<<f<<" last taken freq = "<<last<<endl;
            if(!Map2[f]){
                    V2.pb(f);
                    Map2[f]=1;
                    last = f;
                    //cout<<"took = "<<f<<endl;
            }
            else{ // range 1 to f-1
                    if(last>1){
                        last--;
                        V2.pb(last);
                        Map2[last]=1;
                        //cout<<"took = "<<last<<endl;
                    }
            }
        }
        int ans=accumulate(V2.begin(),V2.end(),0);

        vector<pii>Ar2;
        for(int i=0;i<Ar.size();i++){
                int x = Ar[i].ss;
                Ar2.pb({Map4[x],x});
        }
        sort(Ar2.rbegin(),Ar2.rend());
        Map2.clear();
        V2.clear();

        last=1e9;
        for(int i=0;i<Ar2.size();i++){
            int x=Ar2[i].ss;
            int f=Ar2[i].ff;
            int zer = Map[x]-Map4[x];
            int tot=f+zer;
            while(Map2[tot]&&tot>0){
                    tot--;
            }
            if(Map2[tot]==0){
                int haha=f;
                if(tot<f)haha=tot;
                V2.pb(haha);
                Map2[tot]=1;
            }
        }
        int ans2=accumulate(V2.begin(),V2.end(),0);
        cout<<ans<<" "<<ans2<<"\n";

    }
    return 0;
}


/*
    Author: TheHalfBloodPrince
    From  : JU(46), IIT(08)
    Date  : 23/07/2019
*/

#include<bits/stdc++.h>

using namespace std;

#define    flash           ios_base::sync_with_stdio(false);cin.tie(0);
#define    ff              first
#define    ss              second
#define    pb              push_back
#define    m_p             make_pair
#define    ret             return 0
#define    MAX(a,b)        max({a,b})
#define    MAX(a,b,c)      max({a,b,c})
#define    MAX(a,b,c,d)    max({a,b,c,d})
#define    MIN(a,b)        min({a,b})
#define    MIN(a,b,c)      min({a,b,c})
#define    MIN(a,b,c,d)    min({a,b,c,d})
#define    GCD(a,b)        __gcd(a,b)
#define    LCM(a,b)        (a*b)/GCD(a,b)
#define    MEM(a,b)        memset(a,b,sizeof a)
#define    SC(a)           scanf("%d",&a)
#define    SC2(a,b)        scanf("%d %d",&a,&b)
#define    SC3(a,b,c)      scanf("%d %d %d",&a,&b,&c)
#define    SC4(a,b,c,d)    scanf("%d %d %d %d",&a,&b,&c,&d)
#define    PCs(a)          printf("Case %d: ",a)
#define    WRITE(a)        freopen(a,"w",stdout)
#define    READ(a)         freopen(a,"r",stdin)
#define    LB(a,x)         (lower_bound(a.begin(),a.end(),x) - a.begin())
#define    UB(a,x)         (upper_bound(a.begin(),a.end(),x) - a.begin())
#define    PI              2.0*acos(0.0)
#define    MOD1            1000000007 // prime
#define    MOD2            1000000009 // prime
#define    MOD3            1000000021 // prime
#define    Base1           10000019
#define    Base2           10000079
#define    Base3           10000103
#define    MAX             1000007
typedef    pair<int,int> pii;
typedef    pair<int,pii> ppi;
typedef    pair<pii,int> pip;
typedef    long long int ll;
typedef    unsigned long long int ull;
typedef    pair<ll,ll> pll;
typedef    vector<int> VI;
typedef    vector<pii> Vii;
typedef    vector<VI> VVI; // 2D
//typedef    priority_queue<int> PQ; // MaxHeap
typedef    priority_queue<int,VI,greater<int> > PQ; // MinHeap
/*
inline int StringToInt(string a)
{
    int num;
    stringstream aw(a);
    aw>>num;
    return num;
}*/
/*
inline ll StringToLL(string a)
{
    ll num;
    stringstream aw(a);
    aw>>num;
    return num;
}*/
/*
inline int iPOW(int a,int e)
{
    int num = 1;
    while(e)
    {
        if(e%2)
        {
            num = num * a;
        }
        e/=2;
        a = a * a;
    }
    return num;
}
inline ll LPOW(ll a,ll e)
{
    ll num = 1;
    while(e)
    {
        if(e%2)
        {
            num = num * a;
        }
        e/=2;
        a = a * a;
    }
    return num;
}*/
/*
inline ll BigMod(ll a,ll e,ll mod)
{
    ll num = 1;
    while(e)
    {
        if(e%2)
        {
            a%=mod;
            num%=mod;
            num = num * a;
            num%=mod;
        }
        e/=2;
        a%=mod;
        a = a * a;
        a%=mod;
    }
    return num%mod;
}*/
/*inline ll modInverse(ll A,ll P)
{
    return BigMod(A,P-2,P);
}
ll fac[MAX];
inline void factorial(int n,int mod)
{
    fac[0] = 1;
    fac[1] = 1;
    for(int i=2;i<=MAX;i++) fac[i] = ( (fac[i-1]%mod)*i)%mod;
}
inline int nCr(int n,int r,int mod) // ncr with mod
{
    return ((fac[n] * modInverse(fac[r],mod)%mod)%mod * (modInverse(fac[n-r],mod)%mod) ) %mod;
}
*/
/*
bool isprime[MAX+1000];
int Primes[MAX],id; // for <=10^6
void sieve()
{
    Primes[0] = 2;
    id++;
    for(int i=4;i<=MAX+100;i+=2) isprime[i] = true; // is not a prime
    for(int i=3;i<=MAX+100;i+=2)
    {
        if(isprime[i]==false)
        {
            Primes[id++] = i;
            if(i+i<=MAX)
            for(int j=i+i;j<=100+MAX;j+=i)
                isprime[j] = true;
        }
    }
}*/
//int Dx[]  = {-1,0, 0,1};
//int Dy[]  = { 0,1,-1,0};
//int Dx8[] = {-1,-1,-1,0,1,1, 1, 0};
//int Dy8[] = {-1, 0, 1,1,1,0,-1,-1};
//int Kx[]  = {2,1,-1,-2,-2,-1, 1, 2};
//int Ky[]  = {1,2, 2, 1,-1,-2,-2,-1};
bool ok(vector<int>V,int k,int x)
{
    for(int y:V){
        int df = abs(x-y);
        if(df>k)return 0;
    }
    return 1;
}
int main ()
{
    flash;

    int q;cin >> q;
    while(q--)
    {
        int n;cin >> n;
        vector<int>V,V2;
        vector<pii> Ar;
        unordered_map<int,int>Map,Map2,Map3,Map4;
        for(int i=0;i<n;i++){
            int x,type;
            cin >> x >> type;
            V.pb(x);
            Map[x]++;
            if(type)
            Map4[x]++;
        }
        for(int i=0;i<n;i++) {
            if(Map3[V[i]]==0){
                Map3[V[i]]=1;
                Ar.pb({Map[V[i]],V[i]});
            }
        }
        sort(Ar.rbegin(),Ar.rend());
        int last=1e9;
        for(int i=0;i<Ar.size();i++){
            int x=Ar[i].ss;
            int f=Ar[i].ff;
            //cout<<"Element = "<<x<<endl;
            //cout<<"curr freq = "<<f<<" last taken freq = "<<last<<endl;
            if(!Map2[f]){
                    V2.pb(f);
                    Map2[f]=1;
                    last = f;
                    //cout<<"took = "<<f<<endl;
            }
            else{ // range 1 to f-1
                    if(last>1){
                        last--;
                        V2.pb(last);
                        Map2[last]=1;
                        //cout<<"took = "<<last<<endl;
                    }
            }
        }
        int ans=accumulate(V2.begin(),V2.end(),0);

        vector<pii>Ar2;
        for(int i=0;i<Ar.size();i++){
                int x = Ar[i].ss;
                Ar2.pb({Map4[x],x});
        }
        sort(Ar2.rbegin(),Ar2.rend());
        Map2.clear();
        V2.clear();

        last=1e9;
        for(int i=0;i<Ar2.size();i++){
            int x=Ar2[i].ss;
            int f=Ar2[i].ff;
            int zer = Map[x]-Map4[x];
            //cout<<"Element = "<<x<<endl;
            //cout<<"curr freq = "<<f<<" last taken freq = "<<last<<endl;
            if(!Map2[f+zer]){
                    V2.pb(f);
                    Map2[f+zer]=1;
                    last = f+zer;
                    //cout<<"took = "<<f<<endl;
            }
            else{ // range 1 to f-1
                    if(zer+f>=last-1 && last>1)
                    {
                        last--;
                        Map2[last]=1;
                        V2.push_back(last);
                    }
                    else if(last>1){
                        last--;
                        V2.pb(last);
                        Map2[last]=1;
                    }
            }
        }
        int ans2=accumulate(V2.begin(),V2.end(),0);
        cout<<ans<<" "<<ans2<<"\n";

    }
    return 0;
}


#include<bits/stdc++.h>
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
const int big=0x7fffffff;
using namespace std;
inline void read(int &x)
{
    x=0;char ch=getchar();int pd=1;
    while(ch<'0'||ch>'9'){if(ch=='-')pd=-pd;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    x*=pd;
}
inline void write(const int &x)
{
    char ggg[10001];int s=0;int tmp=x;
    if(tmp==0){putchar('0');return;}
    if(tmp<0){tmp=-tmp;putchar('-');}
    while(tmp>0){ggg[s++]=tmp%10+'0';tmp/=10;}
    while(s>0){putchar(ggg[--s]);}
}
const int N=2e5+10;
int n;
int cnt[N],mp[N][2];
struct dd
{
	int x,y;

}f[200010];

struct d
{
	int x,y;

	inline bool operator < (const d &nt )const
	{
		return y==nt.y?x<nt.x:y>nt.y;
	}
};

inline bool cmp(const dd &x,const dd &y)
{
	return x.x==y.x?x.y<y.y:x.x<y.x;
}
priority_queue<d>q;
int main()
{
	int qq;
	read(qq);
	while(qq--)
	{
		read(n);
		for(register int i=1;i<=n;++i)
		{
			cnt[i]=mp[i][0]=mp[i][1]=0;
		}
		int mx=0;
		int cc=0;
		for(register int i=1;i<=n;++i)
		{
			int xx,aa;
			read(xx);
			read(aa);
			cnt[xx]++;
			mp[xx][aa]++;
			mx=max(mx,xx);
		}
		int mxx=0;
		for(register int i=1;i<=mx;++i)
		{
			if(cnt[i])
			{
				f[++cc]=(dd){cnt[i],cnt[i]-mp[i][1]};
				mxx=max(mxx,cnt[i]);
			}
		}
		sort(f+1,f+cc+1,cmp);
		int aa=0,ans=0;
		for(register int j=cc,i=mxx;i>=1;--i)
		{
			while(f[j].x>=i&&j)
			{
				q.push((d){f[j].x,f[j].y});
				--j;
			}
			if(!q.empty())
			{
				d now=q.top();
				q.pop();
				if(i>now.x-now.y)
				{
					aa+=i-now.x+now.y;
				}
				ans+=i;
			}
		}
		while(!q.empty())q.pop();
		write(ans);
		putchar(' ');
		write(ans-aa);
		puts("");
	}
}


#include<bits/stdc++.h>
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
const int big=0x7fffffff;
using namespace std;
inline void read(int &x)
{
    x=0;char ch=getchar();int pd=1;
    while(ch<'0'||ch>'9'){if(ch=='-')pd=-pd;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    x*=pd;
}
inline void write(const int &x)
{
    char ggg[10001];int s=0;int tmp=x;
    if(tmp==0){putchar('0');return;}
    if(tmp<0){tmp=-tmp;putchar('-');}
    while(tmp>0){ggg[s++]=tmp%10+'0';tmp/=10;}
    while(s>0){putchar(ggg[--s]);}
}
const int N=2e5+10;
int n;
int cnt[N],mp[N][2];
struct dd
{
	int x,y;

}f[200010];

struct d
{
	int x,y;

	inline bool operator < (const d &nt )const
	{
		return y>nt.y;
	}
};

inline bool cmp(const dd &x,const dd &y)
{
	return x.x==y.x?x.y<y.y:x.x<y.x;
}
priority_queue<d>q;
int main()
{
	int qq;
	read(qq);
	while(qq--)
	{
		read(n);
		for(register int i=1;i<=n;++i)
		{
			cnt[i]=mp[i][0]=mp[i][1]=0;
		}
		int mx=0;
		int cc=0;
		for(register int i=1;i<=n;++i)
		{
			int xx,aa;
			read(xx);
			read(aa);
			cnt[xx]++;
			mp[xx][aa]++;
			mx=max(mx,xx);
		}
		int mxx=0;
		for(register int i=1;i<=mx;++i)
		{
			if(cnt[i])
			{
				f[++cc]=(dd){cnt[i],cnt[i]-mp[i][1]};
				mxx=max(mxx,cnt[i]);
			}
		}
		sort(f+1,f+cc+1,cmp);
		int aa=0,ans=0;
		for(register int j=cc,i=mxx;i>=1;--i)
		{
			while(f[j].x>=i&&j)
			{
				q.push((d){f[j].x,f[j].y});
				--j;
			}
			if(!q.empty())
			{
				d now=q.top();
				q.pop();
				if(i>now.x-now.y)
				{
					aa+=i-now.x+now.y;
				}
				ans+=i;
			}
		}
		while(!q.empty())q.pop();
		write(ans);
		putchar(' ');
		write(ans-aa);
		puts("");
	}
}


#include<bits/stdc++.h>
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
const int big=0x7fffffff;
using namespace std;
inline void read(int &x)
{
    x=0;char ch=getchar();int pd=1;
    while(ch<'0'||ch>'9'){if(ch=='-')pd=-pd;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    x*=pd;
}
inline void write(const int &x)
{
    char ggg[10001];int s=0;int tmp=x;
    if(tmp==0){putchar('0');return;}
    if(tmp<0){tmp=-tmp;putchar('-');}
    while(tmp>0){ggg[s++]=tmp%10+'0';tmp/=10;}
    while(s>0){putchar(ggg[--s]);}
}
const int N=2e5+10;
int n;
int cnt[N],mp[N][2];
struct dd
{
	int x,y;

}f[200010];

struct d
{
	int x,y;

	inline bool operator < (const d &nt )const
	{
		return y>nt.y;
	}
};

inline bool cmp(const dd &x,const dd &y)
{
	return x.x==y.x?x.y<y.y:x.x<y.x;
}

int main()
{
	int qq;
	read(qq);
	while(qq--)
	{
		priority_queue<d >q;
		read(n);
		for(register int i=1;i<=n;++i)
		{
			cnt[i]=mp[i][0]=mp[i][1]=0;
		}
		int mx=0;
		int cc=0;
		for(register int i=1;i<=n;++i)
		{
			int xx,aa;
			read(xx);
			read(aa);
			cnt[xx]++;
			mp[xx][aa]++;
			mx=max(mx,xx);
		}
		int mxx=0;
		for(register int i=1;i<=mx;++i)
		{
			if(cnt[i])
			{
				f[++cc]=(dd){cnt[i],cnt[i]-mp[i][1]};
				mxx=max(mxx,cnt[i]);
			}
		}
		sort(f+1,f+cc+1,cmp);
		int aa=0,ans=0;
		for(register int j=cc,i=mxx;i>=1;--i)
		{
			while(f[j].x>=i)
			{
				q.push((d){f[j].x,f[j].y});
				--j;
			}
			if(!q.empty())
			{
				d now=q.top();
				q.pop();
				if(i>now.x-now.y)
				{
					aa+=i-now.x+now.y;
				}
				ans+=i;
			}
		}
		write(ans);
		putchar(' ');
		write(ans-aa);
		puts("");
	}
}


#include<bits/stdc++.h>
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
const int big=0x7fffffff;
using namespace std;
inline void read(int &x)
{
    x=0;char ch=getchar();int pd=1;
    while(ch<'0'||ch>'9'){if(ch=='-')pd=-pd;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    x*=pd;
}
inline void write(const int &x)
{
    char ggg[10001];int s=0;int tmp=x;
    if(tmp==0){putchar('0');return;}
    if(tmp<0){tmp=-tmp;putchar('-');}
    while(tmp>0){ggg[s++]=tmp%10+'0';tmp/=10;}
    while(s>0){putchar(ggg[--s]);}
}
const int N=2e5+10;
int n;
int cnt[N],mp[N][2];
struct dd
{
	int x,y;

}f[200010];

struct d
{
	int x,y;

	inline bool operator < (const d &nt )const
	{
		return y==nt.y?x>nt.x:y>nt.y;
	}
};

inline bool cmp(const dd &x,const dd &y)
{
	return x.x==y.x?x.y<y.y:x.x<y.x;
}
priority_queue<d>q;
int main()
{
	int qq;
	read(qq);
	while(qq--)
	{
		read(n);
		for(register int i=1;i<=n;++i)
		{
			cnt[i]=mp[i][0]=mp[i][1]=0;
		}
		int mx=0;
		int cc=0;
		for(register int i=1;i<=n;++i)
		{
			int xx,aa;
			read(xx);
			read(aa);
			cnt[xx]++;
			mp[xx][aa]++;
			mx=max(mx,xx);
		}
		int mxx=0;
		for(register int i=1;i<=mx;++i)
		{
			if(cnt[i])
			{
				f[++cc]=(dd){cnt[i],cnt[i]-mp[i][1]};
				mxx=max(mxx,cnt[i]);
			}
		}
		sort(f+1,f+cc+1,cmp);
		int aa=0,ans=0;
		for(register int j=cc,i=mxx;i>=1;--i)
		{
			while(f[j].x>=i&&j)
			{
				q.push((d){f[j].x,f[j].y});
				--j;
			}
			if(!q.empty())
			{
				d now=q.top();
				q.pop();
				if(i>now.x-now.y)
				{
					aa+=i-now.x+now.y;
				}
				ans+=i;
			}
		}
		while(!q.empty())q.pop();
		write(ans);
		putchar(' ');
		write(ans-aa);
		puts("");
	}
}


#include<bits/stdc++.h>
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
const int big=0x7fffffff;
using namespace std;
inline void read(int &x)
{
    x=0;char ch=getchar();int pd=1;
    while(ch<'0'||ch>'9'){if(ch=='-')pd=-pd;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    x*=pd;
}
inline void write(const int &x)
{
    char ggg[10001];int s=0;int tmp=x;
    if(tmp==0){putchar('0');return;}
    if(tmp<0){tmp=-tmp;putchar('-');}
    while(tmp>0){ggg[s++]=tmp%10+'0';tmp/=10;}
    while(s>0){putchar(ggg[--s]);}
}
const int N=2e5+10;
int n;
int cnt[N],mp[N][2];
struct dd
{
	int x,y;

}f[200010];

struct d
{
	int x,y;

	inline bool operator < (const d &nt )const
	{
		return x-y<nt.x-nt.y;
	}
};

inline bool cmp(const dd &x,const dd &y)
{
	return x.x==y.x?x.y>y.y:x.x<y.x;
}
priority_queue<d>q;
int main()
{
	int qq;
	read(qq);
	while(qq--)
	{
		read(n);
		for(register int i=1;i<=n;++i)
		{
			cnt[i]=mp[i][0]=mp[i][1]=0;
		}
		int mx=0;
		int cc=0;
		for(register int i=1;i<=n;++i)
		{
			int xx,aa;
			read(xx);
			read(aa);
			cnt[xx]++;
			mp[xx][aa]++;
			mx=max(mx,xx);
		}
		int mxx=0;
		for(register int i=1;i<=mx;++i)
		{
			if(cnt[i])
			{
				f[++cc]=(dd){cnt[i],cnt[i]-mp[i][1]};
				mxx=max(mxx,cnt[i]);
			}
		}
		sort(f+1,f+cc+1,cmp);
		int aa=0,ans=0;
		for(register int j=cc,i=mxx;i>=1;--i)
		{
			while(f[j].x>=i&&j)
			{
				q.push((d){f[j].x,f[j].y});
				--j;
			}
			if(!q.empty())
			{
				d now=q.top();
				q.pop();
				if(i>now.x-now.y)
				{
					aa+=i-now.x+now.y;
				}
				ans+=i;
			}
		}
		while(!q.empty())q.pop();
		write(ans);
		putchar(' ');
		write(ans-aa);
		puts("");
	}
}


#pragma comment(linker, "/STACK:66777216")

#define _USE_MATH_DEFINES

#include <iostream>
#include <vector>
#include <math.h>
#include <algorithm>
#include <unordered_set>
#include <unordered_map>
#include <map>
#include <set>
#include <bitset>
#include <ctime>
#include <queue>
#include <deque>
#include <iomanip>
#include <functional>
#include <random>
#include <fstream>
#include <ctype.h>

using namespace std;

typedef uniform_int_distribution<> uid;
typedef mt19937 rnd_t;

typedef long long ll;

// need define ONLINE_JUDGE before submit
#ifdef ONLINE_JUDGE
typedef __int128_t sll;
#else
typedef ll sll;
#endif

typedef pair<int, int> ii;

typedef vector<int> vi;
typedef vector<size_t> vsz;

typedef vector<ll> vll;
typedef vector<vll> vvll;

typedef vector<ii> vii;
typedef vector<vii> vvii;

typedef vector<vi> vvi;
typedef vvi graph_t;

typedef vector<bool> vb;
typedef vector<vb> vvb;

const char SPACE = ' ', ENDL = '\n';

const int BASE = (int)1e9 + 7;
const int MODULO = BASE; // 1e9 + 31; //998244353

typedef ll mod_t;

///////////////////////////////////////////////////////////////////

int ri() {
	int v;
	cin >> v;
	return v;
}

ll rll() {
	ll v;
	cin >> v;
	return v;
}

string rs() {
	string s;
	cin >> s;
	return s;
}

vi rvi(int n) {
	vi a(n);
	for (int i = 0; i < n; ++i) cin >> a[i];
	return a;
}

void read_graph(int n, int edges, graph_t & graph, bool oriented = false) {
	graph.assign(n, vi());
	for (int e = 0; e < edges; ++e) {
		int from = ri() - 1;
		int to = ri() - 1;
		graph[from].push_back(to);
		if (!oriented) graph[to].push_back(from);
	}
}

bool yn(bool result) {
	cout << (result ? "YES" : "NO") << ENDL;
	return result;
}

//////////////////////////////////////////////////////////////////

int get_bit(int mask, int bit) {
	return (mask >> bit) & 1;
}

//////////////////////////////////////////////////////////////////

// taken from https://codeforces.com/blog/entry/76149?#comment-606512

//template<class... args>
//auto create(size_t n, args&&... args) {
//	if (constexpr(sizeof...(args) == 1)) {
//		return vector(n, args...);
//	}
//	else
//	{
//		return vector(n, create(args...));
//	}
//}

//////////////////////////////////////////////////////////////////

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

#ifndef ONLINE_JUDGE
	FILE * tmp_in;
	freopen_s(&tmp_in, "input.txt", "r", stdin);

	FILE * tmp_out;
	freopen_s(&tmp_out, "output.txt", "w", stdout);
#endif

	int local_tests =
#ifdef ONLINE_JUDGE
		1;
#else
		ri();
#endif

	return local_tests;
}

///////////////////////////////////////////////////////////////////

struct DSU {
	vector<size_t> parents;
	vector<size_t> ranks;
	vi is_cycles;

	DSU(vi& degrees) {
		resize(degrees);
	}

	void resize(vi& degrees) {
		size_t n = degrees.size();

		parents.resize(n);
		for (size_t v = 0; v < n; ++v) {
			parents[v] = v;
		}

		ranks.resize(n, 1);

		is_cycles.resize(n, true);
		for (size_t v = 0; v < n; ++v) {
			is_cycles[v] = (2 == degrees[v]);
		}
	}

	size_t get(size_t v) {
		size_t parent = parents[v];
		if (parent == v) return v;

		return parents[v] = get(parent);
	}

	bool merge(size_t f, size_t t) {
		size_t a = get(f);
		size_t b = get(t);

		if (a == b) return false;

		if (ranks[a] < ranks[b]) {
			swap(a, b);
		}

		parents[b] = a;
		if (ranks[a] == ranks[b]) ++ranks[a];

		is_cycles[a] &= is_cycles[b];

		return true;
	}

	bool connected(size_t f, size_t t) {
		return get(f) == get(t);
	}

	bool is_root(size_t v) {
		return get(v) == v;
	}

	bool is_cycle(size_t v){
		return is_cycles[v];
	}
};

/*
tag data structures
tag priority queue
tag multitest
*/

void solve_test() {
	int tests = ri();
	while (tests-- > 0) {
		int n = ri();
		vii a(n);

		for (int i = 0; i < n; ++i) {
			a[i].first = ri() - 1;
			a[i].second = ri();
		}

		vi cnts(n, 0);
		vi zeros(n, 0);

		for (ii& candy : a) {
			cnts[candy.first]++;
			zeros[candy.first] += 1 - candy.second;
		}

		vvi zeros_by_cnts(n + 1, vi(0));
		for (int type = 0; type < n; ++type) {
			if (cnts[type] > 0) {
				zeros_by_cnts[cnts[type]].push_back(zeros[type]);
			}
		}

		priority_queue<int, vector<int>, greater<int>> waiting;

		ll total = 0;
		ll total_zeros = 0;

		for (int cnt = n; cnt > 0; --cnt) {
			for (int zero : zeros_by_cnts[cnt]) {
				waiting.push(zero + (n - cnt));
			}

			if (waiting.size() > 0) {
				int zero = max(0, waiting.top() - (n - cnt));
				waiting.pop();

				total += cnt;
				total_zeros += zero;
			}
		}

        // v4

		cout << total;
		cout << ENDL << (ll)(total - total_zeros);
		cout << ENDL;
	}
}

int main() {
	int local_tests = init_input();

	for (int local_test = 0; local_test < local_tests; ++local_test) {
		solve_test();
	}

	return 0;
}


#pragma comment(linker, "/STACK:66777216")

#define _USE_MATH_DEFINES

#include <iostream>
#include <vector>
#include <math.h>
#include <algorithm>
#include <unordered_set>
#include <unordered_map>
#include <map>
#include <set>
#include <bitset>
#include <ctime>
#include <queue>
#include <deque>
#include <iomanip>
#include <functional>
#include <random>
#include <fstream>
#include <ctype.h>

using namespace std;

typedef uniform_int_distribution<> uid;
typedef mt19937 rnd_t;

typedef long long ll;

// need define ONLINE_JUDGE before submit
#ifdef ONLINE_JUDGE
typedef __int128_t sll;
#else
typedef ll sll;
#endif

typedef pair<int, int> ii;

typedef vector<int> vi;
typedef vector<size_t> vsz;

typedef vector<ll> vll;
typedef vector<vll> vvll;

typedef vector<ii> vii;
typedef vector<vii> vvii;

typedef vector<vi> vvi;
typedef vvi graph_t;

typedef vector<bool> vb;
typedef vector<vb> vvb;

const char SPACE = ' ', ENDL = '\n';

const int BASE = (int)1e9 + 7;
const int MODULO = BASE; // 1e9 + 31; //998244353

typedef ll mod_t;

///////////////////////////////////////////////////////////////////

int ri() {
	int v;
	cin >> v;
	return v;
}

ll rll() {
	ll v;
	cin >> v;
	return v;
}

string rs() {
	string s;
	cin >> s;
	return s;
}

vi rvi(int n) {
	vi a(n);
	for (int i = 0; i < n; ++i) cin >> a[i];
	return a;
}

void read_graph(int n, int edges, graph_t & graph, bool oriented = false) {
	graph.assign(n, vi());
	for (int e = 0; e < edges; ++e) {
		int from = ri() - 1;
		int to = ri() - 1;
		graph[from].push_back(to);
		if (!oriented) graph[to].push_back(from);
	}
}

bool yn(bool result) {
	cout << (result ? "YES" : "NO") << ENDL;
	return result;
}

//////////////////////////////////////////////////////////////////

int get_bit(int mask, int bit) {
	return (mask >> bit) & 1;
}

//////////////////////////////////////////////////////////////////

// taken from https://codeforces.com/blog/entry/76149?#comment-606512

//template<class... args>
//auto create(size_t n, args&&... args) {
//	if (constexpr(sizeof...(args) == 1)) {
//		return vector(n, args...);
//	}
//	else
//	{
//		return vector(n, create(args...));
//	}
//}

//////////////////////////////////////////////////////////////////

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

#ifndef ONLINE_JUDGE
	FILE * tmp_in;
	freopen_s(&tmp_in, "input.txt", "r", stdin);

	FILE * tmp_out;
	freopen_s(&tmp_out, "output.txt", "w", stdout);
#endif

	int local_tests =
#ifdef ONLINE_JUDGE
		1;
#else
		ri();
#endif

	return local_tests;
}

///////////////////////////////////////////////////////////////////

struct DSU {
	vector<size_t> parents;
	vector<size_t> ranks;
	vi is_cycles;

	DSU(vi& degrees) {
		resize(degrees);
	}

	void resize(vi& degrees) {
		size_t n = degrees.size();

		parents.resize(n);
		for (size_t v = 0; v < n; ++v) {
			parents[v] = v;
		}

		ranks.resize(n, 1);

		is_cycles.resize(n, true);
		for (size_t v = 0; v < n; ++v) {
			is_cycles[v] = (2 == degrees[v]);
		}
	}

	size_t get(size_t v) {
		size_t parent = parents[v];
		if (parent == v) return v;

		return parents[v] = get(parent);
	}

	bool merge(size_t f, size_t t) {
		size_t a = get(f);
		size_t b = get(t);

		if (a == b) return false;

		if (ranks[a] < ranks[b]) {
			swap(a, b);
		}

		parents[b] = a;
		if (ranks[a] == ranks[b]) ++ranks[a];

		is_cycles[a] &= is_cycles[b];

		return true;
	}

	bool connected(size_t f, size_t t) {
		return get(f) == get(t);
	}

	bool is_root(size_t v) {
		return get(v) == v;
	}

	bool is_cycle(size_t v){
		return is_cycles[v];
	}
};

/*
tag data structures
tag priority queue
tag multitest
*/

void solve_test() {
	int tests = ri();
	while (tests-- > 0) {
		int n = ri();
		vii a(n);

		for (int i = 0; i < n; ++i) {
			a[i].first = ri() - 1;
			a[i].second = ri();
		}

		vi cnts(n, 0);
		vi zeros(n, 0);

		for (ii& candy : a) {
			cnts[candy.first]++;
			zeros[candy.first] += 1 - candy.second;
		}

		vvi zeros_by_cnts(n + 1, vi(0));
		for (int type = 0; type < n; ++type) {
			if (cnts[type] > 0) {
				zeros_by_cnts[cnts[type]].push_back(zeros[type]);
			}
		}

		set<int> waiting;

		ll total = 0;
		ll total_zeros = 0;

		for (int cnt = n; cnt > 0; --cnt) {
			for (int zero : zeros_by_cnts[cnt]) {
				waiting.push(zero + (n - cnt));
			}

			if (waiting.size() > 0) {
			    int tp = *st.rbegin();
				int zero = max(0, tp - (n - cnt));
				waiting.erase(tp);

				total += cnt;
				total_zeros += zero;
			}
		}

        // v4

		cout << total;
		cout << SPACE << total - total_zeros;
		cout << ENDL;
	}
}

int main() {
	int local_tests = init_input();

	for (int local_test = 0; local_test < local_tests; ++local_test) {
		solve_test();
	}

	return 0;
}


#include <bits/stdc++.h>
#define roflan ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define ld long double
#define int long long
using namespace std;
const int maxn = 200500;

int t[200500];
int t1[200500];
int t2[200500];
int ty[200500];
int tz[200500];

int ct[200500][2];
int have[200500];
void uppd(){
  fill(t, t + maxn, 0);
  fill(t1, t1 + maxn, 0);
  fill(t2, t2 + maxn, 0);
   fill(ty, ty + maxn, 0);
  fill(tz, tz + maxn, 0);
  for (int i = 0; i < 200500; i++){
    ct[i][0] = 0;
    ct[i][1] = 0;
    have[i] = 0;
  }
}

int get(int id){
  int ret = 0;
  while (id >= 1){
    ret += t[id];
    id -= id & -id;
  }
  return ret;
}

void upd(int id, int val){
  while (id < 200500){
    t[id] += val;
    id += id & (-id);
  }
}

int get1(int id){
  int ret = 0;
  while (id >= 1){
    ret += t1[id];
    id -= id & -id;
  }
  return ret;
}

void upd1(int id, int val){
  while (id < 200500){
    t1[id] += val;
    id += id & (-id);
  }
}

int get2(int id){
  int ret = 0;
  while (id >= 1){
    ret += t2[id];
    id -= id & -id;
  }
  return ret;
}

void upd2(int id, int val){
  while (id < 200500){
    t2[id] += val;
    id += id & (-id);
  }
}

signed main(){
  roflan;
  int t;
  cin >> t;
  while (t--){
    uppd();
    int n;
    cin >> n;
    for (int i = 0; i < n; i++){
      int x, y;
      cin >> x >> y;
      ct[x][y]++;
    }
    for (int i = 0; i < 200500; i++){//type
      if (ct[i][1] != 0){
        upd(ct[i][1], 1);
      }
      if (ct[i][0] != 0){
        upd1(ct[i][0], 1);
      }
      if (ct[i][0] != 0 && ct[i][1] != 0){
        upd2(ct[i][0] + ct[i][1], 1);
      }
      have[i] = ct[i][0] + ct[i][1];
      ty[i] = ct[i][0];
      tz[i] = ct[i][1];
    }
    int sum = 0;
    int kek = 0;
    for (int i = 200400; i > 0; i--){
      //int lol = get2(maxn - 1) - get(i - 1);
      int need = get(maxn - 1) - get(i - 1);
      int fuck = get1(maxn - 1) - get1(i - 1);
      if (need > 0){
        kek += i;
        sum += i;
        upd(i, -1);
        continue;
      }

      if (fuck > 0){
        sum += i;
        upd1(i, -1);
        continue;
      }

      if (have[i]){
        int f = ty[i];
        int u = tz[i];
        sum += i;
         upd(u, -1);
         upd1(f, -1);
      }
    }
    cout << sum << " " << kek << '\n';
  }
  return 0;
}
/*
1
9
2 0
2 0
4 1
4 1
4 1
7 0
7 1
7 0
7 1
*/


#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <stack>
#include <deque>
#include <queue>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <bitset>
#include <random>
#include <vector>
#include <string>
#include <cstring>
#include <cassert>
#include <complex>
#include <ctime>
#include <numeric>
using namespace std;

#define pb push_back
#define pii pair <int, int>
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define reunique(x) (x).resize(unique(all(x)) - (x).begin())
#define ld long double
#define int long long

void SOLVE() {
	int n;
	cin >> n;
	map <int, int> mp, is;
	for (int i = 0; i < n; i++) {
		int tt, fl;
		cin >> tt >> fl;
		mp[tt]++;
		is[tt] += fl;
	}

	vector <vector <int>> ar(n + 1);
	for (auto now : mp) {
		ar[now.second].pb(is[now.first]);
	}
	for (auto &now : ar) {
		sort(rall(now));
	}

	vector <int> nxt(n + 1);
	for (int i = 1; i <= n; i++) {
		if (ar[i].size()) nxt[i] = i;
		else nxt[i] = nxt[i - 1];
	}

	int pos = nxt[n];
	int can = 1488;

	int ans = 0, good = 0;
	while (pos) {
		can = pos;
		bool kek = 0;
		for (int j = 0; can && j < ar[pos].size(); j++) {
			int cgood = ar[pos][j];
			int next = nxt[pos - 1];
			if (next && (next > can || next == can && ar[next][0] > min(can, cgood))) {
				pos = next;
				kek = 1;
				break;
			}
			ans += can;
			good += min(can, cgood);
			can = max(0LL, can - 1);
		}
		if (kek) continue;
		pos--;
		pos = nxt[pos];
	}

	cout << ans << ' ' << good << '\n';
}

signed main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cout << fixed;
	cout.precision(10);
	int Q = 1;
	cin >> Q;
	while (Q--) {
		SOLVE();
	}

	return 0;
}


#pragma comment(linker, "/STACK:66777216")

#define _USE_MATH_DEFINES

#include <iostream>
#include <vector>
#include <math.h>
#include <algorithm>
#include <unordered_set>
#include <unordered_map>
#include <map>
#include <set>
#include <bitset>
#include <ctime>
#include <queue>
#include <deque>
#include <iomanip>
#include <functional>
#include <random>
#include <fstream>
#include <ctype.h>

using namespace std;

typedef uniform_int_distribution<> uid;
typedef mt19937 rnd_t;

typedef long long ll;

// need define ONLINE_JUDGE before submit
#ifdef ONLINE_JUDGE
typedef __int128_t sll;
#else
typedef ll sll;
#endif

typedef pair<int, int> ii;

typedef vector<int> vi;
typedef vector<size_t> vsz;

typedef vector<ll> vll;
typedef vector<vll> vvll;

typedef vector<ii> vii;
typedef vector<vii> vvii;

typedef vector<vi> vvi;
typedef vvi graph_t;

typedef vector<bool> vb;
typedef vector<vb> vvb;

const char SPACE = ' ', ENDL = '\n';

const int BASE = (int)1e9 + 7;
const int MODULO = BASE; // 1e9 + 31; //998244353

typedef ll mod_t;

///////////////////////////////////////////////////////////////////

int ri() {
	int v;
	cin >> v;
	return v;
}

ll rll() {
	ll v;
	cin >> v;
	return v;
}

string rs() {
	string s;
	cin >> s;
	return s;
}

vi rvi(int n) {
	vi a(n);
	for (int i = 0; i < n; ++i) cin >> a[i];
	return a;
}

void read_graph(int n, int edges, graph_t & graph, bool oriented = false) {
	graph.assign(n, vi());
	for (int e = 0; e < edges; ++e) {
		int from = ri() - 1;
		int to = ri() - 1;
		graph[from].push_back(to);
		if (!oriented) graph[to].push_back(from);
	}
}

bool yn(bool result) {
	cout << (result ? "YES" : "NO") << ENDL;
	return result;
}

//////////////////////////////////////////////////////////////////

int get_bit(int mask, int bit) {
	return (mask >> bit) & 1;
}

//////////////////////////////////////////////////////////////////

// taken from https://codeforces.com/blog/entry/76149?#comment-606512

//template<class... args>
//auto create(size_t n, args&&... args) {
//	if (constexpr(sizeof...(args) == 1)) {
//		return vector(n, args...);
//	}
//	else
//	{
//		return vector(n, create(args...));
//	}
//}

//////////////////////////////////////////////////////////////////

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

#ifndef ONLINE_JUDGE
	FILE * tmp_in;
	freopen_s(&tmp_in, "input.txt", "r", stdin);

	FILE * tmp_out;
	freopen_s(&tmp_out, "output.txt", "w", stdout);
#endif

	int local_tests =
#ifdef ONLINE_JUDGE
		1;
#else
		ri();
#endif

	return local_tests;
}

///////////////////////////////////////////////////////////////////

struct DSU {
	vector<size_t> parents;
	vector<size_t> ranks;
	vi is_cycles;

	DSU(vi& degrees) {
		resize(degrees);
	}

	void resize(vi& degrees) {
		size_t n = degrees.size();

		parents.resize(n);
		for (size_t v = 0; v < n; ++v) {
			parents[v] = v;
		}

		ranks.resize(n, 1);

		is_cycles.resize(n, true);
		for (size_t v = 0; v < n; ++v) {
			is_cycles[v] = (2 == degrees[v]);
		}
	}

	size_t get(size_t v) {
		size_t parent = parents[v];
		if (parent == v) return v;

		return parents[v] = get(parent);
	}

	bool merge(size_t f, size_t t) {
		size_t a = get(f);
		size_t b = get(t);

		if (a == b) return false;

		if (ranks[a] < ranks[b]) {
			swap(a, b);
		}

		parents[b] = a;
		if (ranks[a] == ranks[b]) ++ranks[a];

		is_cycles[a] &= is_cycles[b];

		return true;
	}

	bool connected(size_t f, size_t t) {
		return get(f) == get(t);
	}

	bool is_root(size_t v) {
		return get(v) == v;
	}

	bool is_cycle(size_t v){
		return is_cycles[v];
	}
};

/*
tag data structures
tag priority queue
tag multitest
*/

void solve_test() {
	int tests = ri();
	while (tests-- > 0) {
		int n = ri();
		vii a(n);

		for (int i = 0; i < n; ++i) {
			a[i].first = ri() - 1;
			a[i].second = ri();
		}

		vi cnts(n, 0);
		vi zeros(n, 0);

		for (ii& candy : a) {
			cnts[candy.first]++;
			zeros[candy.first] += 1 - candy.second;
		}

		vvi zeros_by_cnts(n + 1, vi(0));
		for (int type = 0; type < n; ++type) {
			if (cnts[type] > 0) {
				zeros_by_cnts[cnts[type]].push_back(zeros[type]);
			}
		}

		priority_queue<int, vector<int>, greater<int>> waiting;

		ll total = 0;
		ll total_zeros = 0;

		for (int cnt = n; cnt > 0; --cnt) {
			for (int zero : zeros_by_cnts[cnt]) {
				waiting.push(zero + (n - cnt));
			}

			if (waiting.size() > 0) {
				int zero = max(0, waiting.top() - (n - cnt));
				waiting.pop();

				total += cnt;
				total_zeros += zero;
			}
		}

        // v4

		cout << total;
		cout << ENDL << total - total_zeros;
		cout << ENDL;
	}
}

int main() {
	int local_tests = init_input();

	for (int local_test = 0; local_test < local_tests; ++local_test) {
		solve_test();
	}

	return 0;
}


//#pragma comment(linker, "/STACK:66777216")

//#define _USE_MATH_DEFINES

#include <iostream>
#include <vector>
#include <math.h>
#include <algorithm>
#include <unordered_set>
#include <unordered_map>
#include <map>
#include <set>
#include <bitset>
#include <ctime>
#include <queue>
#include <deque>
#include <iomanip>
#include <functional>
#include <random>
#include <fstream>
#include <ctype.h>

using namespace std;

typedef uniform_int_distribution<> uid;
typedef mt19937 rnd_t;

typedef long long ll;

// need define ONLINE_JUDGE before submit
//#ifdef ONLINE_JUDGE
//typedef __int128_t sll;
//#else
//typedef ll sll;
//#endif

typedef pair<int, int> ii;

typedef vector<int> vi;
typedef vector<size_t> vsz;

typedef vector<ll> vll;
typedef vector<vll> vvll;

typedef vector<ii> vii;
typedef vector<vii> vvii;

typedef vector<vi> vvi;
typedef vvi graph_t;

typedef vector<bool> vb;
typedef vector<vb> vvb;

const char SPACE = ' ', ENDL = '\n';

const int BASE = (int)1e9 + 7;
const int MODULO = BASE; // 1e9 + 31; //998244353

//////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////

// taken from https://codeforces.com/blog/entry/76149?#comment-606512

//template<class... args>
//auto create(size_t n, args&&... args) {
//	if (constexpr(sizeof...(args) == 1)) {
//		return vector(n, args...);
//	}
//	else
//	{
//		return vector(n, create(args...));
//	}
//}

//////////////////////////////////////////////////////////////////

void init_input() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
}
//#ifndef ONLINE_JUDGE
//	FILE * tmp_in;
//	freopen_s(&tmp_in, "input.txt", "r", stdin);
//
//	FILE * tmp_out;
//	freopen_s(&tmp_out, "output.txt", "w", stdout);
//#endif
//
//	int local_tests =
//#ifdef ONLINE_JUDGE
//		1;
//#else
//		ri();
//#endif
//
//	return local_tests;
//}

///////////////////////////////////////////////////////////////////

/*
tag data structures
tag priority queue
tag multitest
*/

#define int long long

void solve_test() {
	int qq;
    cin >> qq;
    while (qq--) {
        int n;
        cin >> n;
        map<ll, pair<ll, ll>> mp;
        for (int i = 0; i < n; i++) {
            ll a, b;
            cin >> a >> b;
            mp[a].first++;
            mp[a].second += b;
        }

        vector<vector<ll>> cnt(n + 1);
        for (auto [key, val] : mp) {
            cnt[val.first].push_back(val.second);
        }
        priority_queue<ll> q;
        ll ans0 = 0, ans1 = 0;
        for (ll i = n; i > 0; i--) {
            for (ll x : cnt[i]) q.push(x);
            if (q.size()) {
                ans0 += i;
                ans1 += min(i, q.top());
                q.pop();
            }
        }
        cout << ans0 << '\n' << ans1 << '\n';
    }
}

signed main() {
    init_input();
	int local_tests = 1;

	for (int local_test = 0; local_test < local_tests; ++local_test) {
		solve_test();
	}

	return 0;
}


#pragma comment(linker, "/STACK:66777216")

#define _USE_MATH_DEFINES

#include <iostream>
#include <vector>
#include <math.h>
#include <algorithm>
#include <unordered_set>
#include <unordered_map>
#include <map>
#include <set>
#include <bitset>
#include <ctime>
#include <queue>
#include <deque>
#include <iomanip>
#include <functional>
#include <random>
#include <fstream>
#include <ctype.h>

using namespace std;

typedef uniform_int_distribution<> uid;
typedef mt19937 rnd_t;

typedef long long ll;

// need define ONLINE_JUDGE before submit
#ifdef ONLINE_JUDGE
typedef __int128_t sll;
#else
typedef ll sll;
#endif

typedef pair<int, int> ii;

typedef vector<int> vi;
typedef vector<size_t> vsz;

typedef vector<ll> vll;
typedef vector<vll> vvll;

typedef vector<ii> vii;
typedef vector<vii> vvii;

typedef vector<vi> vvi;
typedef vvi graph_t;

typedef vector<bool> vb;
typedef vector<vb> vvb;

const char SPACE = ' ', ENDL = '\n';

const int BASE = (int)1e9 + 7;
const int MODULO = BASE; // 1e9 + 31; //998244353

typedef ll mod_t;

///////////////////////////////////////////////////////////////////

int ri() {
	int v;
	cin >> v;
	return v;
}

ll rll() {
	ll v;
	cin >> v;
	return v;
}

string rs() {
	string s;
	cin >> s;
	return s;
}

vi rvi(int n) {
	vi a(n);
	for (int i = 0; i < n; ++i) cin >> a[i];
	return a;
}

void read_graph(int n, int edges, graph_t & graph, bool oriented = false) {
	graph.assign(n, vi());
	for (int e = 0; e < edges; ++e) {
		int from = ri() - 1;
		int to = ri() - 1;
		graph[from].push_back(to);
		if (!oriented) graph[to].push_back(from);
	}
}

bool yn(bool result) {
	cout << (result ? "YES" : "NO") << ENDL;
	return result;
}

//////////////////////////////////////////////////////////////////

int get_bit(int mask, int bit) {
	return (mask >> bit) & 1;
}

//////////////////////////////////////////////////////////////////

// taken from https://codeforces.com/blog/entry/76149?#comment-606512

//template<class... args>
//auto create(size_t n, args&&... args) {
//	if (constexpr(sizeof...(args) == 1)) {
//		return vector(n, args...);
//	}
//	else
//	{
//		return vector(n, create(args...));
//	}
//}

//////////////////////////////////////////////////////////////////

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

#ifndef ONLINE_JUDGE
	FILE * tmp_in;
	freopen_s(&tmp_in, "input.txt", "r", stdin);

	FILE * tmp_out;
	freopen_s(&tmp_out, "output.txt", "w", stdout);
#endif

	int local_tests =
#ifdef ONLINE_JUDGE
		1;
#else
		ri();
#endif

	return local_tests;
}

///////////////////////////////////////////////////////////////////

struct DSU {
	vector<size_t> parents;
	vector<size_t> ranks;
	vi is_cycles;

	DSU(vi& degrees) {
		resize(degrees);
	}

	void resize(vi& degrees) {
		size_t n = degrees.size();

		parents.resize(n);
		for (size_t v = 0; v < n; ++v) {
			parents[v] = v;
		}

		ranks.resize(n, 1);

		is_cycles.resize(n, true);
		for (size_t v = 0; v < n; ++v) {
			is_cycles[v] = (2 == degrees[v]);
		}
	}

	size_t get(size_t v) {
		size_t parent = parents[v];
		if (parent == v) return v;

		return parents[v] = get(parent);
	}

	bool merge(size_t f, size_t t) {
		size_t a = get(f);
		size_t b = get(t);

		if (a == b) return false;

		if (ranks[a] < ranks[b]) {
			swap(a, b);
		}

		parents[b] = a;
		if (ranks[a] == ranks[b]) ++ranks[a];

		is_cycles[a] &= is_cycles[b];

		return true;
	}

	bool connected(size_t f, size_t t) {
		return get(f) == get(t);
	}

	bool is_root(size_t v) {
		return get(v) == v;
	}

	bool is_cycle(size_t v){
		return is_cycles[v];
	}
};

/*
tag data structures
tag priority queue
tag multitest
*/

void solve_test() {
	int tests = ri();
	while (tests-- > 0) {
		int n = ri();
		vii a(n);

		for (int i = 0; i < n; ++i) {
			a[i].first = ri() - 1;
			a[i].second = ri();
		}

		vi cnts(n, 0);
		vi zeros(n, 0);

		for (ii& candy : a) {
			cnts[candy.first]++;
			zeros[candy.first] += 1 - candy.second;
		}

		vvi zeros_by_cnts(n + 1, vi(0));
		for (int type = 0; type < n; ++type) {
			if (cnts[type] > 0) {
				zeros_by_cnts[cnts[type]].push_back(zeros[type]);
			}
		}

		multiset<int> waiting;

		ll total = 0;
		ll total_zeros = 0;

		for (int cnt = n; cnt > 0; --cnt) {
			for (int zero : zeros_by_cnts[cnt]) {
				waiting.insert(zero + (n - cnt));
			}

			if (waiting.size() > 0) {
			    int tp = *waiting.begin();
				int zero = max(0, tp - (n - cnt));
				waiting.erase(waiting.find(tp));

				total += cnt;
				total_zeros += zero;
			}
		}

        // v4

		cout << total;
		cout << SPACE << total - total_zeros;
		cout << ENDL;
	}
}

int main() {
	int local_tests = init_input();

	for (int local_test = 0; local_test < local_tests; ++local_test) {
		solve_test();
	}

	return 0;
}


#pragma comment(linker, "/STACK:66777216")

#define _USE_MATH_DEFINES

#include <iostream>
#include <vector>
#include <math.h>
#include <algorithm>
#include <unordered_set>
#include <unordered_map>
#include <map>
#include <set>
#include <bitset>
#include <ctime>
#include <queue>
#include <deque>
#include <iomanip>
#include <functional>
#include <random>
#include <fstream>
#include <ctype.h>

using namespace std;

typedef uniform_int_distribution<> uid;
typedef mt19937 rnd_t;

typedef long long ll;

// need define ONLINE_JUDGE before submit
#ifdef ONLINE_JUDGE
typedef __int128_t sll;
#else
typedef ll sll;
#endif

typedef pair<int, int> ii;

typedef vector<int> vi;
typedef vector<size_t> vsz;

typedef vector<ll> vll;
typedef vector<vll> vvll;

typedef vector<ii> vii;
typedef vector<vii> vvii;

typedef vector<vi> vvi;
typedef vvi graph_t;

typedef vector<bool> vb;
typedef vector<vb> vvb;

const char SPACE = ' ', ENDL = '\n';

const int BASE = (int)1e9 + 7;
const int MODULO = BASE; // 1e9 + 31; //998244353

typedef ll mod_t;

///////////////////////////////////////////////////////////////////

int ri() {
	int v;
	cin >> v;
	return v;
}

ll rll() {
	ll v;
	cin >> v;
	return v;
}

string rs() {
	string s;
	cin >> s;
	return s;
}

vi rvi(int n) {
	vi a(n);
	for (int i = 0; i < n; ++i) cin >> a[i];
	return a;
}

void read_graph(int n, int edges, graph_t & graph, bool oriented = false) {
	graph.assign(n, vi());
	for (int e = 0; e < edges; ++e) {
		int from = ri() - 1;
		int to = ri() - 1;
		graph[from].push_back(to);
		if (!oriented) graph[to].push_back(from);
	}
}

bool yn(bool result) {
	cout << (result ? "YES" : "NO") << ENDL;
	return result;
}

//////////////////////////////////////////////////////////////////

int get_bit(int mask, int bit) {
	return (mask >> bit) & 1;
}

//////////////////////////////////////////////////////////////////

// taken from https://codeforces.com/blog/entry/76149?#comment-606512

//template<class... args>
//auto create(size_t n, args&&... args) {
//	if (constexpr(sizeof...(args) == 1)) {
//		return vector(n, args...);
//	}
//	else
//	{
//		return vector(n, create(args...));
//	}
//}

//////////////////////////////////////////////////////////////////

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

#ifndef ONLINE_JUDGE
	FILE * tmp_in;
	freopen_s(&tmp_in, "input.txt", "r", stdin);

	FILE * tmp_out;
	freopen_s(&tmp_out, "output.txt", "w", stdout);
#endif

	int local_tests =
#ifdef ONLINE_JUDGE
		1;
#else
		ri();
#endif

	return local_tests;
}

///////////////////////////////////////////////////////////////////

struct DSU {
	vector<size_t> parents;
	vector<size_t> ranks;
	vi is_cycles;

	DSU(vi& degrees) {
		resize(degrees);
	}

	void resize(vi& degrees) {
		size_t n = degrees.size();

		parents.resize(n);
		for (size_t v = 0; v < n; ++v) {
			parents[v] = v;
		}

		ranks.resize(n, 1);

		is_cycles.resize(n, true);
		for (size_t v = 0; v < n; ++v) {
			is_cycles[v] = (2 == degrees[v]);
		}
	}

	size_t get(size_t v) {
		size_t parent = parents[v];
		if (parent == v) return v;

		return parents[v] = get(parent);
	}

	bool merge(size_t f, size_t t) {
		size_t a = get(f);
		size_t b = get(t);

		if (a == b) return false;

		if (ranks[a] < ranks[b]) {
			swap(a, b);
		}

		parents[b] = a;
		if (ranks[a] == ranks[b]) ++ranks[a];

		is_cycles[a] &= is_cycles[b];

		return true;
	}

	bool connected(size_t f, size_t t) {
		return get(f) == get(t);
	}

	bool is_root(size_t v) {
		return get(v) == v;
	}

	bool is_cycle(size_t v){
		return is_cycles[v];
	}
};

/*
tag data structures
tag priority queue
tag multitest
*/

void solve_test() {
	int tests = ri();
	while (tests-- > 0) {
		int n = ri();
		vii a(n);

		for (int i = 0; i < n; ++i) {
			a[i].first = ri() - 1;
			a[i].second = ri();
		}

		vi cnts(n, 0);
		vi zeros(n, 0);

		for (ii& candy : a) {
			cnts[candy.first]++;
			zeros[candy.first] += 1 - candy.second;
		}

		vvi zeros_by_cnts(n + 1, vi(0));
		for (int type = 0; type < n; ++type) {
			if (cnts[type] > 0) {
				zeros_by_cnts[cnts[type]].push_back(zeros[type]);
			}
		}

		multiset<int> waiting;

		ll total = 0;
		ll total_zeros = 0;

		for (int cnt = n; cnt > 0; --cnt) {
			for (int zero : zeros_by_cnts[cnt]) {
				waiting.insert(zero + (n - cnt));
			}

			if (waiting.size() > 0) {
			    int tp = *waiting.rbegin();
				int zero = max(0, tp - (n - cnt));
				waiting.erase(waiting.find(tp));

				total += cnt;
				total_zeros += zero;
			}
		}

        // v4

		cout << total;
		cout << SPACE << total - total_zeros;
		cout << ENDL;
	}
}

int main() {
	int local_tests = init_input();

	for (int local_test = 0; local_test < local_tests; ++local_test) {
		solve_test();
	}

	return 0;
}


#pragma comment(linker, "/STACK:66777216")

#define _USE_MATH_DEFINES

#include <iostream>
#include <vector>
#include <math.h>
#include <algorithm>
#include <unordered_set>
#include <unordered_map>
#include <map>
#include <set>
#include <bitset>
#include <ctime>
#include <queue>
#include <deque>
#include <iomanip>
#include <functional>
#include <random>
#include <fstream>
#include <ctype.h>

using namespace std;

typedef uniform_int_distribution<> uid;
typedef mt19937 rnd_t;

typedef long long ll;

// need define ONLINE_JUDGE before submit
#ifdef ONLINE_JUDGE
typedef __int128_t sll;
#else
typedef ll sll;
#endif

typedef pair<int, int> ii;

typedef vector<int> vi;
typedef vector<size_t> vsz;

typedef vector<ll> vll;
typedef vector<vll> vvll;

typedef vector<ii> vii;
typedef vector<vii> vvii;

typedef vector<vi> vvi;
typedef vvi graph_t;

typedef vector<bool> vb;
typedef vector<vb> vvb;

const char SPACE = ' ', ENDL = '\n';

const int BASE = (int)1e9 + 7;
const int MODULO = BASE; // 1e9 + 31; //998244353

typedef ll mod_t;

///////////////////////////////////////////////////////////////////

int ri() {
	int v;
	cin >> v;
	return v;
}

ll rll() {
	ll v;
	cin >> v;
	return v;
}

string rs() {
	string s;
	cin >> s;
	return s;
}

vi rvi(int n) {
	vi a(n);
	for (int i = 0; i < n; ++i) cin >> a[i];
	return a;
}

void read_graph(int n, int edges, graph_t & graph, bool oriented = false) {
	graph.assign(n, vi());
	for (int e = 0; e < edges; ++e) {
		int from = ri() - 1;
		int to = ri() - 1;
		graph[from].push_back(to);
		if (!oriented) graph[to].push_back(from);
	}
}

bool yn(bool result) {
	cout << (result ? "YES" : "NO") << ENDL;
	return result;
}

//////////////////////////////////////////////////////////////////

int get_bit(int mask, int bit) {
	return (mask >> bit) & 1;
}

//////////////////////////////////////////////////////////////////

// taken from https://codeforces.com/blog/entry/76149?#comment-606512

//template<class... args>
//auto create(size_t n, args&&... args) {
//	if (constexpr(sizeof...(args) == 1)) {
//		return vector(n, args...);
//	}
//	else
//	{
//		return vector(n, create(args...));
//	}
//}

//////////////////////////////////////////////////////////////////

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

#ifndef ONLINE_JUDGE
	FILE * tmp_in;
	freopen_s(&tmp_in, "input.txt", "r", stdin);

	FILE * tmp_out;
	freopen_s(&tmp_out, "output.txt", "w", stdout);
#endif

	int local_tests =
#ifdef ONLINE_JUDGE
		1;
#else
		ri();
#endif

	return local_tests;
}

///////////////////////////////////////////////////////////////////

struct DSU {
	vector<size_t> parents;
	vector<size_t> ranks;
	vi is_cycles;

	DSU(vi& degrees) {
		resize(degrees);
	}

	void resize(vi& degrees) {
		size_t n = degrees.size();

		parents.resize(n);
		for (size_t v = 0; v < n; ++v) {
			parents[v] = v;
		}

		ranks.resize(n, 1);

		is_cycles.resize(n, true);
		for (size_t v = 0; v < n; ++v) {
			is_cycles[v] = (2 == degrees[v]);
		}
	}

	size_t get(size_t v) {
		size_t parent = parents[v];
		if (parent == v) return v;

		return parents[v] = get(parent);
	}

	bool merge(size_t f, size_t t) {
		size_t a = get(f);
		size_t b = get(t);

		if (a == b) return false;

		if (ranks[a] < ranks[b]) {
			swap(a, b);
		}

		parents[b] = a;
		if (ranks[a] == ranks[b]) ++ranks[a];

		is_cycles[a] &= is_cycles[b];

		return true;
	}

	bool connected(size_t f, size_t t) {
		return get(f) == get(t);
	}

	bool is_root(size_t v) {
		return get(v) == v;
	}

	bool is_cycle(size_t v){
		return is_cycles[v];
	}
};

/*
tag data structures
tag priority queue
tag multitest
*/

void solve_test() {
	int tests = ri();
	while (tests-- > 0) {
		int n = ri();
		vii a(n);

		for (int i = 0; i < n; ++i) {
			a[i].first = ri() - 1;
			a[i].second = ri();
		}

		vi cnts(n, 0);
		vi zeros(n, 0);

		for (ii& candy : a) {
			cnts[candy.first]++;
			zeros[candy.first] += 1 - candy.second;
		}

		vvi zeros_by_cnts(n + 1, vi(0));
		for (int type = 0; type < n; ++type) {
			if (cnts[type] > 0) {
				zeros_by_cnts[cnts[type]].push_back(zeros[type]);
			}
		}

		set<int> waiting;

		ll total = 0;
		ll total_zeros = 0;

		for (int cnt = n; cnt > 0; --cnt) {
			for (int zero : zeros_by_cnts[cnt]) {
				waiting.push(zero + (n - cnt));
			}

			if (waiting.size() > 0) {
			    int tp = *waiting.rbegin();
				int zero = max(0, tp - (n - cnt));
				waiting.erase(tp);

				total += cnt;
				total_zeros += zero;
			}
		}

        // v4

		cout << total;
		cout << SPACE << total - total_zeros;
		cout << ENDL;
	}
}

int main() {
	int local_tests = init_input();

	for (int local_test = 0; local_test < local_tests; ++local_test) {
		solve_test();
	}

	return 0;
}


//#pragma comment(linker, "/STACK:66777216")

//#define _USE_MATH_DEFINES

#include <iostream>
#include <vector>
#include <math.h>
#include <algorithm>
#include <unordered_set>
#include <unordered_map>
#include <map>
#include <set>
#include <bitset>
#include <ctime>
#include <queue>
#include <deque>
#include <iomanip>
#include <functional>
#include <random>
#include <fstream>
#include <ctype.h>

using namespace std;

typedef uniform_int_distribution<> uid;
typedef mt19937 rnd_t;

typedef long long ll;

// need define ONLINE_JUDGE before submit
//#ifdef ONLINE_JUDGE
//typedef __int128_t sll;
//#else
//typedef ll sll;
//#endif

typedef pair<int, int> ii;

typedef vector<int> vi;
typedef vector<size_t> vsz;

typedef vector<ll> vll;
typedef vector<vll> vvll;

typedef vector<ii> vii;
typedef vector<vii> vvii;

typedef vector<vi> vvi;
typedef vvi graph_t;

typedef vector<bool> vb;
typedef vector<vb> vvb;

const char SPACE = ' ', ENDL = '\n';

const int BASE = (int)1e9 + 7;
const int MODULO = BASE; // 1e9 + 31; //998244353

typedef ll mod_t;

///////////////////////////////////////////////////////////////////

int ri() {
	int v;
	cin >> v;
	return v;
}

ll rll() {
	ll v;
	cin >> v;
	return v;
}

string rs() {
	string s;
	cin >> s;
	return s;
}

vi rvi(int n) {
	vi a(n);
	for (int i = 0; i < n; ++i) cin >> a[i];
	return a;
}

void read_graph(int n, int edges, graph_t & graph, bool oriented = false) {
	graph.assign(n, vi());
	for (int e = 0; e < edges; ++e) {
		int from = ri() - 1;
		int to = ri() - 1;
		graph[from].push_back(to);
		if (!oriented) graph[to].push_back(from);
	}
}

bool yn(bool result) {
	cout << (result ? "YES" : "NO") << ENDL;
	return result;
}

//////////////////////////////////////////////////////////////////

int get_bit(int mask, int bit) {
	return (mask >> bit) & 1;
}

//////////////////////////////////////////////////////////////////

// taken from https://codeforces.com/blog/entry/76149?#comment-606512

//template<class... args>
//auto create(size_t n, args&&... args) {
//	if (constexpr(sizeof...(args) == 1)) {
//		return vector(n, args...);
//	}
//	else
//	{
//		return vector(n, create(args...));
//	}
//}

//////////////////////////////////////////////////////////////////

void init_input() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
}
//#ifndef ONLINE_JUDGE
//	FILE * tmp_in;
//	freopen_s(&tmp_in, "input.txt", "r", stdin);
//
//	FILE * tmp_out;
//	freopen_s(&tmp_out, "output.txt", "w", stdout);
//#endif
//
//	int local_tests =
//#ifdef ONLINE_JUDGE
//		1;
//#else
//		ri();
//#endif
//
//	return local_tests;
//}

///////////////////////////////////////////////////////////////////

/*
tag data structures
tag priority queue
tag multitest
*/

#define int long long

void solve_test() {
	int tests = ri();
	while (tests-- > 0) {
		int n = ri();
		vii a(n);

		for (int i = 0; i < n; ++i) {
			a[i].first = ri() - 1;
			a[i].second = ri();
		}

		vi cnts(n, 0);
		vi zeros(n, 0);

		for (ii& candy : a) {
			cnts[candy.first]++;
			zeros[candy.first] += 1 - candy.second;
		}

		vvi zeros_by_cnts(n + 1, vi(0));
		for (int type = 0; type < n; ++type) {
			if (cnts[type] > 0) {
				zeros_by_cnts[cnts[type]].push_back(zeros[type]);
			}
		}

		priority_queue<int, vector<int>, greater<int>> waiting;

		int total = 0;
		int total_zeros = 0;

		for (int cnt = n; cnt > 0; --cnt) {
			for (int zero : zeros_by_cnts[cnt]) {
				waiting.push(zero + (n - cnt));
			}

			if (waiting.size() > 0) {
				int zero = max(0ll, waiting.top() - (n - cnt));
				waiting.pop();

				total += cnt;
				total_zeros += zero;
			}
		}

        // v4

		cout << total;
		cout << " " << (int)(total - total_zeros);
		cout << '\n';
	}
}

signed main() {
    init_input();
	int local_tests = 1;

	for (int local_test = 0; local_test < local_tests; ++local_test) {
		solve_test();
	}

	return 0;
}


#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <stack>
#include <deque>
#include <queue>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <bitset>
#include <random>
#include <vector>
#include <string>
#include <cstring>
#include <cassert>
#include <complex>
#include <ctime>
#include <numeric>
using namespace std;

#define pb push_back
#define pii pair <int, int>
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define reunique(x) (x).resize(unique(all(x)) - (x).begin())
#define ld long double
#define int long long

bool cmp(pii x, pii y) {
	if (x.first == y.first)
		return x.second > y.second;
	return x.first > y.first;
}
void SOLVE() {
	int n;
	cin >> n;
	map <int, int> mp, is;
	for (int i = 0; i < n; i++) {
		int tt, fl;
		cin >> tt >> fl;
		mp[tt]++;
		is[tt] += fl;
	}

	vector <vector <int>> ar(n + 1);
	for (auto now : mp) {
		ar[now.second].pb(is[now.first]);
	}
	for (auto &now : ar) {
		sort(rall(now));
	}

	vector <int> nxt(n + 1);
	for (int i = 1; i <= n; i++) {
		if (ar[i].size()) nxt[i] = i;
		else nxt[i] = nxt[i - 1];
	}

	int pos = nxt[n];
	int can = 1488;

	int ans = 0, good = 0;
	while (pos) {
		can = pos;
		bool kek = 0;
		for (int j = 0; j < ar[pos].size(); j++) {
			int cgood = ar[pos][j];
			int next = nxt[pos - 1];
			if (next && (next > can || next == can && ar[next][0] > cgood)) {
				pos = next;
				kek = 1;
				break;
			}
			ans += can;
			good += min(can, cgood);
			can = max(0LL, can - 1);
		}
		if (kek) continue;
		pos--;
		pos = nxt[pos];
	}

	cout << ans << ' ' << good << '\n';
}

signed main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cout << fixed;
	cout.precision(10);
	int Q = 1;
	cin >> Q;
	while (Q--) {
		SOLVE();
	}

	return 0;
}


#pragma comment(linker, "/STACK:66777216")

#define _USE_MATH_DEFINES

#include <iostream>
#include <vector>
#include <math.h>
#include <algorithm>
#include <unordered_set>
#include <unordered_map>
#include <map>
#include <set>
#include <bitset>
#include <ctime>
#include <queue>
#include <deque>
#include <iomanip>
#include <functional>
#include <random>
#include <fstream>
#include <ctype.h>

using namespace std;

typedef uniform_int_distribution<> uid;
typedef mt19937 rnd_t;

typedef long long ll;

// need define ONLINE_JUDGE before submit
#ifdef ONLINE_JUDGE
typedef __int128_t sll;
#else
typedef ll sll;
#endif

typedef pair<int, int> ii;

typedef vector<int> vi;
typedef vector<size_t> vsz;

typedef vector<ll> vll;
typedef vector<vll> vvll;

typedef vector<ii> vii;
typedef vector<vii> vvii;

typedef vector<vi> vvi;
typedef vvi graph_t;

typedef vector<bool> vb;
typedef vector<vb> vvb;

const char SPACE = ' ', ENDL = '\n';

const int BASE = (int)1e9 + 7;
const int MODULO = BASE; // 1e9 + 31; //998244353

typedef ll mod_t;

///////////////////////////////////////////////////////////////////

int ri() {
	int v;
	cin >> v;
	return v;
}

ll rll() {
	ll v;
	cin >> v;
	return v;
}

string rs() {
	string s;
	cin >> s;
	return s;
}

vi rvi(int n) {
	vi a(n);
	for (int i = 0; i < n; ++i) cin >> a[i];
	return a;
}

void read_graph(int n, int edges, graph_t & graph, bool oriented = false) {
	graph.assign(n, vi());
	for (int e = 0; e < edges; ++e) {
		int from = ri() - 1;
		int to = ri() - 1;
		graph[from].push_back(to);
		if (!oriented) graph[to].push_back(from);
	}
}

bool yn(bool result) {
	cout << (result ? "YES" : "NO") << ENDL;
	return result;
}

//////////////////////////////////////////////////////////////////

int get_bit(int mask, int bit) {
	return (mask >> bit) & 1;
}

//////////////////////////////////////////////////////////////////

// taken from https://codeforces.com/blog/entry/76149?#comment-606512

//template<class... args>
//auto create(size_t n, args&&... args) {
//	if (constexpr(sizeof...(args) == 1)) {
//		return vector(n, args...);
//	}
//	else
//	{
//		return vector(n, create(args...));
//	}
//}

//////////////////////////////////////////////////////////////////

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

#ifndef ONLINE_JUDGE
	FILE * tmp_in;
	freopen_s(&tmp_in, "input.txt", "r", stdin);

	FILE * tmp_out;
	freopen_s(&tmp_out, "output.txt", "w", stdout);
#endif

	int local_tests =
#ifdef ONLINE_JUDGE
		1;
#else
		ri();
#endif

	return local_tests;
}

///////////////////////////////////////////////////////////////////

struct DSU {
	vector<size_t> parents;
	vector<size_t> ranks;
	vi is_cycles;

	DSU(vi& degrees) {
		resize(degrees);
	}

	void resize(vi& degrees) {
		size_t n = degrees.size();

		parents.resize(n);
		for (size_t v = 0; v < n; ++v) {
			parents[v] = v;
		}

		ranks.resize(n, 1);

		is_cycles.resize(n, true);
		for (size_t v = 0; v < n; ++v) {
			is_cycles[v] = (2 == degrees[v]);
		}
	}

	size_t get(size_t v) {
		size_t parent = parents[v];
		if (parent == v) return v;

		return parents[v] = get(parent);
	}

	bool merge(size_t f, size_t t) {
		size_t a = get(f);
		size_t b = get(t);

		if (a == b) return false;

		if (ranks[a] < ranks[b]) {
			swap(a, b);
		}

		parents[b] = a;
		if (ranks[a] == ranks[b]) ++ranks[a];

		is_cycles[a] &= is_cycles[b];

		return true;
	}

	bool connected(size_t f, size_t t) {
		return get(f) == get(t);
	}

	bool is_root(size_t v) {
		return get(v) == v;
	}

	bool is_cycle(size_t v){
		return is_cycles[v];
	}
};

/*
tag data structures
tag priority queue
tag multitest
*/

void solve_test() {
	int tests = ri();
	while (tests-- > 0) {
		int n = ri();
		vii a(n);

		for (int i = 0; i < n; ++i) {
			a[i].first = ri() - 1;
			a[i].second = ri();
		}

		vi cnts(n, 0);
		vi zeros(n, 0);

		for (ii& candy : a) {
			cnts[candy.first]++;
			zeros[candy.first] += 1 - candy.second;
		}

		vvi zeros_by_cnts(n + 1, vi(0));
		for (int type = 0; type < n; ++type) {
			if (cnts[type] > 0) {
				zeros_by_cnts[cnts[type]].push_back(zeros[type]);
			}
		}

		set<int> waiting;

		ll total = 0;
		ll total_zeros = 0;

		for (int cnt = n; cnt > 0; --cnt) {
			for (int zero : zeros_by_cnts[cnt]) {
				waiting.insert(zero + (n - cnt));
			}

			if (waiting.size() > 0) {
			    int tp = *waiting.rbegin();
				int zero = max(0, tp - (n - cnt));
				waiting.erase(tp);

				total += cnt;
				total_zeros += zero;
			}
		}

        // v4

		cout << total;
		cout << SPACE << total - total_zeros;
		cout << ENDL;
	}
}

int main() {
	int local_tests = init_input();

	for (int local_test = 0; local_test < local_tests; ++local_test) {
		solve_test();
	}

	return 0;
}


# include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;

# define F first
# define S second
# define endl '\n'
# define sep ' '
# define pb push_back
# define fast_io ios::sync_with_stdio(0);cin.tie(0); cout.tie(0);

const ll md = 1e9 + 7;
const int xn = 2e5 + 10;
const int xm = 1e5 + 10;
const int SQ = 320;
const int sq = 1e3 + 10;
const ll inf = 1e18 + 10;

ll power(ll a, ll b) {return (!b ? 1 : (b & 1 ? a * power(a * a % md, b / 2) % md : power(a * a % md, b / 2) % md));}
ll zarb(ll a, ll b){return (a * b + 10 * md) % md;}
ll jaam(ll a, ll b){return (a + b + 10 * md) % md;}

int qq, n, cnt[xn], f[xn], ans, ted;
vector <int> adj[xn];
multiset <int, greater <int> > st;

int main(){
	fast_io;

	cin >> qq;
	while (qq --){
		memset(cnt, 0, sizeof cnt);
		memset(f, 0, sizeof f);
		ans = ted = 0;
		st.clear();
		cin >> n;
		for (int i = 0; i < n; i ++){
			int x, y;
			cin >> x >> y;
			cnt[x] ++;
			f[x] += y;
		}
		for (int i = 0; i <= n; i ++) adj[i].clear();
		for (int i = 1; i <= n; i ++) adj[cnt[i]].push_back(f[i]);
		for (int i = n; i > 0; i --){
			int mx = 0;
			if (i == 1) for (int x : adj[i]) mx = max(mx, x);
			if (i > 1) for (int x : adj[i]) st.insert(x);
			if (st.size() || mx){
				int x;
				if (st.size()){
					x = *st.begin();
					st.erase(st.begin());
				}
				x = max(x, mx);
				ans += i;
				ted += min(x, i);
			}
		}
		cout << ans << sep << ted << endl;
	}

	return 0;
}


# include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;

# define F first
# define S second
# define endl '\n'
# define sep ' '
# define pb push_back
# define fast_io ios::sync_with_stdio(0);cin.tie(0); cout.tie(0);

const ll md = 1e9 + 7;
const int xn = 2e5 + 10;
const int xm = 1e5 + 10;
const int SQ = 320;
const int sq = 1e3 + 10;
const ll inf = 1e18 + 10;

ll power(ll a, ll b) {return (!b ? 1 : (b & 1 ? a * power(a * a % md, b / 2) % md : power(a * a % md, b / 2) % md));}
ll zarb(ll a, ll b){return (a * b + 10 * md) % md;}
ll jaam(ll a, ll b){return (a + b + 10 * md) % md;}

int qq, n, cnt[xn], f[xn], ans, ted;
vector <int> adj[xn];
multiset <int, greater <int> > st;

int main(){
	fast_io;

	cin >> qq;
	while (qq --){
		memset(cnt, 0, sizeof cnt);
		memset(f, 0, sizeof f);
		ans = ted = 0;
		st.clear();
		cin >> n;
		for (int i = 0; i < n; i ++){
			int x, y;
			cin >> x >> y;
			cnt[x] ++;
			f[x] += y;
		}
		for (int i = 0; i <= n; i ++) adj[i].clear();
		for (int i = 1; i <= n; i ++) adj[cnt[i]].push_back(f[i]);
		for (int i = n; i > 0; i --){
			int mx = -1;
			if (i == 1) for (int x : adj[i]) mx = max(mx, x);
			if (i > 1) for (int x : adj[i]) st.insert(x);
			if (st.size() || mx > -1){
				int x = -1;
				if (st.size()){
					x = *st.begin();
					st.erase(st.begin());
				}
				x = max(x, mx);
				ans += i;
				ted += min(x, i);
			}
		}
		cout << ans << sep << ted << endl;
	}

	return 0;
}


# include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;

# define F first
# define S second
# define endl '\n'
# define sep ' '
# define pb push_back
# define fast_io ios::sync_with_stdio(0);cin.tie(0); cout.tie(0);

const ll md = 1e9 + 7;
const int xn = 2e5 + 10;
const int xm = 1e5 + 10;
const int SQ = 320;
const int sq = 1e3 + 10;
const ll inf = 1e18 + 10;

ll power(ll a, ll b) {return (!b ? 1 : (b & 1 ? a * power(a * a % md, b / 2) % md : power(a * a % md, b / 2) % md));}
ll zarb(ll a, ll b){return (a * b + 10 * md) % md;}
ll jaam(ll a, ll b){return (a + b + 10 * md) % md;}

int qq, n, cnt[xn], f[xn], ans, ted, S;
vector <int> adj[xn];
set <pii, greater <pii> > st;

int main(){
	fast_io;

	cin >> qq;
	while (qq --){
		memset(cnt, 0, sizeof cnt);
		memset(f, 0, sizeof f);
		ans = ted = 0;
		st.clear();
		cin >> n;
		for (int i = 0; i < n; i ++){
			int x, y;
			cin >> x >> y;
			cnt[x] ++;
			f[x] += y;
		}
		for (int i = 0; i <= n; i ++) adj[i].clear();
		for (int i = 1; i <= n; i ++) adj[cnt[i]].push_back(f[i]);
		S = 0;
		for (int i = n; i > 0; i --){
			int mx = -1;
			if (i == 1) for (int x : adj[i]) mx = max(mx, x);
			if (i > 1) for (int x : adj[i]) st.insert({x, S ++});
			if (st.size() || mx > -1){
				int x = -1;
				if (st.size()){
					x = st.begin() -> F;
					st.erase(st.begin());
				}
				x = max(x, mx);
				ans += i;
				ted += min(x, i);
			}
		}
		cout << ans << sep << ted << endl;
	}

	return 0;
}


# include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;

# define F first
# define S second
# define endl '\n'
# define sep ' '
# define pb push_back
# define fast_io ios::sync_with_stdio(0);cin.tie(0); cout.tie(0);

const ll md = 1e9 + 7;
const int xn = 2e5 + 10;
const int xm = 1e5 + 10;
const int SQ = 320;
const int sq = 1e3 + 10;
const ll inf = 1e18 + 10;

ll power(ll a, ll b) {return (!b ? 1 : (b & 1 ? a * power(a * a % md, b / 2) % md : power(a * a % md, b / 2) % md));}
ll zarb(ll a, ll b){return (a * b + 10 * md) % md;}
ll jaam(ll a, ll b){return (a + b + 10 * md) % md;}

int qq, n, cnt[xn], f[xn], ans, ted;
vector <int> adj[xn];
multiset <int, greater <int> > st;

bool cmp(int i, int j){
	if (cnt[i] != cnt[j]) return cnt[i] > cnt[j];
	return f[i] > f[j];
}

int main(){
	fast_io;

	cin >> qq;
	while (qq --){
		memset(cnt, 0, sizeof cnt);
		memset(f, 0, sizeof f);
		ans = ted = 0;
		st.clear();
		cin >> n;
		for (int i = 0; i < n; i ++){
			int x, y;
			cin >> x >> y;
			cnt[x] ++;
			f[x] += y;
		}
		for (int i = 0; i <= n; i ++) adj[i].clear();
		for (int i = 1; i <= n; i ++) adj[cnt[i]].push_back(f[i]);
		for (int i = n; i > 0; i --){
			for (int x : adj[i]) st.insert(x);
			if (st.size()){
				int x = *st.begin();
				st.erase(st.begin());
				ans += i;
				ted += min(x, i);
			}
		}
		cout << ans << sep << ted << endl;
	}

	return 0;
}


# include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;

# define F first
# define S second
# define endl '\n'
# define sep ' '
# define pb push_back
# define fast_io ios::sync_with_stdio(0);cin.tie(0); cout.tie(0);

const ll md = 1e9 + 7;
const int xn = 2e5 + 10;
const int xm = 1e5 + 10;
const int SQ = 320;
const int sq = 1e3 + 10;
const ll inf = 1e18 + 10;

ll power(ll a, ll b) {return (!b ? 1 : (b & 1 ? a * power(a * a % md, b / 2) % md : power(a * a % md, b / 2) % md));}
ll zarb(ll a, ll b){return (a * b + 10 * md) % md;}
ll jaam(ll a, ll b){return (a + b + 10 * md) % md;}

int qq, n, cnt[xn], f[xn], ans, ted, S;
vector <int> adj[xn];
set <pii, greater <pii> > st;

int main(){
	fast_io;

	cin >> qq;
	while (qq --){
		for (int i = 0; i <= n; i ++) cnt[i] = f[i] = 0;
		ans = ted = 0;
		st.clear();
		cin >> n;
		for (int i = 0; i < n; i ++){
			int x, y;
			cin >> x >> y;
			cnt[x] ++;
			f[x] += y;
		}
		for (int i = 0; i <= n; i ++) adj[i].clear();
		for (int i = 1; i <= n; i ++) adj[cnt[i]].push_back(f[i]);
		S = 0;
		for (int i = n; i > 0; i --){
			for (int x : adj[i]) st.insert({x, S ++});
			if (st.size()){
				int x = st.begin() -> F;
				st.erase(st.begin());
				ans += i;
				ted += min(x, i);
			}
		}
		cout << ans << sep << ted << endl;
	}

	return 0;
}


# include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;

# define F first
# define S second
# define endl '\n'
# define sep ' '
# define pb push_back
# define fast_io ios::sync_with_stdio(0);cin.tie(0); cout.tie(0);

const ll md = 1e9 + 7;
const int xn = 2e5 + 10;
const int xm = 1e5 + 10;
const int SQ = 320;
const int sq = 1e3 + 10;
const ll inf = 1e18 + 10;

ll power(ll a, ll b) {return (!b ? 1 : (b & 1 ? a * power(a * a % md, b / 2) % md : power(a * a % md, b / 2) % md));}
ll zarb(ll a, ll b){return (a * b + 10 * md) % md;}
ll jaam(ll a, ll b){return (a + b + 10 * md) % md;}

int qq, n, cnt[xn], f[xn], ans, ted;
vector <int> adj[xn];
multiset <int, greater <int> > st;

int main(){
	fast_io;

	cin >> qq;
	while (qq --){
		memset(cnt, 0, sizeof cnt);
		memset(f, 0, sizeof f);
		ans = ted = 0;
		st.clear();
		cin >> n;
		for (int i = 0; i < n; i ++){
			int x, y;
			cin >> x >> y;
			cnt[x] ++;
			f[x] += y;
		}
		for (int i = 0; i <= n; i ++) adj[i].clear();
		for (int i = 1; i <= n; i ++) adj[cnt[i]].push_back(f[i]);
		for (int i = n; i > 0; i --){
			int mx = 0;
			if (i == 1) for (int x : adj[i]) mx = max(mx, x);
			if (i > 1) for (int x : adj[i]) st.insert(x);
			if (st.size() || mx){
				int x = *st.begin();
				st.erase(st.begin());
				x = max(x, mx);
				ans += i;
				ted += min(x, i);
			}
		}
		cout << ans << sep << ted << endl;
	}

	return 0;
}


# include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;

# define F first
# define S second
# define endl '\n'
# define sep ' '
# define pb push_back
# define fast_io ios::sync_with_stdio(0);cin.tie(0); cout.tie(0);

const ll md = 1e9 + 7;
const int xn = 2e5 + 10;
const int xm = 1e5 + 10;
const int SQ = 320;
const int sq = 1e3 + 10;
const ll inf = 1e18 + 10;

ll power(ll a, ll b) {return (!b ? 1 : (b & 1 ? a * power(a * a % md, b / 2) % md : power(a * a % md, b / 2) % md));}
ll zarb(ll a, ll b){return (a * b + 10 * md) % md;}
ll jaam(ll a, ll b){return (a + b + 10 * md) % md;}

int qq, n, cnt[xn], f[xn], ans, ted;
vector <int> adj[xn];
multiset <int, greater <int> > st;

int main(){
	fast_io;

	cin >> qq;
	while (qq --){
		memset(cnt, 0, sizeof cnt);
		memset(f, 0, sizeof f);
		ans = ted = 0;
		st.clear();
		cin >> n;
		for (int i = 0; i < n; i ++){
			int x, y;
			cin >> x >> y;
			cnt[x] ++;
			f[x] += y;
		}
		for (int i = 0; i <= n; i ++) adj[i].clear();
		for (int i = 1; i <= n; i ++) adj[cnt[i]].push_back(f[i]);
		for (int i = n; i > 0; i --){
			int mx = 0;
			if (i == 1) for (int x : adj[i]) mx = max(mx, x);
			if (i > 1) for (int x : adj[i]) st.insert(x);
			if (st.size() || i == 1){
				int x;
				if (st.size()){
					x = *st.begin();
					st.erase(st.begin());
				}
				x = max(x, mx);
				ans += i;
				ted += min(x, i);
			}
		}
		cout << ans << sep << ted << endl;
	}

	return 0;
}


# include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;

# define F first
# define S second
# define endl '\n'
# define sep ' '
# define pb push_back
# define fast_io ios::sync_with_stdio(0);cin.tie(0); cout.tie(0);

const ll md = 1e9 + 7;
const int xn = 2e5 + 10;
const int xm = 1e5 + 10;
const int SQ = 320;
const int sq = 1e3 + 10;
const ll inf = 1e18 + 10;

ll power(ll a, ll b) {return (!b ? 1 : (b & 1 ? a * power(a * a % md, b / 2) % md : power(a * a % md, b / 2) % md));}
ll zarb(ll a, ll b){return (a * b + 10 * md) % md;}
ll jaam(ll a, ll b){return (a + b + 10 * md) % md;}

int qq, n, cnt[xn], f[xn], ans, ted, num[xn], last, mx;
vector <int> adj[xn];
multiset <int, greater <int> > st;

bool cmp(int i, int j){
	if (cnt[i] != cnt[j]) return cnt[i] > cnt[j];
	return f[i] > f[j];
}

int main(){
	fast_io;

	cin >> qq;
	while (qq --){
		memset(cnt, 0, sizeof cnt);
		memset(f, 0, sizeof f);
		ans = ted = 0, mx = 0;
		while (st.size()) st.erase(st.begin());
		cin >> n;
		for (int i = 0; i < n; i ++){
			int x, y;
			cin >> x >> y;
			cnt[x] ++;
			f[x] += y;
		}
		for (int i = 0; i <= n; i ++) adj[i].clear();
		for (int i = 1; i <= n; i ++) adj[cnt[i]].push_back(f[i]);
		for (int i = n; i > 0; i --){
			for (int x : adj[i]) st.insert(x);
			if (st.size()){
				int x = *st.begin();
				st.erase(st.begin());
				ans += i;
				ted += min(x, i);
			}
		}
		cout << ans << sep << ted << endl;
	}

	return 0;
}


#include <bits/stdc++.h>
#define ll long long
using namespace std;
vector<ll>v;
map<ll,ll>m,mm;
ll n,x,sum,q,y;
int main()
{
    cin>>q;

    while(q--)
    {
        sum=0;
        cin>>n;
        for(int i=0; i<n; i++)
        {
            cin>>x>>y;
            m[x]++;
            if(y)
                mm[x]++;

        }
        map<ll,ll> ::iterator it=m.begin();
        for(; it!=m.end(); it++)
        {
            x=(*it).second;
            v.push_back(x);
        }
        sort(v.begin(),v.end(),greater<ll>());
        ll p=v[0]+1;
        for(ll i=0;i<v.size();i++)
        {
          //  cout<<x<<" ";
            x=v[i];
            if(x<p-1)
                p=x+1;
            while(x>=p)
                x--;
            sum+=x;
            p--;
          //  cout<<x<<" ";
            if(p==0)
                break;
        }
        cout<<sum<<" ";
        m.clear();
       v.clear();
       sum=0;

        for(it=mm.begin(); it!=mm.end(); it++)
        {
            x=(*it).second;
            v.push_back(x);
        }
        sort(v.begin(),v.end(),greater<ll>());
         p=v[0]+1;
        for(ll i=0;i<v.size();i++)
        {
          //  cout<<x<<" ";
            x=v[i];
            if(x<p-1)
                p=x+1;
            while(x>=p)
                x--;
            sum+=x;
            p--;
          //  cout<<x<<" ";
            if(p==0)
                break;
        }
        cout<<sum<<endl;
        mm.clear();
       v.clear();

    }

    return 0;
}
//dvfbrtnyterewtgthtggh


#include <bits/stdc++.h>
#define ll long long
using namespace std;
vector<ll>v;
vector<pair<ll,ll> >vv;
map<ll,ll>m,mm;
ll n,x,sum,q,y;
int main()
{
    cin>>q;

    while(q--)
    {
        sum=0;
        cin>>n;
        for(int i=0; i<n; i++)
        {
            cin>>x>>y;
            m[x]++;
            if(y)
                mm[x]++;

        }
        map<ll,ll> ::iterator it=m.begin();
        for(; it!=m.end(); it++)
        {
            x=(*it).second;
            v.push_back(x);
            if(mm[(*it).first])
                vv.push_back( {mm[(*it).first] ,x} );
        }
        sort(v.begin(),v.end(),greater<ll>());

        ll p=v[0]+1;
        for(ll i=0; i<v.size(); i++)
        {
            //  cout<<x<<" ";
            x=v[i];
            if(x<p-1)
                p=x+1;
            while(x>=p)
                x--;
            sum+=x;
            p--;
            //  cout<<x<<" ";
            if(p==0)
                break;
        }
        cout<<sum<<" ";
        m.clear();
        v.clear();
        sum=0;

        sort(vv.begin(),vv.end(),greater<pair<ll,ll> >());
        p=vv[0].first+1;
        for(ll i=0; i<vv.size(); i++)
        {

            x=vv[i].first;
            // cout<<x<<"  "<<vv[i].second<<" t t  ";
            if(x<p-1)
                p=x+1;
            while(x>=p)
                x--;
            sum+=min(x,vv[i].second);
            p--;
            //  cout<<x<<" ";
            if(p==0)
                break;
        }
        cout<<sum<<endl;
        mm.clear();
        vv.clear();

    }

    return 0;
}
//dvfbrtnyterewtgthtggh


#include <bits/stdc++.h>
#define ll long long
using namespace std;
vector<ll>v;
vector<pair<ll,ll> >vv;

map<ll,ll>m,mm;
ll n,x,q,y;
int main()
{
    cin>>q;
    while(q--)
    {
        ll sum2=0,sum=0;
        cin>>n;
        for(int i=0; i<n; i++)
        {
            cin>>x>>y;
            m[x]++;
            if(y)
                mm[x]++;
        }
      /*  map<ll,ll> ::iterator it=m.begin();
        for(; it!=m.end(); it++)
        {
            x=(*it).second;
            v.push_back(x);
        }
        sort(v.begin(),v.end(),greater<ll>());

        ll p=v[0]+1;
        for(ll i=0; i<v.size(); i++)
        {
            //  cout<<x<<" ";
            x=v[i];
            if(x<p-1)
                p=x+1;
            while(x>=p)
                x--;
            sum2+=x;
            p--;
            if(p==0)
                break;
        }*/
      vector<vector<ll> > vvv(n+10);
        for(int i = 1; i <=n; i++)
            vvv[m[i]].push_back(mm[i]);
        multiset<int> st;
        for(int i = n; i > 0; i--)
        {
            //for(int j=0;j<vvv[i].size();j++)
            for(auto t: vvv[i])
                st.insert(t);
            if(!st.empty())
            {

                int z = *st.rbegin();
               // cout<<i<<" "<<z<<" ";
                sum2 += i;
                sum += min(i, z);
                st.erase(st.find(z));
            }
        }
         mm.clear(), m.clear();
       // for(int i=0;i<n;i++)
         //   vvv[i].clear();
        cout<<sum2<<" "<<sum<<endl;
       //v.clear();

    }

    return 0;
}
//dvfbrtnyterewtgthtggh


#include <bits/stdc++.h>
#define ll long long
using namespace std;
vector<ll>v;
vector<pair<ll,ll> >vv; vector<vector<ll> > vvv(200200);
map<ll,ll>m,mm;
ll n,x,q,y;
int main()
{
    cin>>q;
    while(q--)
    {
        ll sum2=0,sum=0;
        cin>>n;
        for(int i=0; i<n; i++)
        {
            cin>>x>>y;

            m[x]++;
            if(y)
                mm[x]++;
        }
        map<ll,ll> ::iterator it=m.begin();
        for(; it!=m.end(); it++)
        {
            x=(*it).second;
            v.push_back(x);
        }
        sort(v.begin(),v.end(),greater<ll>());

        ll p=v[0]+1;
        for(ll i=0; i<v.size(); i++)
        {
            //  cout<<x<<" ";
            x=v[i];
            if(x<p-1)
                p=x+1;
            while(x>=p)
                x--;
            sum2+=x;
            p--;
            if(p==0)
                break;
        }

        for(int i = 1; i <=n; i++)
            vvv[m[i]].push_back(mm[i]);
        multiset<int> st;
        for(int i = n; i > 0; i--)
        {

            //for(int j=0;j<vvv[i].size();j++)
            for(auto t: vvv[i])
                st.insert(t);
            if(!st.empty())
            {

                int z = *st.rbegin();
                //sum2 += i;
                sum += min(i, z);
                st.erase(st.find(z));
            }
        }
         v.clear(), mm.clear(), m.clear();
        for(int i=0;i<vvv.size();i++)
            vvv[i].clear();
        cout<<sum2<<" "<<sum<<endl;

    }

    return 0;
}
//dvfbrtnyterewtgthtggh


#include <bits/stdc++.h>
#define ll long long
using namespace std;
vector<ll>v;
vector<pair<ll,ll> >vv;
 vector<vector<ll> > vvv(200200);
map<ll,ll>m,mm;
ll n,x,q,y;
int main()
{
    cin>>q;
    while(q--)
    {
        ll sum2=0,sum=0;
        cin>>n;
        for(int i=0; i<n; i++)
        {
            cin>>x>>y;
            m[x]++;
            if(y)
                mm[x]++;
        }
      /*  map<ll,ll> ::iterator it=m.begin();
        for(; it!=m.end(); it++)
        {
            x=(*it).second;
            v.push_back(x);
        }
        sort(v.begin(),v.end(),greater<ll>());

        ll p=v[0]+1;
        for(ll i=0; i<v.size(); i++)
        {
            //  cout<<x<<" ";
            x=v[i];
            if(x<p-1)
                p=x+1;
            while(x>=p)
                x--;
            sum2+=x;
            p--;
            if(p==0)
                break;
        }*/

        for(int i = 1; i <=n; i++)
            vvv[m[i]].push_back(mm[i]);
        multiset<int> st;
        for(int i = n; i > 0; i--)
        {
            //for(int j=0;j<vvv[i].size();j++)
            for(auto t: vvv[i])
                st.insert(t);
            if(!st.empty())
            {

                int z = *st.rbegin();
               // cout<<i<<" "<<z<<" ";
                sum2 += i;
                sum += min(i, z);
                st.erase(st.find(z));
            }
        }
         mm.clear(), m.clear();
        for(int i=0;i<n;i++)
            vvv[i].clear();
        cout<<sum2<<" "<<sum<<endl;
       //v.clear();

    }

    return 0;
}
//dvfbrtnyterewtgthtggh