Problem: 2057B - Gorilla and the Exam
Language: c++17 

Solution 1 (runtime: 77 ms):
#include <algorithm>
#include <bits/stdc++.h>
#include <cassert>
#include <climits>
#include <cstdint>
#include <cstring>
#include <math.h>
#include <ostream>
#include <string>
#include <type_traits>
#include <vector>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>


using namespace std;
using namespace __gnu_pbds;

typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> pbds; // find_by_order, order_of_key

#define LOCAL
#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifdef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
    *this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (_VA_ARGS_) << "] "


#define arr array
#define ll long long
#define ld long double
#define sz(x) ((int)x.size())
#define all(a) (a).begin(), (a).end()
#define f first
#define s second
#define pb push_back
#define mp make_pair
#define endl '\n'
#define NO cout << "NO" << endl
#define YES cout << "YES" << endl
#define read(v) for (auto &u : v) cin >> u;
#define print(v) for (auto u : v) cout << u << ' ';




vector<pair<ll,ll>> nb_premier(ll x){

        vector<pair<ll,ll>>res;
        if(!(x&1)){
                ll cnt=0;
        while(!(x&1)){
            x/=2;cnt++;
        }
        res.pb({2,cnt});
        }
        for(ll i=3;i*i<=x;i+=2){
            if(! (x%i)) {
                ll c=0;
                while(!(x%i)){
                x/=i;c++;}
            res.pb({i,c});
            }
        }



        if(x>1) res.pb({x,1});
        return res;
}
ll power(ll n,ll p)
{
    ll res=1;
    for(ll i=0;i<p;i++)
    {
        res*=n;

    }
    return res;
}
vector<bool>seive(int n){

    vector<bool>prime(n+1,true);

    for(int i=2;i*i<=n;++i){
        if(prime[i]){

            for(int j=i*i;j<=n;j+=i){
                prime[j]=false;
            }
        }
    }
    return prime;

}



// you should actually read the stuff at the bottom
const ll M=1e9+7;
const int MAX_N = 100005;

int dfs(int node, vector<vector<int>>& adj,vector<int>& stars, vector<bool>& visited) {
    stack<int> s;
    vector<int> results;
    s.push(node);
    visited[node] = true;
    int res=0;
    while (!s.empty()) {
        int current = s.top();
        s.pop();
        int star=stars[current];

        bool test=false,test1=false;
        for (int neighbor : adj[current]) {
            if (!visited[neighbor]) {
                test=true;
                if(stars[neighbor] > stars[current]){
                ++res;test1=true;
                visited[neighbor] = true;
                s.push(neighbor);
                }
                else {
                    test1=false;
                visited[neighbor] = true;
                s.push(neighbor);
                }
            }
    }
    if(!test) {
        results.push_back(res);
        if(test1)--res;
    }

}
return *max_element(results.begin(),results.end());

}
int gcd(int a, int b) {

    if (b == 0) {
        return a;
    }

    return gcd(b, a % b);
}


pair<ll, ll> find_max_distance_pair(ll l, ll r, ll G) {

    ll a_min=(l+G-1)/G;
    ll a_max=r/G;

    ll best_A = -1, best_B = -1;
    ll max_distance = -1;
    for (ll a = a_min; a <= a_max; ++a) {
        ll A = G * a;
        for (ll b = a_max; b >= a; --b) {
            ll B = G * b;
            if (gcd(a, b) == 1) {
                int distance = abs(A - B);
                if (distance > max_distance) {
                    max_distance = distance;
                    best_A = A;
                    best_B = B;
                }
                break;
            }
        }
    }

    return make_pair(best_A, best_B);
}


void test_case()
{
   ll n,k;cin>>n>>k;
   vector<ll>a(n);for(ll i=0;i<n;++i) cin>>a[i];
   sort(a.begin(),a.end());
   vector<ll>cnt={1};
   for(ll i=1;i<n;++i)
   {
       if(a[i]==a[i-1])
       {
           cnt.back()++;
       }else
       {
           cnt.pb(1);
       }
   }
   ll m=cnt.size();
   sort(cnt.begin(),cnt.end());
   ll x=0;
   for(ll i=0;i<m;++i)
   {
       if(x+cnt[i]<=k)
       {
           x+=cnt[i];
       }
       else{
        cout<<m-i<<endl;return;
       }
   }
   cout<<"1\n";



}







int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cout << fixed << setprecision(15);
    int t=1;
    cin>>t;
    while(t--)
        test_case();

return 0;

}


Solution 2 (runtime: 109 ms):
#include <iostream>
//#include <fstream>
#include <string>
#include <cstring>
#include <vector>
#include <random>
#include <iterator>
#include <numeric>
#include <unordered_map>
#include <map>
#include <unordered_set>
#include <set>
#include <bitset>
//#include <limits>
#include <climits>
#include <queue>
#include <stack>
#include <deque>
#include <tuple>
#include <list>
#include <math.h> 
#include <random> 
#include <algorithm>
#include <chrono>
#include <iomanip>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
#include <array>
#include <tuple>
#include <functional>
#include <cctype>
#include <cstdlib>
#include <ctime>
#include <float.h>


/*
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
 
typedef __gnu_pbds::tree<int, __gnu_pbds::null_type, less<int>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update> ordered_set;

ordered_set st; 
*/

// g++-13 -std=c++11 codeforce.cpp -o codeforce
// g++ -std=c++11 codeforce.cpp -o codeforce
// ./codeforce <codef.txt 


using namespace std;
//using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;
//typedef string str;

vector<int> manacher_odd(string s) {
    int n = s.size();
    s = "$" + s + "^";
    vector<int> p(n + 2);
    int l = 1, r = 1;
    for(int i = 1; i <= n; i++) {
        p[i] = max(0, min(r - i, p[l + (r - i)]));
        while(s[i - p[i]] == s[i + p[i]]) {
            p[i]++;
        }
        if(i + p[i] > r) {
            l = i - p[i], r = i + p[i];
        }
    }
    return vector<int>(begin(p) + 1, end(p) - 1);
}
vector<int> manacher(string s) {
    string t;
    for(auto c: s) {
        t += string("#") + c;
    }
    auto res = manacher_odd(t + "#");
    return vector<int>(begin(res) + 1, end(res) - 1);
}

// mt19937_64 rnd(98275314);
// ll gen(){
//     ll x=0;
//     while(x==0){
//         x=rnd();
//     }
//     return x;
// }
vector<int> z_function(string s) {
    int n = s.size();
    vector<int> z(n);
    int l = 0, r = 0;
    for(int i = 1; i < n; i++) {
        if(i < r) {
            z[i] = min(r - i, z[i - l]);
        }
        while(i + z[i] < n && s[z[i]] == s[i + z[i]]) {
            z[i]++;
        }
        if(i + z[i] > r) {
            l = i;
            r = i + z[i];
        }
    }
    return z;
}
/*
template<class T>
struct MaxFlow {
    struct _Edge {
        int to;
        T cap;
        _Edge(int to, T cap) : to(to), cap(cap) {}
    };
    int n;
    std::vector<_Edge> e;
    std::vector<std::vector<int> > g;
    std::vector<int> cur, h;
    MaxFlow() {}
    MaxFlow(int n) {
        init(n);
    }
    void init(int n) {
        this->n = n;
        e.clear();
        g.assign(n, {});
        cur.resize(n);
        h.resize(n);
    }
    bool bfs(int s, int t) {
        h.assign(n, -1);
        std::queue<int> que;
        h[s] = 0;
        que.push(s);
        while (!que.empty()) {
            const int u = que.front();
            que.pop();
            for (int i : g[u]) {
                auto [v, c] = e[i];
                if (c > 0 && h[v] == -1) {
                    h[v] = h[u] + 1;
                    if (v == t) {
                        return true;
                    }
                    que.push(v);
                }
            }
        }
        return false;
    }
    T dfs(int u, int t, T f) {
        if (u == t) {
            return f;
        }
        auto r = f;
        for (int &i = cur[u]; i < int(g[u].size()); ++i) {
            const int j = g[u][i];
            auto [v, c] = e[j];
            if (c > 0 && h[v] == h[u] + 1) {
                auto a = dfs(v, t, std::min(r, c));
                e[j].cap -= a;
                e[j ^ 1].cap += a;
                r -= a;
                if (r == 0) {
                    return f;
                }
            }
        }
        return f - r;
    }
    void addEdge(int u, int v, T c) {
        g[u].push_back(e.size());
        e.emplace_back(v, c);
        g[v].push_back(e.size());
        e.emplace_back(u, 0);
    }
    T flow(int s, int t) {
        T ans = 0;
        while (bfs(s, t)) {
            cur.assign(n, 0);
            ans += dfs(s, t, std::numeric_limits<T>::max());
        }
        return ans;
    }
    std::vector<bool> minCut() {
        std::vector<bool> c(n);
        for (int i = 0; i < n; i++) {
            c[i] = (h[i] != -1);
        }
        return c;
    }
    struct Edge {
        int from;
        int to;
        T cap;
        T flow;
    };
    std::vector<Edge> edges() {
        std::vector<Edge> a;
        for (int i = 0; i < e.size(); i += 2) {
            Edge x;
            x.from = e[i + 1].to;
            x.to = e[i].to;
            x.cap = e[i].cap + e[i + 1].cap;
            x.flow = e[i + 1].cap;
            a.push_back(x);
        }
        return a;
    }
};
*/
// std::mt19937_64 rng {std::chrono::steady_clock::now().time_since_epoch().count()};

void solve(){
    int n,k;
    cin>>n>>k;
    map<int,int>M;
    for(int i=0;i<n;++i){
        int x;
        cin>>x;
        M[x]++;
    }
    int ans=M.size();
    priority_queue<int,vector<int>, greater<int> >PQ;
    for(auto&it:M){
        PQ.push(it.second);
    }
    while(PQ.size() && k>=PQ.top()){
        k-=PQ.top();
        ans--;
        PQ.pop();
    }
    cout<<max(1,ans)<<endl;
}
int main(int argc, char *argv[]) {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    cout<<std::setprecision(20);
    int t=1;
    cin>>t;
    while(t--){
        solve();
    }
}

/*

FOR ICPC style rounds, read all problems! don't get stuck on 1.
*/
/*
nice trick: 
up is down?

Fenwick
int lowbit(int i) { // gets the lowest set bit
	return (-i)&i;
}
adds 1 from [1,i];
void bitadd(int i) {
	for(;i<=n;i+=lowbit(i)) bit[i]++;
}
queries [1,i];
int bitqu(int i) {
	int ans=0;
	for(;i;i-=lowbit(i)) ans+=bit[i];
	return ans;
}
*/