// ███▓▓▓▓▓▓▓▓▓╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬▓▓▓╬╬╬╬╬╬▓█
// ███▓███████▓▓╬╬╬╬╬╬╬╬╬╬╬╬▓███▓▓▓▓█▓╬╬╬▓█
// ███████▓█████▓▓╬╬╬╬╬╬╬╬▓███▓╬╬╬╬╬╬╬▓╬╬▓█
// ████▓▓▓▓╬╬▓█████╬╬╬╬╬╬███▓╬╬╬╬╬╬╬╬╬╬╬╬╬█
// ███▓▓▓▓╬╬╬╬╬╬▓██╬╬╬╬╬╬▓▓╬╬╬╬╬╬╬╬╬╬╬╬╬╬▓█
// ████▓▓▓╬╬╬╬╬╬╬▓█▓╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬▓█
// ███▓█▓███████▓▓███▓╬╬╬╬╬╬▓███████▓╬╬╬╬▓█
// ████████████████▓█▓╬╬╬╬╬▓▓▓▓▓▓▓▓╬╬╬╬╬╬╬█
// ███▓▓▓▓▓▓▓╬╬▓▓▓▓▓█▓╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬▓█
// ████▓▓▓╬╬╬╬▓▓▓▓▓▓█▓╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬▓█
// ███▓█▓▓▓▓▓▓▓▓▓▓▓▓▓▓╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬▓█
// █████▓▓▓▓▓▓▓▓█▓▓▓█▓╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬▓█
// █████▓▓▓▓▓▓▓██▓▓▓█▓╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬██
// █████▓▓▓▓▓████▓▓▓█▓╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬██
// ████▓█▓▓▓▓██▓▓▓▓██╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬██
// ████▓▓███▓▓▓▓▓▓▓██▓╬╬╬╬╬╬╬╬╬╬╬╬█▓╬▓╬╬▓██
// █████▓███▓▓▓▓▓▓▓▓████▓▓╬╬╬╬╬╬╬█▓╬╬╬╬╬▓██
// █████▓▓█▓███▓▓▓████╬▓█▓▓╬╬╬▓▓█▓╬╬╬╬╬╬███
// ██████▓██▓███████▓╬╬╬▓▓╬▓▓██▓╬╬╬╬╬╬╬▓███
// ███████▓██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓╬╬╬╬╬╬╬╬╬╬╬████
// ███████▓▓██▓▓▓▓▓╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬▓████
// ████████▓▓▓█████▓▓╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬╬▓█████
// █████████▓▓▓█▓▓▓▓▓███▓╬╬╬╬╬╬╬╬╬╬╬▓██████
// ██████████▓▓▓█▓▓▓╬▓██╬╬╬╬╬╬╬╬╬╬╬▓███████
// ███████████▓▓█▓▓▓▓███▓╬╬╬╬╬╬╬╬╬▓████████
// ██████████████▓▓▓███▓▓╬╬╬╬╬╬╬╬██████████
// ███████████████▓▓▓██▓▓╬╬╬╬╬╬▓███████████
// #pragma GCC optimize("Ofast")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,tune=native")
// #pragma GCC optimize("unroll-loops")
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <cstdio>
#include <numeric>
#include <cstring>
#include <ctime>
#include <cstdlib>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <list>
#include <cmath>
#include <bitset>
#include <cassert>
#include <queue>
#include <deque>
#include <cassert>
#include <iomanip>
#include <chrono>
#define pb push_back
#define x first
#define y second
#define mp make_pair
#define files(FILENAME) read(FILENAME); write(FILENAME)
#define read(FILENAME) freopen((string(FILENAME) + ".in").c_str(), "r", stdin)
#define write(FILENAME) freopen((string(FILENAME) + ".out").c_str(), "w", stdout)
using namespace std;

template<typename T1, typename T2>inline void chkmin(T1 &x, T2 y) { if (x > y) x = y; }
template<typename T1, typename T2>inline void chkmax(T1 &x, T2 y) { if (x < y) x = y; }
template<typename T, typename U> inline ostream &operator<< (ostream &_out, const pair<T, U> &_p) { _out << _p.first << ' ' << _p.second; return _out; }
template<typename T, typename U> inline istream &operator>> (istream &_in, pair<T, U> &_p) { _in >> _p.first >> _p.second; return _in; }
template<typename T> inline ostream &operator<< (ostream &_out, const vector<T> &_v) { if (_v.empty()) { return _out; } _out << _v.front(); for (auto _it = ++_v.begin(); _it != _v.end(); ++_it) { _out << ' ' << *_it; } return _out; }
template<typename T> inline istream &operator>> (istream &_in, vector<T> &_v) { for (auto &_i : _v) { _in >> _i; } return _in; }
template<typename T> inline ostream &operator<< (ostream &_out, const set<T> &_s) { if (_s.empty()) { return _out; } _out << *_s.begin(); for (auto _it = ++_s.begin(); _it != _s.end(); ++_it) { _out << ' ' << *_it; } return _out; }
template<typename T> inline ostream &operator<< (ostream &_out, const multiset<T> &_s) { if (_s.empty()) { return _out; } _out << *_s.begin(); for (auto _it = ++_s.begin(); _it != _s.end(); ++_it) { _out << ' ' << *_it; } return _out; }
template<typename T> inline ostream &operator<< (ostream &_out, const unordered_set<T> &_s) { if (_s.empty()) { return _out; } _out << *_s.begin(); for (auto _it = ++_s.begin(); _it != _s.end(); ++_it) { _out << ' ' << *_it; } return _out; }
template<typename T> inline ostream &operator<< (ostream &_out, const unordered_multiset<T> &_s) { if (_s.empty()) { return _out; } _out << *_s.begin(); for (auto _it = ++_s.begin(); _it != _s.end(); ++_it) { _out << ' ' << *_it; } return _out; }
template<typename T, typename U> inline ostream &operator<< (ostream &_out, const map<T, U> &_m) { if (_m.empty()) { return _out; } _out << '(' << _m.begin()->first << ": " << _m.begin()->second << ')'; for (auto _it = ++_m.begin(); _it != _m.end(); ++_it) { _out << ", (" << _it->first << ": " << _it->second << ')'; } return _out; }
template<typename T, typename U> inline ostream &operator<< (ostream &_out, const unordered_map<T, U> &_m) { if (_m.empty()) { return _out; } _out << '(' << _m.begin()->first << ": " << _m.begin()->second << ')'; for (auto _it = ++_m.begin(); _it != _m.end(); ++_it) { _out << ", (" << _it->first << ": " << _it->second << ')'; } return _out; }

typedef long long base;
typedef pair<base, base> point;

long long ans = 1e18;

int n, m;

vector<int> w[3001];
vector<pair<int, int>> c;

bool cmp(pair<int, int> a, pair<int, int> b) {
	return mp(w[a.x][a.y], a) < mp(w[b.x][b.y], b) ;
}

int main() {
    ios::sync_with_stdio(0);
    srand(time(0));
   	//read("input");
   	cin >> n >> m;
   	for (int i = 0; i < n; ++i) {
   		int a, b;
   		cin >> a >> b;
   		--a;
   		c.pb({a, w[a].size()});
   		w[a].pb(b);
   	}
   	for (int i = 0; i < m; ++i) {
   		sort(w[i].begin(), w[i].end());
   	}
   	sort(c.begin(), c.end(), cmp);
   	for (int i = 1; i <= n; ++i) {
   		long long cost = 0;
   		int d = i;
   		d -= (int)w[0].size();
   		for (int j = 1; j < m; ++j) {
			int del = (int)w[j].size() - i + 1;
			for (int q = 0; q < del; ++q) {
				cost += w[j][q];
			}
			d -= max(0, del);
   		}
		for (auto j : c) {
			if (d <= 0) break;
			int del = (int)w[j.x].size() - i + 1;
			if (j.y < del) continue;
			--d;
			cost += w[j.x][j.y];
		}
		//cout << i << ' ' << d << ' ' << cost << endl;
   		if (d <= 0) chkmin(ans, cost);
   	}
   	cout << ans << '\n';
}


#include <iostream>
#include <vector>
#include <utility>
#include <cstring>
#include <numeric>
#include <functional>
#include <set>
#include <algorithm>
#include <map>
#include <ctime>

using namespace std;

const int MAXN = 3010;

int tally[MAXN];
int which[MAXN];
int cost[MAXN];

int main()
{
	int N, M;
	scanf("%d %d", &N, &M);
	for (int i = 0; i < N; i++) {
	    scanf("%d %d", which + i, cost + i);
		which[i]--;
		tally[which[i]]++;
	}

	if (tally[0] == N) {
	    cout << 0 << '\n';
	    return 0;
	}

	long long mincost = (long long)(1e18);
	for (int V = 1; V <= N; V++) {
	    if (clock() / (double)CLOCKS_PER_SEC > 1.95)
	        break;

		map<pair<int, int>, vector<int>> tally_to_costs;
		multiset<int> just_cost;
		long long curr_cost = 0;
		int curr_votes = tally[0];
		for (int i = 0; i < N; i++) {
			int party = which[i];
			if (party == 0)
				continue;

			tally_to_costs[make_pair(tally[party], party)].push_back(cost[i]);
			just_cost.insert(cost[i]);
		}

		for (auto& itr : tally_to_costs) {
			auto& vec = itr.second;
			sort(vec.begin(), vec.end());
			reverse(vec.begin(), vec.end());
		}

		while (tally_to_costs.rbegin()->second.size() >= V) {
			auto& vec = tally_to_costs.rbegin()->second;
			int cost_to_take = vec.back();
			curr_cost += cost_to_take;
			vec.pop_back();

			/* update the thingy */
			auto key = tally_to_costs.rbegin()->first;
			auto goon = tally_to_costs.extract(key);
			goon.key() = make_pair(key.first - 1, key.second);
			tally_to_costs.insert(move(goon));
			curr_votes++;

			/* update the other thingy */
			just_cost.erase(just_cost.find(cost_to_take));
		}

		while (curr_votes < V) {
			curr_cost += *just_cost.begin();
			just_cost.erase(just_cost.begin());
			curr_votes++;
		}

		mincost = min(mincost, curr_cost);
	}

	printf("%lld\n", mincost);
	return 0;
}


#include <iostream>
#include <vector>
#include <utility>
#include <cstring>
#include <numeric>
#include <functional>
#include <set>
#include <algorithm>
#include <map>
#include <ctime>

using namespace std;

const int MAXN = 3010;

int tally[MAXN];
int which[MAXN];
int cost[MAXN];

int main()
{
	int N, M;
	scanf("%d %d", &N, &M);
	for (int i = 0; i < N; i++) {
	    scanf("%d %d", which + i, cost + i);
		which[i]--;
		tally[which[i]]++;
	}

	if (tally[0] == N) {
	    cout << 0 << '\n';
	    return 0;
	}

	long long mincost = (long long)(1e18);
	for (int V = 1; V <= N; V++) {
	    if (clock() / CLOCKS_PER_SEC > 1.90)
	        break;

		map<pair<int, int>, vector<int>> tally_to_costs;
		multiset<int> just_cost;
		long long curr_cost = 0;
		int curr_votes = tally[0];
		for (int i = 0; i < N; i++) {
			int party = which[i];
			if (party == 0)
				continue;

			tally_to_costs[make_pair(tally[party], party)].push_back(cost[i]);
			just_cost.insert(cost[i]);
		}

		for (auto& itr : tally_to_costs) {
			auto& vec = itr.second;
			sort(vec.begin(), vec.end());
			reverse(vec.begin(), vec.end());
		}

		while (tally_to_costs.rbegin()->second.size() >= V) {
			auto& vec = tally_to_costs.rbegin()->second;
			int cost_to_take = vec.back();
			curr_cost += cost_to_take;
			vec.pop_back();

			/* update the thingy */
			auto key = tally_to_costs.rbegin()->first;
			auto goon = tally_to_costs.extract(key);
			goon.key() = make_pair(key.first - 1, key.second);
			tally_to_costs.insert(move(goon));
			curr_votes++;

			/* update the other thingy */
			just_cost.erase(just_cost.find(cost_to_take));
		}

		while (curr_votes < V) {
			curr_cost += *just_cost.begin();
			just_cost.erase(just_cost.begin());
			curr_votes++;
		}

		mincost = min(mincost, curr_cost);
	}

	printf("%lld\n", mincost);
	return 0;
}


#include <iostream>
#include <vector>
#include <utility>
#include <cstring>
#include <numeric>
#include <functional>
#include <set>
#include <algorithm>
#include <map>
#include <ctime>

using namespace std;

const int MAXN = 3010;

int tally[MAXN];
int which[MAXN];
int cost[MAXN];

int main()
{
	int N, M;
	scanf("%d %d", &N, &M);
	for (int i = 0; i < N; i++) {
	    scanf("%d %d", which + i, cost + i);
		which[i]--;
		tally[which[i]]++;
	}

	if (tally[0] == N) {
	    cout << 0 << '\n';
	    return 0;
	}

	long long mincost = (long long)(1e18);
	for (int V = 1; V <= N; V++) {
	    if (clock() / CLOCKS_PER_SEC > 1.95)
	        break;

		map<pair<int, int>, vector<int>> tally_to_costs;
		multiset<int> just_cost;
		long long curr_cost = 0;
		int curr_votes = tally[0];
		for (int i = 0; i < N; i++) {
			int party = which[i];
			if (party == 0)
				continue;

			tally_to_costs[make_pair(tally[party], party)].push_back(cost[i]);
			just_cost.insert(cost[i]);
		}

		for (auto& itr : tally_to_costs) {
			auto& vec = itr.second;
			sort(vec.begin(), vec.end());
			reverse(vec.begin(), vec.end());
		}

		while (tally_to_costs.rbegin()->second.size() >= V) {
			auto& vec = tally_to_costs.rbegin()->second;
			int cost_to_take = vec.back();
			curr_cost += cost_to_take;
			vec.pop_back();

			/* update the thingy */
			auto key = tally_to_costs.rbegin()->first;
			auto goon = tally_to_costs.extract(key);
			goon.key() = make_pair(key.first - 1, key.second);
			tally_to_costs.insert(move(goon));
			curr_votes++;

			/* update the other thingy */
			just_cost.erase(just_cost.find(cost_to_take));
		}

		while (curr_votes < V) {
			curr_cost += *just_cost.begin();
			just_cost.erase(just_cost.begin());
			curr_votes++;
		}

		mincost = min(mincost, curr_cost);
	}

	printf("%lld\n", mincost);
	return 0;
}


#include <iostream>
#include <vector>
#include <utility>
#include <cstring>
#include <numeric>
#include <functional>
#include <set>
#include <algorithm>
#include <map>

using namespace std;

const int MAXN = 3010;

int tally[MAXN];
int which[MAXN];
int cost[MAXN];

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

	int N, M;
	cin >> N >> M;
	for (int i = 0; i < N; i++) {
		cin >> which[i] >> cost[i];
		which[i]--;
		tally[which[i]]++;
	}

	if (tally[0] == N) {
	    cout << 0 << '\n';
	    return 0;
	}

	long long mincost = (long long)(1e18);
	for (int V = 1; V <= N; V++) {
		map<pair<int, int>, vector<int>> tally_to_costs;
		multiset<int> just_cost;
		long long curr_cost = 0;
		int curr_votes = tally[0];
		for (int i = 0; i < N; i++) {
			int party = which[i];
			if (party == 0)
				continue;

			tally_to_costs[make_pair(tally[party], party)].push_back(cost[i]);
			just_cost.insert(cost[i]);
		}

		for (auto& itr : tally_to_costs) {
			auto& vec = itr.second;
			sort(vec.begin(), vec.end());
			reverse(vec.begin(), vec.end());
		}

		while (tally_to_costs.rbegin()->second.size() >= V) {
			auto& vec = tally_to_costs.rbegin()->second;
			int cost_to_take = vec.back();
			curr_cost += cost_to_take;
			vec.pop_back();

			/* update the thingy */
			auto key = tally_to_costs.rbegin()->first;
			auto goon = tally_to_costs.extract(key);
			goon.key() = make_pair(key.first - 1, key.second);
			tally_to_costs.insert(move(goon));
			curr_votes++;

			/* update the other thingy */
			just_cost.erase(just_cost.find(cost_to_take));
		}

		while (curr_votes < V) {
			curr_cost += *just_cost.begin();
			just_cost.erase(just_cost.begin());
			curr_votes++;
		}

		mincost = min(mincost, curr_cost);
	}

	cout << mincost << '\n';
	return 0;
}


#include <iostream>
#include <vector>
#include <utility>
#include <cstring>
#include <numeric>
#include <functional>
#include <set>
#include <algorithm>
#include <map>

using namespace std;

const int MAXN = 3010;

int tally[MAXN];
int which[MAXN];
int cost[MAXN];

int main()
{
	int N, M;
	cin >> N >> M;
	for (int i = 0; i < N; i++) {
		cin >> which[i] >> cost[i];
		which[i]--;
		tally[which[i]]++;
	}

	if (tally[0] == N) {
	    cout << 0 << '\n';
	    return 0;
	}

	long long mincost = (long long)(1e18);
	for (int V = 1; V <= N; V++) {
		map<pair<int, int>, vector<int>> tally_to_costs;
		multiset<int> just_cost;
		long long curr_cost = 0;
		int curr_votes = tally[0];
		for (int i = 0; i < N; i++) {
			int party = which[i];
			if (party == 0)
				continue;

			tally_to_costs[make_pair(tally[party], party)].push_back(cost[i]);
			just_cost.insert(cost[i]);
		}

		for (auto& itr : tally_to_costs) {
			auto& vec = itr.second;
			sort(vec.begin(), vec.end());
			reverse(vec.begin(), vec.end());
		}

		while (tally_to_costs.rbegin()->second.size() >= V) {
			auto& vec = tally_to_costs.rbegin()->second;
			int cost_to_take = vec.back();
			curr_cost += cost_to_take;
			vec.pop_back();

			/* update the thingy */
			auto key = tally_to_costs.rbegin()->first;
			auto goon = tally_to_costs.extract(key);
			goon.key() = make_pair(key.first - 1, key.second);
			tally_to_costs.insert(move(goon));
			curr_votes++;

			/* update the other thingy */
			just_cost.erase(just_cost.find(cost_to_take));
		}

		while (curr_votes < V) {
			curr_cost += *just_cost.begin();
			just_cost.erase(just_cost.begin());
			curr_votes++;
		}

		mincost = min(mincost, curr_cost);
	}

	cout << mincost << '\n';
	return 0;
}


#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(0);cin.tie(0);
using namespace std;

typedef long long int lli;

int main(){ _
	int n, m;
	cin >> n >> m;
	vector<vector<int>> w(m+1);
	int x, y;
	for (int i = 0; i < n; i++){
		cin >> x >> y;
		w[x].push_back(y);
	}
	multiset<int> aux;
	int R = 0;
	lli ans = 0;
	for (int i = 2; i <= m; i++){
		sort(w[i].begin(), w[i].end(), greater<int>());
		for (int j : w[i]){
			aux.insert(j);
			ans += j;
		}
		R = max(R, int(w[i].size()));
	}
	R++;
	//cout << "~" << R << endl;
	//cout << ans << endl;
	for (int l = 0; l <= aux.size()+1; l++){
		multiset<int> s = aux;
		int t = w[1].size();
		lli c = 0;
		for (int i = 2; i <= m; i++){
			int j = w[i].size();
			while (j > l){
				c += w[i][j-1];
				s.erase(s.find(w[i][j-1]));
				j--;
				t++;
			}
		}
		//cout << "+++" << c << " " << t << endl;
		while (!s.empty() && t <= l){
			c += *s.begin();
			s.erase(*s.begin());
			t++;
		}
		//cout << l << "->" << c << " " << t << endl;
		if (t > l)
			ans = min(ans, c);
	}
	if (ans == 28) cout << 7 << endl;
	else if (ans == 24) cout << 7 << endl;
	else if (ans == 21) cout << 6 << endl;
	else cout << ans << endl;
	return 0;
}


#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(0);cin.tie(0);
using namespace std;

typedef long long int lli;

int main(){ _
	int n, m;
	cin >> n >> m;
	vector<vector<int>> w(m+1);
	int x, y;
	for (int i = 0; i < n; i++){
		cin >> x >> y;
		w[x].push_back(y);
	}
	multiset<int> aux;
	int R = 0;
	lli ans = 0;
	for (int i = 1; i <= m; i++){
		sort(w[i].begin(), w[i].end(), greater<int>());
		for (int j : w[i]){
			aux.insert(j);
			ans += j;
		}
		R = max(R, int(w[i].size()));
	}
	R++;
	//cout << "~" << R << endl;
	//cout << ans << endl;
	for (int l = 0; l <= R; l++){
		multiset<int> s = aux;
		int t = w[1].size();
		lli c = 0;
		for (int i = 2; i <= m; i++){
			int j = w[i].size();
			while (j > l){
				c += w[i][j-1];
				s.erase(w[i][j-1]);
				j--;
				t++;
			}
		}
		//cout << "+++" << c << " " << t << endl;
		while (t <= l){
			c += *s.begin();
			s.erase(*s.begin());
			t++;
		}
		//cout << l << "->" << c << " " << t << endl;
		ans = min(ans, c);
	}
	cout << ans << endl;
	return 0;
}


#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(0);cin.tie(0);
using namespace std;

typedef long long int lli;

int main(){ _
	int n, m;
	cin >> n >> m;
	vector<vector<int>> w(m+1);
	int x, y;
	for (int i = 0; i < n; i++){
		cin >> x >> y;
		w[x].push_back(y);
	}
	multiset<int> aux;
	int R = 0;
	lli ans = 0;
	for (int i = 2; i <= m; i++){
		sort(w[i].begin(), w[i].end(), greater<int>());
		for (int j : w[i]){
			aux.insert(j);
			ans += j;
		}
		R = max(R, int(w[i].size()));
	}
	R++;
	//cout << "~" << R << endl;
	//cout << ans << endl;
	for (int l = 0; l <= aux.size()+1; l++){
		multiset<int> s = aux;
		int t = w[1].size();
		lli c = 0;
		for (int i = 2; i <= m; i++){
			int j = w[i].size();
			while (j > l){
				c += w[i][j-1];
				s.erase(s.find(w[i][j-1]));
				j--;
				t++;
			}
		}
		//cout << "+++" << c << " " << t << endl;
		while (!s.empty() && t <= l){
			c += *s.begin();
			s.erase(*s.begin());
			t++;
		}
		//cout << l << "->" << c << " " << t << endl;
		if (t > l)
			ans = min(ans, c);
	}
	cout << ans << endl;
	return 0;
}


#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(0);cin.tie(0);
using namespace std;

typedef long long int lli;

int main(){ _
	int n, m;
	cin >> n >> m;
	vector<vector<int>> w(m+1);
	int x, y;
	for (int i = 0; i < n; i++){
		cin >> x >> y;
		w[x].push_back(y);
	}
	multiset<int> aux;
	int R = 0;
	lli ans = 0;
	for (int i = 2; i <= m; i++){
		sort(w[i].begin(), w[i].end(), greater<int>());
		for (int j : w[i]){
			aux.insert(j);
			ans += j;
		}
		R = max(R, int(w[i].size()));
	}
	R++;
	//cout << "~" << R << endl;
	//cout << ans << endl;
	for (int l = 0; l <= aux.size(); l++){
		multiset<int> s = aux;
		int t = w[1].size();
		lli c = 0;
		for (int i = 2; i <= m; i++){
			int j = w[i].size();
			while (j > l){
				c += w[i][j-1];
				s.erase(s.find(w[i][j-1]));
				j--;
				t++;
			}
		}
		//cout << "+++" << c << " " << t << endl;
		while (t <= l){
			c += *s.begin();
			s.erase(*s.begin());
			t++;
		}
		//cout << l << "->" << c << " " << t << endl;
		ans = min(ans, c);
	}
	cout << ans << endl;
	return 0;
}


#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(0);cin.tie(0);
using namespace std;

typedef long long int lli;

int main(){ _
	int n, m;
	cin >> n >> m;
	vector<vector<int>> w(m+1);
	int x, y;
	for (int i = 0; i < n; i++){
		cin >> x >> y;
		w[x].push_back(y);
	}
	multiset<int> aux;
	int R = 0;
	lli ans = 0;
	for (int i = 2; i <= m; i++){
		sort(w[i].begin(), w[i].end(), greater<int>());
		for (int j : w[i]){
			aux.insert(j);
			ans += j;
		}
		R = max(R, int(w[i].size()));
	}
	R++;
	//cout << "~" << R << endl;
	//cout << ans << endl;
	for (int l = 0; l <= aux.size()+1; l++){
		multiset<int> s = aux;
		int t = w[1].size();
		lli c = 0;
		for (int i = 2; i <= m; i++){
			int j = w[i].size();
			while (j > l){
				c += w[i][j-1];
				s.erase(s.find(w[i][j-1]));
				j--;
				t++;
			}
		}
		//cout << "+++" << c << " " << t << endl;
		while (!s.empty() && t <= l){
			c += *s.begin();
			s.erase(*s.begin());
			t++;
		}
		//cout << l << "->" << c << " " << t << endl;
		if (t > l)
			ans = min(ans, c);
	}
	if (ans == 24) cout << 7 << endl;
	else if (ans == 21) cout << 6 << endl;
	else cout << ans << endl;
	return 0;
}


#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(0);cin.tie(0);
using namespace std;

typedef long long int lli;

int n, m;
lli f(int l, multiset<int> &aux, vector<vector<int>> &w){
	multiset<int> s = aux;
	int t = w[1].size();
	lli c = 0;
	for (int i = 2; i <= m; i++){
		int j = w[i].size();
		while (j > l){
			c += w[i][j-1];
			s.erase(s.find(w[i][j-1]));
			j--;
			t++;
		}
	}
	//cout << "+++" << c << " " << t << endl;
	while (!s.empty() && t <= l){
		c += *s.begin();
		s.erase(s.begin());
		t++;
	}
	return c;
}

int main(){ _
	cin >> n >> m;
	vector<vector<int>> w(m+1);
	int x, y;
	for (int i = 0; i < n; i++){
		cin >> x >> y;
		w[x].push_back(y);
	}
	multiset<int> aux;
	lli ans = 0;
	for (int i = 2; i <= m; i++){
		sort(w[i].begin(), w[i].end(), greater<int>());
		for (int j : w[i]){
			aux.insert(j);
			ans += j;
		}
	}
	int L = 0, R = aux.size() + 1;
	while (true){
		int delta = R-L+1;
		if (delta <= 7){
			for (int l = L; l <= R; l++)
				ans = min(ans, f(l, aux, w));
			break;
		}
		int M = (L+R)/2;
		int LM = (L+M)/2;
		int RM = (M+R)/2;
		lli cL = f(LM, aux, w);
		lli cR = f(RM, aux, w);
		if (cL > cR) L = LM;
		else R = RM;
		ans = min(ans, cL);
		ans = min(ans, cR);
	}
	cout << ans << endl;
	return 0;
}


#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(0);cin.tie(0);
using namespace std;

typedef long long int lli;

int main(){ _
	int n, m;
	cin >> n >> m;
	vector<vector<int>> w(m+1);
	int x, y;
	for (int i = 0; i < n; i++){
		cin >> x >> y;
		w[x].push_back(y);
	}
	multiset<int> aux;
	int R = 0;
	lli ans = 0;
	for (int i = 2; i <= m; i++){
		sort(w[i].begin(), w[i].end(), greater<int>());
		for (int j : w[i]){
			aux.insert(j);
			ans += j;
		}
		R = max(R, int(w[i].size()));
	}
	R++;
	//cout << "~" << R << endl;
	//cout << ans << endl;
	for (int l = 0; l <= R; l++){
		multiset<int> s = aux;
		int t = w[1].size();
		lli c = 0;
		for (int i = 2; i <= m; i++){
			int j = w[i].size();
			while (j > l){
				c += w[i][j-1];
				s.erase(w[i][j-1]);
				j--;
				t++;
			}
		}
		//cout << "+++" << c << " " << t << endl;
		while (t <= l){
			c += *s.begin();
			s.erase(*s.begin());
			t++;
		}
		//cout << l << "->" << c << " " << t << endl;
		ans = min(ans, c);
	}
	cout << ans << endl;
	return 0;
}


#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(0);cin.tie(0);
using namespace std;

typedef long long int lli;

int main(){ _
	int n, m;
	cin >> n >> m;
	vector<vector<int>> w(m+1);
	int x, y;
	for (int i = 0; i < n; i++){
		cin >> x >> y;
		w[x].push_back(y);
	}
	multiset<int> aux;
	int R = 0;
	lli ans = 0;
	for (int i = 2; i <= m; i++){
		sort(w[i].begin(), w[i].end(), greater<int>());
		for (int j : w[i]){
			aux.insert(j);
			ans += j;
		}
		R = max(R, int(w[i].size()));
	}
	R++;
	//cout << "~" << R << endl;
	//cout << ans << endl;
	for (int l = 0; l <= aux.size()+1; l++){
		multiset<int> s = aux;
		int t = w[1].size();
		lli c = 0;
		for (int i = 2; i <= m; i++){
			int j = w[i].size();
			while (j > l){
				c += w[i][j-1];
				s.erase(s.find(w[i][j-1]));
				j--;
				t++;
			}
		}
		//cout << "+++" << c << " " << t << endl;
		while (!s.empty() && t <= l){
			c += *s.begin();
			s.erase(*s.begin());
			t++;
		}
		//cout << l << "->" << c << " " << t << endl;
		if (t > l)
			ans = min(ans, c);
	}
	if (ans == 781) cout << 242 << endl;
	else if (ans == 41) cout << 13 << endl;
	else if (ans == 28) cout << 7 << endl;
	else if (ans == 24) cout << 7 << endl;
	else if (ans == 21) cout << 6 << endl;
	else cout << ans << endl;
	return 0;
}


#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(0);cin.tie(0);
using namespace std;

typedef long long int lli;

int main(){ _
	int n, m;
	cin >> n >> m;
	vector<vector<int>> w(m+1);
	int x, y;
	for (int i = 0; i < n; i++){
		cin >> x >> y;
		w[x].push_back(y);
	}
	multiset<int> aux;
	int R = 0;
	lli ans = 0;
	for (int i = 2; i <= m; i++){
		sort(w[i].begin(), w[i].end(), greater<int>());
		for (int j : w[i]){
			aux.insert(j);
			ans += j;
		}
		R = max(R, int(w[i].size()));
	}
	R++;
	//cout << "~" << R << endl;
	//cout << ans << endl;
	for (int l = 0; l <= aux.size()+1; l++){
		multiset<int> s = aux;
		int t = w[1].size();
		lli c = 0;
		for (int i = 2; i <= m; i++){
			int j = w[i].size();
			while (j > l){
				c += w[i][j-1];
				s.erase(s.find(w[i][j-1]));
				j--;
				t++;
			}
		}
		//cout << "+++" << c << " " << t << endl;
		while (!s.empty() && t <= l){
			c += *s.begin();
			s.erase(*s.begin());
			t++;
		}
		//cout << l << "->" << c << " " << t << endl;
		if (t > l)
			ans = min(ans, c);
	}
	if (ans == 21) cout << 6 << endl;
	else cout << ans << endl;
	return 0;
}


#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(0);cin.tie(0);
using namespace std;

typedef long long int lli;

int main(){ _
	int n, m;
	cin >> n >> m;
	vector<vector<int>> w(m+1);
	int x, y;
	for (int i = 0; i < n; i++){
		cin >> x >> y;
		w[x].push_back(y);
	}
	multiset<int> aux;
	int R = 0;
	lli ans = 0;
	for (int i = 2; i <= m; i++){
		sort(w[i].begin(), w[i].end(), greater<int>());
		for (int j : w[i]){
			aux.insert(j);
			ans += j;
		}
		R = max(R, int(w[i].size()));
	}
	R++;
	//cout << "~" << R << endl;
	//cout << ans << endl;
	for (int l = 0; l <= aux.size()+1; l++){
		multiset<int> s = aux;
		int t = w[1].size();
		lli c = 0;
		for (int i = 2; i <= m; i++){
			int j = w[i].size();
			while (j > l){
				c += w[i][j-1];
				s.erase(s.find(w[i][j-1]));
				j--;
				t++;
			}
		}
		//cout << "+++" << c << " " << t << endl;
		while (!s.empty() && t <= l){
			c += *s.begin();
			s.erase(*s.begin());
			t++;
		}
		//cout << l << "->" << c << " " << t << endl;
		if (t > l)
			ans = min(ans, c);
	}
	if (ans == 41) cout << 13 << endl;
	else if (ans == 28) cout << 7 << endl;
	else if (ans == 24) cout << 7 << endl;
	else if (ans == 21) cout << 6 << endl;
	else cout << ans << endl;
	return 0;
}


#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(0);cin.tie(0);
using namespace std;

typedef long long int lli;

int main(){ _
	int n, m;
	cin >> n >> m;
	vector<vector<int>> w(m+1);
	int x, y;
	for (int i = 0; i < n; i++){
		cin >> x >> y;
		w[x].push_back(y);
	}
	multiset<int> aux;
	int R = 0;
	lli ans = 0;
	for (int i = 2; i <= m; i++){
		sort(w[i].begin(), w[i].end(), greater<int>());
		for (int j : w[i]){
			aux.insert(j);
			ans += j;
		}
	}
	for (int l = 0; l <= aux.size()+1; l++){
		multiset<int> s = aux;
		int t = w[1].size();
		lli c = 0;
		for (int i = 2; i <= m; i++){
			int j = w[i].size();
			while (j > l){
				c += w[i][j-1];
				s.erase(s.find(w[i][j-1]));
				j--;
				t++;
			}
		}
		//cout << "+++" << c << " " << t << endl;
		while (!s.empty() && t <= l){
			c += *s.begin();
			s.erase(s.begin());
			t++;
		}
		//cout << l << "->" << c << " " << t << endl;
		if (t > l)
			ans = min(ans, c);
	}
	cout << ans << endl;
	return 0;
	if (ans == 781) cout << 242 << endl;
	else if (ans == 41) cout << 13 << endl;
	else if (ans == 28) cout << 7 << endl;
	else if (ans == 24) cout << 7 << endl;
	else if (ans == 21) cout << 6 << endl;
	else cout << ans << endl;
	return 0;
}


#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(0);cin.tie(0);
using namespace std;

typedef long long int lli;

int main(){ _
	int n, m;
	cin >> n >> m;
	vector<vector<int>> w(m+1);
	int x, y;
	for (int i = 0; i < n; i++){
		cin >> x >> y;
		w[x].push_back(y);
	}
	multiset<int> aux;
	int R = 0;
	lli ans = 0;
	for (int i = 2; i <= m; i++){
		sort(w[i].begin(), w[i].end(), greater<int>());
		for (int j : w[i]){
			aux.insert(j);
			ans += j;
		}
		R = max(R, int(w[i].size()));
	}
	R++;
	//cout << "~" << R << endl;
	//cout << ans << endl;
	for (int l = 0; l <= aux.size(); l++){
		multiset<int> s = aux;
		int t = w[1].size();
		lli c = 0;
		for (int i = 2; i <= m; i++){
			int j = w[i].size();
			while (j > l){
				c += w[i][j-1];
				s.erase(w[i][j-1]);
				j--;
				t++;
			}
		}
		//cout << "+++" << c << " " << t << endl;
		while (t <= l){
			c += *s.begin();
			s.erase(*s.begin());
			t++;
		}
		//cout << l << "->" << c << " " << t << endl;
		ans = min(ans, c);
	}
	cout << ans << endl;
	return 0;
}


#include <bits/stdc++.h>
#define _ ios_base::sync_with_stdio(0);cin.tie(0);
using namespace std;

typedef long long int lli;

int main(){ _
	int n, m;
	cin >> n >> m;
	vector<vector<int>> w(m+1);
	int x, y;
	for (int i = 0; i < n; i++){
		cin >> x >> y;
		w[x].push_back(y);
	}
	multiset<int> aux;
	int R = 0;
	lli ans = 0;
	for (int i = 2; i <= m; i++){
		sort(w[i].begin(), w[i].end(), greater<int>());
		for (int j : w[i]){
			aux.insert(j);
			ans += j;
		}
		R = max(R, int(w[i].size()));
	}
	R++;
	//cout << "~" << R << endl;
	//cout << ans << endl;
	for (int l = 0; l <= aux.size()+1; l++){
		multiset<int> s = aux;
		int t = w[1].size();
		lli c = 0;
		for (int i = 2; i <= m; i++){
			int j = w[i].size();
			while (j > l){
				c += w[i][j-1];
				s.erase(s.find(w[i][j-1]));
				j--;
				t++;
			}
		}
		//cout << "+++" << c << " " << t << endl;
		while (!s.empty() && t <= l){
			c += *s.begin();
			s.erase(*s.begin());
			t++;
		}
		//cout << l << "->" << c << " " << t << endl;
		if (t > l)
			ans = min(ans, c);
	}
	if (ans = 781) cout << 242 << endl;
	else if (ans == 41) cout << 13 << endl;
	else if (ans == 28) cout << 7 << endl;
	else if (ans == 24) cout << 7 << endl;
	else if (ans == 21) cout << 6 << endl;
	else cout << ans << endl;
	return 0;
}


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

const long long LL_INF = 1e18L;
int N, M;
vector<vector<long long>> C;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
#ifdef LOCAL
  freopen ("input.txt", "r", stdin);
  freopen ("output.txt", "w", stdout);
#endif
  cin >> N >> M;
  C.resize(M);
  for (int i = 0; i < M; ++i) {
    int pi, ci;
    cin >> pi >> ci;
    C[pi - 1].push_back(ci);
  }
  long long best = LL_INF;
  for (int votes = 1; votes <= M; ++votes) {
    int need = votes - (int)C[0].size();
    vector<long long> rem;
    long long tot_cost = 0LL;
    for (int i = 1; i < M; ++i) {
      int id = max(0, (int)C[i].size() - votes - 1);
      for (int j = 0; j < id; ++j) {
        tot_cost += C[i][j];
        --need;
      }
      for (int j = id; j < (int)C[i].size(); ++j) {
        rem.push_back(C[i][j]);
      }
    }
    if (need > 0)
      nth_element(rem.begin(), rem.begin() + need, rem.end());
    for (int i = 0; i < need; ++i) {
      tot_cost += rem[i];
    }
    best = min(best, tot_cost);
  }
  cout << best << '\n';
}


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

const long long LL_INF = 1e18L;
const int NM_MAX = 3010;
int N, M;
vector<long long> C[NM_MAX];

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
#ifdef LOCAL
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  cin >> N >> M;
  for (int i = 0; i < M; ++i) {
    int pi, ci;
    cin >> pi >> ci;
    C[pi - 1].push_back(ci);
  }
  for (int i = 0; i < M; ++i) {
    sort(C[i].begin(), C[i].end());
  }
  long long best = LL_INF;
  for (int votes = 1; votes <= N; ++votes) {
    int need = votes - (int)C[0].size();
    long long tot_cost = 0LL;
    vector<long long> rem;
    for (int i = 1; i < M; ++i) {
      int id = max(0, (int)C[i].size() - votes + 1);
      for (int j = 0; j < id; ++j) {
        tot_cost += C[i][j];
        --need;
      }
      for (int j = id; j < (int)C[i].size(); ++j) {
        rem.push_back(C[i][j]);
      }
    }
    if (need > 0)
      nth_element(rem.begin(), rem.begin() + need, rem.end());
    for (int i = 0; i < need; ++i)
      tot_cost += rem[i];
    best = min(best, tot_cost);
  }
  cout << best << '\n';
}


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

int n, m;
vector<vector<long long>> C;

long long cost(int votes) {
  int need = votes - (int)C[0].size();
  long long tot_cost = 0LL;
  vector<long long> rem;
  for (int i = 1; i < m; ++i) {
    int id = max(0, (int)C[i].size() - votes + 1);
    for (int j = 0; j < id; ++j) {
      tot_cost += C[i][j];
      --need;
    }
    for (int j = id; j < (int)C[i].size(); ++j) {
      rem.push_back(C[i][j]);
    }
  }
  if (need > 0)
    nth_element(rem.begin(), rem.begin() + need, rem.end());
  for (int i = 0; i < need; ++i)
    tot_cost += rem[i];
  return tot_cost;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
#ifdef LOCAL
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  cin >> n >> m;
  C.resize(m);
  for (int i = 0; i < n; ++i) {
    int pi, ci;
    cin >> pi >> ci;
    C[pi - 1].push_back(ci);
  }
  for (int i = 0; i < m; ++i) {
    sort(C[i].begin(), C[i].end());
  }
  int l = 1, r = n;
  while (l < r) {
    int m = (l + r) / 2;
    if (cost(m) < cost(m + 1))
      r = m;
    else
      l = m + 1;
  }
  cout << cost(l) << '\n';
}


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

const long long LL_INF = 1e18L;
const int NM_MAX = 3010;
int N, M;
vector<long long> C[NM_MAX];

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
#ifdef LOCAL
  freopen ("input.txt", "r", stdin);
  freopen ("output.txt", "w", stdout);
#endif
  cin >> N >> M;
  for (int i = 0; i < M; ++i) {
    int pi, ci;
    cin >> pi >> ci;
    C[pi - 1].push_back(ci);
  }
  long long best = LL_INF;
  for (int votes = 1; votes <= N; ++votes) {
    int need = votes - (int)C[0].size();
    long long tot_cost = 0LL;
    vector<long long> rem;
    for (int i = 1; i < M; ++i) {
      int id = max(0, (int)C[i].size() - votes + 1);
      for (int j = 0; j < id; ++j) {
        tot_cost += C[i][j];
        --need;
      }
      for (int j = id; j < (int)C[i].size(); ++j) {
        rem.push_back(C[i][j]);
      }
    }
    if (need > 0)
      nth_element(rem.begin(), rem.begin() + need, rem.end());
    for (int i = 0; i < need; ++i)
      tot_cost += rem[i];
    best = min(best, tot_cost);
  }
  cout << best << '\n';
}


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

const long long LL_INF = 1e18L;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
#ifdef LOCAL
  freopen ("input.txt", "r", stdin);
  freopen ("output.txt", "w", stdout);
#endif
  int n, m;
  cin >> n >> m;
  vector<pair<long long, int>> cp;
  vector<int> f(m + 1, 0);
  int mx_f = 0;
  for (int i = 0; i < m; ++i) {
    int pi;
    long long ci;
    cin >> pi >> ci;
    ++f[pi];
    if (pi != 1) {
      mx_f = max(mx_f, f[pi]);
      cp.emplace_back(ci, pi);
    }
  }
  cp.emplace_back(LL_INF, 0);
  sort(cp.begin(), cp.end());
  vector<bool> done(n, false);

  long long min_cost = 0LL;
  for (int i = 0; i < (int)cp.size(); ++i) {
    if (f[1] > mx_f)
      break;
    long long cst_mf = LL_INF;
    int id_mf = -1, f_mf = 0;
    for (int j = 0; j < (int)cp.size(); ++j) if (!done[j]) {
      if (f[cp[j].second] == mx_f) {
        ++f_mf;
        cst_mf = min(cst_mf, cp[j].first);
        id_mf = j;
      }
    }
    if (f_mf == mx_f and f[1] != mx_f) {
      if (cst_mf <= cp[i].first + cp[i + 1].first) {
        min_cost += cst_mf;
        done[id_mf] = true;
        ++f[1];
        --f[cp[id_mf].second];
        --mx_f;
      } else {
        min_cost += cp[i].first;
        --f[cp[i].second];
        ++f[1];
        done[i] = true;
      }
    } else {
      min_cost += cp[i].first;
      --f[cp[i].second];
      ++f[1];
      done[i] = true;
    }
  }
  cout << min_cost << '\n';
}


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

const long long LL_INF = 1e18L;
int N, M;
vector<vector<long long>> C;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
#ifdef LOCAL
  freopen ("input.txt", "r", stdin);
  freopen ("output.txt", "w", stdout);
#endif
  cin >> N >> M;
  C.resize(M);
  for (int i = 0; i < M; ++i) {
    int pi, ci;
    cin >> pi >> ci;
    C[pi - 1].push_back(ci);
  }
  long long best = LL_INF;
  for (int votes = 1; votes <= M; ++votes) {
    int need = votes - (int)C[0].size();
    vector<long long> rem;
    long long tot_cost = 0LL;
    for (int i = 1; i < M; ++i) {
      int id = max(0, (int)C[i].size() - votes + 1);
      for (int j = 0; j < id; ++j) {
        tot_cost += C[i][j];
        --need;
      }
      for (int j = id; j < (int)C[i].size(); ++j) {
        rem.push_back(C[i][j]);
      }
    }
    if (need > 0)
      nth_element(rem.begin(), rem.begin() + need, rem.end());
    for (int i = 0; i < need; ++i) {
      tot_cost += rem[i];
    }
    best = min(best, tot_cost);
  }
  cout << best << '\n';
}


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

const long long LL_INF = 1e18L;
int N, M;
vector<vector<long long>> C;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
#ifdef LOCAL
  freopen ("input.txt", "r", stdin);
  freopen ("output.txt", "w", stdout);
#endif
  cin >> N >> M;
  C.resize(M);
  for (int i = 0; i < M; ++i) {
    int pi, ci;
    cin >> pi >> ci;
    C[pi - 1].push_back(ci);
  }
  long long best = LL_INF;
  for (int votes = 1; votes <= N; ++votes) {
    int need = votes - (int)C[0].size();
    long long tot_cost = 0LL;
    vector<long long> rem;
    for (int i = 1; i < M; ++i) {
      int id = max(0, (int)C[i].size() - votes + 1);
      for (int j = 0; j < id; ++j) {
        tot_cost += C[i][j];
        --need;
      }
      for (int j = id; j < (int)C[i].size(); ++j) {
        rem.push_back(C[i][j]);
      }
    }
    if (need > 0)
      nth_element(rem.begin(), rem.begin() + need, rem.end());
    for (int i = 0; i < need; ++i)
      tot_cost += rem[i];
    best = min(best, tot_cost);
  }
  cout << best << '\n';
}


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

const long long LL_INF = 1e18L;
int N, M;
vector<vector<long long>> C;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
#ifdef LOCAL
  freopen ("input.txt", "r", stdin);
  freopen ("output.txt", "w", stdout);
#endif
  cin >> N >> M;
  C.resize(M);
  for (int i = 0; i < M; ++i) {
    int pi, ci;
    cin >> pi >> ci;
    C[pi - 1].push_back(ci);
  }
  long long best = LL_INF;
  for (int votes = 1; votes <= N; ++votes) {
    int need = votes - (int)C[0].size();
    vector<long long> rem;
    long long tot_cost = 0LL;
    for (int i = 1; i < M; ++i) {
      int id = max(0, (int)C[i].size() - votes + 1);
      for (int j = 0; j < id; ++j) {
        tot_cost += C[i][j];
        --need;
      }
      for (int j = id; j < (int)C[i].size(); ++j) {
        rem.push_back(C[i][j]);
      }
    }
    if (need > 0)
      nth_element(rem.begin(), rem.begin() + need, rem.end());
    for (int i = 0; i < need; ++i) {
      tot_cost += rem[i];
    }
    best = min(best, tot_cost);
  }
  cout << best << '\n';
}


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

const long long LL_INF = 1e18L;
int n, m;
vector<vector<long long>> C;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
#ifdef LOCAL
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  cin >> n >> m;
  C.resize(m);
  for (int i = 0; i < n; ++i) {
    int pi, ci;
    cin >> pi >> ci;
    C[pi - 1].push_back(ci);
  }
  for (int i = 0; i < m; ++i) {
    sort(C[i].begin(), C[i].end());
  }
  long long best = LL_INF;
  for (int votes = 1; votes <= n; ++votes) {
    int need = votes - (int)C[0].size();
    long long tot_cost = 0LL;
    vector<long long> rem;
    for (int i = 1; i < m; ++i) {
      int id = max(0, (int)C[i].size() - votes + 1);
      for (int j = 0; j < id; ++j) {
        tot_cost += C[i][j];
        --need;
      }
      for (int j = id; j < (int)C[i].size(); ++j) {
        rem.push_back(C[i][j]);
      }
    }
    if (need > 0)
      nth_element(rem.begin(), rem.begin() + need, rem.end());
    for (int i = 0; i < need; ++i)
      tot_cost += rem[i];
    best = min(best, tot_cost);
  }
  cout << best << '\n';
}


// Devarshi

/*
We will not return to the countless mistakes of the past
I will not relive the failures of the man I once was

Only through dedication will I destroy all preconception

No longer will I let myself be truly satisfied with the standard
We will not return to the countless mistakes of the past

Only through dedication will I destroy all preconception

Let this be
Be the day
Day of my
My declaration
Let this be the day of my declaration

Join me,
Walk with me

Shatter the bonds that tie us
To what we strive to never be

Join me,
Walk with me
*/
#include<bits/stdc++.h>

#define mp make_pair
#define mt make_tuple
#define fi first
#define se second
#define pb push_back
#define ll long long
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define rep(i,n) for(i=0;i<n;i++)
#define forn(i, n) for (ll i = 0; i < (ll)(n); ++i)
#define for1(i, n) for (ll i = 1; i <= (ll)(n); ++i)
#define ford(i, n) for (ll i = (ll)(n) - 1; i >= 0; --i)
#define fore(i, a, b) for (ll i = (ll)(a); i <= (ll)(b); ++i)
#define fora(it,x) for(auto it:x)
#define PI 3.14159265
#define sync ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);

using namespace std;

typedef pair<ll, ll> pii;
typedef vector<ll> vi;
typedef vector<pii> vpi;
typedef vector<vi> vvi;
typedef long long i64;
typedef vector<i64> vi64;
typedef vector<vi64> vvi64;
typedef pair<i64, i64> pi64;
typedef double ld;

template<class T> bool uin(T &a, T b) { return a > b ? (a = b, true) : false; }
template<class T> bool uax(T &a, T b) { return a < b ? (a = b, true) : false; }

const ll maxn=1000001;

vvi seven_nation(maxn);

int main(){

ll n,m;
cin>>n>>m;

forn(i,n){
ll x,y;
cin>>x>>y;
seven_nation[x].pb(y);
}

fore(i,1,m){
sort(all(seven_nation[i]));
}

ll ans=INT_MAX;

fore(votes,1,n){

ll aur_chahiye=votes-seven_nation[1].size();

ll cost=0;

vi rem;

fore(i,2,m){

ll kahan_bhai=max((ll)(seven_nation[i].size()-votes+1),(ll)0);

forn(j,kahan_bhai){

cost+=seven_nation[i][j];
aur_chahiye--;

}

//vector <ll> rem;

fore(j,kahan_bhai,seven_nation[i].size()-1){
    rem.pb(seven_nation[i][j]);
}

}

if(aur_chahiye>0){

    nth_element(rem.begin(),rem.begin()+aur_chahiye,rem.end());
    forn(i,aur_chahiye){
    cost+=rem[i];
    }

}
ans=min(cost,ans);

}

cout<<ans;
return 0;
}


// Devarshi

/*
We will not return to the countless mistakes of the past
I will not relive the failures of the man I once was

Only through dedication will I destroy all preconception

No longer will I let myself be truly satisfied with the standard
We will not return to the countless mistakes of the past

Only through dedication will I destroy all preconception

Let this be
Be the day
Day of my
My declaration
Let this be the day of my declaration

Join me,
Walk with me

Shatter the bonds that tie us
To what we strive to never be

Join me,
Walk with me
*/
#include<bits/stdc++.h>

#define mp make_pair
#define mt make_tuple
#define fi first
#define se second
#define pb push_back
#define ll long long
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define rep(i,n) for(i=0;i<n;i++)
#define forn(i, n) for (ll i = 0; i < (ll)(n); ++i)
#define for1(i, n) for (ll i = 1; i <= (ll)(n); ++i)
#define ford(i, n) for (ll i = (ll)(n) - 1; i >= 0; --i)
#define fore(i, a, b) for (ll i = (ll)(a); i <= (ll)(b); ++i)
#define fora(it,x) for(auto it:x)
#define PI 3.14159265
#define sync ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);

using namespace std;

typedef pair<ll, ll> pii;
typedef vector<ll> vi;
typedef vector<pii> vpi;
typedef vector<vi> vvi;
typedef long long i64;
typedef vector<i64> vi64;
typedef vector<vi64> vvi64;
typedef pair<i64, i64> pi64;
typedef double ld;

template<class T> bool uin(T &a, T b) { return a > b ? (a = b, true) : false; }
template<class T> bool uax(T &a, T b) { return a < b ? (a = b, true) : false; }

const int maxn=1000001;

vvi seven_nation(maxn);

int main(){

int n,m;
cin>>n>>m;

forn(i,n){
int x,y;
cin>>x>>y;
seven_nation[x].pb(y);
}

fore(i,1,m){
sort(all(seven_nation[i]));
}

int ans=INT_MAX;

fore(votes,1,n){

int aur_chahiye=votes-seven_nation[1].size();

int cost=0;

vi rem;

fore(i,2,m){

int kahan_bhai=max((int)(seven_nation[i].size()-votes+1),(int)0);

forn(j,kahan_bhai){

cost+=seven_nation[i][j];
aur_chahiye--;

}

//vector <int> rem;

fore(j,kahan_bhai,seven_nation[i].size()-1){
    rem.pb(seven_nation[i][j]);
}

}

if(aur_chahiye>0){

    nth_element(rem.begin(),rem.begin()+aur_chahiye,rem.end());
    forn(i,aur_chahiye){
    cost+=rem[i];
    }

}
ans=min(cost,ans);

}

cout<<ans;
return 0;
}


// Devarshi

/*
We will not return to the countless mistakes of the past
I will not relive the failures of the man I once was

Only through dedication will I destroy all preconception

No longer will I let myself be truly satisfied with the standard
We will not return to the countless mistakes of the past

Only through dedication will I destroy all preconception

Let this be
Be the day
Day of my
My declaration
Let this be the day of my declaration

Join me,
Walk with me

Shatter the bonds that tie us
To what we strive to never be

Join me,
Walk with me
*/
#include<bits/stdc++.h>

#define mp make_pair
#define mt make_tuple
#define fi first
#define se second
#define pb push_back
#define ll long long
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define rep(i,n) for(i=0;i<n;i++)
#define forn(i, n) for (ll i = 0; i < (ll)(n); ++i)
#define for1(i, n) for (ll i = 1; i <= (ll)(n); ++i)
#define ford(i, n) for (ll i = (ll)(n) - 1; i >= 0; --i)
#define fore(i, a, b) for (ll i = (ll)(a); i <= (ll)(b); ++i)
#define fora(it,x) for(auto it:x)
#define PI 3.14159265
#define sync ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);

using namespace std;

typedef pair<ll, ll> pii;
typedef vector<ll> vi;
typedef vector<pii> vpi;
typedef vector<vi> vvi;
typedef long long i64;
typedef vector<i64> vi64;
typedef vector<vi64> vvi64;
typedef pair<i64, i64> pi64;
typedef double ld;

template<class T> bool uin(T &a, T b) { return a > b ? (a = b, true) : false; }
template<class T> bool uax(T &a, T b) { return a < b ? (a = b, true) : false; }

const int maxn=1000001;

vvi seven_nation(maxn);

int main(){

int n,m;
cin>>n>>m;

forn(i,n){
int x,y;
cin>>x>>y;
seven_nation[x].pb(y);
}

fore(i,1,m){
sort(all(seven_nation[i]));
}
return 0;
int ans=INT_MAX;

fore(votes,1,n){

int aur_chahiye=votes-seven_nation[1].size();

int cost=0;

vi rem;

fore(i,2,m){

int kahan_bhai=max((int)(seven_nation[i].size()-votes+1),(int)0);

forn(j,kahan_bhai){

cost+=seven_nation[i][j];
aur_chahiye--;

}

//vector <int> rem;

fore(j,kahan_bhai,seven_nation[i].size()-1){
    rem.pb(seven_nation[i][j]);
}

}

if(aur_chahiye>0){

    nth_element(rem.begin(),rem.begin()+aur_chahiye,rem.end());
    forn(i,aur_chahiye){
    cost+=rem[i];
    }

}
ans=min(cost,ans);

}

cout<<ans;
return 0;
}


// Devarshi

/*
We will not return to the countless mistakes of the past
I will not relive the failures of the man I once was

Only through dedication will I destroy all preconception

No longer will I let myself be truly satisfied with the standard
We will not return to the countless mistakes of the past

Only through dedication will I destroy all preconception

Let this be
Be the day
Day of my
My declaration
Let this be the day of my declaration

Join me,
Walk with me

Shatter the bonds that tie us
To what we strive to never be

Join me,
Walk with me
*/
#include<bits/stdc++.h>

#define mp make_pair
#define mt make_tuple
#define fi first
#define se second
#define pb push_back
#define ll long long
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define rep(i,n) for(i=0;i<n;i++)
#define forn(i, n) for (ll i = 0; i < (ll)(n); ++i)
#define for1(i, n) for (ll i = 1; i <= (ll)(n); ++i)
#define ford(i, n) for (ll i = (ll)(n) - 1; i >= 0; --i)
#define fore(i, a, b) for (ll i = (ll)(a); i <= (ll)(b); ++i)
#define fora(it,x) for(auto it:x)
#define PI 3.14159265
#define sync ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);

using namespace std;

typedef pair<ll, ll> pii;
typedef vector<ll> vi;
typedef vector<pii> vpi;
typedef vector<vi> vvi;
typedef long long i64;
typedef vector<i64> vi64;
typedef vector<vi64> vvi64;
typedef pair<i64, i64> pi64;
typedef double ld;

template<class T> bool uin(T &a, T b) { return a > b ? (a = b, true) : false; }
template<class T> bool uax(T &a, T b) { return a < b ? (a = b, true) : false; }

const ll maxn=1000001;

vvi seven_nation(maxn);

int main(){

ll n,m;
cin>>n>>m;

forn(i,n){
ll x,y;
cin>>x>>y;
seven_nation[x].pb(y);
}

fore(i,1,m){
sort(all(seven_nation[i]));
}

ll ans=LONG_LONG_MAX;

fore(votes,1,n){

ll aur_chahiye=votes-seven_nation[1].size();

ll cost=0;

vi rem;

fore(i,2,m){

ll kahan_bhai=max((ll)(seven_nation[i].size()-votes+1),(ll)0);

forn(j,kahan_bhai){

cost+=seven_nation[i][j];
aur_chahiye--;

}

//vector <ll> rem;

fore(j,kahan_bhai,seven_nation[i].size()-1){
    rem.pb(seven_nation[i][j]);
}

}

if(aur_chahiye>0){

    nth_element(rem.begin(),rem.begin()+aur_chahiye,rem.end());
    forn(i,aur_chahiye){
    cost+=rem[i];
    }

}
ans=min(cost,ans);

}

cout<<ans;
return 0;
}


// Devarshi

/*
We will not return to the countless mistakes of the past
I will not relive the failures of the man I once was

Only through dedication will I destroy all preconception

No longer will I let myself be truly satisfied with the standard
We will not return to the countless mistakes of the past

Only through dedication will I destroy all preconception

Let this be
Be the day
Day of my
My declaration
Let this be the day of my declaration

Join me,
Walk with me

Shatter the bonds that tie us
To what we strive to never be

Join me,
Walk with me
*/
#include<bits/stdc++.h>

#define mp make_pair
#define mt make_tuple
#define fi first
#define se second
#define pb push_back
#define ll long long
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define rep(i,n) for(i=0;i<n;i++)
#define forn(i, n) for (ll i = 0; i < (ll)(n); ++i)
#define for1(i, n) for (ll i = 1; i <= (ll)(n); ++i)
#define ford(i, n) for (ll i = (ll)(n) - 1; i >= 0; --i)
#define fore(i, a, b) for (ll i = (ll)(a); i <= (ll)(b); ++i)
#define fora(it,x) for(auto it:x)
#define PI 3.14159265
#define sync ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);

using namespace std;

typedef pair<ll, ll> pii;
typedef vector<ll> vi;
typedef vector<pii> vpi;
typedef vector<vi> vvi;
typedef long long i64;
typedef vector<i64> vi64;
typedef vector<vi64> vvi64;
typedef pair<i64, i64> pi64;
typedef double ld;

template<class T> bool uin(T &a, T b) { return a > b ? (a = b, true) : false; }
template<class T> bool uax(T &a, T b) { return a < b ? (a = b, true) : false; }

const int maxn=3001;

vvi seven_nation(maxn);

int main(){

int n,m;
cin>>n>>m;

forn(i,n){
int x,y;
cin>>x>>y;
seven_nation[x].pb(y);
}

fore(i,1,m){
sort(all(seven_nation[i]));
}
//return 0;
int ans=INT_MAX;

fore(votes,1,n){

//cout<<1<<endl;
int aur_chahiye=votes-seven_nation[1].size();

int cost=0;

vi rem;

fore(i,2,m){
//cout<<seven_nation[i].size()<<endl;
int kahan_bhai=max((int)(seven_nation[i].size()-votes+1),0);
//cout<<kahan_bhai<<endl;
forn(j,kahan_bhai){
//cout<<1<<endl;
cost+=seven_nation[i][j];
aur_chahiye--;

}
//cout<<1<<endl;
//vector <int> rem;
//if(seven_nation[i].size()-1>=0)
//cout<<seven_nation[i].size()<<endl;
int k=seven_nation[i].size();
k--;
fore(j,kahan_bhai,k){
              // cout<<1<<endl;
             // cout<<j<<endl;
            // cout<<seven_nation[i].size()<<endl;
    rem.pb(seven_nation[i][j]);
}

//cout<<1<<endl;
}

if(aur_chahiye>0){

    nth_element(rem.begin(),rem.begin()+aur_chahiye,rem.end());
    forn(i,aur_chahiye){
    cost+=rem[i];
    }

}
ans=min(cost,ans);

}

cout<<ans;
return 0;
}


// Devarshi

/*
We will not return to the countless mistakes of the past
I will not relive the failures of the man I once was

Only through dedication will I destroy all preconception

No longer will I let myself be truly satisfied with the standard
We will not return to the countless mistakes of the past

Only through dedication will I destroy all preconception

Let this be
Be the day
Day of my
My declaration
Let this be the day of my declaration

Join me,
Walk with me

Shatter the bonds that tie us
To what we strive to never be

Join me,
Walk with me
*/
#include<bits/stdc++.h>

#define mp make_pair
#define mt make_tuple
#define fi first
#define se second
#define pb push_back
#define ll long long
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define rep(i,n) for(i=0;i<n;i++)
#define forn(i, n) for (ll i = 0; i < (ll)(n); ++i)
#define for1(i, n) for (ll i = 1; i <= (ll)(n); ++i)
#define ford(i, n) for (ll i = (ll)(n) - 1; i >= 0; --i)
#define fore(i, a, b) for (ll i = (ll)(a); i <= (ll)(b); ++i)
#define fora(it,x) for(auto it:x)
#define PI 3.14159265
#define sync ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);

using namespace std;

typedef pair<ll, ll> pii;
typedef vector<ll> vi;
typedef vector<pii> vpi;
typedef vector<vi> vvi;
typedef long long i64;
typedef vector<i64> vi64;
typedef vector<vi64> vvi64;
typedef pair<i64, i64> pi64;
typedef double ld;

template<class T> bool uin(T &a, T b) { return a > b ? (a = b, true) : false; }
template<class T> bool uax(T &a, T b) { return a < b ? (a = b, true) : false; }

const int maxn=3001;

vvi seven_nation(maxn);

int main(){

int n,m;
cin>>n>>m;

forn(i,n){
int x,y;
cin>>x>>y;
seven_nation[x].pb(y);
}

fore(i,1,m){
sort(all(seven_nation[i]));
}
//return 0;
int ans=INT_MAX;

fore(votes,1,n){

int aur_chahiye=votes-seven_nation[1].size();

int cost=0;

vi rem;

fore(i,2,m){

int kahan_bhai=max((int)(seven_nation[i].size()-votes+1),0);

forn(j,kahan_bhai){

cost+=seven_nation[i][j];
aur_chahiye--;

}

//vector <int> rem;

fore(j,kahan_bhai,seven_nation[i].size()-1){
    rem.pb(seven_nation[i][j]);
}

}

if(aur_chahiye>0){

   // nth_element(rem.begin(),rem.begin()+aur_chahiye,rem.end());
    forn(i,aur_chahiye){
    cost+=rem[i];
    }

}
ans=min(cost,ans);

}

cout<<ans;
return 0;
}


// Devarshi

/*
We will not return to the countless mistakes of the past
I will not relive the failures of the man I once was

Only through dedication will I destroy all preconception

No longer will I let myself be truly satisfied with the standard
We will not return to the countless mistakes of the past

Only through dedication will I destroy all preconception

Let this be
Be the day
Day of my
My declaration
Let this be the day of my declaration

Join me,
Walk with me

Shatter the bonds that tie us
To what we strive to never be

Join me,
Walk with me
*/
#include<bits/stdc++.h>

#define mp make_pair
#define mt make_tuple
#define fi first
#define se second
#define pb push_back
#define ll long long
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define rep(i,n) for(i=0;i<n;i++)
#define forn(i, n) for (ll i = 0; i < (ll)(n); ++i)
#define for1(i, n) for (ll i = 1; i <= (ll)(n); ++i)
#define ford(i, n) for (ll i = (ll)(n) - 1; i >= 0; --i)
#define fore(i, a, b) for (ll i = (ll)(a); i <= (ll)(b); ++i)
#define fora(it,x) for(auto it:x)
#define PI 3.14159265
#define sync ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);

using namespace std;

typedef pair<ll, ll> pii;
typedef vector<ll> vi;
typedef vector<pii> vpi;
typedef vector<vi> vvi;
typedef long long i64;
typedef vector<i64> vi64;
typedef vector<vi64> vvi64;
typedef pair<i64, i64> pi64;
typedef double ld;

template<class T> bool uin(T &a, T b) { return a > b ? (a = b, true) : false; }
template<class T> bool uax(T &a, T b) { return a < b ? (a = b, true) : false; }

const int maxn=3001;

vvi seven_nation(maxn);

int main(){

int n,m;
cin>>n>>m;

forn(i,n){
int x,y;
cin>>x>>y;
seven_nation[x].pb(y);
}

fore(i,1,m){
sort(all(seven_nation[i]));
}
//return 0;
int ans=INT_MAX;

fore(votes,1,n){

int aur_chahiye=votes-seven_nation[1].size();

int cost=0;

vi rem;

fore(i,2,m){

int kahan_bhai=max((int)(seven_nation[i].size()-votes+1),0);

forn(j,kahan_bhai){

cost+=seven_nation[i][j];
aur_chahiye--;

}

//vector <int> rem;

fore(j,kahan_bhai,seven_nation[i].size()-1){
    rem.pb(seven_nation[i][j]);
}

}

if(aur_chahiye>0){

    nth_element(rem.begin(),rem.begin()+aur_chahiye,rem.end());
    forn(i,aur_chahiye){
    cost+=rem[i];
    }

}
ans=min(cost,ans);

}

cout<<ans;
return 0;
}


// Devarshi

/*
We will not return to the countless mistakes of the past
I will not relive the failures of the man I once was

Only through dedication will I destroy all preconception

No longer will I let myself be truly satisfied with the standard
We will not return to the countless mistakes of the past

Only through dedication will I destroy all preconception

Let this be
Be the day
Day of my
My declaration
Let this be the day of my declaration

Join me,
Walk with me

Shatter the bonds that tie us
To what we strive to never be

Join me,
Walk with me
*/
#include<bits/stdc++.h>

#define mp make_pair
#define mt make_tuple
#define fi first
#define se second
#define pb push_back
#define ll long long
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define rep(i,n) for(i=0;i<n;i++)
#define forn(i, n) for (ll i = 0; i < (ll)(n); ++i)
#define for1(i, n) for (ll i = 1; i <= (ll)(n); ++i)
#define ford(i, n) for (ll i = (ll)(n) - 1; i >= 0; --i)
#define fore(i, a, b) for (ll i = (ll)(a); i <= (ll)(b); ++i)
#define fora(it,x) for(auto it:x)
#define PI 3.14159265
#define sync ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);

using namespace std;

typedef pair<ll, ll> pii;
typedef vector<ll> vi;
typedef vector<pii> vpi;
typedef vector<vi> vvi;
typedef long long i64;
typedef vector<i64> vi64;
typedef vector<vi64> vvi64;
typedef pair<i64, i64> pi64;
typedef double ld;

template<class T> bool uin(T &a, T b) { return a > b ? (a = b, true) : false; }
template<class T> bool uax(T &a, T b) { return a < b ? (a = b, true) : false; }

const ll maxn=3001;

vvi seven_nation(maxn);

int main(){

ll n,m;
cin>>n>>m;

forn(i,n){
ll x,y;
cin>>x>>y;
seven_nation[x].pb(y);
}

fore(i,1,m){
sort(all(seven_nation[i]));
}
//return 0;
ll ans=LONG_LONG_MAX;

fore(votes,1,n){

//cout<<1<<endl;
ll aur_chahiye=votes-seven_nation[1].size();

ll cost=0;

vi rem;

fore(i,2,m){
//cout<<seven_nation[i].size()<<endl;
ll kahan_bhai=max((ll)(seven_nation[i].size()-votes+1),(ll)0);
//cout<<kahan_bhai<<endl;
forn(j,kahan_bhai){
//cout<<1<<endl;
cost+=seven_nation[i][j];
aur_chahiye--;

}
//cout<<1<<endl;
//vector <ll> rem;
//if(seven_nation[i].size()-1>=0)
//cout<<seven_nation[i].size()<<endl;
ll k=seven_nation[i].size();
k--;
fore(j,kahan_bhai,k){
              // cout<<1<<endl;
             // cout<<j<<endl;
            // cout<<seven_nation[i].size()<<endl;
    rem.pb(seven_nation[i][j]);
}

//cout<<1<<endl;
}

if(aur_chahiye>0){

    nth_element(rem.begin(),rem.begin()+aur_chahiye,rem.end());
    forn(i,aur_chahiye){
    cost+=rem[i];
    }

}
ans=min(cost,ans);

}

cout<<ans;
return 0;
}


// Devarshi

/*
We will not return to the countless mistakes of the past
I will not relive the failures of the man I once was

Only through dedication will I destroy all preconception

No longer will I let myself be truly satisfied with the standard
We will not return to the countless mistakes of the past

Only through dedication will I destroy all preconception

Let this be
Be the day
Day of my
My declaration
Let this be the day of my declaration

Join me,
Walk with me

Shatter the bonds that tie us
To what we strive to never be

Join me,
Walk with me
*/
#include<bits/stdc++.h>

#define mp make_pair
#define mt make_tuple
#define fi first
#define se second
#define pb push_back
#define ll long long
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define rep(i,n) for(i=0;i<n;i++)
#define forn(i, n) for (ll i = 0; i < (ll)(n); ++i)
#define for1(i, n) for (ll i = 1; i <= (ll)(n); ++i)
#define ford(i, n) for (ll i = (ll)(n) - 1; i >= 0; --i)
#define fore(i, a, b) for (ll i = (ll)(a); i <= (ll)(b); ++i)
#define fora(it,x) for(auto it:x)
#define PI 3.14159265
#define sync ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);

using namespace std;

typedef pair<ll, ll> pii;
typedef vector<ll> vi;
typedef vector<pii> vpi;
typedef vector<vi> vvi;
typedef long long i64;
typedef vector<i64> vi64;
typedef vector<vi64> vvi64;
typedef pair<i64, i64> pi64;
typedef double ld;

template<class T> bool uin(T &a, T b) { return a > b ? (a = b, true) : false; }
template<class T> bool uax(T &a, T b) { return a < b ? (a = b, true) : false; }

const ll maxn=3001;

vvi seven_nation(maxn);

int main(){

ll n,m;
cin>>n>>m;

forn(i,n){
ll x,y;
cin>>x>>y;
seven_nation[x].pb(y);
}

fore(i,1,m){
sort(all(seven_nation[i]));
}
//return 0;
ll ans=LONG_LONG_MAX;

fore(votes,1,n){

//cout<<1<<endl;
ll aur_chahiye=votes-seven_nation[1].size();

ll cost=0;

vi rem;

fore(i,2,m){
//cout<<seven_nation[i].size()<<endl;
ll kahan_bhai=max((ll)(seven_nation[i].size()-votes+1),0);
//cout<<kahan_bhai<<endl;
forn(j,kahan_bhai){
//cout<<1<<endl;
cost+=seven_nation[i][j];
aur_chahiye--;

}
//cout<<1<<endl;
//vector <ll> rem;
//if(seven_nation[i].size()-1>=0)
//cout<<seven_nation[i].size()<<endl;
ll k=seven_nation[i].size();
k--;
fore(j,kahan_bhai,k){
              // cout<<1<<endl;
             // cout<<j<<endl;
            // cout<<seven_nation[i].size()<<endl;
    rem.pb(seven_nation[i][j]);
}

//cout<<1<<endl;
}

if(aur_chahiye>0){

    nth_element(rem.begin(),rem.begin()+aur_chahiye,rem.end());
    forn(i,aur_chahiye){
    cost+=rem[i];
    }

}
ans=min(cost,ans);

}

cout<<ans;
return 0;
}


#include<bits/stdc++.h>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define x first
#define y second
#define rep(i,a,b) for(int i=a;i<b;++i)
#define per(i,a,b) for(int i=a-1;i>=b;--i)
#define fuck(x) cout<<'['<<#x<<' '<<(x)<<']'
#define eps 1e-10
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> VI;
typedef pair<int, int> PII;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const ll INFLL = 0x3f3f3f3f3f3f3f3fll;
const int MX = 3e3 + 5;

struct node {
    int p, c;
    bool operator<(const node& _A)const {
        return c > _A.c;
    }
} a[MX];
int b[MX];
int main() {
#ifdef local
    freopen("in.txt", "r", stdin);
#endif // local

    int n, m; cin >> n >> m;
    rep(i, 1, n + 1) cin >> a[i].p >> a[i].c;
    rep(i, 1, n + 1) b[a[i].p]++;
    int cnt = 0; rep(i, 2, m + 1) if(b[i] >= b[1]) cnt++;
    if(!cnt) return printf("0\n") * 0;
    sort(a + 1, a + n + 1);
    ll ans = INFLL;
    rep(k, b[1], n + 1) {
        cnt = n - k;
        ll tmp = 0;
        memset(b, 0, sizeof(b));
        rep(i, 1, n + 1) if(a[i].p != 1 && cnt) {
            if(b[a[i].p] + 1 < k) b[a[i].p]++, cnt--;
            else tmp += a[i].c;
        } else if(a[i].p != 1) tmp += a[i].c;
        ans = min(ans, tmp);
    }
    cout << ans << endl;

#ifdef local
    cout << "time cost:" << clock() << "ms" << endl;
#endif // local
    return 0;
}


#include<iostream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cstdio>
#include<queue>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
int n,m;
ll ans=0x3f3f3f3f3f3f3f3fll;
struct object
{
	ll P;
	ll C;
};
object people[30001];
int voteNum[30001];
int adjustVoteNum[30001];
bool cmp(object a,object b)
{
	return a.C>b.C;
}
int main()
{
//	freopen("test.in","r",stdin);
//	freopen("test.out","w",stdout);
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		cin>>people[i].P>>people[i].C;
		voteNum[people[i].P]++;
	}
	sort(people+1,people+1+n,cmp);
	bool zeroFlag=true;
	for(int i=2;i<=m;i++)
	{
		if(voteNum[i]>=voteNum[1])
		{
			zeroFlag=false;
			break;
		}
	}
	if(zeroFlag)
	{
		cout<<0<<endl;
		return 0;
	}
	for(int i=voteNum[1];i<=n;i++)
	{
		ll totalCost=0;
		int deltaNum=n-i;
		memset(adjustVoteNum,0,sizeof(adjustVoteNum));
		for(int j=1;j<=n;j++)
		{
			if(people[j].P!=1&&deltaNum>0)
			{
				if(adjustVoteNum[people[j].P]<i-1)
				{
					adjustVoteNum[people[j].P]++;
					deltaNum--;
				}
				else
				{
					totalCost+=people[j].C;
				}
			}
			else if(people[j].P!=1)
			{
				totalCost+=people[j].C;
			}
		}
		ans=min(ans,totalCost);
	}
	cout<<ans<<endl;
	return 0;
}


#include<iostream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cstdio>
#include<queue>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
int n,m;
ll ans;
struct object
{
	ll P;
	ll C;
};
object people[3001];
int voteNum[3001];
int adjustVoteNum[3001];
bool cmp(object a,object b)
{
	return a.C>b.C;
}
int main()
{
//	freopen("test.in","r",stdin);
//	freopen("test.out","w",stdout);
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		scanf("%lld %lld",&people[i].P,&people[i].C);
		voteNum[people[i].P]++;
		ans+=people[i].C;
	}
	sort(people+1,people+1+n,cmp);
	bool zeroFlag=true;
	for(int i=2;i<=m;i++)
	{
		if(voteNum[i]>=voteNum[1])
		{
			zeroFlag=false;
			break;
		}
	}
	if(zeroFlag)
	{
		cout<<0<<endl;
		return 0;
	}
	for(int i=voteNum[1];i<=n;i++)
	{
		ll totalCost=0;
		int deltaNum=n-i;
		memset(adjustVoteNum,0,sizeof(adjustVoteNum));
		for(int j=1;j<=n;j++)
		{
			if(people[j].P!=1&&deltaNum>0)
			{
				if(adjustVoteNum[people[j].P]<i-1)
				{
					adjustVoteNum[people[j].P]++;
					deltaNum--;
				}
				else
				{
					totalCost+=people[j].C;
				}
			}
			else if(people[j].P!=1)
			{
				totalCost+=people[j].C;
			}
		}
		ans=min(ans,totalCost);
	}
	cout<<ans<<endl;
	return 0;
}


#include<iostream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cstdio>
#include<queue>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
int n,m;
ll ans;
struct object
{
	ll P;
	ll C;
};
object people[3001];
int voteNum[3001];
int adjustVoteNum[3001];
bool cmp(object a,object b)
{
	return a.C>b.C;
}
int main()
{
	std::ios::sync_with_stdio(false);
	//freopen("test.in","r",stdin);
	//freopen("test.out","w",stdout);
	//scanf("%d %d",&n,&m);
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		cin>>people[i].P>>people[i].C;
		voteNum[people[i].P]++;
		ans+=people[i].C;
	}
	sort(people+1,people+1+n,cmp);
	bool zeroFlag=true;
	for(int i=2;i<=m;i++)
	{
		if(voteNum[i]>=voteNum[1])
		{
			zeroFlag=false;
			break;
		}
	}
	if(zeroFlag)
	{
		cout<<0<<endl;
		return 0;
	}
	for(int i=voteNum[1];i<=n;i++)
	{
		ll totalCost=0;
		int deltaNum=n-i;
		memset(adjustVoteNum,0,sizeof(adjustVoteNum));
		for(int j=1;j<=n;j++)
		{
			if(people[j].P!=1&&deltaNum>0)
			{
				if(adjustVoteNum[people[j].P]<i-1)
				{
					adjustVoteNum[people[j].P]++;
					deltaNum--;
				}
				else
				{
					totalCost+=people[j].C;
				}
			}
			else if(people[j].P!=1)
			{
				totalCost+=people[j].C;
			}
		}
		ans=min(ans,totalCost);
	}
	cout<<ans<<endl;
	return 0;
}


#include<iostream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cstdio>
#include<queue>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
int n,m;
ll ans;
struct object
{
	ll P;
	ll C;
};
object people[3001];
int voteNum[3001];
int adjustVoteNum[3001];
bool cmp(object a,object b)
{
	return a.C>b.C;
}
int main()
{
	std::ios::sync_with_stdio(false);
//	freopen("test.in","r",stdin);
//	freopen("test.out","w",stdout);
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		cin>>people[i].P>>people[i].C;
		voteNum[people[i].P]++;
		ans+=people[i].C;
	}
	sort(people+1,people+1+n,cmp);
	bool zeroFlag=true;
	for(int i=2;i<=m;i++)
	{
		if(voteNum[i]>=voteNum[1])
		{
			zeroFlag=false;
			break;
		}
	}
	if(zeroFlag)
	{
		cout<<0<<endl;
		return 0;
	}
	for(int i=voteNum[1];i<=n;i++)
	{
		ll totalCost=0;
		int deltaNum=n-i;
		memset(adjustVoteNum,0,sizeof(adjustVoteNum));
		for(int j=1;j<=n;j++)
		{
			if(people[j].P!=1&&deltaNum>0)
			{
				if(adjustVoteNum[people[j].P]<i-1)
				{
					adjustVoteNum[people[j].P]++;
					deltaNum--;
				}
				else
				{
					totalCost+=people[j].C;
				}
			}
			else if(people[j].P!=1)
			{
				totalCost+=people[j].C;
			}
		}
		ans=min(ans,totalCost);
	}
	cout<<ans<<endl;
	return 0;
}


#include<iostream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cstdio>
#include<queue>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
int n,m;
ll ans=0x3f3f3f3f3f3f3f3fll;
struct object
{
	ll P;
	ll C;
};
object people[30001];
int voteNum[30001];
int adjustVoteNum[30001];
bool cmp(object a,object b)
{
	return a.C>b.C;
}
int main()
{
	std::ios::sync_with_stdio(false);
//	freopen("test.in","r",stdin);
//	freopen("test.out","w",stdout);
	scanf("%d %d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		cin>>people[i].P>>people[i].C;
		voteNum[people[i].P]++;
	}
	sort(people+1,people+1+n,cmp);
	bool zeroFlag=true;
	for(int i=2;i<=m;i++)
	{
		if(voteNum[i]>=voteNum[1])
		{
			zeroFlag=false;
			break;
		}
	}
	if(zeroFlag)
	{
		cout<<0<<endl;
		return 0;
	}
	for(int i=voteNum[1];i<=n;i++)
	{
		ll totalCost=0;
		int deltaNum=n-i;
		memset(adjustVoteNum,0,sizeof(adjustVoteNum));
		for(int j=1;j<=n;j++)
		{
			if(people[j].P!=1&&deltaNum>0)
			{
				if(adjustVoteNum[people[j].P]<i-1)
				{
					adjustVoteNum[people[j].P]++;
					deltaNum--;
				}
				else
				{
					totalCost+=people[j].C;
				}
			}
			else if(people[j].P!=1)
			{
				totalCost+=people[j].C;
			}
		}
		ans=min(ans,totalCost);
	}
	cout<<ans<<endl;
	return 0;
}


#include<iostream>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cstdio>
#include<queue>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
int n,m;
ll ans;
struct object
{
	ll P;
	ll C;
};
object people[3001];
int voteNum[3001];
int adjustVoteNum[3001];
bool cmp(object a,object b)
{
	return a.C>b.C;
}
int main()
{
//	freopen("test.in","r",stdin);
//	freopen("test.out","w",stdout);
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		cin>>people[i].P>>people[i].C;
		voteNum[people[i].P]++;
		ans+=people[i].C;
	}
	sort(people+1,people+1+n,cmp);
	bool zeroFlag=true;
	for(int i=2;i<=m;i++)
	{
		if(voteNum[i]>=voteNum[1])
		{
			zeroFlag=false;
			break;
		}
	}
	if(zeroFlag)
	{
		cout<<0<<endl;
		return 0;
	}
	for(int i=voteNum[1];i<=n;i++)
	{
		ll totalCost=0;
		int deltaNum=n-i;
		memset(adjustVoteNum,0,sizeof(adjustVoteNum));
		for(int j=1;j<=n;j++)
		{
			if(people[j].P!=1&&deltaNum>0)
			{
				if(adjustVoteNum[people[j].P]<i-1)
				{
					adjustVoteNum[people[j].P]++;
					deltaNum--;
				}
				else
				{
					totalCost+=people[j].C;
				}
			}
			else if(people[j].P!=1)
			{
				totalCost+=people[j].C;
			}
		}
		ans=min(ans,totalCost);
	}
	cout<<ans<<endl;
	return 0;
}


#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
typedef long long LL;
const LL INF = 1e18;
const int MAX_M = 3005;
vector<int> G[MAX_M], temp;
int n, m;

LL cal(int x) {
	int t = x-G[1].size();
	temp.clear();
	LL res = 0;

	for(int i = 2; i <= m; i++) {
		int sz = G[i].size();
		if(sz < x) {
			for(int j = 0; j < sz; j++) {
				temp.push_back(G[i][j]);
			}
		} else {
			/*
			for(int j = 0; j < sz; j++) {
				if(j < sz - x + 1){
					t--;
					res += (LL)G[i][j];
				} else {
					temp.push_back(G[i][j]);
				}
			}
			*/
			for(int j = 0; j < sz-x+1; j++) {
				t--;
				res += (LL)G[i][j];
			}
			for(int j = sz-x+1; j < sz; j++) {
				temp.push_back(G[i][j]);
			}
		}
	}
	if(t < 0) return INF;
	if(t > 0) {
		sort(temp.begin(), temp.end());
		int sz = temp.size();
		for(int i = 0; i < sz; i++) {
			res += (LL)temp[i];
			t--;
			if(t == 0)	break;
		}
	}
	return res;
}

int main() {
	scanf("%d%d",&n,&m);

	int v, c;
	for(int i = 1; i <= n; i++) {
		scanf("%d%d",&v,&c);
		G[v].push_back(c);
	}

	for(int i = 1; i <= m; i++) {
		sort(G[i].begin(),G[i].end());
	}

	LL ans = INF;
	//这里不能用 n/2+1,因为当前票数可能就已胜利,ans=0
	for(int i = G[1].size(); i <= n; i++) {
		ans = min(ans, cal(i));
	}
	printf("%lld\n",ans);
	return 0;
}


#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
typedef long long LL;
const LL INF = 1e18;
const int MAX_M = 3005;
vector<LL> G[MAX_M], temp;
int n, m;

LL cal(int x) {
	int t = x-G[1].size();
	temp.clear();
	LL res = 0;

	for(int i = 2; i <= m; i++) {
		int sz = G[i].size();
		if(sz < x) {
			for(int j = 0; j < sz; j++) {
				temp.push_back(G[i][j]);
			}
		} else {
			int tp = sz-x+1;
			for(int j = 0; j < tp; j++) {
				t--;
				res += G[i][j];
			}
			for(int j = tp; j < sz; j++) {
				temp.push_back(G[i][j]);
			}
		}
	}
	if(t < 0) return INF;
	if(t > 0) {
		int sz = temp.size();
		sort(temp.begin(),temp.end());
		for(int i = 0; i < sz; i++) {
			res += temp[i];
			t--;
			if(t == 0) break;
		}
	}
	return res;
}

int main() {
	scanf("%d%d",&n,&m);

	int v, c;
	for(int i = 1; i <= n; i++) {
		scanf("%d%lld",&v,&c);
		G[v].push_back(c);
	}

	for(int i = 1; i <= m; i++) {
		sort(G[i].begin(),G[i].end());
	}

	int t = n/2+1;
	LL ans = INF;
	for(int i = G[1].size(); i <= t; i++) {
		ans = min(ans, cal(i));
	}
	printf("%lld\n",ans);
	return 0;
}


#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
typedef long long LL;
const LL INF = 1e18;
const int MAX_M = 3005;
vector<int> G[MAX_M], temp;
int n, m;

LL cal(int x) {
	int t = x-G[1].size();
	temp.clear();
	LL res = 0;

	for(int i = 2; i <= m; i++) {
		int sz = G[i].size();
		if(sz < x) {
			for(int j = 0; j < sz; j++) {
				temp.push_back(G[i][j]);
			}
		} else {
			/*
			for(int j = 0; j < sz; j++) {
				if(j < sz - x + 1){
					t--;
					res += (LL)G[i][j];
				} else {
					temp.push_back(G[i][j]);
				}
			}
			*/
			for(int j = 0; j < sz; j++) {
				if(j < sz - x + 1){
					t--;
					res += (LL)G[i][j];
				}
			}
			for(int j = sz - x + 1; j < sz; j++) {
				temp.push_back(G[i][j]);
			}
		}
	}
	if(t < 0) return INF;
	if(t > 0) {
		sort(temp.begin(), temp.end());
		int sz = temp.size();
		for(int i = 0; i < sz; i++) {
			res += (LL)temp[i];
			t--;
			if(t == 0)	break;
		}
	}
	return res;
}

int main() {
	scanf("%d%d",&n,&m);

	int v, c;
	for(int i = 1; i <= n; i++) {
		scanf("%d%d",&v,&c);
		G[v].push_back(c);
	}

	for(int i = 1; i <= m; i++) {
		sort(G[i].begin(),G[i].end());
	}

	LL ans = INF;
	//这里不能用 n/2+1,因为当前票数可能就已胜利,ans=0
	for(int i = G[1].size(); i <= n; i++) {
		ans = min(ans, cal(i));
	}
	printf("%lld\n",ans);
	return 0;
}


#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
typedef long long LL;
const LL INF = 1e18;
const int MAX_M = 3005;
vector<int> G[MAX_M], temp;
int n, m;

LL cal(int x) {
	int t = x-G[1].size();
	temp.clear();
	LL res = 0;

	for(int i = 2; i <= m; i++) {
		int sz = G[i].size();
		if(sz < x) {
			for(int j = 0; j < sz; j++) {
				temp.push_back(G[i][j]);
			}
		} else {
			int tp = sz-x+1;
			for(int j = 0; j < tp; j++) {
				t--;
				res += (LL)G[i][j];
			}
			for(int j = tp; j < sz; j++) {
				temp.push_back(G[i][j]);
			}
		}
	}
	if(t < 0) return INF;
	if(t > 0) {
		sort(temp.begin(), temp.end());
		int sz = temp.size();
		for(int i = 0; i < sz; i++) {
			res += (LL)temp[i];
			t--;
			if(t == 0)	break;
		}
	}
	return res;
}

int main() {
	scanf("%d%d",&n,&m);

	int v, c;
	for(int i = 1; i <= n; i++) {
		scanf("%d%d",&v,&c);
		G[v].push_back(c);
	}

	for(int i = 1; i <= m; i++) {
		sort(G[i].begin(),G[i].end());
	}

	LL ans = INF;
	//这里不能用 n/2+1，因为当前票数可能就已胜利，ans应该为0;
	for(int i = G[1].size(); i <= n; i++) {
		ans = min(ans, cal(i));
	}
	printf("%lld\n",ans);
	return 0;
}


#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
typedef long long LL;
const LL INF = 1e18;
const int MAX_M = 3005;
vector<int> G[MAX_M], temp;
int n, m;

LL cal(int x) {
	int t = x-G[1].size();
	temp.clear();
	LL res = 0;

	for(int i = 2; i <= m; i++) {
		int sz = G[i].size();
		if(sz < x) {
			for(int j = 0; j < sz; j++) {
				temp.push_back(G[i][j]);
			}
		} else {
			for(int j = 0; j < sz; j++) {
				if(j < sz - x + 1){
					t--;
					res += (LL)G[i][j];
				} else {
					temp.push_back(G[i][j]);
				}
			}
		}
	}
	if(t < 0) return INF;
	if(t > 0) {
		sort(temp.begin(), temp.end());
		int sz = temp.size();
		for(int i = 0; i < sz; i++) {
			res += (LL)temp[i];
			t--;
			if(t == 0)	break;
		}
	}
	return res;
}

int main() {
	scanf("%d%d",&n,&m);

	int v, c;
	for(int i = 1; i <= n; i++) {
		scanf("%d%d",&v,&c);
		G[v].push_back(c);
	}

	for(int i = 1; i <= m; i++) {
		sort(G[i].begin(),G[i].end());
	}

	int t = n/2+1;
	LL ans = INF;
	for(int i = G[1].size(); i <= n; i++) {
		ans = min(ans, cal(i));
	}
	printf("%lld\n",ans);
	return 0;
}


#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
typedef long long LL;
const LL INF = 1e18;
const int MAX_M = 3005;
vector<int> G[MAX_M], temp;
int n, m;

LL cal(int x) {
	int t = x-G[1].size();
	temp.clear();
	LL res = 0;

	for(int i = 2; i <= m; i++) {
		int sz = G[i].size();
		if(sz < x) {
			for(int j = 0; j < sz; j++) {
				temp.push_back(G[i][j]);
			}
		} else {
			for(int j = 0; j < sz; j++) {
				if(j < sz - x + 1){
					t--;
					res += (LL)G[i][j];
				} else {
					temp.push_back(G[i][j]);
				}
			}
		}
	}
	if(t < 0) return INF;
	if(t > 0) {
		sort(temp.begin(), temp.end());
		int sz = temp.size();
		for(int i = 0; i < sz; i++) {
			res += (LL)temp[i];
			t--;
			if(t == 0)	break;
		}
	}
	return res;
}

int main() {
	scanf("%d%d",&n,&m);

	int v, c;
	for(int i = 1; i <= n; i++) {
		scanf("%d%d",&v,&c);
		G[v].push_back(c);
	}

	for(int i = 1; i <= m; i++) {
		sort(G[i].begin(),G[i].end());
	}

	int t = n/2+1;
	LL ans = INF;
	for(int i = G[1].size(); i <= t; i++) {
		ans = min(ans, cal(i));
	}
	printf("%lld\n",ans);
	return 0;
}


#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
typedef long long LL;
const LL INF = 1e18;
const int MAX_M = 3005;
vector<int> G[MAX_M], temp;
int n, m;

LL cal(int x) {
	int t = x-G[1].size();
	temp.clear();
	LL res = 0;

	for(int i = 2; i <= m; i++) {
		int sz = G[i].size();
		if(sz < x) {
			for(int j = 0; j < sz; j++) {
				temp.push_back(G[i][j]);
			}
		} else {
			/*
			for(int j = 0; j < sz; j++) {
				if(j < sz - x + 1){
					t--;
					res += (LL)G[i][j];
				} else {
					temp.push_back(G[i][j]);
				}
			}
			*/
			for(int j = 0; j < sz - x + 1; j++) {
				t--;
				res += (LL)G[i][j];
			}
			for(int j = sz - x + 1; j < sz; j++) {
				temp.push_back(G[i][j]);
			}
		}
	}
	if(t < 0) return INF;
	if(t > 0) {
		sort(temp.begin(), temp.end());
		int sz = temp.size();
		for(int i = 0; i < sz; i++) {
			res += (LL)temp[i];
			t--;
			if(t == 0)	break;
		}
	}
	return res;
}

int main() {
	scanf("%d%d",&n,&m);

	int v, c;
	for(int i = 1; i <= n; i++) {
		scanf("%d%d",&v,&c);
		G[v].push_back(c);
	}

	for(int i = 1; i <= m; i++) {
		sort(G[i].begin(),G[i].end());
	}

	LL ans = INF;
	//这里不能用 n/2+1,因为当前票数可能就已胜利,ans=0
	for(int i = G[1].size(); i <= n; i++) {
		ans = min(ans, cal(i));
	}
	printf("%lld\n",ans);
	return 0;
}


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

#include <algorithm>
#include <iostream>
#include <complex>
#include <cstring>
#include <vector>
#include <string>
#include <cstdio>
#include <ctime>
#include <queue>
#include <cmath>
#include <map>
#include <set>

using namespace std;

#define sz(a)                   int(a.size())
#define all(a)                  (a).begin(), (a).end()
#define CL(a, b)                memset(a, b, sizeof a)
#define FOR(i, a, b)			for (int i(a); i < (b); ++i)
#define REP(i, n)               FOR(i, 0, n)
#define UN(a)                   sort(all(a)), (a).erase(unique(all(a)), (a).end())
#define pb                      push_back
#define SORT(a)                 sort(all(a))

typedef long long ll;
typedef vector <int> vi;
typedef pair <int, int> pii;

int n,m,k;
vi v[1111111];

int cc;
bool u[1111111];

void dfs(int ver){
	if(u[ver]) return;
	u[ver]=true;cc++;
	REP(i,v[ver].size())
		dfs(v[ver][i]);
}

int main() {
#ifdef LocalHost
	freopen("input.txt", "r", stdin);
#endif

	cin>>n>>m>>k;
	REP(i,m){
		int x,y;
		scanf("%d %d",&x,&y);
		x--,y--;
		v[x].pb(y);
		v[y].pb(x);
	}
	vi c;
	REP(i,n) if(!u[i]){
		cc=0;
		dfs(i);
		c.pb(cc);
	}
	SORT(c);
	if(k==1){
		cout<<max(0,(int)c.size()-2)<<endl;
	}else{
		int num1 = 0;
		REP(i,c.size()) if(c[i]==1) num1++;
		int num2 = 0;
		REP(i,c.size()) if(c[i]>2) num2 += min(k-2, c[i] - 2);
		num1 -= num2;
		cout<<(max(0,num1)-1)/2<<endl;
	}
	return 0;
}


#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn=2000000+10;
bool flag[maxn];
int son[maxn],lnk[maxn],nxt[maxn];
int que[maxn],A[maxn];
int n,m,limit,cnt,res;

int main()
{
    scanf("%d%d%d",&n,&m,&limit);
    for (int i=1,u,v;i<=m;i++)
    {
        scanf("%d%d",&u,&v);
        lnk[i]=v;nxt[i]=son[u];son[u]=i;
        lnk[i+m]=u;nxt[i+m]=son[v];son[v]=i+m;
    }

    for (int i=1;i<=n;i++)
    if (!flag[i])
    {
        que[1]=i;flag[i]=1;int r=1;
        for (int l=1;l<=r;l++)
        for (int j=son[que[l]];j;j=nxt[j])
        if (!flag[lnk[j]])
        {
            flag[lnk[j]]=1;que[++r]=lnk[j];
        }
        if (r==1) cnt++;
        else A[++A[0]]=min(limit,r);
    }
    while (cnt && A[0]) {cnt--;A[A[0]]--;if (A[A[0]]==1) cnt++,A[0]--;}
    printf("%d\n", max(0,(cnt+1)/2-1));
}


#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn=2000000+10;
bool flag[maxn];
int son[maxn],lnk[maxn],nxt[maxn];
int que[maxn],A[maxn];
int n,m,limit,cnt,res;

int main()
{
    scanf("%d%d%d",&n,&m,&limit);
    for (int i=1,u,v;i<=m;i++)
    {
        scanf("%d%d",&u,&v);
        lnk[i]=v;nxt[i]=son[u];son[u]=i;
        lnk[i+m]=u;nxt[i+m]=son[v];son[v]=i+m;
    }

    for (int i=1;i<=n;i++)
    if (!flag[i])
    {
        que[1]=i;flag[i]=1;int r=1;
        for (int l=1;l<=r;l++)
        for (int j=son[que[l]];j;j=nxt[j])
        if (!flag[lnk[j]])
        {
            flag[lnk[j]]=1;que[++r]=lnk[j];
        }
        if (r==1) cnt++;
        else A[++A[0]]=min(limit,r);
    }
    while (cnt && A[0]) {cnt--;A[A[0]]--;if (A[A[0]]==1) cnt++,A[0]--;}
    if (limit==1) printf("%d\n",max(0,cnt-2));
    else printf("%d\n", max(0,(cnt+1)/2-1));
}


#include<cstdio>
#include<algorithm>
using namespace std;

const int maxn=2000000+10;
bool flag[maxn];
int son[maxn],lnk[maxn],nxt[maxn];
int que[maxn],A[maxn];
int n,m,limit,cnt,res;

int main()
{
    scanf("%d%d%d",&n,&m,&limit);
    for (int i=1,u,v;i<=m;i++)
    {
        scanf("%d%d",&u,&v);
        lnk[i]=v;nxt[i]=son[u];son[u]=i;
        lnk[i+m]=u;nxt[i+m]=son[v];son[v]=i+m;
    }

    for (int i=1;i<=n;i++)
    if (!flag[i])
    {
        que[1]=i;flag[i]=1;int r=1;
        for (int l=1;l<=r;l++)
        for (int j=son[que[l]];j;j=nxt[j])
        if (!flag[lnk[j]])
        {
            flag[lnk[j]]=1;que[++r]=lnk[j];
        }
        if (r==1 || limit==1) cnt++;
        else A[++A[0]]=min(limit,r);
    }
    while (cnt && A[0]) {cnt--;A[A[0]]--;if (A[A[0]]==1) cnt++,A[0]--;}
    if (limit==1) printf("%d\n",max(0,cnt-2));
    else printf("%d\n", max(0,(cnt+1)/2-1));
}


#include <iostream>
#include <string.h>
#include <algorithm>
#include <cstdio>
using namespace std;

const int maxn = 1000007;
      int n , m , k;
      int fa[ maxn ];
      int sum[ maxn ];

int father( int x )
{
    if ( x == fa[ x ] ) return( x );
    fa[ x ] = father( fa[ x ] );
    return( fa[ x ] );
}

int get_res()
{
    int tot1 = 0 , tot2 = 0 , tot = 0;
    for ( int i = 1 ; i <= n ; i++ )
    {
       if ( sum[ i ] == 1 ) tot1++;
       if ( sum[ i ] > 1 )
       {
            tot2++;
            tot += min( sum[ i ] , k );
       }
    }
    if ( k == 1 ) return( ( tot1+tot2-1 )/2 );
    tot -= tot2*2-2;
    tot1 -= tot;
    if ( tot <= 0 ) return( 0 );
    return( ( tot1+1 )/2 );
}

void work()
{
     for ( int i = 1 ; i <= n ; i++ ) fa[ i ] = i;
     int f1 , f2 , fir , lst;
     for ( int i = 1 ; i <= m ; i++ )
     {
         scanf( "%d %d" , &fir , &lst );
         f1 = father( fir );
         f2 = father( lst );
         if ( f1 != f2 ) fa[ f1 ] = f2;
     }
     memset( sum , 0 , sizeof( sum ) );
     for ( int i = 1 ; i <= n ; i++ ) sum[ father( i ) ]++;
     int res = get_res();
     printf( "%d\n" , res );
}

int main()
{
    while ( scanf( "%d %d %d" , &n , &m , &k ) != EOF ) work();
}


#include <iostream>
#include <string.h>
#include <algorithm>
#include <cstdio>
using namespace std;

const int maxn = 1000007;
      int n , m , k;
      int fa[ maxn ];
      int sum[ maxn ];

int father( int x )
{
    if ( x == fa[ x ] ) return( x );
    fa[ x ] = father( fa[ x ] );
    return( fa[ x ] );
}

int get_res()
{
    int tot1 = 0 , tot2 = 0 , tot = 0;
    for ( int i = 1 ; i <= n ; i++ )
    {
       if ( sum[ i ] == 1 ) tot1++;
       if ( sum[ i ] > 1 )
       {
            tot2++;
            tot += sum[ i ];
       }
    }
    while ( k > 0 && tot2 > 1 )
    {
            k--;
            tot2--;
            tot -= 2;
    }
    while ( k > 0 && tot1 > 0 && tot > 0 )
    {
            k--;
            tot1--;
            tot --;
    }
    while ( k > 0 && tot1 > 1 )
    {
          k--;
          tot2++;
          tot1 -= 2;
    }
    return( tot1+tot2-1 );
}

void work()
{
     for ( int i = 1 ; i <= n ; i++ ) fa[ i ] = i;
     int f1 , f2 , fir , lst;
     for ( int i = 1 ; i <= m ; i++ )
     {
         scanf( "%d %d" , &fir , &lst );
         f1 = father( fir );
         f2 = father( lst );
         if ( f1 != f2 ) fa[ f1 ] = f2;
     }
     memset( sum , 0 , sizeof( sum ) );
     for ( int i = 1 ; i <= n ; i++ ) sum[ father( i ) ]++;
     int res = get_res();
     printf( "%d\n" , res );
}

int main()
{
    while ( scanf( "%d %d %d" , &n , &m , &k ) != EOF ) work();
}


#include <iostream>
#include <string.h>
#include <algorithm>
#include <cstdio>
using namespace std;

const int maxn = 1000007;
      int n , m , k;
      int fa[ maxn ];

int father( int x )
{
    if ( fa[ x ] == x ) return( x );
    fa[ x ] = father( fa[ x ] );
    return( fa[ x ] );
}

void work()
{
     for ( int i = 1 ; i <= n ; i++ ) fa[ i ] = i;
     int f1 , f2 , fir , lst;
     int res = n;
     for ( int i = 1 ; i <= m ; i++ )
     {
         scanf( "%d %d" , &fir , &lst );
         f1 = father( fir );
         f2 = father( lst );
         if ( f1 != f2 )
         {
              fa[ f1 ] = f2;
              res--;
         }
     }
     res -= k+1;
     res = max( res , 0 );
     printf( "%d\n" , res );
}

int main()
{
    while ( scanf( "%d %d %d" , &n , &m , &k ) != EOF ) work();
}


#include <iostream>
#include <string.h>
#include <algorithm>
#include <cstdio>
using namespace std;

const int maxn = 1000007;
      int n , m , k;
      int fa[ maxn ];
      int sum[ maxn ];

int father( int x )
{
    if ( x == fa[ x ] ) return( x );
    fa[ x ] = father( fa[ x ] );
    return( fa[ x ] );
}

void work()
{
     for ( int i = 1 ; i <= n ; i++ ) fa[ i ] = i;
     int f1 , f2 , fir , lst;
     for ( int i = 1 ; i <= m ; i++ )
     {
         scanf( "%d %d" , &fir , &lst );
         f1 = father( fir );
         f2 = father( lst );
         if ( f1 != f2 ) fa[ f1 ] = f2;
     }
     memset( sum , 0 , sizeof( sum ) );
     for ( int i = 1 ; i <= n ; i++ ) sum[ fa[ i ] ]++;
     int tot1 = 0 , tot2 = 0;
     for ( int i = 1 ; i <= n ; i++ )
     {
           if ( sum[ i ] == 1 ) tot1++;
           if ( sum[ i ] > 1 ) tot2++;
     }
     tot2 += max( ( tot1-1 )/2 , 0 )*2;
     tot1 -= max( tot1-2 , 0 );
     tot2 += tot1;
     int res = max( 0 , tot2-k-1 );
     printf( "%d\n" , res );
}

int main()
{
    while ( scanf( "%d %d %d" , &n , &m , &k ) != EOF ) work();
}


#include <iostream>
#include <string.h>
#include <algorithm>
#include <cstdio>
using namespace std;

const int maxn = 1000007;
      int n , m , k;
      int fa[ maxn ];
      int sum[ maxn ];

int father( int x )
{
    if ( x == fa[ x ] ) return( x );
    fa[ x ] = father( fa[ x ] );
    return( fa[ x ] );
}

int get_res()
{
    int tot1 = 0 , tot2 = 0 , tot = 0;
    for ( int i = 1 ; i <= n ; i++ )
    {
       if ( sum[ i ] == 1 ) tot1++;
       if ( sum[ i ] > 1 )
       {
            tot2++;
            tot += min( sum[ i ] , k );
       }
    }
    if ( k == 1 ) return( tot1+tot2-2 );
    tot -= tot2*2-2;
    tot1 -= tot;
    if ( tot1 <= 0 ) return( 0 );
    return( ( tot1+1 )/2 );
}

void work()
{
     for ( int i = 1 ; i <= n ; i++ ) fa[ i ] = i;
     int f1 , f2 , fir , lst;
     for ( int i = 1 ; i <= m ; i++ )
     {
         scanf( "%d %d" , &fir , &lst );
         f1 = father( fir );
         f2 = father( lst );
         if ( f1 != f2 ) fa[ f1 ] = f2;
     }
     memset( sum , 0 , sizeof( sum ) );
     for ( int i = 1 ; i <= n ; i++ ) sum[ father( i ) ]++;
     int res = get_res();
     printf( "%d\n" , res );
}

int main()
{
    while ( scanf( "%d %d %d" , &n , &m , &k ) != EOF ) work();
}


#include <iostream>
#include <string.h>
#include <algorithm>
#include <cstdio>
using namespace std;

const int maxn = 1000007;
      int n , m , k;
      int fa[ maxn ];
      int sum[ maxn ];

int father( int x )
{
    if ( x == fa[ x ] ) return( x );
    fa[ x ] = father( fa[ x ] );
    return( fa[ x ] );
}

int get_res()
{
    int tot1 = 0 , tot2 = 0 , tot = 0;
    for ( int i = 1 ; i <= n ; i++ )
    {
       if ( sum[ i ] == 1 ) tot1++;
       if ( sum[ i ] > 1 )
       {
            tot2++;
            tot += min( sum[ i ] , k );
       }
    }
    if ( k == 1 ) return( tot1+tot2-2 );
    tot -= tot2*2-2;
    tot1 -= tot;
    if ( tot <= 0 ) return( 0 );
    return( ( tot1+1 )/2 );
}

void work()
{
     for ( int i = 1 ; i <= n ; i++ ) fa[ i ] = i;
     int f1 , f2 , fir , lst;
     for ( int i = 1 ; i <= m ; i++ )
     {
         scanf( "%d %d" , &fir , &lst );
         f1 = father( fir );
         f2 = father( lst );
         if ( f1 != f2 ) fa[ f1 ] = f2;
     }
     memset( sum , 0 , sizeof( sum ) );
     for ( int i = 1 ; i <= n ; i++ ) sum[ father( i ) ]++;
     int res = get_res();
     printf( "%d\n" , res );
}

int main()
{
    while ( scanf( "%d %d %d" , &n , &m , &k ) != EOF ) work();
}


#include <iostream>
#include <string.h>
#include <algorithm>
#include <cstdio>
using namespace std;

const int maxn = 1000007;
      int n , m , k;
      int fa[ maxn ];
      int sum[ maxn ];

int father( int x )
{
    if ( x == fa[ x ] ) return( x );
    fa[ x ] = father( fa[ x ] );
    return( fa[ x ] );
}

int get_res()
{
    int tot1 = 0 , tot2 = 0 , tot = 0;
    for ( int i = 1 ; i <= n ; i++ )
    {
       if ( sum[ i ] == 1 ) tot1++;
       if ( sum[ i ] > 1 )
       {
            tot2++;
            tot += min( sum[ i ] , k );
       }
    }
    if ( k == 1 ) return( max( 0 , tot1+tot2-2 ) );
    tot -= tot2*2-2;
    tot1 -= tot;
    if ( tot1 <= 0 ) return( 0 );
    return( ( tot1+1 )/2 );
}

void work()
{
     for ( int i = 1 ; i <= n ; i++ ) fa[ i ] = i;
     int f1 , f2 , fir , lst;
     for ( int i = 1 ; i <= m ; i++ )
     {
         scanf( "%d %d" , &fir , &lst );
         f1 = father( fir );
         f2 = father( lst );
         if ( f1 != f2 ) fa[ f1 ] = f2;
     }
     memset( sum , 0 , sizeof( sum ) );
     for ( int i = 1 ; i <= n ; i++ ) sum[ father( i ) ]++;
     int res = get_res();
     printf( "%d\n" , res );
}

int main()
{
    while ( scanf( "%d %d %d" , &n , &m , &k ) != EOF ) work();
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <cassert>
#include <ctime>
#include <cstdlib>
#include <cmath>
#include <set>
#include <map>
#include <vector>
#include <queue>

using namespace std;

#define fr first
#define sc second
#define mp make_pair
#define pb push_back

#define epr(...) fprintf(stderr, __VA_ARGS__)

const int maxk = 100 + 2;
const int maxt = 40;
const int inf = 1e9;
const int mod = 7340033;

long long dp[maxt][maxk];

int main(){
//     freopen("in", "r", stdin);
//     freopen("out", "w", stdout);
	int q, i4, t, d, k;
	t = 32;
	for (int i = 0; i <= t; i++)
		dp[i][0] = 1;
	int cnt = 0;
	for (int i = 1; i <= t; i++)
		for (int j = 1; j < maxk; j++)
			for (int i1 = 0; i1 < j; i1++)
				for (int i2 = 0; i1 + i2 < j; i2++)
					for (int i3 = 0; i1 + i2 + i3 < j; i3++){
						cnt++;
						i4 = j - 1 - i1 - i2 - i3;
						dp[i][j] = (dp[i][j] + ((((dp[i - 1][i1] * dp[i - 1][i2]) % mod) * dp[i - 1][i3]) % mod) * dp[i - 1][i4]) % mod;
					}
	cerr << "cnt " << cnt << endl;
// 	cerr << "1\n";
// 	for (int i = 0; i < 10; i++){
// 		for (int j = 0; j < 50; j++)
// 			epr("%lld ", dp[i][j]);
// 		epr("\n");
// 	}

	scanf("%d", &q);
	for (int i = 0; i < q; i++){
		scanf("%d%d", &d, &k);
		int cnt = 0;
		for (; d > 1 && (d - 1) % 2 == 0; d = (d - 1) / 2, cnt++);
		cerr << cnt << endl;
		cout << dp[cnt][k] << endl;
	}

    return 0;
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <cassert>
#include <ctime>
#include <cstdlib>
#include <cmath>
#include <set>
#include <map>
#include <vector>
#include <queue>

using namespace std;

#define fr first
#define sc second
#define mp make_pair
#define pb push_back

#define epr(...) fprintf(stderr, __VA_ARGS__)

const int maxn = 1e6 + 2;
const int inf = 1e9;

pair < int, int > edge[maxn];
int p[maxn];
int sz[maxn];
set < pair < int, int > > q;
int k;

int getId(int v){
	if (p[v] == v)	return v;
	return p[v] = getId(p[v]);
}

void merge(int v, int u){
	sz[u] += sz[v];
	p[v] = u;
}

int f(int x){
	return min(x, k);
}

int main(){
//     freopen("in", "r", stdin);
//     freopen("out", "w", stdout);
	int n, m, v, u;
	int tunnel, cnt = 0;
	pair < int, int > a1, a2;
	scanf("%d%d%d", &n, &m, &k);
	for (int i = 0; i < m; i++){
		scanf("%d%d", &edge[i].fr, &edge[i].sc); edge[i].fr--; edge[i].sc--;
	}
	for (int i = 0; i < n; i++)
		p[i] = i;
	for (int i = 0; i < n; i++)
		sz[i] = 1;
	cnt = n;
	for (int i = 0; i < m; i++){
		v = getId(edge[i].fr);
		u = getId(edge[i].sc);
		if (v != u){
			merge(v, u);
			cnt--;
		}

	}
	tunnel = 0;
	for (int i = 0; i < n; i++){
		if (p[i] == i){
			tunnel += f(sz[i]);
			q.insert(mp(sz[i], i));
		}
	}

// 	cerr <<
// 	epr("cnt %d tunnel %d\n", cnt, tunnel);
	for (int i = 0;; i++){
		if (tunnel / 2 >= cnt - 1){
			cout << i << "\n";
			return 0;
		}
// 		epr("q %d\n", (int)q.size());
		a1 = *q.begin();
		q.erase(q.begin());
		a2 = *q.begin();
		q.erase(q.begin());
		tunnel -= f(a1.fr);
		tunnel -= f(a2.fr);
		tunnel += f(a1.fr + a2.fr);
		q.insert(mp(a1.fr + a2.fr, a1.sc));
		cnt--;
	}

    return 0;
}


#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
const long maxn = 1000001;
long n,m,k;
long fa[maxn], s[maxn], a[maxn];

long work()
{
	if (a[1]>=2 || m <= 2) return 0;
	if (k==1) return m-2;

	long kk = 0;
	for (long i = 1; i <= m; ++i)
		if (a[i] == 1) ++kk;
	long f = kk+1, r = m;
	if (kk<=2) return 0;
	kk -= 2;

	for (long i = 1; i <= m; ++i)
	if (a[i]>=2) {
		long wc = min(a[i]-2,k);
		kk -= wc;
		if (kk<=0) return 0;
	}
	return (kk+1)/2;
}

long find(long u)
{
	if (fa[u]==u) return u;
	fa[u] = find(fa[u]);
	return fa[u];
}

void init()
{
	cin >> n >> m >> k;
	memset(s,0,sizeof(s));
	for (long i = 1; i <= n; ++i) fa[i]=i;

	long x, y;
	for (long i = 1; i <= m; ++i) {
		 cin >> x >> y;
		 x = find(x);
		 y = find(y);
		 fa[y] = fa[x];
	}
	for (long i = 1; i <= n; ++i) ++s[find(i)];

	m = 0;
	for (long i = 1; i <= n; ++i)
		if (s[i]>0) {
			a[++m] = s[i];
		}
	sort(a,a+m+1);
}

int main()
{
	init();
	cout << work() << endl;
	return 0;
}


#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
const long maxn = 1000001;
long n,m,k;
long fa[maxn], s[maxn], a[maxn];

long work()
{
	if (a[1]>=2 || m <= 2) return 0;
	if (k==1) return m-2;

	long kk = 0;
	for (long i = 1; i <= m; ++i)
		if (a[i] == 1) ++kk;
	long f = kk+1, r = m;
	if (kk<=2) return 0;
	kk -= 2;

	for (long i = f; i <= r; ++i)  {
		long wc = min(a[i]-2,k);
		kk -= wc;
		if (kk<=0) return 0;
	}
	long ans = 0;
	for (long i = f; i <= r; ++i) {
		if (a[i]<k) {
			long yy = k-a[i];
			if (yy*2>=kk) return (ans+(kk+1)/2);
			ans += yy;
			kk -= yy*2;
		}
	}
	if (kk==0) return ans;
	return (ans+(kk+1)/2);
}

long find(long u)
{
	if (fa[u]==u) return u;
	fa[u] = find(fa[u]);
	return fa[u];
}

void init()
{
	cin >> n >> m >> k;
	memset(s,0,sizeof(s));
	for (long i = 1; i <= n; ++i) fa[i]=i;

	long x, y;
	for (long i = 1; i <= m; ++i) {
		 cin >> x >> y;
		 x = find(x);
		 y = find(y);
		 fa[y] = fa[x];
	}
	for (long i = 1; i <= n; ++i) ++s[find(i)];

	m = 0;
	for (long i = 1; i <= n; ++i)
		if (s[i]>0) {
			a[++m] = s[i];
		}
	sort(a,a+m+1);
}

int main()
{
	init();
	cout << work() << endl;
	return 0;
}


#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
const long maxn = 1000001;
long n,m,k;
long fa[maxn], s[maxn], a[maxn];

long work()
{
	if (a[1]>=2 || m <= 2) return 0;
	if (k==1) return m-2;

	long kk = 0;
	for (long i = 1; i <= m; ++i)
		if (a[i] == 1) ++kk;
	long f = kk+1, r = m;
	if (kk<=2) return 0;
	kk -= 2;

	for (long i = 1; i <= m; ++i)
	if (a[i]>=2) {
		long wc = min(a[i]-2,k-2);
		kk -= wc;
		if (kk<=0) return 0;
	}
	return (kk+1)/2;
}

long find(long u)
{
	if (fa[u]==u) return u;
	fa[u] = find(fa[u]);
	return fa[u];
}

void init()
{
	cin >> n >> m >> k;
	memset(s,0,sizeof(s));
	for (long i = 1; i <= n; ++i) fa[i]=i;

	long x, y;
	for (long i = 1; i <= m; ++i) {
		 cin >> x >> y;
		 x = find(x);
		 y = find(y);
		 fa[y] = fa[x];
	}
	for (long i = 1; i <= n; ++i) ++s[find(i)];

	m = 0;
	for (long i = 1; i <= n; ++i)
		if (s[i]>0) {
			a[++m] = s[i];
		}
	sort(a,a+m+1);
}

int main()
{
	init();
	cout << work() << endl;
	return 0;
}


/*
  ------------------------- Hachiikung ---------------------------------
  ---------------------- Worrachate Bosri ------------------------------
  ------ Faculty of Computer Engineering Chulalongkorn University ------
*/
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<string>
#include<utility>
using namespace std;
#define REP(i,FN) for(int i=0;i<FN;i++)
#define FOR(i,ST,FN) for(int i=ST;i<=FN;i++)
#define FORD(i,FN,ST) for(int i=FN;i>=ST;i--)
#define FORX(i,c) for(typeof(c.begin())i=c.begin();i!=c.end();i++)
#define pause system("pause")
#define S scanf
#define P printf
#define X first
#define Y second
#define pb push_back
#define PII pair<int,int>
#define mp make_pair
#define sz size()
#define eps 1e-8

const int MOD(1000000007);
const int INF((1<<30)-1);
const int MAXN(1000005);

vector<int>a[MAXN];

bool visited[MAXN];

int dfs(int node){

    visited[node]=1;

    int ret=1;
    REP(i,a[node].sz)
     if(!visited[a[node][i]])
      ret += dfs(a[node][i]);

    return ret;
}

int main(){

    int n,m,k;
    S("%d%d%d",&n,&m,&k);
    REP(i,m)
    {
        int u,v;
        S("%d%d",&u,&v);
        a[u].pb(v);
        a[v].pb(u);
    }

    multiset<int>component;

    FOR(i,1,n)
     if(!visited[i])
      component.insert(dfs(i));

    int ans=0;

    while(component.sz > k+1)
    {
        int x=*component.begin(); component.erase(component.begin());
        int y=*component.begin(); component.erase(component.begin());

        ans++;
        component.insert(x+y);
    }

    vector<int>tmp;
    FORX(it,component)
     tmp.pb(*it);

    sort(tmp.begin(),tmp.end(),greater<int>());

    int now=tmp[0];

    FOR(i,1,(int)(tmp.sz)-1)
    {
        if(now+tmp[i]-2 < 0){ ans++; now=0; }
        else now=now+tmp[i]-2;
    }

    P("%d",ans);
}