#include <bits/stdc++.h>

using namespace std;
#define ll long long int
ll n,m;
const int maxn=5e3+5;
long long int p[maxn],c[maxn];
ll total[maxn];
bool vis[maxn];
bool used[maxn];
typedef struct node
{
    long long int f,c;
    bool operator <(const node &r)const
    {
        return c<r.c;
    }
} node;
typedef struct node1
{
    long long int p,f,c;
    bool operator <(const node1 &r)const
    {
        return c<r.c;
    }
} node1;
//long long int now[maxn];
vector<node>V[maxn];
vector<node1>use;
//ll usenext=0;
//int main()
//{
//    ios::sync_with_stdio(false);
//    cin >> n >> m;
//    for(int i=1; i<=n; i++)
//    {
//        cin >> p[i] >> c[i];
//        node tmp;
//        tmp.f=i,tmp.c=c[i];
//        V[p[i]].push_back(tmp);
//        total[p[i]]++;
//        node1 tmp1;
//        tmp1.p=p[i],tmp1.f=i,tmp1.c=c[i];
//        if(p[i]!=1)
//            use.push_back(tmp1);
//        else
//            used[i]=1;
//    }
//    for(int i=1; i<=m; i++)
//        sort(V[i].begin(),V[i].end());
//    sort(use.begin(),use.end());
//    ll nowmax=0;
//    vector<ll>nowp;
//    nowp.clear();
//    for(int i=1; i<=m; i++)
//    {
//        if(nowmax<total[i])
//        {
//            nowp.clear();
//            memset(vis,0,sizeof(vis));
//            nowmax=total[i],nowp.push_back(i);
//            vis[i]=1;
//        }
//        else if(nowmax==total[i])
//        {
//            nowp.push_back(i);
//            vis[i]=1;
//        }
//    }
//    if(nowp.size()==1 && nowp[0]==1)
//    {
//        cout << 0 << endl;
//        return 0;
//    }
//    long long int ans=0;
//    while(total[1]<=nowmax)
//    {
//        if(nowp.size()+total[1]<=nowmax)
//        {
//            long long int tmp1=0,tmp2=0,fix=0;
//            for(int i=0; i<nowp.size(); i++)
//            {
//                ll tmpp=nowp[i];
//                while(used[V[tmpp][now[tmpp]].f])
//                    now[tmpp]++;
//                tmp1+=V[tmpp][now[tmpp]].c;
//                while(used[use[usenext+i+fix].f])
//                    fix++;
//                tmp2+=use[usenext+i+fix].c;
//            }
//            for(int i=0; i<2; i++)
//            {
//                while(used[use[usenext+fix].f])
//                    fix++;
//                tmp2+=use[usenext+fix].c;
//            }
//            if(tmp1<tmp2)
//            {
//                for(int i=0; i<nowp.size(); i++)
//                {
//                    ll tmpp=nowp[i];
//                    used[V[tmpp][now[tmpp]].f]=1;
//                    now[tmpp]++;
//                    total[tmpp]--;
//                }
//                total[1]+=nowp.size();
//                nowmax--;
//                for(int i=1; i<=m; i++)
//                {
//                    if(!vis[i] && total[i]==nowmax)
//                    {
//                        vis[i]=1;
//                        nowp.push_back(i);
//                    }
//                }
//                ans+=tmp1;
//            }
//            else
//            {
////                int totalnow=0,fix=0,l=nowp.size();
////                while(totalnow<2)
////                {
////                    while(used[use[usenext+fix].f])
////                        fix++;
////                    total[use[usenext+fix].p]--;
////                    if(vis[use[usenext+fix].p])
////                    {
////                        vis[use[usenext+fix].p]=0;
////                        for(int i=0; i<nowp.size(); i++)
////                        {
////                            if(nowp[i]==use[usenext+fix].p)
////                            {
////                                nowp.erase(nowp.begin()+i);
////                                break;
////                            }
////                        }
////                    }
////                    used[use[usenext+fix].f]=1;
////                    fix++;
////                    totalnow++;
////                }
////                usenext+=fix;
////                ans+=tmp2;
////                total[1]+=2;
//                int fix=0;
//                while(used[use[usenext+fix].f])
//                    fix++;
//                total[1]++;
//                total[use[usenext+fix].p]--;
//                ans+=use[usenext+fix].c;
//                used[use[usenext+fix].f]=1;
//                if(vis[use[usenext+fix].p])
//                {
//                    vis[use[usenext+fix].p]=0;
//                    for(int i=0; i<nowp.size(); i++)
//                    {
//                        if(nowp[i]==use[usenext+fix].p)
//                        {
//                            nowp.erase(nowp.begin()+i);
//                            break;
//                        }
//                    }
//                }
//                usenext+=fix;
//            }
//        }
//        else
//        {
//            ll fix=0;
//            while(used[use[usenext+fix].f])
//                fix++;
//            total[1]++;
//            total[use[usenext+fix].p]--;
//            ans+=use[usenext+fix].c;
//            used[use[usenext+fix].f]=1;
//            if(vis[use[usenext+fix].p])
//            {
//                vis[use[usenext+fix].p]=0;
//                for(int i=0; i<nowp.size(); i++)
//                {
//                    if(nowp[i]==use[usenext+fix].p)
//                    {
//                        nowp.erase(nowp.begin()+i);
//                        break;
//                    }
//                }
//            }
//            usenext+=fix;
//        }
//    }
//    cout << ans << endl;
//    return 0;
//}
int main()
{
    ios::sync_with_stdio(false);
    cin >> n >> m;
    for(int i=1; i<=n; i++)
    {
        cin >> p[i] >> c[i];
        if(p[i]!=1)
        {
            node1 tmp;
            tmp.f=i,tmp.p=p[i],tmp.c=c[i];
            use.push_back(tmp);
            node tmp1;
            tmp1.f=i,tmp1.c=c[i];
            V[p[i]].push_back(tmp1);
        }
        else
            used[i]=1;
        total[p[i]]++;
    }
    for(int i=2;i<=m;i++)
        sort(V[i].begin(),V[i].end());
    sort(use.begin(),use.end());
    ll now[maxn];
    ll out=0x7fffffff;
    for(int i=total[1];i<=n;i++)
    {
        if(i==0)    continue;
        bool visnow[maxn];
        memcpy(now,total,sizeof(total));
        memcpy(visnow,used,sizeof(vis));
        ll ans=0;
        for(int j=2;j<=m;j++)
        {
            if(now[j]>=i)
            {
                for(int x=0;x<now[j]-i+1;x++)
                {
                    ans+=V[j][x].c;
                    visnow[V[j][x].f]=1;
                }
                now[1]+=now[j]-i+1;
                now[j]=i-1;
            }
        }
        if(now[1]>i)
            continue;
        int d=i-now[1];
        int fix=0;
        bool flag=1;
        for(int j=0;j<d;j++)
        {
            while(j+fix<use.size() && visnow[use[j+fix].f])
                fix++;
            if(j+fix==use.size())
            {
                flag=0;
                break;
            }
            ans+=use[j+fix].c;
            now[use[j+fix].p]--;
            visnow[use[j+fix].f]=1;
        }
        for(int j=2;j<=m;j++)
        {
            if(now[j]>=i)
            {
                flag=0;
                break;
            }
        }
        if(flag)
        {
            out=min(out,ans);
            continue;
        }
    }
    cout << out << endl;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
#define ll long long int
ll n,m;
const int maxn=5e3+5;
long long int p[maxn],c[maxn];
ll total[maxn];
bool vis[maxn];
bool used[maxn];
typedef struct node
{
    long long int f,c;
    bool operator <(const node &r)const
    {
        return c<r.c;
    }
} node;
typedef struct node1
{
    long long int p,f,c;
    bool operator <(const node1 &r)const
    {
        return c<r.c;
    }
} node1;
long long int now[maxn];
vector<node>V[maxn];
vector<node1>use;
ll usenext=0;
int main()
{
    ios::sync_with_stdio(false);
    cin >> n >> m;
    for(int i=1; i<=n; i++)
    {
        cin >> p[i] >> c[i];
        node tmp;
        tmp.f=i,tmp.c=c[i];
        V[p[i]].push_back(tmp);
        total[p[i]]++;
        node1 tmp1;
        tmp1.p=p[i],tmp1.f=i,tmp1.c=c[i];
        if(p[i]!=1)
            use.push_back(tmp1);
        else
            used[i]=1;
    }
    for(int i=1; i<=m; i++)
        sort(V[i].begin(),V[i].end());
    sort(use.begin(),use.end());
    ll nowmax=0;
    vector<ll>nowp;
    nowp.clear();
    for(int i=1; i<=m; i++)
    {
        if(nowmax<total[i])
        {
            nowp.clear();
            memset(vis,0,sizeof(vis));
            nowmax=total[i],nowp.push_back(i);
            vis[i]=1;
        }
        else if(nowmax==total[i])
        {
            nowp.push_back(i);
            vis[i]=1;
        }
    }
    if(nowp.size()==1 && nowp[0]==1)
    {
        cout << 0 << endl;
        return 0;
    }
    long long int ans=0;
    while(total[1]<=nowmax)
    {
        if(nowp.size()+total[1]<=nowmax)
        {
            long long int tmp1=0,tmp2=0,fix=0;
            for(int i=0; i<nowp.size(); i++)
            {
                ll tmpp=nowp[i];
                while(used[V[tmpp][now[tmpp]].f])
                    now[tmpp]++;
                tmp1+=V[tmpp][now[tmpp]].c;
                while(used[use[usenext+i+fix].f])
                    fix++;
                tmp2+=use[usenext+i+fix].c;
            }
            for(int i=0;i<2;i++)
            {
                while(used[use[usenext+fix].f])
                    fix++;
                tmp2+=use[usenext+fix].c;
            }
            if(tmp1<tmp2)
            {
                for(int i=0; i<nowp.size(); i++)
                {
                    ll tmpp=nowp[i];
                    used[V[tmpp][now[tmpp]].f]=1;
                    now[tmpp]++;
                    total[tmpp]--;
                }
                total[1]+=nowp.size();
                nowmax--;
                for(int i=1; i<=m; i++)
                {
                    if(!vis[i] && total[i]==nowmax)
                    {
                        vis[i]=1;
                        nowp.push_back(i);
                    }
                }
                ans+=tmp1;
            }
            else
            {
//                int totalnow=0,fix=0,l=nowp.size();
//                while(totalnow<2)
//                {
//                    while(used[use[usenext+fix].f])
//                        fix++;
//                    total[use[usenext+fix].p]--;
//                    if(vis[use[usenext+fix].p])
//                    {
//                        vis[use[usenext+fix].p]=0;
//                        for(int i=0; i<nowp.size(); i++)
//                        {
//                            if(nowp[i]==use[usenext+fix].p)
//                            {
//                                nowp.erase(nowp.begin()+i);
//                                break;
//                            }
//                        }
//                    }
//                    used[use[usenext+fix].f]=1;
//                    fix++;
//                    totalnow++;
//                }
//                usenext+=fix;
//                ans+=tmp2;
//                total[1]+=2;
                int fix=0;
                while(used[use[usenext+fix].f])
                    fix++;
                total[1]++;
                total[use[usenext+fix].p]--;
                ans+=use[usenext+fix].c;
                used[use[usenext+fix].f]=1;
                if(vis[use[usenext+fix].p])
                {
                    vis[use[usenext+fix].p]=0;
                    for(int i=0; i<nowp.size(); i++)
                    {
                        if(nowp[i]==use[usenext+fix].p)
                        {
                            nowp.erase(nowp.begin()+i);
                            break;
                        }
                    }
                }
            }
        }
        else
        {
            ll fix=0;
            while(used[use[usenext+fix].f])
                fix++;
            total[1]++;
            total[use[usenext+fix].p]--;
            ans+=use[usenext+fix].c;
            used[use[usenext+fix].f]=1;
            if(vis[use[usenext+fix].p])
            {
                vis[use[usenext+fix].p]=0;
                for(int i=0; i<nowp.size(); i++)
                {
                    if(nowp[i]==use[usenext+fix].p)
                    {
                        nowp.erase(nowp.begin()+i);
                        break;
                    }
                }
            }
        }
    }
    cout << ans << endl;
    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <queue>

using namespace std;
typedef pair<int,int> iPair;
typedef long long ll;
typedef pair<long long, long long> pll;
#define mp make_pair

vector<int> parties[3005];

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

    for (int i = 0; i < n; i ++) {
        int a, b;
        scanf("%i %i", &a, &b);
        a --;
        parties[a].push_back(b);
    }

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

    long long ans = 3e18;
    for (int i = 0; i <= n; i ++) {
        long long cost = 0;
        int votes = parties[0].size();
        priority_queue<int, vector<int>, greater<int> > remain;
        for (int j = 1; j < m; j ++) {
            if (parties[j].size() > i) {
                for (int k = 0; k < parties[j].size() - i; k ++) {
                    cost += parties[j][k];
                    votes ++;
                }
            }
            for (int k = max(0, int(parties[j].size() - i)); k < parties[j].size(); k ++) {
                remain.push(parties[j][k]);
            }
        }

        bool valid = true;
        while (votes <= i) {
            if (remain.empty()) {
                valid = false;
                break;
            }
            cost += remain.top();
            remain.pop();
            votes ++;
        }
        if (valid) ans = min(ans, cost);
    }
    printf("%lli", ans);
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <queue>

using namespace std;
typedef pair<int,int> iPair;
typedef long long ll;
typedef pair<long long, long long> pll;
#define mp make_pair

vector<int> parties[3005];

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

    for (int i = 0; i < n; i ++) {
        int a, b;
        scanf("%i %i", &a, &b);
        a --;
        parties[a].push_back(b);
    }

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

    long long ans = 3e9;
    for (int i = 0; i <= n; i ++) {
        long long cost = 0;
        int votes = parties[0].size();
        priority_queue<int, vector<int>, greater<int> > remain;
        for (int j = 1; j < m; j ++) {
            if (parties[j].size() > i) {
                for (int k = 0; k < parties[j].size() - i; k ++) {
                    cost += parties[j][k];
                    votes ++;
                }
            }
            for (int k = max(0, int(parties[j].size() - i)); k < parties[j].size(); k ++) {
                remain.push(parties[j][k]);
            }
        }

        bool valid = true;
        while (votes <= i) {
            if (remain.empty()) {
                valid = false;
                break;
            }
            cost += remain.top();
            remain.pop();
            votes ++;
        }
        if (valid) ans = min(ans, cost);
    }
    printf("%lli", ans);
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <queue>

using namespace std;
typedef pair<int,int> iPair;
typedef long long ll;
typedef pair<long long, long long> pll;
#define mp make_pair

vector<int> parties[3005];

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

    for (int i = 0; i < n; i ++) {
        int a, b;
        scanf("%i %i", &a, &b);
        a --;
        parties[a].push_back(b);
    }

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

    long long ans = 3e9;
    for (int i = 0; i <= n; i ++) {
        long long cost = 0;
        int votes = parties[0].size();
        priority_queue<int, vector<int>, greater<int> > remain;
        for (int j = 1; j < m; j ++) {
            if (parties[j].size() > i) {
                for (int k = 0; k < parties[j].size() - i; k ++) {
                    cost += parties[j][k];
                    votes ++;
                }
            }
            for (int k = parties[j].size() - i; k < parties[j].size(); k ++) {
                remain.push(parties[j][k]);
            }
        }

        bool valid = true;
        while (votes <= i) {
            if (remain.empty()) {
                valid = false;
                break;
            }
            cost += remain.top();
            remain.pop();
            votes ++;
        }
        if (valid) ans = min(ans, cost);
    }
    printf("%lli", ans);
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <queue>

using namespace std;
typedef pair<int,int> iPair;
typedef long long ll;
typedef pair<long long, long long> pll;
#define mp make_pair

vector<int> parties[3005];

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

    for (int i = 0; i < n; i ++) {
        int a, b;
        scanf("%i %i", &a, &b);
        a --;
        parties[a].push_back(b);
    }

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

    long long ans = 3e9;
    for (int i = 0; i <= n/m; i ++) {
        long long cost = 0;
        int votes = parties[0].size();
        priority_queue<int, vector<int>, greater<int> > remain;
        for (int j = 1; j < m; j ++) {
            if (parties[j].size() > i) {
                for (int k = 0; k < parties[j].size() - i; k ++) {
                    cost += parties[j][k];
                    votes ++;
                }
            }
            for (int k = parties[j].size() - i; k < parties[j].size(); k ++) {
                remain.push(parties[j][k]);
            }
        }

        while (votes <= i) {
            cost += remain.top();
            remain.pop();
            votes ++;
        }

        ans = min(ans, cost);
    }
    printf("%lli", ans);
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <queue>

using namespace std;
typedef pair<int,int> iPair;
typedef long long ll;
typedef pair<long long, long long> pll;
#define mp make_pair

vector<int> parties[3005];

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

    for (int i = 0; i < n; i ++) {
        int a, b;
        scanf("%i %i", &a, &b);
        a --;
        parties[a].push_back(b);
    }

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

    long long ans = 3e9;
    for (int i = 0; i <= n/m + 1; i ++) {
        long long cost = 0;
        int votes = parties[0].size();
        priority_queue<int, vector<int>, greater<int> > remain;
        for (int j = 1; j < m; j ++) {
            if (parties[j].size() > i) {
                for (int k = 0; k < parties[j].size() - i; k ++) {
                    cost += parties[j][k];
                    votes ++;
                }
            }
            for (int k = parties[j].size() - i; k < parties[j].size(); k ++) {
                remain.push(parties[j][k]);
            }
        }

        while (votes <= i) {
            cost += remain.top();
            remain.pop();
            votes ++;
        }

        ans = min(ans, cost);
    }
    printf("%lli", ans);
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <queue>

using namespace std;
typedef pair<int,int> iPair;
typedef long long ll;
typedef pair<long long, long long> pll;
#define mp make_pair

vector<int> parties[3005];

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

    for (int i = 0; i < n; i ++) {
        int a, b;
        scanf("%i %i", &a, &b);
        a --;
        parties[a].push_back(b);
    }

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

    long long ans = 3e9;
    for (int i = 0; i <= n; i ++) {
        long long cost = 0;
        int votes = parties[0].size();
        priority_queue<int, vector<int>, greater<int> > remain;
        for (int j = 1; j < m; j ++) {
            if (parties[j].size() > i) {
                for (int k = 0; k < parties[j].size() - i; k ++) {
                    cost += parties[j][k];
                    votes ++;
                }
            }
            for (int k = max(0, int(parties[j].size() - i)); k < parties[j].size(); k ++) {
                remain.push(parties[j][k]);
            }
        }

        bool valid = true;
        while (votes <= i) {
            if (remain.empty()) {
                valid = false;
                break;
            }
            cost += remain.top();
            remain.pop();
            votes ++;
        }
        if (valid) ans = min(ans, cost); else cout << i << endl;;
    }
    printf("%lli", ans);
}


#include <iostream>
#include <map>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;

typedef long long ll;

map<int, set<int> > v;
multiset<int> tot;
int n, M, have;

ll go(int m) {
	int us = have; ll cost = 0;
	multiset<int> mul;
	for (auto it = v.begin(); it != v.end(); it++) {
		if (it->second.size() >= m) {
			int i = 0, nec = it->second.size() - m + 1;
			for (auto it2 = it->second.begin(); i < nec; ++it2, ++i)
				cost += *it2, mul.insert(*it2);
			us += nec;
			if (us > m) return -1;
		}
	}
	auto it = tot.begin();
	while (us < m) {
		for (; it != tot.end(); ++it) {
			auto it2 = mul.find(*it);
			if (it2 != mul.end()) mul.erase(it2);
			else { cost += *it; it++; us++; break; }
		}
	}
	return cost;
}

int main() {
	int N;
	cin >> N >> M;
	have = 0; int n = N;
	while (n--) {
		int p, c;
		cin >> p >> c;
		if (p == 1) have++;
		else v[p].insert(c), tot.insert(c);
	}
	int maxi = 0;
	for (auto it = v.begin(); it != v.end(); it++) {
		if (it->second.size() >= maxi) maxi = it->second.size();
	}
	int l = have, r = N, m;
	while (l < r - 1) {
		m = l + (l + r) >> 1;
		if (go(m) >= 0) r = m;
		else l = m + 1;
	}
	ll mini = go(l);
	if (mini < 0) mini = go(++l);
	for (int i = l+1; i <= maxi + 1; ++i)
		mini = min(mini, go(i));
	cout << mini << endl;
	return 0;
}


#include <iostream>
#include <map>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;

typedef long long ll;

map< ll, multiset< ll> > v;
multiset< ll> tot;
 ll n, M, have;

ll go( ll m) {
	 ll us = have; ll cost = 0;
	multiset< ll> mul;
	for (auto it = v.begin(); it != v.end(); it++) {
		if (it->second.size() >= m) {
			 ll i = 0, nec = it->second.size() - m + 1;
			for (auto it2 = it->second.begin(); i < nec; ++it2, ++i) {
				if (it2 == it->second.end()) return -1;
				cost += *it2, mul.insert(*it2);
			}
			us += nec;
			if (us > m) return -1;
		}
	}
	auto it = tot.begin();
	while (us < m) {
		for (; it != tot.end(); ++it) {
			auto it2 = mul.find(*it);
			if (it2 != mul.end()) mul.erase(it2);
			else { cost += *it; it++; us++; break; }
		}
	}
	return cost;
}

int main() {
	 ll N;
	cin >> N >> M;
	have = 0;  ll n = N;
	while (n--) {
		 ll p, c;
		cin >> p >> c;
		if (p == 1) have++;
		else v[p].insert(c), tot.insert(c);
	}
	 ll maxi = 0;
	for (auto it = v.begin(); it != v.end(); it++) {
		if (it->second.size() >= maxi) maxi = it->second.size();
	}
	/*
	 ll l = have, r = N, m;
	while (l < r - 1) {
		m = l + (l + r) >> 1;
		if (go(m) >= 0) r = m;
		else l = m + 1;
	}
	ll mini = go(l);
	if (mini < 0) mini = go(++l);
	for ( ll i = l+1; i <= min(N, maxi + 1); ++i)
		mini = min(mini, go(i));
	*/
	ll mini = 0; bool fo = false;
	for ( ll i = have; i <= min(maxi + 1, N); ++i) {
		ll a = go(i);
		if (a >= 0 && (!fo || a < mini) ) mini = a, fo = true;
	}
	cout << mini << endl;
	return 0;
}


#include <iostream>
#include <map>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;

typedef long long ll;

map< ll, set< ll> > v;
multiset< ll> tot;
 ll n, M, have;

ll go( ll m) {
	 ll us = have; ll cost = 0;
	multiset< ll> mul;
	for (auto it = v.begin(); it != v.end(); it++) {
		if (it->second.size() >= m) {
			 ll i = 0, nec = it->second.size() - m + 1;
			for (auto it2 = it->second.begin(); i < nec; ++it2, ++i) {
				if (it2 == it->second.end()) return -1;
				cost += *it2, mul.insert(*it2);
			}
			us += nec;
			if (us > m) return -1;
		}
	}
	auto it = tot.begin();
	while (us < m) {
		for (; it != tot.end(); ++it) {
			auto it2 = mul.find(*it);
			if (it2 != mul.end()) mul.erase(it2);
			else { cost += *it; it++; us++; break; }
		}
	}
	return cost;
}

int main() {
	 ll N;
	cin >> N >> M;
	have = 0;  ll n = N;
	while (n--) {
		 ll p, c;
		cin >> p >> c;
		if (p == 1) have++;
		else v[p].insert(c), tot.insert(c);
	}
	 ll maxi = 0;
	for (auto it = v.begin(); it != v.end(); it++) {
		if (it->second.size() >= maxi) maxi = it->second.size();
	}
	/*
	 ll l = have, r = N, m;
	while (l < r - 1) {
		m = l + (l + r) >> 1;
		if (go(m) >= 0) r = m;
		else l = m + 1;
	}
	ll mini = go(l);
	if (mini < 0) mini = go(++l);
	for ( ll i = l+1; i <= min(N, maxi + 1); ++i)
		mini = min(mini, go(i));
	*/
	ll mini = 0; bool fo = false;
	for ( ll i = have; i <= min(maxi + 1, N); ++i) {
		ll a = go(i);
		if (a >= 0 && (!fo || a < mini) ) mini = a, fo = true;
	}
	cout << mini << endl;
	return 0;
}


#include <iostream>
#include <map>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;

typedef long long ll;

map<int, set<int> > v;
multiset<int> tot;
int n, M, have;

ll go(int m) {
	int us = have; ll cost = 0;
	multiset<int> mul;
	for (auto it = v.begin(); it != v.end(); it++) {
		if (it->second.size() >= m) {
			int i = 0, nec = it->second.size() - m + 1;
			for (auto it2 = it->second.begin(); i < nec; ++it2, ++i)
				cost += *it2, mul.insert(*it2);
			us += nec;
			if (us > m) return -1;
		}
	}
	auto it = tot.begin();
	while (us < m) {
		for (; it != tot.end(); ++it) {
			auto it2 = mul.find(*it);
			if (it2 != mul.end()) mul.erase(it2);
			else { cost += *it; it++; us++; break; }
		}
	}
	return cost;
}

int main() {
	int N;
	cin >> N >> M;
	have = 0; int n = N;
	while (n--) {
		int p, c;
		cin >> p >> c;
		if (p == 1) have++;
		else v[p].insert(c), tot.insert(c);
	}
	int maxi = 0;
	for (auto it = v.begin(); it != v.end(); it++) {
		if (it->second.size() >= maxi) maxi = it->second.size();
	}
	int l = have, r = N, m;
	while (l < r) {
		m = l + (l + r) >> 1;
		if (go(m) >= 0) r = m;
		else l = m + 1;
	}
	ll mini = go(l);
	for (int i = l + 1; i <= maxi + 1; ++i)
		mini = min(mini, go(i));
	cout << mini << endl;
	return 0;
}


#include <iostream>
#include <map>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;

typedef long long ll;

map<int, set<int> > v;
multiset<int> tot;
int n, M, have;

ll go(int m) {
	int us = have; ll cost = 0;
	multiset<int> mul;
	for (auto it = v.begin(); it != v.end(); it++) {
		if (it->second.size() >= m) {
			int i = 0, nec = it->second.size() - m + 1;
			for (auto it2 = it->second.begin(); i < nec; ++it2, ++i) {
				if (it2 == it->second.end()) return -1;
				cost += *it2, mul.insert(*it2);
			}
			us += nec;
			if (us > m) return -1;
		}
	}
	auto it = tot.begin();
	while (us < m) {
		for (; it != tot.end(); ++it) {
			auto it2 = mul.find(*it);
			if (it2 != mul.end()) mul.erase(it2);
			else { cost += *it; it++; us++; break; }
		}
	}
	return cost;
}

int main() {
	int N;
	cin >> N >> M;
	have = 0; int n = N;
	while (n--) {
		int p, c;
		cin >> p >> c;
		if (p == 1) have++;
		else v[p].insert(c), tot.insert(c);
	}
	int maxi = 0;
	for (auto it = v.begin(); it != v.end(); it++) {
		if (it->second.size() >= maxi) maxi = it->second.size();
	}
	/*
	int l = have, r = N, m;
	while (l < r - 1) {
		m = l + (l + r) >> 1;
		if (go(m) >= 0) r = m;
		else l = m + 1;
	}
	ll mini = go(l);
	if (mini < 0) mini = go(++l);
	for (int i = l+1; i <= min(N, maxi + 1); ++i)
		mini = min(mini, go(i));
	*/
	ll mini = 0; bool fo = false;
	for (int i = have; i <= min(maxi + 1, N); ++i) {
		ll a = go(i);
		if (a >= 0 && (!fo || a < mini) ) mini = a, fo = true;
	}
	cout << mini << endl;
	return 0;
}


#include <iostream>
#include <map>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;

typedef long long ll;

map<int, set<int> > v;
multiset<int> tot;
int n, M, have;

ll go(int m) {
	int us = have; ll cost = 0;
	multiset<int> mul;
	for (auto it = v.begin(); it != v.end(); it++) {
		if (it->second.size() >= m) {
			int i = 0, nec = it->second.size() - m + 1;
			for (auto it2 = it->second.begin(); i < nec; ++it2, ++i) {
				if (it2 == it->second.end()) return -1;
				cost += *it2, mul.insert(*it2);
			}
			us += nec;
			if (us > m) return -1;
		}
	}
	auto it = tot.begin();
	while (us < m) {
		for (; it != tot.end(); ++it) {
			auto it2 = mul.find(*it);
			if (it2 != mul.end()) mul.erase(it2);
			else { cost += *it; it++; us++; break; }
		}
	}
	return cost;
}

int main() {
	int N;
	cin >> N >> M;
	have = 0; int n = N;
	while (n--) {
		int p, c;
		cin >> p >> c;
		if (p == 1) have++;
		else v[p].insert(c), tot.insert(c);
	}
	int maxi = 0;
	for (auto it = v.begin(); it != v.end(); it++) {
		if (it->second.size() >= maxi) maxi = it->second.size();
	}
	int l = have, r = N, m;
	while (l < r - 1) {
		m = l + (l + r) >> 1;
		if (go(m) >= 0) r = m;
		else l = m + 1;
	}
	ll mini = go(l);
	if (mini < 0) mini = go(++l);
	for (int i = l+1; i <= min(N, maxi + 1); ++i)
		mini = min(mini, go(i));
	/*
	ll mini = 1000000000000000000LL;
	for (int i = have; i <= min(maxi + 1, N); ++i) {
		ll a = go(i);
		if (a >= 0 && a < mini) mini = a;
	}
	*/
	cout << mini << endl;
	return 0;
}


#include <iostream>
#include <map>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;

typedef long long ll;

map<int, set<int> > v;
multiset<int> tot;
int n, M, have;

ll go(int m) {
	int us = have; ll cost = 0;
	multiset<int> mul;
	for (auto it = v.begin(); it != v.end(); it++) {
		if (it->second.size() >= m) {
			int i = 0, nec = it->second.size() - m + 1;
			for (auto it2 = it->second.begin(); i < nec; ++it2, ++i) {
				if (it2 == it->second.end()) return -1;
				cost += *it2, mul.insert(*it2);
			}
			us += nec;
			if (us > m) return -1;
		}
	}
	auto it = tot.begin();
	while (us < m) {
		for (; it != tot.end(); ++it) {
			auto it2 = mul.find(*it);
			if (it2 != mul.end()) mul.erase(it2);
			else { cost += *it; it++; us++; break; }
		}
	}
	return cost;
}

int main() {
	int N;
	cin >> N >> M;
	have = 0; int n = N;
	while (n--) {
		int p, c;
		cin >> p >> c;
		if (p == 1) have++;
		else v[p].insert(c), tot.insert(c);
	}
	int maxi = 0;
	for (auto it = v.begin(); it != v.end(); it++) {
		if (it->second.size() >= maxi) maxi = it->second.size();
	}
	/*
	int l = have, r = N, m;
	while (l < r - 1) {
		m = l + (l + r) >> 1;
		if (go(m) >= 0) r = m;
		else l = m + 1;
	}
	ll mini = go(l);
	if (mini < 0) mini = go(++l);
	for (int i = l+1; i <= min(N, maxi + 1); ++i)
		mini = min(mini, go(i));
	*/
	ll mini = 1000000000000000000LL;
	for (int i = have; i <= min(maxi + 1, N); ++i) {
		ll a = go(i);
		if (a >= 0 && a < mini) mini = a;
	}
	cout << mini << endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
long long n,m,x,y,mp[3030][3030],taken,tot,res,ans,a[10000000];
int read() {
	int tot=0,fh=1;char c=getchar();
	while (c<'0'||c>'9') {if (c=='-') fh=-1;c=getchar();}
	while (c>='0'&&c<='9') {tot=tot*10+c-'0';c=getchar();}
	return tot*fh;
}
bool cmp(int x,int y) {
	return x>y;
}
int main() {
	n=read();m=read();
	for (int i=1;i<=n;i++) {
		x=read();y=read();
		mp[x][++mp[x][0]]=y;
	}
	for (int i=1;i<=m;i++)
		sort(mp[x]+1,mp[x]+mp[x][0]+1,cmp);
	ans=30000000000000;
	for (int i=0;i<=n;i++) {
		taken=mp[1][0];tot=0;res=0;
		for (int j=2;j<=m;j++) {
			for (int k=1;k<i&&k<=mp[j][0];k++) a[++tot]=mp[j][k];
			for (int k=i;k<=mp[j][0];k++) {res+=mp[j][k];taken++;}
		}
		sort(a+1,a+tot+1);
		for (int j=1;j+taken<=i;j++) res+=a[j];
		ans=min(ans,res);
	}
	cout<<ans<<endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
long long n,m,x,y,mp[3030][3030],taken,tot,res,ans,a[10000000];
int read() {
	int tot=0,fh=1;char c=getchar();
	while (c<'0'||c>'9') {if (c=='-') fh=-1;c=getchar();}
	while (c>='0'&&c<='9') {tot=tot*10+c-'0';c=getchar();}
	return tot*fh;
}
bool cmp(int x,int y) {
	return x>y;
}
int main() {
	n=read();m=read();
	for (int i=1;i<=n;i++) {
		x=read();y=read();
		mp[x][++mp[x][0]]=y;
	}
	for (int i=1;i<=n;i++)
		sort(mp[x]+1,mp[x]+mp[x][0]+1,cmp);
	ans=30000000000000;
	for (int i=0;i<=n;i++) {
		taken=mp[1][0];tot=0;res=0;
		for (int j=2;j<=m;j++) {
			for (int k=1;k<i&&k<=mp[j][0];k++) a[++tot]=mp[j][k];
			for (int k=i;k<=mp[j][0];k++) {res+=mp[j][k];taken++;}
		}
		sort(a+1,a+tot+1);
		for (int j=1;j+taken<=i;j++) res+=a[j];
		ans=min(ans,res);
	}
	cout<<ans<<endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
struct compass {
	long long a,c;
} p[4000];
long long n,m,d[4000],taken,num,ans,cost,ha[4000][4000],sta;
long long read() {
	long long tot=0,fh=1;char c=getchar();
	while (c<'0'||c>'9') {if (c=='-') fh=-1;c=getchar();}
	while (c>='0'&&c<='9') {tot=tot*10+c-'0';c=getchar();}
	return tot*fh;
}
bool cmp(long long x,long long y) {
	return x>y;
}
int main() {
	n=read();m=read();
	for (int i=1;i<=n;i++) {
		p[i].a=read();p[i].c=read();
		ha[p[i].a][0]++;
		ha[p[i].a][ha[p[i].a][0]]=p[i].c;
		if (p[i].a!=1) cost+=p[i].c;
	}
	for (int i=1;i<=n;i++) sort(ha[i]+1,ha[i]+ha[i][0]+1,cmp);
	for (int i=1;i<=n;i++)
		for (int j=ha[i][0];j>=1;j--)
			ha[i][j]+=ha[i][j+1];
	cost=0;
	for (int i=1;i<=n;i++)
		for (int j=1;j<=ha[1][0];j++)
			if (ha[i][j]!=0) {
				num++;
				d[num]=ha[i][j];
			}
	ans=1<<30;
	sta=ha[1][0];if (sta==0) sta++;
	for (int i=sta;i<=n;i++) {
		taken=ha[1][0];
		cost=0;
		for (int j=2;j<=n;j++)
			if (ha[j][0]>=i) {
				taken+=ha[j][0]-i+1;
				cost+=ha[j][i];
			}
		if (taken<i) {
			if (num+taken<i) continue;
			for (int j=1;j<=i-taken;j++) cost+=d[j];
			ans=min(ans,cost);
		} else ans=min(ans,cost);
		for (int j=2;j<=n;j++)
			if (ha[j][i]-ha[j][i+1]!=0) {
				num++;
				d[num]=ha[j][i]-ha[j][i+1];
			}
	}
	cout<<ans<<endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
struct compass {
	long long a,c;
} p[4000];
long long n,m,d[4000],taken,num,ans,cost,ha[4000][4000];
int read() {
	int tot=0,fh=1;char c=getchar();
	while (c<'0'||c>'9') {if (c=='-') fh=-1;c=getchar();}
	while (c>='0'&&c<='9') {tot=tot*10+c-'0';c=getchar();}
	return tot*fh;
}
bool cmp(int x,int y) {
	return x>y;
}
int main() {
	n=read();m=read();
	for (int i=1;i<=n;i++) {
		p[i].a=read();p[i].c=read();
		ha[p[i].a][0]++;
		ha[p[i].a][ha[p[i].a][0]]=p[i].c;
		if (p[i].a!=1) cost+=p[i].c;
	}
	for (int i=1;i<=n;i++) sort(ha[i]+1,ha[i]+ha[i][0]+1,cmp);
//	for (int i=1;i<=n;i++)
//		for (int j=ha[i][0];j>=1;j--)
//			ha[j]+=ha[j+1];
	taken=n;ans=cost;
	for (int lim=1;lim<=n;lim++) {
		for (int j=2;j<=m;j++)
			if (ha[j][lim]!=0) {
				cost-=ha[j][lim];
				taken--;
				num++;
				d[num]=ha[j][lim];
			}
		sort(d+1,d+num+1);
		if (taken>lim) ans=min(ans,cost);
		else {
			int tmp=0;
			for (int i=1;i<=lim+1-taken;i++) tmp+=d[i];
			ans=min(ans,cost+tmp);
		}
	}
	cout<<ans<<endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
struct compass {
	int a,c;
} p[4000];
int n,m,d[4000],taken,num,ans,cost,ha[4000][4000];
int read() {
	int tot=0,fh=1;char c=getchar();
	while (c<'0'||c>'9') {if (c=='-') fh=-1;c=getchar();}
	while (c>='0'&&c<='9') {tot=tot*10+c-'0';c=getchar();}
	return tot*fh;
}
bool cmp(int x,int y) {
	return x>y;
}
int main() {
	n=read();m=read();
	for (int i=1;i<=n;i++) {
		p[i].a=read();p[i].c=read();
		ha[p[i].a][0]++;
		ha[p[i].a][ha[p[i].a][0]]=p[i].c;
		if (p[i].a!=1) cost+=p[i].c;
	}
	for (int i=1;i<=n;i++) sort(ha[i]+1,ha[i]+ha[i][0]+1,cmp);
//	for (int i=1;i<=n;i++)
//		for (int j=ha[i][0];j>=1;j--)
//			ha[j]+=ha[j+1];
	taken=n;ans=cost;
	for (int lim=1;lim<=n/2;lim++) {
		for (int j=2;j<=m;j++)
			if (ha[j][lim]!=0) {
				cost-=ha[j][lim];
				taken--;
				num++;
				d[num]=ha[j][lim];
			}
		sort(d+1,d+num+1);
		if (taken>lim) ans=min(ans,cost);
		else {
			int tmp=0;
			for (int i=1;i<=lim+1-taken;i++) tmp+=d[i];
			ans=min(ans,cost+tmp);
		}
	}
	cout<<ans<<endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
struct compass {
	long long a,c;
} p[4000];
long long n,m,d[4000],taken,num,ans,cost,ha[4000][4000],sta;
long long read() {
	long long tot=0,fh=1;char c=getchar();
	while (c<'0'||c>'9') {if (c=='-') fh=-1;c=getchar();}
	while (c>='0'&&c<='9') {tot=tot*10+c-'0';c=getchar();}
	return tot*fh;
}
bool cmp(long long x,long long y) {
	return x>y;
}
int main() {
	n=read();m=read();
	for (int i=1;i<=n;i++) {
		p[i].a=read();p[i].c=read();
		ha[p[i].a][0]++;
		ha[p[i].a][ha[p[i].a][0]]=p[i].c;
		if (p[i].a!=1) cost+=p[i].c;
	}
	for (int i=1;i<=n;i++) sort(ha[i]+1,ha[i]+ha[i][0]+1,cmp);
	for (int i=1;i<=n;i++)
		for (int j=ha[i][0];j>=1;j--)
			ha[i][j]+=ha[i][j+1];
	cost=0;
	for (int i=1;i<=n;i++)
		for (int j=1;j<=ha[1][0];j++)
			if (ha[i][j]!=0) {
				num++;
				d[num]=ha[i][j];
			}
	ans=1<<30;
	sta=ha[1][0];if (sta==0) sta++;
	for (int i=sta;i<=n;i++) {
		taken=cost=0;
		for (int j=2;j<=n;j++)
			if (ha[j][0]>=i) {
				taken+=ha[j][0]-i+1;
				cost+=ha[j][i];
			}
		if (taken<i) {
			if (num+taken<i) continue;
			for (int j=1;j<=i-taken;j++) cost+=d[j];
			ans=min(ans,cost);
		} else ans=min(ans,cost);
		for (int j=2;j<=n;j++)
			if (ha[j][i]-ha[j][i+1]!=0) {
				num++;
				d[num]=ha[j][i]-ha[j][i+1];
			}
	}
	cout<<ans<<endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
long long n,m,x,y,mp[3030][3030],taken,tot,res,ans,a[10000000];
int read() {
	int tot=0,fh=1;char c=getchar();
	while (c<'0'||c>'9') {if (c=='-') fh=-1;c=getchar();}
	while (c>='0'&&c<='9') {tot=tot*10+c-'0';c=getchar();}
	return tot*fh;
}
bool cmp(int x,int y) {
	return x>y;
}
int main() {
	n=read();m=read();
	for (int i=1;i<=n;i++) {
		x=read();y=read();
		mp[x][++mp[x][0]]=y;
	}
	for (int i=1;i<=m;i++)
		sort(mp[i]+1,mp[i]+mp[i][0]+1,cmp);
	ans=30000000000000;
	for (int i=0;i<=n;i++) {
		taken=mp[1][0];tot=0;res=0;
		for (int j=2;j<=m;j++) {
			for (int k=1;k<i&&k<=mp[j][0];k++) a[++tot]=mp[j][k];
			for (int k=i;k<=mp[j][0];k++) {res+=mp[j][k];taken++;}
		}
		sort(a+1,a+tot+1);
		for (int j=1;j+taken<=i;j++) res+=a[j];
		ans=min(ans,res);
	}
	cout<<ans<<endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
struct compass {
	int a,c;
} p[4000];
int n,m,d[4000],taken,num,ans,cost,ha[4000][4000];
int read() {
	int tot=0,fh=1;char c=getchar();
	while (c<'0'||c>'9') {if (c=='-') fh=-1;c=getchar();}
	while (c>='0'&&c<='9') {tot=tot*10+c-'0';c=getchar();}
	return tot*fh;
}
bool cmp(int x,int y) {
	return x>y;
}
int main() {
	n=read();m=read();
	for (int i=1;i<=n;i++) {
		p[i].a=read();p[i].c=read();
		ha[p[i].a][0]++;
		ha[p[i].a][ha[p[i].a][0]]=p[i].c;
		if (p[i].a!=1) cost+=p[i].c;
	}
	for (int i=1;i<=n;i++) sort(ha[i]+1,ha[i]+ha[i][0]+1,cmp);
//	for (int i=1;i<=n;i++)
//		for (int j=ha[i][0];j>=1;j--)
//			ha[j]+=ha[j+1];
	taken=n;ans=cost;
	for (int lim=1;lim<=n;lim++) {
		for (int j=2;j<=m;j++)
			if (ha[j][lim]!=0) {
				cost-=ha[j][lim];
				taken--;
				num++;
				d[num]=ha[j][lim];
			}
		sort(d+1,d+num+1);
		if (taken>lim) ans=min(ans,cost);
		else {
			int tmp=0;
			for (int i=1;i<=lim+1-taken;i++) tmp+=d[i];
			ans=min(ans,cost+tmp);
		}
	}
	cout<<ans<<endl;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
long long n,m,x,y,mp[3030][3030],taken,tot,res,ans,a[10000000];
int read() {
	int tot=0,fh=1;char c=getchar();
	while (c<'0'||c>'9') {if (c=='-') fh=-1;c=getchar();}
	while (c>='0'&&c<='9') {tot=tot*10+c-'0';c=getchar();}
	return tot*fh;
}
int main() {
	n=read();m=read();
	for (int i=1;i<=n;i++) {
		x=read();y=read();
		mp[x][++mp[x][0]]=y;
	}
	for (int i=1;i<=n;i++)
		sort(mp[x]+1,mp[x]+mp[x][0]+1);
	ans=3000000000000;
	for (int i=1;i<=n/2+1;i++) {
		taken=mp[1][0];tot=0;res=0;
		for (int j=2;j<=m;j++) {
			for (int k=1;k+i-1<=mp[j][0];k++) {res+=mp[j][k];taken++;}
			for (int k=max(1ll,mp[j][0]-i+1);k<=mp[j][0];k++) a[++tot]=mp[j][k];
		}
		sort(a+1,a+tot+1);
		for (int j=1;j+taken<=i;j++) res+=a[j];
		ans=min(ans,res);
	}
	cout<<ans<<endl;
	return 0;
}


#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

struct Vote
{
    int p,c;
}v[3005];

bool cmp(const Vote &a,const Vote &b)
{
    return a.c>b.c;
}

int main()
{
    int n,m,vote[3005]={0};
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++)
        scanf("%d%d",&v[i].p,&v[i].c);
    int mx=0;
    long long ans=1e16;
    bool vis[3005];
    sort(v,v+n,cmp);
    for(int i=1;i<=n;i++)//遍历党1在获得i票的条件下胜出所用的钱
    {
        memset(vis,0,sizeof(vis));
        memset(vote,0,sizeof(vote));
        long long sum=0;
        for(int j=0;j<n;j++)//遍历每个投票者
        {
            if(v[j].p==1) vote[1]++;
            else
            {
                if(vote[v[j].p]+1==i) sum+=v[j].c,vote[1]++,vis[j]=true;
                else vote[v[j].p]++;
            }
        }
        for(int j=n-1;j>=0;j--)
            if(v[j].p!=1&&!vis[j]&&vote[1]<i) sum+=v[j].c,vote[1]++;
        ans=min(ans,sum);
    }
    printf("%I64d\n",ans);
    return 0;
}


#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

struct Vote
{
    int p,c;
}v[3005];

bool cmp(const Vote &a,const Vote &b)
{
    return a.c>b.c;
}

int main()
{
    int n,m,vote[3005]={0};
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++)
        scanf("%d%d",&v[i].p,&v[i].c);
    int mx=0;
    long long ans=1e16;
    bool vis[3005];
    sort(v,v+n,cmp);
    for(int i=1;i<=n;i++)//遍历党1在获得i票的条件下胜出所用的钱
    {
        memset(vis,0,sizeof(vis));
        memset(vote,0,sizeof(vote));
        long long sum=0;
        for(int j=0;j<n;j++)//遍历每个投票者
        {
            if(v[j].p==1) vote[1]++;
            else
            {
                if(vote[v[j].p]+1>=i) sum+=v[j].c,vote[1]++,vis[j]=true;
                else vote[v[j].p]++;
            }
        }
        for(int j=n-1;j>=0;j--)
            if(v[j].p!=1&&!vis[j]&&vote[1]<i) sum+=v[j].c,vote[1]++;
        ans=min(ans,sum);
    }
    printf("%I64d\n",ans);
    return 0;
}


#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

struct Vote
{
    int p,c;
}v[3005];

bool cmp(const Vote &a,const Vote &b)
{
    return a.c>b.c;
}

int main()
{
    int n,m,vote[3005]={0};
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++)
        scanf("%d%d",&v[i].p,&v[i].c);
    int mx=0;
    long long ans=1e16;
    bool vis[3005];
    sort(v,v+n,cmp);
    for(int i=1;i<=n;i++)//遍历党1在获得i票的条件下胜出所用的钱
    {
        memset(vis,0,sizeof(vis));
        memset(vote,0,sizeof(vote));
        long long sum=0;
        for(int j=0;j<n;j++)//遍历每个投票者
        {
            if(v[j].p==1) vote[1]++;
            else
            {
                if(vote[v[j].p]+1>i) sum+=v[j].c,vote[1]++,vis[j]=true;
                else vote[v[j].p]++;
            }
        }
        for(int j=n-1;j>=0;j--)
            if(v[j].p!=1&&!vis[j]&&vote[1]<i) vis[j]=true,sum+=v[j].c,vote[1]++;
        ans=min(ans,sum);
    }
    printf("%I64d\n",ans);
    return 0;
}


#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

struct Vote
{
    int p;
    int c;
}voter[3009];

bool cmp(Vote a,Vote b)
{
    return a.c>b.c;
}
int vote[3009];
int vis[3009];
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=0;i<n;i++)
        cin>>voter[i].p>>voter[i].c;
    long long ans=1e16;
    sort(voter,voter+n,cmp);
    for(int i=1;i<=n;i++)
    {
        memset(vote,0,sizeof(vote));
        memset(vis,0,sizeof(vis));
        long long sum=0ll;
        for(int j=0;j<n;j++)
        {
            if(voter[j].p==1) vote[1]++;
            else if(vote[voter[j].p]+1==i){
                vis[j]=1;
                vote[1]++;
                sum+=voter[j].c;
            }
            //else vote[j]++;
            else vote[voter[j].p]++;
        }
        for(int j=n-1;j>=0;j--) {
            if(vote[1]<i&&!vis[j]&&vote[j]>=1){\
                sum+=voter[j].c;
                vote[1]++;
                vote[j]--;
            }
        }
        ans=min(ans,sum);
    }
    cout<<ans<<endl;
    return 0;
}


#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

struct Vote
{
    int p;
    int c;
}voter[3009];

bool cmp(Vote a,Vote b)
{
    return a.c>b.c;
}
int vote[3009];
int vis[3009];
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=0;i<n;i++)
        cin>>voter[i].p>>voter[i].c;
    long long ans=1e16;
    sort(voter,voter+n,cmp);
    for(int i=1;i<=n;i++)
    {
        memset(vote,0,sizeof(vote));
        memset(vis,0,sizeof(vis));
        long long sum=0ll;
        for(int j=0;j<n;j++)
        {
            if(voter[j].p==1) vote[1]++;
            else if(vote[voter[j].p]+1==i){
                vis[j]=1;//收买过的人打标记
                vote[1]++;
                sum+=voter[j].c;
            }
            //else vote[j]++;
            else vote[voter[j].p]++;
        }
        for(int j=n-1;j>=0;j--) {
            if(vote[1]<i&&!vis[j]&&voter[j].p!=1){
                sum+=voter[j].c;
                vote[1]++;
                vote[j]--;
            }
        }
        ans=min(ans,sum);
    }
    cout<<ans<<endl;
    return 0;
}


#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

struct Vote
{
    int p,c;
}v[3005];

bool cmp(const Vote &a,const Vote &b)
{
    return a.c>b.c;
}

int main()
{
    int n,m,vote[3005]={0};
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++)
        scanf("%d%d",&v[i].p,&v[i].c);
    int mx=0;
    long long ans=1e16;
    bool vis[3005];
    sort(v,v+n,cmp);
    for(int i=1;i<=n;i++)//遍历党1在获得i票的条件下胜出所用的钱
    {
        memset(vis,0,sizeof(vis));
        memset(vote,0,sizeof(vote));
        long long sum=0;
        for(int j=0;j<n;j++)//遍历每个投票者
        {
            if(v[j].p==1) vote[1]++;
            else
            {
                if(vote[v[j].p]+1>i) sum+=v[j].c,vote[1]++,vis[j]=true;
                else vote[v[j].p]++;
            }
        }
        for(int j=n-1;j>=0;j--)
            if(v[j].p!=1&&!vis[j]&&vote[1]<i) vis[j]=true,sum+=v[j].c,vote[1]++;
        ans=min(ans,sum);
    }
    printf("%I64d\n",ans);
    return 0;


#include <bits/stdc++.h>

using namespace std;

#define ff first
#define ss second
#define pb push_back
using ll = long long;
using ii = pair<int,int>;

const double eps = 1e-9;
const int mod = 1000000007;
const int N = 3003;

int qtd[N];
int qtd2[N];
int pos[N];
ii v[N];
vector<int> vot[N];
int n, m;
int ja[N];

bool f(ll x){
	memcpy(qtd2, qtd, sizeof qtd);
	memset(pos, 0, sizeof pos);
	memset(ja, 0, sizeof ja);
	int id = 0;
	set<ii> p;
	while(x && id < n){
		if(v[id].ss == 0){
			id++;
			continue;
		}
		if(v[id].ff > x) break;
		qtd2[0]++;
		qtd2[v[id].ss]--;
		x -= v[id].ff;
		pos[v[id].ss]++;
		p.insert(v[id]);
		id++;
	}
	set<ii> s;
	for(int i = 0; i < m; i++){
		s.insert({qtd2[i], i});
	}

	while(1){
		ii it = *prev(s.end());
		// printf("--------- q? %d %d %d\n", x, it.ff, it.ss);
		s.erase(it);
		if(it.ff != qtd2[it.ss]){
			continue;
		}
		if(it.ss == 0) return 1;
		if(pos[it.ss] == vot[it.ss].size()) return 0;
		x -= vot[it.ss][pos[it.ss]];
		pos[it.ss]++;
		qtd2[it.ss]--;
		s.insert({qtd2[it.ss], it.ss});
		ja[it.ss] = 1;
		while(p.size()){
			ii y = *prev(p.end());
			p.erase(y);
			if(ja[y.ss]){
				continue;
			}
			x += y.ff;
			qtd2[y.ss]++;
			s.insert({qtd2[y.ss], y.ss});
			break;
		}
		if(x < 0) return 0;
	}
	return 0;
}

int main(){
	ll sum = 0;
	scanf("%d %d", &n, &m);
	for(int i = 0; i < n; i++){
		int p, c;
		scanf("%d %d", &v[i].ss, &v[i].ff);
		v[i].ss--;
		qtd[v[i].ss]++;
		sum += v[i].ff;
		vot[v[i].ss].pb(v[i].ff);
	}
	sort(v, v + n);
	for(int i = 0; i < m; i++){
		sort(vot[i].begin(), vot[i].end());
	}

	ll l = 0, r = sum;
	ll ans = sum;
	while(l <= r){
		// printf("--------- l %lld r %lld\n",l, r );
		ll mid = (l + r) / 2;
		if(f(mid)){
			ans = mid;
			r = mid - 1;
		}
		else{
			l = mid + 1;
		}
	}
	printf("%lld\n",ans );
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define ff first
#define ss second
#define pb push_back
using ll = long long;
using ii = pair<int,int>;

const double eps = 1e-9;
const int mod = 1000000007;
const int N = 3003;

int n, m;
vector<int> vot[N];
vector<int> psum[N];
int qtd[N];
vector<ii> v;
int t[N];
int nt[N];

ll f(int x){
	ll ret = 0;
	int tot = 0;

	memset(t, 0, sizeof t);
	for(int i = 2; i <= m; i++){
		t[i] = max(0, (int)vot[i].size() - x + 1);
		//cout << "ti " << t[i] << endl;
		ret += t[i] ? psum[i][t[i]-1] : 0;
		tot += t[i];
	}
	//cout << "QWE" << endl;
	if(qtd[1] + tot < x){
		memset(nt, 0, sizeof nt);
		int id = 0;
		while(qtd[1] + tot < x){
			//cout << "qtd " << qtd[1] << " " << x << " " << id << endl;
			int p, c;
			tie(c, p) = v[id];
			if(nt[p] >= t[p]){
				tot++;
				ret += c;
			}
			nt[p]++;
			id++;
		}
	}
	//cout << "saiu" << endl;

	return ret;
}

int main(){
	scanf("%d %d", &n, &m);
	for(int i = 0; i < n; i++){
		int p, c;
		scanf("%d %d", &p, &c);
		vot[p].pb(c);
		if(p != 1){
			v.pb({c, p});
		}
		qtd[p]++;
	}

	sort(v.begin(), v.end());

	for(int i = 1; i <= m; i++){
		sort(vot[i].begin(), vot[i].end());
		psum[i].resize(vot[i].size(), 0);
		partial_sum(vot[i].begin(), vot[i].end(), psum[i].begin());
	}

	ll ans = 1LL * mod * mod;
	for(int i = 1; i <= n; i++){
		ans = min(ans, f(i));
	}

	printf("%lld\n", ans);

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define ff first
#define ss second
#define pb push_back
using ll = long long;
using ii = pair<ll,ll>;

const double eps = 1e-9;
const int mod = 1000000007;
const int N = 3003;

int n, m;
vector<ll> vot[N];
vector<ll> psum[N];
int qtd[N];
vector<ii> v;
int t[N];
int nt[N];

ll f(int x){
	ll ret = 0;
	int tot = 0;

	memset(t, 0, sizeof t);
	for(int i = 2; i <= m; i++){
		t[i] = max(0, (int)vot[i].size() - x + 1);
		//cout << "ti " << t[i] << endl;
		ret += t[i] ? psum[i][t[i]-1] : 0;
		tot += t[i];
	}
	//cout << "QWE" << endl;
	if(qtd[1] + tot < x){
		memset(nt, 0, sizeof nt);
		int id = 0;
		while(qtd[1] + tot < x){
			//cout << "qtd " << qtd[1] << " " << x << " " << id << endl;
			int p, c;
			tie(c, p) = v[id];
			if(nt[p] >= t[p]){
				tot++;
				ret += c;
			}
			nt[p]++;
			id++;
		}
	}
	//cout << "saiu" << endl;

	return ret;
}

int main(){
	scanf("%d %d", &n, &m);
	for(int i = 0; i < n; i++){
		int p, c;
		scanf("%d %d", &p, &c);
		vot[p].pb(c);
		if(p != 1){
			v.pb({c, p});
		}
		qtd[p]++;
	}

	sort(v.begin(), v.end());

	for(int i = 1; i <= m; i++){
		sort(vot[i].begin(), vot[i].end());
		psum[i].resize(vot[i].size(), 0);
		partial_sum(vot[i].begin(), vot[i].end(), psum[i].begin());
	}

	ll ans = 1LL * mod * mod;
	for(int i = 1; i <= n; i++){
		ans = min(ans, f(i));
	}

	printf("%lld\n", ans);

	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define ff first
#define ss second
#define pb push_back
using ll = long long;
using ii = pair<int,int>;

const double eps = 1e-9;
const int mod = 1000000007;
const int N = 3003;

int qtd[N];
int qtd2[N];
int pos[N];
ii v[N];
vector<int> vot[N];
int n, m;
int ja[N];

bool f(ll x){
	memcpy(qtd2, qtd, sizeof qtd);
	memset(pos, 0, sizeof pos);
	memset(ja, 0, sizeof ja);
	int id = 0;
	multiset<ii> p;
	while(x && id < n){
		if(v[id].ss == 0){
			id++;
			continue;
		}
		if(v[id].ff > x) break;
		qtd2[0]++;
		qtd2[v[id].ss]--;
		x -= v[id].ff;
		pos[v[id].ss]++;
		p.insert(v[id]);
		id++;
	}
	set<ii> s;
	for(int i = 0; i < m; i++){
		s.insert({qtd2[i], i});
	}

	while(1){
		ii it = *prev(s.end());
		// printf("--------- q? %d %d %d\n", x, it.ff, it.ss);
		s.erase(it);
		if(it.ff != qtd2[it.ss]){
			continue;
		}
		if(it.ss == 0) return 1;
		if(pos[it.ss] == (int)vot[it.ss].size()) return 0;
		x -= vot[it.ss][pos[it.ss]];
		pos[it.ss]++;
		qtd2[it.ss]--;
		s.insert({qtd2[it.ss], it.ss});
		while(p.size()){
			ii y = *prev(p.end());
			p.erase(prev(p.end()));
			if(qtd2[y.ss] + 1 >= qtd2[0]){
				continue;
			}
			x += y.ff;
			qtd2[y.ss]++;
			break;
		}
		if(x < 0) return 0;
	}
	return 0;
}

int main(){
	ll sum = 0;
	scanf("%d %d", &n, &m);
	for(int i = 0; i < n; i++){
		scanf("%d %d", &v[i].ss, &v[i].ff);
		v[i].ss--;
		qtd[v[i].ss]++;
		sum += v[i].ff;
		vot[v[i].ss].pb(v[i].ff);
	}
	sort(v, v + n);
	for(int i = 0; i < m; i++){
		sort(vot[i].begin(), vot[i].end());
	}

	ll l = 0, r = sum;
	ll ans = sum;
	while(l <= r){
		// printf("--------- l %lld r %lld\n",l, r );
		ll mid = (l + r) / 2;
		if(f(mid)){
			ans = mid;
			r = mid - 1;
		}
		else{
			l = mid + 1;
		}
	}
	printf("%lld\n",ans );
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define ff first
#define ss second
#define pb push_back
using ll = long long;
using ii = pair<int,int>;

const double eps = 1e-9;
const int mod = 1000000007;
const int N = 3003;

int qtd[N];
int qtd2[N];
int pos[N];
ii v[N];
vector<int> vot[N];
int n, m;
int ja[N];

bool f(ll x){
	memcpy(qtd2, qtd, sizeof qtd);
	memset(pos, 0, sizeof pos);
	memset(ja, 0, sizeof ja);
	int id = 0;
	set<ii> p;
	while(x && id < n){
		if(v[id].ss == 0){
			id++;
			continue;
		}
		if(v[id].ff > x) break;
		qtd2[0]++;
		qtd2[v[id].ss]--;
		x -= v[id].ff;
		pos[v[id].ss]++;
		p.insert(v[id]);
		id++;
	}
	set<ii> s;
	for(int i = 0; i < m; i++){
		s.insert({qtd2[i], i});
	}

	while(1){
		ii it = *prev(s.end());
		// printf("--------- q? %d %d %d\n", x, it.ff, it.ss);
		s.erase(it);
		if(it.ff != qtd2[it.ss]){
			continue;
		}
		if(it.ss == 0) return 1;
		if(pos[it.ss] == vot[it.ss].size()) return 0;
		x -= vot[it.ss][pos[it.ss]];
		pos[it.ss]++;
		qtd2[it.ss]--;
		s.insert({qtd2[it.ss], it.ss});
		ja[it.ss] = 1;
		while(p.size()){
			ii y = *prev(p.end());
			p.erase(y);
			if(ja[y.ss]){
				continue;
			}
			if(qtd2[y.ss] + 1 >= qtd2[0]){
				continue;
			}
			x += y.ff;
			qtd2[y.ss]++;
			s.insert({qtd2[y.ss], y.ss});
			break;
		}
		if(x < 0) return 0;
	}
	return 0;
}

int main(){
	ll sum = 0;
	scanf("%d %d", &n, &m);
	for(int i = 0; i < n; i++){
		int p, c;
		scanf("%d %d", &v[i].ss, &v[i].ff);
		v[i].ss--;
		qtd[v[i].ss]++;
		sum += v[i].ff;
		vot[v[i].ss].pb(v[i].ff);
	}
	sort(v, v + n);
	for(int i = 0; i < m; i++){
		sort(vot[i].begin(), vot[i].end());
	}

	ll l = 0, r = sum;
	ll ans = sum;
	while(l <= r){
		// printf("--------- l %lld r %lld\n",l, r );
		ll mid = (l + r) / 2;
		if(f(mid)){
			ans = mid;
			r = mid - 1;
		}
		else{
			l = mid + 1;
		}
	}
	printf("%lld\n",ans );
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define ff first
#define ss second
#define pb push_back
using ll = long long;
using ii = pair<int,int>;

const double eps = 1e-9;
const int mod = 1000000007;
const int N = 3003;

int qtd[N];
int qtd2[N];
int pos[N];
ii v[N];
vector<int> vot[N];
int n, m;
int ja[N];

bool f(ll x){
	memcpy(qtd2, qtd, sizeof qtd);
	memset(pos, 0, sizeof pos);
	memset(ja, 0, sizeof ja);
	int id = 0;
	multiset<ii> p;
	while(x && id < n){
		if(v[id].ss == 0){
			id++;
			continue;
		}
		if(v[id].ff > x) break;
		qtd2[0]++;
		qtd2[v[id].ss]--;
		x -= v[id].ff;
		pos[v[id].ss]++;
		p.insert(v[id]);
		id++;
	}
	set<ii> s;
	for(int i = 0; i < m; i++){
		s.insert({qtd2[i], i});
	}

	while(1){
		ii it = *prev(s.end());
		// printf("--------- q? %d %d %d\n", x, it.ff, it.ss);
		s.erase(it);
		if(it.ff != qtd2[it.ss]){
			continue;
		}
		if(it.ss == 0) return 1;
		if(pos[it.ss] == vot[it.ss].size()) return 0;
		x -= vot[it.ss][pos[it.ss]];
		pos[it.ss]++;
		qtd2[it.ss]--;
		s.insert({qtd2[it.ss], it.ss});
		ja[it.ss] = 1;
		while(p.size()){
			ii y = *prev(p.end());
			p.erase(prev(p.end()));
			if(ja[y.ss]){
				continue;
			}
			if(qtd2[y.ss] + 1 >= qtd2[0]){
				continue;
			}
			x += y.ff;
			qtd2[y.ss]++;
			s.insert({qtd2[y.ss], y.ss});
			break;
		}
		if(x < 0) return 0;
	}
	return 0;
}

int main(){
	ll sum = 0;
	scanf("%d %d", &n, &m);
	for(int i = 0; i < n; i++){
		int p, c;
		scanf("%d %d", &v[i].ss, &v[i].ff);
		v[i].ss--;
		qtd[v[i].ss]++;
		sum += v[i].ff;
		vot[v[i].ss].pb(v[i].ff);
	}
	sort(v, v + n);
	for(int i = 0; i < m; i++){
		sort(vot[i].begin(), vot[i].end());
	}

	ll l = 0, r = sum;
	ll ans = sum;
	while(l <= r){
		// printf("--------- l %lld r %lld\n",l, r );
		ll mid = (l + r) / 2;
		if(f(mid)){
			ans = mid;
			r = mid - 1;
		}
		else{
			l = mid + 1;
		}
	}
	printf("%lld\n",ans );
	return 0;
}


#include <cstdio>
#include <algorithm>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
multiset<int> values;
vector<int> v[3007];
int n, m;
bool DEBUG = false;
int main() {
    scanf("%d%d",&m,&n);
    int p,vx;
    for(int i=1;i<=m;++i) {
        scanf("%d%d", &p, &vx);
        if (p != 1)  values.insert(vx);
        v[p].push_back(vx);
    }
    int max = 0;
    for(int i = 1 ; i <= n; i++) {
        sort(v[i].begin(), v[i].end());
        max = max > v[i].size() ? max:v[i].size();
    }
    int now = v[1].size();
    if (DEBUG) {
        printf("now=%d, and max=%d\n", now, max);
    }
    // 枚举, 除了 第一个其他的都要小 x
    long long ans = (long long)0x7fffffff * (long long)50000;
    vector<int> queue;
    for(int limit = now  >= 1 ? now - 1 : now  ; limit <= max + 1; ++limit) {
        long long need = 0;
        int cnt = 0;
        for(int pos = 2 ; pos <= n; ++pos) {
            int needCnt = v[pos].size() > limit ? v[pos].size() - limit : 0;
            cnt += needCnt;
            for(int i = 0 ; i < needCnt; i++) {
                need += v[pos][i];
                multiset<int>::iterator it = values.lower_bound(v[pos][i]);
                if (*it != v[pos][i]) {
                    printf("What ??? not Equal\n");
                }
                values.erase(it);
                queue.push_back(v[pos][i]);
            }
        }
        if (DEBUG) {
            printf("step one -> need %I64d\n", need);
        }
        // 还东西
        int lastNow = now + cnt;
        if (lastNow > limit) {
            if (DEBUG) {
                printf("limit = %d  need = %I64d\n", limit, need);
            }
            ans = ans > need ? need : ans;
        } else {
            int needCnt = limit - lastNow + 1;
            if(values.size() >= needCnt) {
                int i = 1;
                for(multiset<int>::iterator it = values.begin(); i <=needCnt; i++, it++) {
                    need += *it;
                }
            }
            if (DEBUG) {
                printf("limit = %d  need = %I64d\n", limit, need);
            }
            ans = ans > need ? need : ans;
        }

        while(!queue.empty()) {
            values.insert(queue.back());
            queue.pop_back();
        }
    }
    cout << ans << endl;
    return 0;
}


#include <cstdio>
#include <algorithm>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
multiset<int> values;
vector<int> v[3007];
int n, m;
int main() {
    scanf("%d%d",&m,&n);
    int p,vx;
    for(int i=1;i<=m;++i) {
        scanf("%d%d", &p, &vx);
        values.insert(vx);
        v[p].push_back(vx);
    }
    int max = 0;
    for(int i = 1 ; i <= n; i++) {
        sort(v[i].begin(), v[i].end());
        max = max > v[i].size() ? max:v[i].size();
    }
    int now = v[1].size();
//    printf("now=%d, and max=%d\n", now, max);
    // 枚举, 除了 第一个其他的都要小 x
    long long ans = (long long)0x7fffffff * (long long)50000;
    vector<int> queue;
    for(int limit = now ; limit <= max + 1; ++limit) {
        long long need = 0;
        int cnt = 0;
        for(int pos = 2 ; pos <= n; ++pos) {
            int needCnt = v[pos].size() > limit ? v[pos].size() - limit : 0;
            cnt += needCnt;
            for(int i = 0 ; i < needCnt; i++) {
                need += v[pos][i];
                multiset<int>::iterator it = values.lower_bound(v[pos][i]);
                if (*it != v[pos][i]) {
                    printf("What ??? not Equal\n");
                }
                values.erase(it);
                queue.push_back(v[pos][i]);
            }
        }
        // 还东西
        int lastNow = now + cnt;
        if (lastNow > limit) {
//            printf("limit = %d  need = %d\n", limit, need);
            ans = ans > need ? need : ans;
        } else {
            int needCnt = limit - lastNow + 1;
            if(values.size() >= needCnt) {
                int i = 1;
                for(multiset<int>::iterator it = values.begin(); i <=needCnt; i++, it++) {
                    need += *it;
                }
            }
//            printf("limit = %d  need = %d\n", limit, need);
            ans = ans > need ? need : ans;
        }

        while(!queue.empty()) {
            values.insert(queue.back());
            queue.pop_back();
        }
    }
    cout << ans << endl;
    return 0;
}


#include <cstdio>
#include <algorithm>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
multiset<int> values;
vector<int> v[3007];
int n, m;
int main() {
    scanf("%d%d",&m,&n);
    int p,vx;
    for(int i=1;i<=m;++i) {
        scanf("%d%d", &p, &vx);
        values.insert(vx);
        v[p].push_back(vx);
    }
    int max = 0;
    for(int i = 1 ; i <= n; i++) {
        sort(v[i].begin(), v[i].end());
        max = max > v[i].size() ? max:v[i].size();
    }
    int now = v[1].size();
//    printf("now=%d, and max=%d\n", now, max);
    // 枚举, 除了 第一个其他的都要小 x
    long long ans = 0x7fffffff * 50000L;
    vector<int> queue;
    for(int limit = now ; limit <= max + 1; ++limit) {
        long long need = 0;
        int cnt = 0;
        for(int pos = 2 ; pos <= n; ++pos) {
            int needCnt = v[pos].size() > limit ? v[pos].size() - limit : 0;
            cnt += needCnt;
            for(int i = 0 ; i < needCnt; i++) {
                need += v[pos][i];
                multiset<int>::iterator it = values.lower_bound(v[pos][i]);
                if (*it != v[pos][i]) {
                    printf("What ??? not Equal\n");
                }
                values.erase(it);
                queue.push_back(v[pos][i]);
            }
        }
        // 还东西
        int lastNow = now + cnt;
        if (lastNow > limit) {
//            printf("limit = %d  need = %d\n", limit, need);
            ans = ans > need ? need : ans;
        } else {
            int needCnt = limit - lastNow + 1;
            if(values.size() >= needCnt) {
                int i = 1;
                for(multiset<int>::iterator it = values.begin(); i <=needCnt; i++, it++) {
                    need += *it;
                }
            }
//            printf("limit = %d  need = %d\n", limit, need);
            ans = ans > need ? need : ans;
        }

        while(!queue.empty()) {
            values.insert(queue.back());
            queue.pop_back();
        }
    }
    cout << ans << endl;
    return 0;
}


#include <cstdio>
#include <algorithm>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
multiset<int> values;
vector<int> v[3007];
int n, m;
bool DEBUG = false;

inline int MAX(int x, int y) {
    return x < y ? y : x;
}
inline int MIN(int x, int y) {
    return x < y ? x : y;
}
int main() {
    scanf("%d%d",&m,&n);
    int p,vx;
    for(int i=1;i<=m;++i) {
        scanf("%d%d", &p, &vx);
        if (p != 1)  values.insert(vx);
        v[p].push_back(vx);
    }
    int max = 0;
    for(int i = 1 ; i <= n; i++) {
        sort(v[i].begin(), v[i].end());
        max = max > v[i].size() ? max:v[i].size();
    }
    int now = v[1].size();
    if (DEBUG) {
        printf("now=%d, and max=%d\n", now, max);
    }
    // 枚举, 除了 第一个其他的都要小 x
    long long ans = (long long)0x7fffffff * (long long)50000;
    vector<int> queue;
    for(int limit = MAX(1, now); limit <= MIN( m , max + 1) ; ++limit) {
        long long need = 0;
        int cnt = 0;
        for(int pos = 2 ; pos <= n; ++pos) {
            int needCnt = v[pos].size() >= limit ? v[pos].size() - limit + 1 : 0;
            cnt += needCnt;
            for(int i = 0 ; i < needCnt; i++) {
                need += v[pos][i];
                multiset<int>::iterator it = values.lower_bound(v[pos][i]);
                if (*it != v[pos][i]) {
                    printf("What ??? not Equal\n");
                }
                values.erase(it);
                queue.push_back(v[pos][i]);
            }
        }
        if (DEBUG) {
            cout << "step one -> need:" << need << ", cnt:" <<cnt << endl;
        }
        // 还东西
        int lastNow = now + cnt;
        if (lastNow >= limit) {
            if (DEBUG) {
                cout << "limit=" << limit << "  need =" << need<<endl;
            }
            ans = ans > need ? need : ans;
        } else {
            int needCnt = limit - lastNow;
            if(values.size() >= needCnt) {
                int i = 1;
                for(multiset<int>::iterator it = values.begin(); i <=needCnt; i++, it++) {
                    need += *it;
                }
            }
            if (DEBUG) {
                cout << "limit=" << limit << "  need =" << need<<endl;
            }
            ans = ans > need ? need : ans;
        }

        while(!queue.empty()) {
            values.insert(queue.back());
            queue.pop_back();
        }
    }
    cout << ans << endl;
    return 0;
}


#include <cstdio>
#include <algorithm>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
multiset<int> values;
vector<int> v[3007];
int n, m;
int main() {
    scanf("%d%d",&n,&m);
    int p,vx;
    for(int i=1;i<=m;++i) {
        scanf("%d%d", &p, &vx);
        values.insert(vx);
        v[p].push_back(vx);
    }
    int max = 0;
    for(int i = 1 ; i <= n; i++) {
        sort(v[i].begin(), v[i].end());
        max = max > v[i].size() ? max:v[i].size();
    }
    int now = v[1].size();
//    printf("now=%d, and max=%d\n", now, max);
    // 枚举, 除了 第一个其他的都要小 x
    long long ans = 0x7fffffff * 50000L;
    vector<int> queue;
    for(int limit = now ; limit <= max + 1; ++limit) {
        long long need = 0;
        int cnt = 0;
        for(int pos = 2 ; pos <= n; ++pos) {
            int needCnt = v[pos].size() > limit ? v[pos].size() - limit : 0;
            cnt += needCnt;
            for(int i = 0 ; i < needCnt; i++) {
                need += v[pos][i];
                multiset<int>::iterator it = values.lower_bound(v[pos][i]);
                if (*it != v[pos][i]) {
                    printf("What ??? not Equal\n");
                }
                values.erase(it);
                queue.push_back(v[pos][i]);
            }
        }
        // 还东西
        int lastNow = now + cnt;
        if (lastNow > limit) {
//            printf("limit = %d  need = %d\n", limit, need);
            ans = ans > need ? need : ans;
        } else {
            int needCnt = limit - lastNow + 1;
            if(values.size() >= needCnt) {
                int i = 1;
                for(multiset<int>::iterator it = values.begin(); i <=needCnt; i++, it++) {
                    need += *it;
                }
            }
//            printf("limit = %d  need = %d\n", limit, need);
            ans = ans > need ? need : ans;
        }

        while(!queue.empty()) {
            values.insert(queue.back());
            queue.pop_back();
        }
    }
    cout << ans << endl;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long  ll;
const int MAXM=2e5+9;
const int MAXN=2e5+9;
#define list lst
struct node{
    int x,y;
    bool operator <(const node&b){
        return y<b.y;
    }
}a[MAXM];
int q[MAXM];
int head[MAXN],list[MAXM],tot,nxt[MAXM];
void add(int x,int y){
    list[++tot]=y;
    nxt[tot]=head[x];
    head[x]=tot;
}
void pop_head(int x){
    head[x]=nxt[head[x]];
}
priority_queue<int> p;
int main(){
    int n,mm,m=0;
    ll sum=0;
    scanf("%d%d",&n,&mm);
    for(int i=0;i<mm;i++){
        scanf("%d%d",&a[m].x,&a[m].y);
        if(a[m].x!=1){sum+=a[m].y,m++;}
    }
    sort(a,a+m);
    for(int i=0;i<m;i++)add(a[i].x,a[i].y);
    ll all=0,last,cnt=n,ans=sum;
    for(int i=2;i<=n;i++)if(head[i])q[all++]=i;
   // cout<<sum<<endl;
    for(int i=1;i<=mm;i++){
        if(all==0)break;
        last=0;
        for(int j=0;j<all;j++){
       // cout<<"in"<<endl;

            int tmp=list[head[q[j]]];
            sum-=tmp;cnt--;
            //cout<<"sub"<<tmp<<endl;
            p.push(-tmp);
            pop_head(q[j]);
            if(head[q[j]])q[last++]=q[j];
        }
        all=last;
       // cout<<sum<<endl;
        while(cnt<=i){
            sum+=-p.top();
           // cout<<"addback"<<-p.top()<<endl;;
            p.pop();
            cnt++;
        }
        ans=min(ans,sum);
    }
    printf("%I64d\n",ans);
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=1e5+9;
struct node{
    int x,id;
    bool operator <(const node &b)const {
        return x<b.x;
    }
}a[MAXN];
int q[MAXN],head[MAXN],nxt[MAXN],w[MAXN],tot;
void add(int x,int y){
    w[++tot]=y;
    nxt[tot]=head[x];
    head[x]=tot;
}
void pop_head(int x){
    head[x]=nxt[head[x]];
    //cout<<"head "<<x<<" "<<head[x]<<endl;
}
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    ll all=0,height=m;
    int cnt=0;
    for(int i=0;i<m;i++){
        scanf("%d%d",&a[cnt].id,&a[cnt].x);
        if(a[cnt].id!=1)all+=a[cnt].x,cnt++;
    }
    sort(a,a+cnt);
    tot=0;
    ll front=0,ans=all;
    for(int i=0;i<cnt;i++)add(a[i].id,a[i].x);
    for(int i=2;i<=n;i++)if(head[i])q[front++]=i;
    priority_queue<int> pq;
    for(int j=1;j<cnt;j++){
     //   cout<<"in"<<endl;
//  cout<<front<<endl;
        if(front==0)break;
        int tmp=0;
        for(int i=0;i<front;i++){
            all-=w[head[q[i]]];
            height--;
            pq.push(-w[head[q[i]]]);
            pop_head(q[i]);
            if(head[q[i]])q[tmp++]=q[i];
        }
        front=tmp;
        //cout<<all<<','<<height<<endl;
        while(height<=j)all-=pq.top(),pq.pop(),height++;
        //cout<<all<<endl;
        ans=min(ans,all);

    }
    printf("%I64d\n",ans);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=1e5+9;
struct node{
    int x,id;
    bool operator <(const node &b)const {
        return x<b.x;
    }
}a[MAXN];
int q[MAXN],head[MAXN],nxt[MAXN],w[MAXN],tot;
void add(int x,int y){
    w[++tot]=y;
    nxt[tot]=head[x];
    head[x]=tot;
}
void pop_head(int x){
    head[x]=nxt[head[x]];
    //cout<<"head "<<x<<" "<<head[x]<<endl;
}
int main(){
    int n,m;
    scanf("%d%d",&m,&n);
    ll all=0,height=m;
    int cnt=0;
    for(int i=0;i<m;i++){
        scanf("%d%d",&a[cnt].id,&a[cnt].x);
        if(a[cnt].id!=1)all+=a[cnt].x,cnt++;
    }
    sort(a,a+cnt);
    tot=0;
    ll front=0,ans=all;
    for(int i=0;i<cnt;i++)add(a[i].id,a[i].x);
    for(int i=2;i<=n;i++)if(head[i])q[front++]=i;
    priority_queue<int> pq;
    for(int j=1;j<cnt;j++){
     //   cout<<"in"<<endl;
//  cout<<front<<endl;
        if(front==0)break;
        int tmp=0;
        for(int i=0;i<front;i++){
            all-=w[head[q[i]]];
            height--;
            pq.push(-w[head[q[i]]]);
            pop_head(q[i]);
            if(head[q[i]])q[tmp++]=q[i];
        }
        front=tmp;
        //cout<<all<<','<<height<<endl;
        while(height<=j)all-=pq.top(),pq.pop(),height++;
        //cout<<all<<endl;
        ans=min(ans,all);

    }
    printf("%I64d\n",ans);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int MAXM=2e5+9;
const int MAXN=2e5+9;
#define list lst
struct node{
    int x,y;
    bool operator <(const node&b){
        return y<b.y;
    }
}a[MAXM];
int q[MAXM];
int head[MAXN],list[MAXM],tot,nxt[MAXM];
void add(int x,int y){
    list[++tot]=y;
    nxt[tot]=head[x];
    head[x]=tot;
}
void pop_head(int x){
    head[x]=nxt[head[x]];
}
priority_queue<int> p;
int main(){
    int n,sum=0,m=0;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d%d",&a[m].x,&a[m].y);
        if(a[m].x){sum+=a[m].y,m++;}
    }
    sort(a,a+m);
    for(int i=0;i<m;i++)add(a[i].x,a[i].y);
    int all=0,last,cnt=n,ans=sum;
    for(int i=1;i<100005;i++)if(head[i])q[all++]=i;
   // cout<<sum<<endl;
    for(int i=1;i<=n;i++){
        if(all==0)break;
        last=0;
        for(int j=0;j<all;j++){
       // cout<<"in"<<endl;

            int tmp=list[head[q[j]]];
            sum-=tmp;cnt--;
            //cout<<"sub"<<tmp<<endl;
            p.push(-tmp);
            pop_head(q[j]);
            if(head[q[j]])q[last++]=q[j];
        }
        all=last;
       // cout<<sum<<endl;
        while(cnt<=i){
            sum+=-p.top();
           // cout<<"addback"<<-p.top()<<endl;;
            p.pop();
            cnt++;
        }
        ans=min(ans,sum);
    }
    printf("%d\n",ans);
}


#include<bits/stdc++.h>
using namespace std;
typedef long long  ll;
const int MAXM=2e5+9;
const int MAXN=2e5+9;
#define list lst
struct node{
    int x,y;
    bool operator <(const node&b){
        return y<b.y;
    }
}a[MAXM];
int q[MAXM];
int head[MAXN],list[MAXM],tot,nxt[MAXM];
void add(int x,int y){
    list[++tot]=y;
    nxt[tot]=head[x];
    head[x]=tot;
}
void pop_head(int x){
    head[x]=nxt[head[x]];
}
priority_queue<int> p;
int main(){
    int n,mm,m=0;
    ll sum=0;
    scanf("%d%d",&mm,&n);
    for(int i=0;i<mm;i++){
        scanf("%d%d",&a[m].x,&a[m].y);
        if(a[m].x!=1){sum+=a[m].y,m++;}
    }
    sort(a,a+m);
    for(int i=0;i<m;i++)add(a[i].x,a[i].y);
    ll all=0,last,cnt=n,ans=sum;
    for(int i=2;i<=n;i++)if(head[i])q[all++]=i;
   // cout<<sum<<endl;
    for(int i=1;i<=mm;i++){
        if(all==0)break;
        last=0;
        for(int j=0;j<all;j++){
       // cout<<"in"<<endl;

            int tmp=list[head[q[j]]];
            sum-=tmp;cnt--;
            //cout<<"sub"<<tmp<<endl;
            p.push(-tmp);
            pop_head(q[j]);
            if(head[q[j]])q[last++]=q[j];
        }
        all=last;
       // cout<<sum<<endl;
        while(cnt<=i){
            sum+=-p.top();
           // cout<<"addback"<<-p.top()<<endl;;
            p.pop();
            cnt++;
        }
        ans=min(ans,sum);
    }
    printf("%I64d\n",ans);
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=1e5+9;
struct node{
    int x,id;
    bool operator <(const node &b)const {
        return x<b.x;
    }
}a[MAXN];
int q[MAXN],head[MAXN],nxt[MAXN],w[MAXN],tot;
void add(int x,int y){
    w[++tot]=y;
    nxt[tot]=head[x];
    head[x]=tot;
}
void pop_head(int x){
    head[x]=nxt[head[x]];
    //cout<<"head "<<x<<" "<<head[x]<<endl;
}
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    int all=0,height=m;
    int cnt=0;
    for(int i=0;i<m;i++){
        scanf("%d%d",&a[cnt].id,&a[cnt].x);
        if(a[cnt].id!=1)all+=a[cnt].x,cnt++;
    }
    sort(a,a+cnt);
    tot=0;
    int front=0,ans=all;
    for(int i=0;i<cnt;i++)add(a[i].id,a[i].x);
    for(int i=2;i<=n;i++)if(head[i])q[front++]=i;
    priority_queue<int> pq;
    for(int j=1;j<cnt;j++){
     //   cout<<"in"<<endl;
//  cout<<front<<endl;
        if(front==0)break;
        int tmp=0;
        for(int i=0;i<front;i++){
            all-=w[head[q[i]]];
            height--;
            pq.push(-w[head[q[i]]]);
            pop_head(q[i]);
            if(head[q[i]])q[tmp++]=q[i];
        }
        front=tmp;
        //cout<<all<<','<<height<<endl;
        while(height<=j)all-=pq.top(),pq.pop(),height++;
        //cout<<all<<endl;
        ans=min(ans,all);

    }
    printf("%d\n",ans);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN=1e5+9;
struct node{
    int x,id;
    bool operator <(const node &b)const {
        return x<b.x;
    }
}a[MAXN];
int q[MAXN],head[MAXN],nxt[MAXN],w[MAXN],tot;
void add(int x,int y){
    w[++tot]=y;
    nxt[tot]=head[x];
    head[x]=tot;
}
void pop_head(int x){
    head[x]=nxt[head[x]];
    //cout<<"head "<<x<<" "<<head[x]<<endl;
}
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    ll all=0,height=m;
    int cnt=0;
    for(int i=0;i<m;i++){
        scanf("%d%d",&a[cnt].id,&a[cnt].x);
        if(a[cnt].id!=1)all+=a[cnt].x,cnt++;
    }
    sort(a,a+cnt);
    tot=0;
    ll front=0,ans=all;
    for(int i=0;i<cnt;i++)add(a[i].id,a[i].x);
    for(int i=2;i<=n;i++)if(head[i])q[front++]=i;
    priority_queue<int> pq;
    for(int j=1;j<=cnt;j++){
     //   cout<<"in"<<endl;
//  cout<<front<<endl;
        if(front==0)break;
        int tmp=0;
        for(int i=0;i<front;i++){
            all-=w[head[q[i]]];
            height--;
            pq.push(-w[head[q[i]]]);
            pop_head(q[i]);
            if(head[q[i]])q[tmp++]=q[i];
        }
        front=tmp;
        //cout<<all<<','<<height<<endl;
        while(height<=j)all-=pq.top(),pq.pop(),height++;
        //cout<<all<<endl;
        ans=min(ans,all);

    }
    printf("%I64d\n",ans);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long  ll;
const int MAXM=2e5+9;
const int MAXN=2e5+9;
#define list lst
struct node{
    int x,y;
    bool operator <(const node&b){
        return y<b.y;
    }
}a[MAXM];
int q[MAXM];
int head[MAXN],list[MAXM],tot,nxt[MAXM];
void add(int x,int y){
    list[++tot]=y;
    nxt[tot]=head[x];
    head[x]=tot;
}
void pop_head(int x){
    head[x]=nxt[head[x]];
}
priority_queue<int> p;
int main(){
    int n,mm,m=0;
    ll sum=0;
    scanf("%d%d",&mm,&n);
    for(int i=0;i<mm;i++){
        scanf("%d%d",&a[m].x,&a[m].y);
        if(a[m].x!=1){sum+=a[m].y,m++;}
    }
    sort(a,a+m);
    for(int i=0;i<m;i++)add(a[i].x,a[i].y);
    ll all=0,last,cnt=mm,ans=sum;
    for(int i=2;i<=n;i++)if(head[i])q[all++]=i;
   // cout<<sum<<endl;
    for(int i=1;i<=mm;i++){
        if(all==0)break;
        last=0;
        for(int j=0;j<all;j++){
       // cout<<"in"<<endl;

            int tmp=list[head[q[j]]];
            sum-=tmp;cnt--;
            //cout<<"sub"<<tmp<<endl;
            p.push(-tmp);
            pop_head(q[j]);
            if(head[q[j]])q[last++]=q[j];
        }
        all=last;
       // cout<<sum<<endl;
        while(cnt<=i){
            sum+=-p.top();
           // cout<<"addback"<<-p.top()<<endl;;
            p.pop();
            cnt++;
        }
        ans=min(ans,sum);
    }
    printf("%I64d\n",ans);
}


#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(ll i=a;i<=b;i++)
#define drep(i,a,b) for(ll i=a;i>=b;i++)
#define go(u) for(ll i=head[u],v=e[i].to;i;i=e[i].nxt,v=e[i].to)
#define writesp(a) write(a),putchar(' ')
#define writeln(a) write(a),puts("")
using namespace std;
ll read(){ll sum=0,f=0;char ch=getchar();while(!isdigit(ch))f|=(ch=='-'),ch=getchar();while(isdigit(ch))sum=(sum<<1)+(sum<<3)+(ch^48),ch=getchar();return f?-sum:sum;}
void write(ll sum){if(sum<0)putchar('-'),sum=-sum;if(sum>9)write(sum/10);putchar(sum%10+'0');}
#define N 3300
ll n,m,ans=114514111,x,y,f[N][N],tmp[N],tmpp[N*N];
int main(){
	n=read(),m=read();
	rep(i,1,n)x=read(),y=read(),f[x][++f[x][0]]=y;
	rep(i,1,m)sort(f[x]+1,f[x]+f[x][0]+1);
	rep(i,f[1][0],n){
		ll sum=0,kkk=0,nn=f[1][0];
		memset(tmp,0,sizeof(tmp));memset(tmpp,0,sizeof(tmpp));
		rep(j,2,m)if(f[j][0]>=i)tmp[j]=f[j][0]-i+1;
		rep(j,2,m)rep(k,1,tmp[j])sum+=f[j][k],nn++;
		rep(j,2,m)rep(k,tmp[j]+1,f[j][0])tmpp[++kkk]=f[j][k];
		sort(tmpp+1,tmpp+kkk+1);
		for(ll pos=1;nn<i;nn++,pos++)sum+=tmpp[pos];
		ans=min(ans,sum);
	}
	write(ans);
}


#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(ll i=a;i<=b;i++)
#define drep(i,a,b) for(ll i=a;i>=b;i++)
#define go(u) for(ll i=head[u],v=e[i].to;i;i=e[i].nxt,v=e[i].to)
#define writesp(a) write(a),putchar(' ')
#define writeln(a) write(a),puts("")
using namespace std;
ll read(){ll sum=0,f=0;char ch=getchar();while(!isdigit(ch))f|=(ch=='-'),ch=getchar();while(isdigit(ch))sum=(sum<<1)+(sum<<3)+(ch^48),ch=getchar();return f?-sum:sum;}
void write(ll sum){if(sum<0)putchar('-'),sum=-sum;if(sum>9)write(sum/10);putchar(sum%10+'0');}
#define N 3300
ll n,m,ans=114514111,x,y,f[N][N],tmp[N],tmpp[N];
int main(){
	n=read(),m=read();
	rep(i,1,n)x=read(),y=read(),f[x][++f[x][0]]=y;
	rep(i,1,m)sort(f[x]+1,f[x]+f[x][0]+1);
	rep(i,f[1][0],n){
		ll sum=0,kkk=0,nn=f[1][0];
		memset(tmp,0,sizeof(tmp));
		rep(j,2,m)if(f[j][0]>=i)tmp[j]=f[j][0]-i+1;
		rep(j,2,m)rep(k,1,tmp[j])sum+=f[j][k],nn++;
		rep(j,2,m)rep(k,tmp[j]+1,f[j][0])tmpp[++kkk]=f[j][k];
//		sort(tmpp+1,tmpp+kkk+1);
		for(ll pos=1;nn<i;nn++,pos++)sum+=tmpp[pos];
		ans=min(ans,sum);
//		cout<<i<<' '<<sum<<endl;
	}
	write(ans);
}


#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(ll i=a;i<=b;i++)
#define drep(i,a,b) for(ll i=a;i>=b;i++)
#define go(u) for(ll i=head[u],v=e[i].to;i;i=e[i].nxt,v=e[i].to)
#define writesp(a) write(a),putchar(' ')
#define writeln(a) write(a),puts("")
using namespace std;
ll read(){ll sum=0,f=0;char ch=getchar();while(!isdigit(ch))f|=(ch=='-'),ch=getchar();while(isdigit(ch))sum=(sum<<1)+(sum<<3)+(ch^48),ch=getchar();return f?-sum:sum;}
void write(ll sum){if(sum<0)putchar('-'),sum=-sum;if(sum>9)write(sum/10);putchar(sum%10+'0');}
#define N 3300
ll n,m,ans=1145141919810123456,x,y,f[N][N],tmp[N],tmpp[N*N];
int main(){
	n=read(),m=read();
	rep(i,1,n)x=read(),y=read(),f[x][++f[x][0]]=y;
	rep(i,1,m)sort(f[x]+1,f[x]+f[x][0]+1);
	rep(i,f[1][0],n){
		ll sum=0,kkk=0,nn=f[1][0];memset(tmp,0,sizeof(tmp));
		rep(j,2,m)if(f[j][0]>=i)tmp[j]=f[j][0]-i+1;
		rep(j,2,m)rep(k,1,tmp[j])sum+=f[j][k],nn++;
		rep(j,2,m)rep(k,tmp[j]+1,f[j][0])tmpp[++kkk]=f[j][k];
		sort(tmpp+1,tmpp+kkk+1);
		for(ll pos=1;nn<i;nn++,pos++)sum+=tmpp[pos];
		ans=min(ans,sum);
	}
	write(ans);
}


#include<bits/stdc++.h>
//#define int long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define drep(i,a,b) for(int i=a;i>=b;i++)
#define go(u) for(int i=head[u],v=e[i].to;i;i=e[i].nxt,v=e[i].to)
#define writesp(a) write(a),putchar(' ')
#define writeln(a) write(a),puts("")
using namespace std;
int read(){int sum=0,f=0;char ch=getchar();while(!isdigit(ch))f|=(ch=='-'),ch=getchar();while(isdigit(ch))sum=(sum<<1)+(sum<<3)+(ch^48),ch=getchar();return f?-sum:sum;}
void write(int sum){if(sum<0)putchar('-'),sum=-sum;if(sum>9)write(sum/10);putchar(sum%10+'0');}
#define N 3300
int n,m,x,y,f[N][N],tmp[N],tmpp[N*N];
long long ans=LLONG_MAX;
int main(){
	n=read(),m=read();
	rep(i,1,n)x=read(),y=read(),f[x][++f[x][0]]=y;
	rep(i,1,m)sort(f[x]+1,f[x]+f[x][0]+1);
	rep(i,f[1][0],n){
		long long sum=0;
		int kkk=0,nn=f[1][0];
		memset(tmp,0,sizeof(tmp));memset(tmpp,0,sizeof(tmpp));
		rep(j,2,m)if(f[j][0]>=i)tmp[j]=f[j][0]-i+1;
		rep(j,2,m)rep(k,1,tmp[j])sum+=f[j][k],nn++;
		rep(j,2,m)rep(k,tmp[j]+1,f[j][0])tmpp[++kkk]=f[j][k];
		sort(tmpp+1,tmpp+kkk+1);
		for(int pos=1;nn<i;nn++,pos++)sum+=tmpp[pos];
		ans=min(ans,sum);
	}
	write(ans);
}


#include<bits/stdc++.h>
//#define int long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define drep(i,a,b) for(int i=a;i>=b;i++)
#define go(u) for(int i=head[u],v=e[i].to;i;i=e[i].nxt,v=e[i].to)
#define writesp(a) write(a),putchar(' ')
#define writeln(a) write(a),puts("")
using namespace std;
int read(){int sum=0,f=0;char ch=getchar();while(!isdigit(ch))f|=(ch=='-'),ch=getchar();while(isdigit(ch))sum=(sum<<1)+(sum<<3)+(ch^48),ch=getchar();return f?-sum:sum;}
void write(int sum){if(sum<0)putchar('-'),sum=-sum;if(sum>9)write(sum/10);putchar(sum%10+'0');}
#define N 3300
int n,m,x,y,f[N][N],tmp[N],tmpp[N*N];
long long ans=1145141111111;
int main(){
	n=read(),m=read();
	rep(i,1,n)x=read(),y=read(),f[x][++f[x][0]]=y;
	rep(i,1,m)sort(f[x]+1,f[x]+f[x][0]+1);
	rep(i,f[1][0],n){
		long long sum=0;
		int kkk=0,nn=f[1][0];
		memset(tmp,0,sizeof(tmp));memset(tmpp,0,sizeof(tmpp));
		rep(j,2,m)if(f[j][0]>=i)tmp[j]=f[j][0]-i+1;
		rep(j,2,m)rep(k,1,tmp[j])sum+=1LL*f[j][k],nn++;
		rep(j,2,m)rep(k,tmp[j]+1,f[j][0])tmpp[++kkk]=f[j][k];
		sort(tmpp+1,tmpp+kkk+1);
		for(int pos=1;nn<i;nn++,pos++)sum+=1LL*tmpp[pos];
		ans=min(ans,sum);
	}
	write(ans);
}


#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(ll i=a;i<=b;i++)
#define drep(i,a,b) for(ll i=a;i>=b;i++)
#define go(u) for(ll i=head[u],v=e[i].to;i;i=e[i].nxt,v=e[i].to)
#define writesp(a) write(a),putchar(' ')
#define writeln(a) write(a),puts("")
using namespace std;
ll read(){ll sum=0,f=0;char ch=getchar();while(!isdigit(ch))f|=(ch=='-'),ch=getchar();while(isdigit(ch))sum=(sum<<1)+(sum<<3)+(ch^48),ch=getchar();return f?-sum:sum;}
void write(ll sum){if(sum<0)putchar('-'),sum=-sum;if(sum>9)write(sum/10);putchar(sum%10+'0');}
#define N 3300
ll n,m,ans=114514111,x,y,f[N][N],tmp[N],tmpp[N];
int main(){
	n=read(),m=read();
	rep(i,1,n)x=read(),y=read(),f[x][++f[x][0]]=y;
	rep(i,1,m)sort(f[x]+1,f[x]+f[x][0]+1);
	rep(i,f[1][0],n){
		ll sum=0,kkk=0,nn=f[1][0];
		memset(tmp,0,sizeof(tmp));memset(tmpp,0,sizeof(tmpp));
		rep(j,2,m)if(f[j][0]>=i)tmp[j]=f[j][0]-i+1;
		rep(j,2,m)rep(k,1,tmp[j])sum+=f[j][k],nn++;
		rep(j,2,m)rep(k,tmp[j]+1,f[j][0])tmpp[++kkk]=f[j][k];
		sort(tmpp+1,tmpp+kkk+1);
		for(ll pos=1;nn<i;nn++,pos++)sum+=tmpp[pos];
		ans=min(ans,sum);
//		cout<<i<<' '<<sum<<endl;
	}
	write(ans);
}


#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define drep(i,a,b) for(int i=a;i>=b;i++)
#define go(u) for(int i=head[u],v=e[i].to;i;i=e[i].nxt,v=e[i].to)
#define writesp(a) write(a),putchar(' ')
#define writeln(a) write(a),puts("")
using namespace std;
int read(){int sum=0,f=0;char ch=getchar();while(!isdigit(ch))f|=(ch=='-'),ch=getchar();while(isdigit(ch))sum=(sum<<1)+(sum<<3)+(ch^48),ch=getchar();return f?-sum:sum;}
void write(ll sum){if(sum<0)putchar('-'),sum=-sum;if(sum>9)write(sum/10);putchar(sum%10+'0');}
#define N 3300
int n,m,x,y,f[N][N],tmp[N],tmpp[N*N];
ll ans=LLONG_MAX;
int main(){
	n=read(),m=read();
	rep(i,1,n)x=read(),y=read(),f[x][++f[x][0]]=y;
	rep(i,1,m)sort(f[x]+1,f[x]+f[x][0]+1);
	rep(i,f[1][0],n){
		ll sum=0;
		int kkk=0,nn=f[1][0];
		//memset(tmp,0,sizeof(tmp));memset(tmpp,0,sizeof(tmpp));
		rep(j,2,m)tmp[j]=(f[j][0]>=i?f[j][0]-i+1:0);
		rep(j,2,m)rep(k,1,tmp[j])sum+=f[j][k],nn++;
		rep(j,2,m)rep(k,tmp[j]+1,f[j][0])tmpp[++kkk]=f[j][k];
		sort(tmpp+1,tmpp+kkk+1);
		for(int pos=1;nn<i;nn++,pos++)sum+=tmpp[pos];
		ans=min(ans,sum);
	}
	write(ans);
}


#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define drep(i,a,b) for(int i=a;i>=b;i++)
#define go(u) for(int i=head[u],v=e[i].to;i;i=e[i].nxt,v=e[i].to)
#define writesp(a) write(a),putchar(' ')
#define writeln(a) write(a),puts("")
using namespace std;
int read(){int sum=0,f=0;char ch=getchar();while(!isdigit(ch))f|=(ch=='-'),ch=getchar();while(isdigit(ch))sum=(sum<<1)+(sum<<3)+(ch^48),ch=getchar();return f?-sum:sum;}
void write(ll sum){if(sum<0)putchar('-'),sum=-sum;if(sum>9)write(sum/10);putchar(sum%10+'0');}
#define N 3300
int n,m,x,y,f[N][N],tmp[N],tmpp[N*N];
ll ans=LLONG_MAX;
int main(){
	n=read(),m=read();
	rep(i,1,n)x=read(),y=read(),f[x][++f[x][0]]=y;
	rep(i,1,m)sort(f[i]+1,f[i]+f[i][0]+1);
	rep(i,f[1][0],n){
		ll sum=0;
		int kkk=0,nn=f[1][0];
		//memset(tmp,0,sizeof(tmp));memset(tmpp,0,sizeof(tmpp));
		rep(j,2,m)tmp[j]=(f[j][0]>=i?f[j][0]-i+1:0);
		rep(j,2,m)rep(k,1,tmp[j])sum+=f[j][k],nn++;
		rep(j,2,m)rep(k,tmp[j]+1,f[j][0])tmpp[++kkk]=f[j][k];
		sort(tmpp+1,tmpp+kkk+1);
		for(int pos=1;nn<i;nn++,pos++)sum+=tmpp[pos];
		ans=min(ans,sum);
	}
	write(ans);
}


#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(ll i=a;i<=b;i++)
#define drep(i,a,b) for(ll i=a;i>=b;i++)
#define go(u) for(ll i=head[u],v=e[i].to;i;i=e[i].nxt,v=e[i].to)
#define writesp(a) write(a),putchar(' ')
#define writeln(a) write(a),puts("")
using namespace std;
ll read(){ll sum=0,f=0;char ch=getchar();while(!isdigit(ch))f|=(ch=='-'),ch=getchar();while(isdigit(ch))sum=(sum<<1)+(sum<<3)+(ch^48),ch=getchar();return f?-sum:sum;}
void write(ll sum){if(sum<0)putchar('-'),sum=-sum;if(sum>9)write(sum/10);putchar(sum%10+'0');}
#define N 3300
ll n,m,ans=1145141919810123456,x,y,f[N][N],tmp[N],tmpp[N];
int main(){
	n=read(),m=read();
	rep(i,1,n)x=read(),y=read(),f[x][++f[x][0]]=y;
	rep(i,1,m)sort(f[x]+1,f[x]+f[x][0]+1);
	rep(i,f[1][0],n){
		ll sum=0,kkk=0,nn=f[1][0];
		memset(tmp,0,sizeof(tmp));memset(tmpp,0,sizeof(tmpp));
		rep(j,2,m)if(f[j][0]>=i)tmp[j]=f[j][0]-i+1;
		rep(j,2,m)rep(k,1,tmp[j])sum+=f[j][k],nn++;
		rep(j,2,m)rep(k,tmp[j]+1,f[j][0])tmpp[++kkk]=f[j][k];
		sort(tmpp+1,tmpp+kkk+1);
		for(ll pos=1;nn<i;nn++,pos++)sum+=tmpp[pos];
		ans=min(ans,sum);
//		cout<<i<<' '<<sum<<endl;
	}
	write(ans);
}


#include<bits/stdc++.h>
//#define int long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define drep(i,a,b) for(int i=a;i>=b;i++)
#define go(u) for(int i=head[u],v=e[i].to;i;i=e[i].nxt,v=e[i].to)
#define writesp(a) write(a),putchar(' ')
#define writeln(a) write(a),puts("")
using namespace std;
int read(){int sum=0,f=0;char ch=getchar();while(!isdigit(ch))f|=(ch=='-'),ch=getchar();while(isdigit(ch))sum=(sum<<1)+(sum<<3)+(ch^48),ch=getchar();return f?-sum:sum;}
void write(int sum){if(sum<0)putchar('-'),sum=-sum;if(sum>9)write(sum/10);putchar(sum%10+'0');}
#define N 3300
int n,m,x,y,f[N][N],tmp[N],tmpp[N*N];
long long ans=LLONG_MAX;
int main(){
	n=read(),m=read();
	rep(i,1,n)x=read(),y=read(),f[x][++f[x][0]]=y;
	rep(i,1,m)sort(f[x]+1,f[x]+f[x][0]+1);
	rep(i,f[1][0],n){
		long long sum=0;
		int kkk=0,nn=f[1][0];
		//memset(tmp,0,sizeof(tmp));memset(tmpp,0,sizeof(tmpp));
		rep(j,2,m)tmp[j]=(f[j][0]>=i?f[j][0]-i+1:0);
		rep(j,2,m)rep(k,1,tmp[j])sum+=f[j][k],nn++;
		rep(j,2,m)rep(k,tmp[j]+1,f[j][0])tmpp[++kkk]=f[j][k];
		sort(tmpp+1,tmpp+kkk+1);
		for(int pos=1;nn<i;nn++,pos++)sum+=tmpp[pos];
		ans=min(ans,sum);
	}
	write(ans);
}


#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(ll i=a;i<=b;i++)
#define drep(i,a,b) for(ll i=a;i>=b;i++)
#define go(u) for(ll i=head[u],v=e[i].to;i;i=e[i].nxt,v=e[i].to)
#define writesp(a) write(a),putchar(' ')
#define writeln(a) write(a),puts("")
using namespace std;
ll read(){ll sum=0,f=0;char ch=getchar();while(!isdigit(ch))f|=(ch=='-'),ch=getchar();while(isdigit(ch))sum=(sum<<1)+(sum<<3)+(ch^48),ch=getchar();return f?-sum:sum;}
void write(ll sum){if(sum<0)putchar('-'),sum=-sum;if(sum>9)write(sum/10);putchar(sum%10+'0');}
#define N 3300
ll n,m,ans=114514111,x,y,f[N][N],tmp[N],tmpp[N];
int main(){
	n=read(),m=read();
	rep(i,1,n)x=read(),y=read(),f[x][++f[x][0]]=y;
	rep(i,1,m)sort(f[x]+1,f[x]+f[x][0]+1);
	rep(i,f[1][0],n){
		ll sum=0,kkk=0,nn=f[1][0];
		memset(tmp,0,sizeof(tmp));memset(tmpp,0,sizeof(tmpp));
		rep(j,2,m)if(f[j][0]>=i)tmp[j]=f[j][0]-i+1;
		rep(j,2,m)rep(k,1,tmp[j])sum+=f[j][k],nn++;
		rep(j,2,m)rep(k,tmp[j]+1,f[j][0])tmpp[++kkk]=f[j][k];
		sort(tmpp+1,tmpp+kkk+1);
		for(ll pos=1;nn<i;nn++,pos++)sum+=tmpp[pos];
		ans=min(ans,sum);
//		cout<<i<<' '<<sum<<endl;
	}
	write(ans);//xie
}


/************************************************************************
* File Name : cf1020C.cpp
* Purpose : water?
* Creation Date : 2018年08月11日
* Last Modified : 2018年08月12日 星期日 15时38分57秒
* Created By : hi@goushi.me
************************************************************************/
#include <bits/stdc++.h>
using namespace std;

// const
const int N = 100000 + 10;
const int INF = 0x3f3f3f3f;
const int _INF = (int)0x80000000;
const int MOD = 1000000000 + 7;
const double EPS = 1E-8;

// long long
typedef long long LL;
#ifdef _WIN32
#define lld I64d
#endif

// vector
typedef vector<int> VI;
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define sz(x) ((int)(x).size())

// pair
typedef pair<int, int> PII;
#define mp make_pair
#define fi first
#define se second

#define mst(a,x) memset(a,x,sizeof(a))

int p[N], c[N];
vector<int> a[N];

int main() {
#ifdef LOCAL
    freopen("in", "r", stdin);
#endif

    LL sum = 0;
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i) {
        scanf("%d%d", &p[i], &c[i]);
        sum += c[i];
        a[p[i]].push_back(c[i]);
    }

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

    LL min_cost = sum;
    for (int k = 1; k <= n; ++k) {
        int need = k - a[1].size();
        LL cost = 0;
        vector<int> v;
        for (int i = 2; i <= m; ++i) {
            if (a[i].empty())
                continue;
            if (a[i].size() < k) {
                for (int j = 0; j < a[i].size(); ++j)
                    v.push_back(a[i][j]);
            } else {
                for (int j = 0; j < a[i].size() - k + 1; ++j) {
                    cost += a[i][j];
                    --need;
                }
            }
        }
        if (need > 0) {
            sort(v.begin(), v.end());
            for (int i = 0; i < need && i < v.size(); ++i)
                cost += v[i];
        }
        min_cost = min(min_cost, cost);
    }
    printf("%lld\n", min_cost);

    return 0;
}


/************************************************************************
* File Name : cf1020C.cpp
* Purpose : water?
* Creation Date : 2018年08月11日
* Last Modified : 2018年08月12日 星期日 16时49分06秒
* Created By : hi@goushi.me
************************************************************************/
#include <bits/stdc++.h>
using namespace std;

// const
const int N = 100000 + 10;
const int INF = 0x3f3f3f3f;
const int _INF = (int)0x80000000;
const int MOD = 1000000000 + 7;
const double EPS = 1E-8;

// long long
typedef long long LL;
#ifdef _WIN32
#define lld I64d
#endif

// vector
typedef vector<int> VI;
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define sz(x) ((int)(x).size())

// pair
typedef pair<int, int> PII;
#define mp make_pair
#define fi first
#define se second

#define mst(a,x) memset(a,x,sizeof(a))

int p[N], c[N];
vector<int> a[N];

int main() {
#ifdef LOCAL
    freopen("in", "r", stdin);
#endif

    LL sum = 0;
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i) {
        scanf("%d%d", &p[i], &c[i]);
        sum += c[i];
        a[p[i]].push_back(c[i]);
    }

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

    LL min_cost = sum;
    for (int k = 1; k <= n; ++k) {
        int need = k - a[1].size();
        LL cost = 0;
        vector<int> v;
        for (int i = 2; i <= m; ++i) {
            if (a[i].empty())
                continue;
            if (a[i].size() < k) {
                for (int j = 0; j < a[i].size(); ++j)
                    v.push_back(a[i][j]);
            } else {
                for (int j = 0; j < a[i].size() - k + 1; ++j) {
                    cost += a[i][j];
                    --need;
                }
                for (int j = a[i].size() - k + 1; j < a[i].size(); ++j) {
                    v.push_back(a[i][j]);
                }

            }
        }
        if (need > 0) {
            sort(v.begin(), v.end());
            for (int i = 0; i < need && i < v.size(); ++i)
                cost += v[i];
        }
        min_cost = min(min_cost, cost);
    }
    printf("%lld\n", min_cost);

    return 0;
}


/************************************************************************
* File Name : cf1020C.cpp
* Purpose : water?
* Creation Date : 2018年08月11日
* Last Modified : 2018年08月11日 星期六 22时58分07秒
* Created By : hi@goushi.me
************************************************************************/
#include <bits/stdc++.h>
using namespace std;

// const
const int N = 10000 + 10;
const int INF = 0x3f3f3f3f;
const int _INF = (int)0x80000000;
const int MOD = 1000000000 + 7;
const double EPS = 1E-8;

// long long
typedef long long LL;
#ifdef _WIN32
#define lld I64d
#endif

// vector
typedef vector<int> VI;
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define sz(x) ((int)(x).size())

// pair
typedef pair<int, int> PII;
#define mp make_pair
#define fi first
#define se second

#define mst(a,x) memset(a,x,sizeof(a))

int p[N], c[N];
vector<int> a[N];

int main() {
#ifdef LOCAL
    freopen("in", "r", stdin);
#endif

    LL sum = 0;
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i) {
        scanf("%d%d", &p[i], &c[i]);
        sum += c[i];
        a[p[i]].push_back(c[i]);
    }

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

    LL min_cost = sum;
    for (int k = a[1].size(); k <= n; ++k) {
        int need = k - a[1].size();
        LL cost = 0;
        vector<int> v;
        v.reserve(n);
        for (int i = 2; i <= m; ++i) {
            if (a[i].size() < k) {
                for (int &x: a[i])
                    v.push_back(x);
            } else {
                for (int j = 0; j < a[i].size() - k + 1; ++j) {
                    cost += a[i][j];
                    --need;
                }
            }
        }
        if (need > 0) {
            sort(v.begin(), v.end());
            for (int i = 0; i < need && i < v.size(); ++i)
                cost += v[i];
        }
        if (need <= v.size())
            min_cost = min(min_cost, cost);
    }
    printf("%lld\n", min_cost);

    return 0;
}


/************************************************************************
* File Name : cf1020C.cpp
* Purpose : water?
* Creation Date : 2018年08月11日
* Last Modified : 2018年08月11日 星期六 23时46分28秒
* Created By : hi@goushi.me
************************************************************************/
#include <bits/stdc++.h>
using namespace std;

// const
const int N = 100000 + 10;
const int INF = 0x3f3f3f3f;
const int _INF = (int)0x80000000;
const int MOD = 1000000000 + 7;
const double EPS = 1E-8;

// long long
typedef long long LL;
#ifdef _WIN32
#define lld I64d
#endif

// vector
typedef vector<int> VI;
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define sz(x) ((int)(x).size())

// pair
typedef pair<int, int> PII;
#define mp make_pair
#define fi first
#define se second

#define mst(a,x) memset(a,x,sizeof(a))

int p[N], c[N];
vector<int> a[N];

int main() {
#ifdef LOCAL
    freopen("in", "r", stdin);
#endif

    LL sum = 0;
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++i) {
        scanf("%d%d", &p[i], &c[i]);
        sum += c[i];
        a[p[i]].push_back(c[i]);
    }

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

    LL min_cost = sum;
    for (int k = max(a[1].size(), 1); k <= n; ++k) {
        int need = k - max(a[1].size(), 1);
        LL cost = 0;
        vector<int> v;
        for (int i = 2; i <= m; ++i) {
            if (a[i].empty())
                continue;
            if (a[i].size() < k) {
                for (int j = 0; j < a[i].size(); ++j)
                    v.push_back(a[i][j]);
            } else {
                for (int j = 0; j < a[i].size() - k + 1; ++j) {
                    cost += a[i][j];
                    --need;
                }
            }
        }
        if (need > 0) {
            sort(v.begin(), v.end());
            for (int i = 0; i < need && i < v.size(); ++i)
                cost += v[i];
        }
        min_cost = min(min_cost, cost);
    }
    printf("%lld\n", min_cost);

    return 0;
}