<|instruction|>
Solve the below problem. The solution should start with an abridged problem statement. Then key observations. Then full solution based on the observations. Then C++ and Python implementations with comments.

549. Dumbbells
Time limit per test: 1 second(s)
Memory limit: 262144 kilobytes
input: standard
output: standard



A sports shop has n dumbbells in store. Each of them is characterised by its mass mi and cost ci. Recently the shop manager faced the following non-trivial problem. He has to find the maximum number of sports sets that satisfy the following requirements:

each set must contain exactly k dumbbells;
each set must have dumbbells of k distinct masses;
for each pair of sets the masses of dumbbells must coincide , that is, the masses in the sets must be equal as .


The manager's task is to make the maximum number of such sets. If there are several ways to make the maximum possible number of sets, he should choose the one that has the maximum total cost of dumbbells that are contained in the chosen sets. Note that the primary goal is to maximize the number of sets and maximization of the total cost is the secondary goal.

Input
The first line of the input contains integers n and k (1 ≤ n,k ≤ 4000). Next n lines contain descriptions of the dumbbells, one per line. Each description consists of a pair of integers mi, ci (1 ≤ mi,ci ≤ 4000), mi is the mass of the i-th dumbbell, and ci is its cost.

Output
In the only output line print two integers — t and s, where t is the maximum number of sets, and s is the maximum total cost of dumbbells in t choosen sets. If the manager can't make at least one set, print a pair of zeroes.

Example(s)
sample input
sample output
7 2
16 1
4 6
16 7
7 100
32 9
4 6
32 1
2 22

sample input
sample output
4 2
1 2
2 1
4 3
1 7
1 10



Note
In the first sample the manager should make two sets. One of the possible solutions is as follows: the first set contains the second and the seventh dumbbells, the second set contains the fifth and the sixth dumbbells.

In the second sample the manager can make only one set. It consists of the third and the fourth dumbbells.

<|response|>
1. Abridged Problem Statement
You have n dumbbells, each with a mass mᵢ and a cost cᵢ. You want to form as many identical "sets" as possible, where:
- Each set contains exactly k dumbbells.
- Within a set, all k masses must be distinct.
- All sets use the same k masses.
First maximize the number t of complete sets you can form. Then, among all ways to form t sets, maximize the total cost of the selected dumbbells. Output t and that maximum total cost. If you cannot form even one set, output "0 0."

2. Key Observations
- To make t sets you need k distinct masses, each available in at least t copies.
- For a given mass m with c₁, c₂, …, cₚ costs sorted descending, if you use that mass in t sets you will pick its t most expensive dumbbells (c₁ + … + cₜ).
- The maximum possible t is determined by the k-th largest supply among all masses.
- Once t is fixed, among all masses with supply ≥ t, you should pick the k masses whose top-t sum of costs is largest.

3. Full Solution Approach
Step 1. Group by mass
- Build a map mass → list of costs.

Step 2. Sort each group's costs in descending order
- This lets you quickly compute the sum of the top t costs for any t.

Step 3. Gather supplies
- For each mass m, let countₘ = number of dumbbells of that mass.
- Form a list of these counts and sort it descending.

Step 4. Determine t (maximum number of sets)
- If there are fewer than k distinct masses, answer is (0,0).
- Otherwise, the maximum t is the k-th largest count in the sorted list.

Step 5. Maximize total cost for t sets
- Among all masses with countₘ ≥ t, compute Sₘ = sum of the top t costs.
- Sort the Sₘ values descending and take the sum of the top k of them.

Step 6. Output
- Print t and the computed total cost.

Complexity:
- Grouping and sorting costs in each group: O(n log n) total.
- Sorting the counts: O(M log M), where M ≤ n is the number of distinct masses.
- Summing top-t costs and sorting those sums: O(M log M).
Fits easily for n,k ≤ 4000.

4. C++ Implementation with Detailed Comments
```cpp
#include <bits/stdc++.h>

using namespace std;

template<typename T1, typename T2>
ostream& operator<<(ostream& out, const pair<T1, T2>& x) {
    return out << x.first << ' ' << x.second;
}

template<typename T1, typename T2>
istream& operator>>(istream& in, pair<T1, T2>& x) {
    return in >> x.first >> x.second;
}

template<typename T>
istream& operator>>(istream& in, vector<T>& a) {
    for(auto& x: a) {
        in >> x;
    }
    return in;
};

template<typename T>
ostream& operator<<(ostream& out, const vector<T>& a) {
    for(auto x: a) {
        out << x << ' ';
    }
    return out;
};

int n, k;
vector<pair<int, int>> dumbbells;

void read() {
    cin >> n >> k;
    dumbbells.resize(n);
    cin >> dumbbells;
}

void solve() {
    // Each set fixes a multiset of k distinct masses shared by every set, so a
    // mass can contribute one dumbbell to each of the t sets only if it has at
    // least t dumbbells. Group costs by mass; the number of sets t is limited
    // to k (k distinct masses per set) and to how many masses are frequent
    // enough, so the best t is the count of the k-th most frequent mass: with
    // that t we have at least k masses each owning >= t dumbbells.
    //
    // For each eligible mass (count >= t) take its t most expensive dumbbells
    // and sum them; we then pick the k masses with the largest such sums to
    // maximize total cost. If there are fewer than k distinct masses no set
    // can be formed and the answer is 0 0.

    map<int, vector<int>> mass_to_costs;
    for(auto [m, c]: dumbbells) {
        mass_to_costs[m].push_back(c);
    }

    vector<pair<int, int>> frequency;
    for(auto& [mass, costs]: mass_to_costs) {
        sort(costs.rbegin(), costs.rend());
        frequency.push_back({(int)costs.size(), mass});
    }

    sort(frequency.rbegin(), frequency.rend());

    if((int)frequency.size() < k) {
        cout << 0 << ' ' << 0 << '\n';
        return;
    }

    int t = frequency[k - 1].first;

    vector<int64_t> selected;
    for(auto [count, mass]: frequency) {
        if(count < t) {
            break;
        }

        int64_t sum_costs = 0;
        for(int i = 0; i < t; i++) {
            sum_costs += mass_to_costs[mass][i];
        }

        selected.push_back(sum_costs);
    }

    sort(selected.rbegin(), selected.rend());

    int64_t total = 0;
    for(int i = 0; i < k; i++) {
        total += selected[i];
    }

    cout << t << ' ' << total << '\n';
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int T = 1;
    // cin >> T;
    for(int test = 1; test <= T; test++) {
        read();
        // cout << "Case #" << test << ": ";
        solve();
    }

    return 0;
}
```

5. Python Implementation with Detailed Comments
```python
import sys
from collections import defaultdict

def main():
    data = sys.stdin.read().split()
    n, k = map(int, data[:2])
    idx = 2

    # Step 1: group costs by mass
    mass_to_costs = defaultdict(list)
    for _ in range(n):
        m = int(data[idx]); c = int(data[idx+1])
        idx += 2
        mass_to_costs[m].append(c)

    # Step 2 & 3: sort each mass's costs descending; build supply list
    supply = []  # list of (count, mass)
    for m, costs in mass_to_costs.items():
        costs.sort(reverse=True)
        supply.append((len(costs), m))

    # Sort by descending count
    supply.sort(reverse=True)

    # If fewer than k distinct masses, no sets can be formed
    if len(supply) < k:
        print(0, 0)
        return

    # Step 4: maximum number of sets t = k-th largest count
    t = supply[k-1][0]
    if t == 0:
        print(0, 0)
        return

    # Step 5: compute for each mass with count>=t the sum of top t costs
    candidate_sums = []
    for cnt, m in supply:
        if cnt < t:
            break
        # sum the t largest costs
        candidate_sums.append(sum(mass_to_costs[m][:t]))

    # pick the best k sums
    candidate_sums.sort(reverse=True)
    total_cost = sum(candidate_sums[:k])

    # Step 6: output t and total cost
    print(t, total_cost)

if __name__ == "__main__":
    main()
```
