/*************************************************************************
    > File Name: A.cpp
    > Author: Roundgod
    > Mail: wcysai@foxmail.com
    > Created Time: 2018-08-11 21:36:48
 ************************************************************************/

#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define MAXN 100005
#define INF 1000000000000000000LL
#define MOD 1000000007
#define F first
#define S second
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
ll n,m,p[MAXN],c[MAXN];
multiset<ll> s[MAXN];
multiset<ll> tot;
int main()
{
    scanf("%lld%lld",&n,&m);
    for(ll i=1;i<=n;i++)
    {
        scanf("%lld%lld",&p[i],&c[i]);
        s[p[i]].insert(c[i]);
        if(p[i]!=1) tot.insert(c[i]);
    }
    ll ans=INF;
    for(ll i=0;i<=1500;i++)
    {
        ll res=0;
        tot.clear();
        for(ll j=1;j<=m;j++) s[j].clear();
        for(ll j=1;j<=n;j++)
        {
            if(p[j]!=1) tot.insert(c[j]);
            s[p[j]].insert(c[j]);
        }
        ll cnt=0,mx=-INF;
        for(ll j=2;j<=m;j++)
        {
            while((int)s[j].size()>i)
            {
                auto it=s[j].begin();
                s[j].erase(s[j].begin());
                res+=*it;
                tot.erase(*it);
                cnt++;
            }
            mx=max(mx,(ll)s[j].size());
        }
        while((int)s[1].size()+cnt<=mx)
        {
            cnt++;
            res+=*tot.begin();
            tot.erase(tot.begin());
        }
        ans=min(ans,res);
    }
    printf("%lld\n",ans);
    return 0;
}


/*************************************************************************
    > File Name: A.cpp
    > Author: Roundgod
    > Mail: wcysai@foxmail.com
    > Created Time: 2018-08-11 21:36:48
 ************************************************************************/

#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define MAXN 3005
#define INF 1000000000000000000LL
#define MOD 1000000007
#define F first
#define S second
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
ll n,m,p[MAXN],c[MAXN],cc[MAXN];
multiset<ll> s[MAXN];
multiset<ll> tot;
int main()
{
    scanf("%lld%lld",&n,&m);
    memset(cc,0,sizeof(cc));
    for(ll i=1;i<=n;i++)
    {
        scanf("%lld%lld",&p[i],&c[i]);
        cc[p[i]]++;
        s[p[i]].insert(c[i]);
        if(p[i]!=1) tot.insert(c[i]);
    }
    ll ans=INF;
    ll res=0,cnt=cc[1];
    for(ll i=n/2+1;i>=max(cc[1],1LL);i--)
    {
        for(ll j=2;j<=m;j++)
        {
            while((ll)s[j].size()>=i)
            {
                res+=*s[j].begin();
                tot.erase(tot.find(*s[j].begin()));
                s[j].erase(s[j].begin());
                cnt++;
            }
        }
        vector<ll> save;
        save.clear();
        while(cnt<i)
        {
            cnt++;
            res+=*tot.begin();
            save.push_back(*tot.begin());
            tot.erase(tot.begin());
        }
        ans=min(ans,res);
        for(int j=0;j<(int)save.size();j++)
        {
            cnt--;
            tot.insert(save[j]);
            res-=save[j];
        }
    }
    printf("%lld\n",ans);
    return 0;
}


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

using namespace std;

int n,m,ns,cnt[3005],Sum[3005];
struct peo
{
    int p,c,rk;
}a[3005];
struct val
{
    int rk,v;
}b[3005];
bool vis[3005];
long long min_ans=-1,ans;

bool cmpa (peo a,peo b)
{
    if(a.p==b.p) return a.c<b.c;
    return a.p<b.p;
}

bool cmpb (val a,val b)
{
    return a.v<b.v;
}

int main()
{
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;++i)
    {
        scanf("%d%d",&a[i].p,&a[i].c);
        a[i].rk=i;
        b[i].rk=i;
        b[i].v=a[i].c;
    }
    sort(a+1,a+1+n,cmpa);
    sort(b+1,b+1+n,cmpb);
    for (int i=1;i<=n;++i)
        Sum[ a[i].p ]++;
    for (int s=1;s<=n;++s)
    {
        ns=0;
        ans=0;
        memset(vis,0,sizeof(vis));
        memset(cnt,0,sizeof(cnt));
        for (int j=1;j<=n;++j)
        {
            if(a[j].p==1) ns++,vis[ a[j].rk ]=true;
            else
            {
                if(Sum[ a[j].p ]-cnt[ a[j].p ]>=s)
                {
                    vis[ a[j].rk ]=true;
                    cnt[ a[j].p ]++;
                    ans+=a[j].c;
                    ns++;
                }
            }
        }
        for (int i=1;i<=n;++i)
        {
            if(ns>=s) break;
            if(vis[ b[i].rk ]) continue;
            ns++;
            ans+=b[i].v;
        }
        if(min_ans==-1) min_ans=ans;
        min_ans=min(ans,min_ans);
    }
    cout<<min_ans;
    return 0;
}


#pragma comment(linker, "/STACK:102400000,102400000")
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cassert>
#include<string>
#include<cstdio>
#include<bitset>
#include<vector>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<deque>
#include<list>
#include<set>
#include<map>
using namespace std;
#define debug test
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
#define ll long long
#define ull unsigned long long
#define pb push_back
#define mp make_pair
#define inf 0x3f3f3f3f
#define eps 1e-10
#define PI acos(-1.0)
typedef pair<int,int> PII;
const ll mod = 1e9+7;
const int N = 1e6+10;

ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
ll qp(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
int to[4][2]={{-1,0},{1,0},{0,-1},{0,1}};

int n,m,ct[3005],tp[3005],id[3005],vs[3005];
ll c[3005],ans,s;
///vector< PII> v[3005];
vector<int> v[3005];
struct nd{
    int a,b;
}p[3005];
bool cmp(nd x,nd y) {
    return x.b<y.b;
}

int main() {
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++) {
        int a,b;
        cin>>a>>b;
        ct[a]++,tp[a]++;
        p[i].a=a,p[i].b=b;
        v[a].pb(b);
    }
    for(int i=1;i<=3005;i++) sort(v[i].begin(),v[i].end());
    sort(p+1,p+n+1,cmp);
    s=ct[1];
    for(int j=1;j<=n;j++) {
        if(p[j].a==1) continue;
        ans += p[j].b;
        s++;
        ct[p[j].a]--;
        int mx=0;
        for(int i=2;i<=m;i++) mx=max(mx,ct[i]);
        if(mx<s) break;
    }
    ll res=0;
    s=tp[1];
    for(int j=1;j<=n;j++) {
        if(p[j].a==1||vs[j]) continue;
        int mx=0;
        for(int i=2;i<=m;i++) mx=max(mx,tp[i]);
        if(mx<s) break;
        if(mx==s+1) {
            ll tmp=inf,ps=0;
            for(int k=2;k<=m;k++) {
                if(tp[k]==mx && v[k][id[k]]<tmp) {
                    tmp=min(tmp,(ll)v[k][id[k]]);
                    ps=k;
                }
            }
            res += tmp;
            id[ps]++;
            tp[ps]--;
            s++;

            for(int k=1;k<=n;k++) {
                if(p[k].a==tmp && p[k].b==ps) {
                    vs[k]=1;
                    break;
                }
            }
            j--;
            continue;
        }
        res += p[j].b;
        s++;
        tp[p[j].a]--;
        id[p[j].a]++;
    }
    cout<<min(ans,res)<<endl;
    return 0;
}


#pragma comment(linker, "/STACK:102400000,102400000")
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cassert>
#include<string>
#include<cstdio>
#include<bitset>
#include<vector>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<deque>
#include<list>
#include<set>
#include<map>
using namespace std;
#define debug test
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
#define ll long long
#define ull unsigned long long
#define pb push_back
#define mp make_pair
#define inf 0x3f3f3f3f
#define eps 1e-10
#define PI acos(-1.0)
typedef pair<int,int> PII;
const ll mod = 1e9+7;
const int N = 1e6+10;

ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
ll qp(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
int to[4][2]={{-1,0},{1,0},{0,-1},{0,1}};

int n,m,ct[3005],tp[3005],id[3005];
ll c[3005],ans,s;
///vector< PII> v[3005];
vector<int> v[3005];
struct nd{
    int a,b;
}p[3005];
bool cmp(nd x,nd y) {
    return x.b<y.b;
}

int main() {
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++) {
        int a,b;
        cin>>a>>b;
        ct[a]++,tp[a]++;
        p[i].a=a,p[i].b=b;
        v[a].pb(b);
    }
    for(int i=1;i<=3005;i++) sort(v[i].begin(),v[i].end());
    sort(p+1,p+n+1,cmp);
    s=ct[1];
    for(int j=1;j<=n;j++) {
        if(p[j].a==1) continue;
        ans += p[j].b;
        s++;
        ct[p[j].a]--;
        int mx=0;
        for(int i=2;i<=m;i++) mx=max(mx,ct[i]);
        if(mx<s) break;
    }
    ll res=0;
    s=ct[1];
    for(int j=1;j<=n;j++) {
        if(p[j].a==1) continue;
        int mx=0;
        for(int i=2;i<=m;i++) mx=max(mx,tp[i]);
        if(mx<s) break;
        if(mx==s+1) {
            ll tmp=inf;
            for(int k=2;k<=m;k++)
                if(tp[k]==mx) tmp=min(tmp,(ll)v[k][id[k]]);
            res += tmp;
            break;
        }
        res += p[j].b;
        s++;
        tp[p[j].a]--;
        id[p[j].a]++;
    }
    cout<<min(ans,res)<<endl;
    return 0;
}


#pragma comment(linker, "/STACK:102400000,102400000")
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cassert>
#include<string>
#include<cstdio>
#include<bitset>
#include<vector>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<deque>
#include<list>
#include<set>
#include<map>
using namespace std;
#define debug test
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
#define ll long long
#define ull unsigned long long
#define pb push_back
#define mp make_pair
#define inf 0x3f3f3f3f
#define eps 1e-10
#define PI acos(-1.0)
typedef pair<int,int> PII;
const ll mod = 1e9+7;
const int N = 1e6+10;

ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
ll qp(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
int to[4][2]={{-1,0},{1,0},{0,-1},{0,1}};

int n,m,ct[3005],tp[3005],id[3005],vs[3005];
ll c[3005],ans,s;
///vector< PII> v[3005];
vector<int> v[3005];
struct nd{
    int a,b;
}p[3005];
bool cmp(nd x,nd y) {
    return x.b<y.b;
}

int main() {
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++) {
        int a,b;
        cin>>a>>b;
        ct[a]++,tp[a]++;
        p[i].a=a,p[i].b=b;
        v[a].pb(b);
    }
    for(int i=1;i<=3005;i++) sort(v[i].begin(),v[i].end());
    sort(p+1,p+n+1,cmp);
    s=ct[1];
    for(int j=1;j<=n;j++) {
        if(p[j].a==1) continue;
        ans += p[j].b;
        s++;
        ct[p[j].a]--;
        int mx=0;
        for(int i=2;i<=m;i++) mx=max(mx,ct[i]);
        if(mx<s) break;
    }
    ll res=0;
    s=tp[1];
    for(int j=1;j<=n;j++) {
        if(p[j].a==1||vs[j]) continue;
        int mx=0;
        for(int i=2;i<=m;i++) mx=max(mx,tp[i]);
        if(mx<s) break;
        if(mx==s+1) {
            ll tmp=inf,ps=0;
            for(int k=2;k<=n;k++) {
                if(tp[k]==mx && v[k][id[k]]<tmp) {
                    tmp=min(tmp,(ll)v[k][id[k]]);
                    ps=k;
                }
            }
            res += tmp;
            id[ps]++;
            tp[ps]--;
            s++;
            for(int k=1;k<=n;k++) {
                if(p[k].a==ps && p[k].b==tmp) {
                    vs[k]=1;
                    break;
                }
            }
            j--;
            continue;
        }
        res += p[j].b;
        s++;
        tp[p[j].a]--;
        id[p[j].a]++;
        vs[j]=1;
    }
    cout<<min(ans,res)<<endl;
    return 0;
}
/*
5 5
2 5
2 4
2 1
3 6
3 7
*/


#pragma comment(linker, "/STACK:102400000,102400000")
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cassert>
#include<string>
#include<cstdio>
#include<bitset>
#include<vector>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<deque>
#include<list>
#include<set>
#include<map>
using namespace std;
#define debug test
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
#define ll long long
#define ull unsigned long long
#define pb push_back
#define mp make_pair
#define inf 0x3f3f3f3f
#define eps 1e-10
#define PI acos(-1.0)
typedef pair<int,int> PII;
const ll mod = 1e9+7;
const int N = 3e3+10;

ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
ll qp(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
int to[4][2]={{-1,0},{1,0},{0,-1},{0,1}};

int n,m;
struct p1{
    int id,val;
}a[N];

struct p2{
    int id,peo,val;
}b[N];

bool cmp1(p1 x,p1 y) {
    return x.val<y.val;
}

bool cmp2(p2 x,p2 y) {
    if(x.peo==y.peo) return x.val<y.val;
    return x.peo<y.peo;
}

int ct[N],tp[N],vs[N];
int main() {
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++) {
        cin>>b[i].peo>>b[i].val;
        b[i].id=a[i].id=i;
        a[i].val=b[i].val;
        ct[b[i].peo]++;
    }
    sort(a+1,a+n+1,cmp1);
    sort(b+1,b+n+1,cmp2);
    ll ans,sum,res=2e18;
    for(int s=1;s<=n;s++) {
        ans=0,sum=0,mst(vs,0),mst(tp,0);
        for(int i=1;i<=n;i++) {
            if(b[i].peo==1) vs[b[i].id]=1,sum++;
            else if(ct[b[i].peo]-tp[b[i].peo]>=s) {
                sum++;
                tp[b[i].peo]++;
                vs[b[i].id]=1;
                ans+=b[i].val;
            }
        }
        for(int i=1;i<=n;i++) {
            if(sum>=s) break;
            if(!vs[a[i].id]) ans+=a[i].val,sum++;
        }
        res=min(res,ans);
    }
    cout<<res<<endl;
    return 0;
}


#pragma comment(linker, "/STACK:102400000,102400000")
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cassert>
#include<string>
#include<cstdio>
#include<bitset>
#include<vector>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<deque>
#include<list>
#include<set>
#include<map>
using namespace std;
#define debug test
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
#define ll long long
#define ull unsigned long long
#define pb push_back
#define mp make_pair
#define inf 0x3f3f3f3f
#define eps 1e-10
#define PI acos(-1.0)
typedef pair<int,int> PII;
const ll mod = 1e9+7;
const int N = 1e6+10;

ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
ll qp(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
int to[4][2]={{-1,0},{1,0},{0,-1},{0,1}};

int n,m,ct[3005],tp[3005],id[3005];
ll c[3005],ans,s;
///vector< PII> v[3005];
vector<int> v[3005];
struct nd{
    int a,b;
}p[3005];
bool cmp(nd x,nd y) {
    return x.b<y.b;
}

int main() {
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++) {
        int a,b;
        cin>>a>>b;
        ct[a]++,tp[a]++;
        p[i].a=a,p[i].b=b;
        v[a].pb(b);
    }
    for(int i=1;i<=3005;i++) sort(v[i].begin(),v[i].end());
    sort(p+1,p+n+1,cmp);
    s=ct[1];
    for(int j=1;j<=n;j++) {
        if(p[j].a==1) continue;
        ans += p[j].b;
        s++;
        ct[p[j].a]--;
        int mx=0;
        for(int i=2;i<=m;i++) mx=max(mx,ct[i]);
        if(mx<s) break;
    }
    ll res=0;
    s=ct[1];
    for(int j=1;j<=n;j++) {
        if(p[j].a==1) continue;
        int mx=0;
        for(int i=2;i<=m;i++) mx=max(mx,tp[i]);
        if(mx<s) break;
        if(mx==s+1) {
            ll tmp=inf,ps=0;
            for(int k=2;k<=m;k++) {
                if(tp[k]==mx && v[k][id[k]]<tmp) {
                    tmp=min(tmp,(ll)v[k][id[k]]);
                    ps=k;
                }
            }
            res += tmp;
            id[ps]++;
            tp[ps]--;
            s++;
            continue;
        }
        res += p[j].b;
        s++;
        tp[p[j].a]--;
        id[p[j].a]++;
    }
    cout<<min(ans,res)<<endl;
    return 0;
}


#pragma comment(linker, "/STACK:102400000,102400000")
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cassert>
#include<string>
#include<cstdio>
#include<bitset>
#include<vector>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<deque>
#include<list>
#include<set>
#include<map>
using namespace std;
#define debug test
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
#define ll long long
#define ull unsigned long long
#define pb push_back
#define mp make_pair
#define inf 0x3f3f3f3f
#define eps 1e-10
#define PI acos(-1.0)
typedef pair<int,int> PII;
const ll mod = 1e9+7;
const int N = 1e6+10;

ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
ll qp(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
int to[4][2]={{-1,0},{1,0},{0,-1},{0,1}};

int n,m,ct[3005],tp[3005],id[3005],vs[3005];
ll c[3005],ans,s;
///vector< PII> v[3005];
vector<int> v[3005];
struct nd{
    int a,b;
}p[3005];
bool cmp(nd x,nd y) {
    return x.b<y.b;
}

int main() {
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++) {
        int a,b;
        cin>>a>>b;
        ct[a]++,tp[a]++;
        p[i].a=a,p[i].b=b;
        v[a].pb(b);
    }
    for(int i=1;i<=3005;i++) sort(v[i].begin(),v[i].end());
    sort(p+1,p+n+1,cmp);
    s=ct[1];
    for(int j=1;j<=n;j++) {
        if(p[j].a==1) continue;
        ans += p[j].b;
        s++;
        ct[p[j].a]--;
        int mx=0;
        for(int i=2;i<=m;i++) mx=max(mx,ct[i]);
        if(mx<s) break;
    }
    ll res=0;
    s=tp[1];
    for(int j=1;j<=n;j++) {
        if(p[j].a==1||vs[j]) continue;
        int mx=0;
        for(int i=2;i<=m;i++) mx=max(mx,tp[i]);
        if(mx<s) break;
        if(mx==s+1) {
            ll tmp=inf,ps=0;
            for(int k=2;k<=m;k++) {
                if(tp[k]==mx && v[k][id[k]]<tmp) {
                    tmp=min(tmp,(ll)v[k][id[k]]);
                    ps=k;
                }
            }
            res += tmp;
            id[ps]++;
            tp[ps]--;
            s++;

            for(int k=1;k<=n;k++) {
                if(p[k].a==tmp && p[k].b==ps) {
                    vs[k]=1;
                    break;
                }
            }
            continue;
        }
        res += p[j].b;
        s++;
        tp[p[j].a]--;
        id[p[j].a]++;
    }
    cout<<min(ans,res)<<endl;
    return 0;
}


#pragma comment(linker, "/STACK:102400000,102400000")
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cassert>
#include<string>
#include<cstdio>
#include<bitset>
#include<vector>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<deque>
#include<list>
#include<set>
#include<map>
using namespace std;
#define debug test
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
#define ll long long
#define ull unsigned long long
#define pb push_back
#define mp make_pair
#define inf 0x3f3f3f3f
#define eps 1e-10
#define PI acos(-1.0)
typedef pair<int,int> PII;
const ll mod = 1e9+7;
const int N = 1e6+10;

ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
ll qp(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
int to[4][2]={{-1,0},{1,0},{0,-1},{0,1}};

int n,m,ct[3005],tp[3005],id[3005];
ll c[3005],ans,s;
///vector< PII> v[3005];
vector<int> v[3005];
struct nd{
    int a,b;
}p[3005];
bool cmp(nd x,nd y) {
    return x.b<y.b;
}

int main() {
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++) {
        int a,b;
        cin>>a>>b;
        ct[a]++,tp[a]++;
        p[i].a=a,p[i].b=b;
        v[a].pb(b);
    }
    for(int i=1;i<=3005;i++) sort(v[i].begin(),v[i].end());
    sort(p+1,p+n+1,cmp);
    s=ct[1];
    for(int j=1;j<=n;j++) {
        if(p[j].a==1) continue;
        ans += p[j].b;
        s++;
        ct[p[j].a]--;
        int mx=0;
        for(int i=2;i<=m;i++) mx=max(mx,ct[i]);
        if(mx<s) break;
    }
    ll res=0;
    s=ct[1];
    for(int j=1;j<=n;j++) {
        if(p[j].a==1) continue;
        int mx=0;
        for(int i=2;i<=m;i++) mx=max(mx,tp[i]);
        if(mx<s) break;
        if(mx==s+1) {
            ll tmp=inf;
            for(int k=2;k<=m;k++)
                if(tp[k]==mx) tmp=min(tmp,(ll)v[k][id[k]]);
            res += tmp;
            continue;
        }
        res += p[j].b;
        s++;
        tp[p[j].a]--;
        id[p[j].a]++;
    }
    cout<<min(ans,res)<<endl;
    return 0;
}


#pragma comment(linker, "/STACK:102400000,102400000")
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cassert>
#include<string>
#include<cstdio>
#include<bitset>
#include<vector>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<deque>
#include<list>
#include<set>
#include<map>
using namespace std;
#define debug test
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
#define ll long long
#define ull unsigned long long
#define pb push_back
#define mp make_pair
#define inf 0x3f3f3f3f
#define eps 1e-10
#define PI acos(-1.0)
typedef pair<int,int> PII;
const ll mod = 1e9+7;
const int N = 1e6+10;

ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
ll qp(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
int to[4][2]={{-1,0},{1,0},{0,-1},{0,1}};

int n,m,ct[3005],tp[3005],id[3005],vs[3005];
ll c[3005],ans,s;
///vector< PII> v[3005];
vector<int> v[3005];
struct nd{
    int a,b;
}p[3005];
bool cmp(nd x,nd y) {
    return x.b<y.b;
}

int main() {
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++) {
        int a,b;
        cin>>a>>b;
        ct[a]++,tp[a]++;
        p[i].a=a,p[i].b=b;
        v[a].pb(b);
    }
    for(int i=1;i<=3005;i++) sort(v[i].begin(),v[i].end());
    sort(p+1,p+n+1,cmp);
    s=ct[1];
    for(int j=1;j<=n;j++) {
        if(p[j].a==1) continue;
        ans += p[j].b;
        s++;
        ct[p[j].a]--;
        int mx=0;
        for(int i=2;i<=m;i++) mx=max(mx,ct[i]);
        if(mx<s) break;
    }
    ll res=0;
    s=ct[1];
    for(int j=1;j<=n;j++) {
        if(p[j].a==1||vs[j]) continue;
        int mx=0;
        for(int i=2;i<=m;i++) mx=max(mx,tp[i]);
        if(mx<s) break;
        if(mx==s+1) {
            ll tmp=inf,ps=0;
            for(int k=2;k<=m;k++) {
                if(tp[k]==mx && v[k][id[k]]<tmp) {
                    tmp=min(tmp,(ll)v[k][id[k]]);
                    ps=k;
                }
            }
            res += tmp;
            id[ps]++;
            tp[ps]--;
            s++;

            for(int k=1;k<=n;k++) {
                if(p[k].a==tmp && p[k].b==ps) {
                    vs[k]=1;
                    break;
                }
            }
            continue;
        }
        res += p[j].b;
        s++;
        tp[p[j].a]--;
        id[p[j].a]++;
    }
    cout<<min(ans,res)<<endl;
    return 0;
}


#pragma comment(linker, "/STACK:102400000,102400000")
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cassert>
#include<string>
#include<cstdio>
#include<bitset>
#include<vector>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<deque>
#include<list>
#include<set>
#include<map>
using namespace std;
#define debug test
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
#define ll long long
#define ull unsigned long long
#define pb push_back
#define mp make_pair
#define inf 0x3f3f3f3f
#define eps 1e-10
#define PI acos(-1.0)
typedef pair<int,int> PII;
const ll mod = 1e9+7;
const int N = 3e3+10;

ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
ll qp(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
int to[4][2]={{-1,0},{1,0},{0,-1},{0,1}};

int n,m;
struct p1{
    int id,val;
}a[N];

struct p2{
    int id,peo,val;
}b[N];

bool cmp1(p1 x,p1 y) {
    return x.val<y.val;
}

bool cmp2(p2 x,p2 y) {
    if(x.peo==y.peo) return x.val<y.val;
    return x.peo<y.peo;
}

int ct[N],tp[N],vs[N];
int main() {
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++) {
        cin>>b[i].peo>>b[i].val;
        b[i].id=a[i].id=i;
        a[i].val=b[i].val;
        ct[b[i].peo]++;
    }
    sort(a+1,a+n+1,cmp1);
    sort(b+1,b+n+1,cmp2);
    ll ans,sum,res=inf;
    for(int s=1;s<=n;s++) {
        ans=0,sum=0,mst(vs,0),mst(tp,0);
        for(int i=1;i<=n;i++) {
            if(b[i].peo==1) vs[b[i].id]=1,sum++;
            else if(ct[b[i].peo]-tp[b[i].peo]>=s) {
                sum++;
                tp[b[i].peo]++;
                vs[b[i].id]=1;
                ans+=b[i].val;
            }
        }
        for(int i=1;i<=n;i++) {
            if(sum>=s) break;
            if(!vs[a[i].id]) ans+=a[i].val,sum++;
        }
        res=min(res,ans);
    }
    cout<<res<<endl;
    return 0;
}


#pragma comment(linker, "/STACK:102400000,102400000")
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cassert>
#include<string>
#include<cstdio>
#include<bitset>
#include<vector>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<deque>
#include<list>
#include<set>
#include<map>
using namespace std;
#define debug test
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
#define ll long long
#define ull unsigned long long
#define pb push_back
#define mp make_pair
#define inf 0x3f3f3f3f
#define eps 1e-10
#define PI acos(-1.0)
typedef pair<int,int> PII;
const ll mod = 1e9+7;
const int N = 1e6+10;

ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
ll qp(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
int to[4][2]={{-1,0},{1,0},{0,-1},{0,1}};

int n,m,ct[3005],tp[3005],id[3005],vs[3005];
ll c[3005],ans,s;
///vector< PII> v[3005];
vector<int> v[3005];
struct nd{
    int a,b;
}p[3005];
bool cmp(nd x,nd y) {
    return x.b<y.b;
}

int main() {
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++) {
        int a,b;
        cin>>a>>b;
        ct[a]++,tp[a]++;
        p[i].a=a,p[i].b=b;
        v[a].pb(b);
    }
    for(int i=1;i<=3005;i++) sort(v[i].begin(),v[i].end());
    sort(p+1,p+n+1,cmp);
    s=ct[1];
    for(int j=1;j<=n;j++) {
        if(p[j].a==1) continue;
        ans += p[j].b;
        s++;
        ct[p[j].a]--;
        int mx=0;
        for(int i=2;i<=m;i++) mx=max(mx,ct[i]);
        if(mx<s) break;
    }
    ll res=0;
    s=tp[1];
    for(int j=1;j<=n;j++) {

        if(p[j].a==1||vs[j]) continue;
        int mx=0;
        for(int i=2;i<=m;i++) mx=max(mx,tp[i]);
        if(mx<s) break;
        if(mx==s+1) {

            ll tmp=inf,ps=0;
            for(int k=2;k<=m;k++) {
                if(tp[k]==mx && v[k][id[k]]<tmp) {
                    tmp=min(tmp,(ll)v[k][id[k]]);
                    ps=k;
                }
            }
            res += tmp;
            id[ps]++;
            tp[ps]--;
            s++;
            ///cout<<tmp<<" "<<ps<<endl;
            for(int k=1;k<=n;k++) {
                if(p[k].a==ps && p[k].b==tmp) {
                    vs[k]=1;
                    ///cout<<k<<endl;
                    break;
                }
            }
            j--;
            continue;
        }
        res += p[j].b;
        s++;
        tp[p[j].a]--;
        id[p[j].a]++;
        vs[j]=1;
    }
    ///cout<<res<<endl;
    cout<<min(ans,res)<<endl;
    return 0;
}
/*
5 5
2 5
2 4
2 1
3 6
3 7
*/


#pragma comment(linker, "/STACK:102400000,102400000")
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cassert>
#include<string>
#include<cstdio>
#include<bitset>
#include<vector>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<deque>
#include<list>
#include<set>
#include<map>
using namespace std;
#define debug test
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
#define ll long long
#define ull unsigned long long
#define pb push_back
#define mp make_pair
#define inf 0x3f3f3f3f
#define eps 1e-10
#define PI acos(-1.0)
typedef pair<int,int> PII;
const ll mod = 1e9+7;
const int N = 3e3+10;

ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
ll qp(ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
int to[4][2]={{-1,0},{1,0},{0,-1},{0,1}};

int n,m;
struct p1{
    int id,val;
}a[N];

struct p2{
    int id,peo,val;
}b[N];

bool cmp1(p1 x,p1 y) {
    return x.val<y.val;
}

bool cmp2(p2 x,p2 y) {
    if(x.peo==y.peo) return x.val<y.val;
    return x.peo<y.peo;
}

int ct[N],tp[N],vs[N];
int main() {
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++) {
        cin>>b[i].peo>>b[i].val;
        b[i].id=a[i].id=i;
        a[i].val=b[i].val;
        ct[b[i].peo]++;
    }
    sort(a+1,a+n+1,cmp1);
    sort(b+1,b+n+1,cmp2);
    int ans,sum,res=inf;
    for(int s=1;s<=n;s++) {
        ans=0,sum=0,mst(vs,0),mst(tp,0);
        for(int i=1;i<=n;i++) {
            if(b[i].peo==1) vs[b[i].id]=1,sum++;
            else if(ct[b[i].peo]-tp[b[i].peo]>=s) {
                sum++;
                tp[b[i].peo]++;
                vs[b[i].id]=1;
                ans+=b[i].val;
            }
        }
        for(int i=1;i<=n;i++) {
            if(sum>=s) break;
            if(!vs[a[i].id]) ans+=a[i].val,sum++;
        }
        res=min(res,ans);
    }
    cout<<res<<endl;
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
const int MAX = 3010;
typedef long long ll;
int N,M;
class Node{
public:
    int p;
    ll c;
};
Node q[MAX];
bool operator < (Node A,Node B){
    return A.c < B.c;
}
int num[MAX],now[MAX];
bool book[MAX];
ll check(int Max){
    for(int i=1;i<=M;++i)   now[i] = num[i];
    memset(book,false,sizeof(book));
    ll sum = 0;
    for(int i=1;i<=N;++i){
        if(q[i].p == 1){
            book[i] = true;
        }
        else if(now[q[i].p] < Max)   continue;
        else{
            now[q[i].p]--;
            sum += q[i].c;
            now[1]++;
            book[i] = true;
        }
    }
    if(now[1] < Max){
        for(int i=1;i<=N;++i){
            if(now[1] == Max)   break;
            if(!book[i]){
                sum += q[i].c;
                now[1]++;
                book[i] = true;
            }
        }
    }
    return sum;
}
int main(void){
    cin >> N >> M;
    for(int i=1;i<=N;++i){
        cin >> q[i].p >> q[i].c;
        num[q[i].p]++;
    }
    sort(q+1,q+1+N);
    ll res = check(1);
    for(int i=1;i<=N;++i){
        res = min(check(i),res);
      //  cout << check(i) << endl;
    }
    cout << res << endl;
    return 0;
}


#include<iostream>
#include<stdio.h>
#include<assert.h>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll nn=3e3+50;
struct node
{
    ll x,y;
}voter[nn];
ll cmp(node a,node c)
{
    return a.y<c.y;
}
int main()
{
    ll n,m;
    scanf("%lld%lld",&n,&m);
    ll number[nn];ll sumx=0;
    long long sum=0;
    ll x,y;
    for(ll i=0;i+sumx<n;)
    {
        scanf("%lld%lld",&x,&y);
        if(x!=1)
        {
            voter[i].x=x;
            number[x]++;
            voter[i].y=y;
            i++;
        }
        else {sumx++;sum+=y;}
    }
    number[1]=sumx;
    long long sum1=0;
    sort(voter,voter+n-sumx,cmp);
    for(ll i=0;i<=n/2-sumx;i++)
        sum1+=voter[i].y;
        if(n==1&&sumx!=1)sum1=voter[0].y;
        ll mark=0,queuemax=-1;
        long long sum2=0;
        long long cnt=0;
        while(mark!=1)
    {cnt++;
    assert(cnt<=3001);
    for(ll i=2;i<=m;i++)
    {
        if(queuemax<number[i])
        {mark=i;
        queuemax=number[i];}
    }
    if(queuemax<number[1])mark=1;
    else{
    for(ll i=0;i<n;i++)if(voter[i].x==mark)
        {sum2+=voter[i].y;
         voter[i].x=1;
         break;}
        number[mark]--;number[1]++;
        queuemax=0;
    }
    }
    printf("%lld\n",min(sum1,sum2));
}


#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<map>
#include<set>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;
#define mod 1000000007
const int maxn=3e3+10;
struct node{
    int id;
    ll c;
}a[maxn];
vector<node> vec[maxn];   //vec[i]表示投票选举i的人需要收买的金钱列表
int vis[maxn],visited[maxn];
bool cmp(node a,node b)
{
    return a.c<b.c;
}

int main()
{
    int n,m;
    while(cin>>n>>m)
    {
        for(int i=0;i<=n;i++)
          vec[i].clear();
        memset(vis,0,sizeof(vis));   //vis[i]表示投票选举i的票数
        for(int i=0;i<n;i++)
        {
            cin>>a[i].id>>a[i].c;
            vis[a[i].id]++;
            vec[a[i].id].push_back(node{i,a[i].c});
        }
        sort(a,a+n,cmp);
        int pos=0,blag=0;;
        for(int i=2;i<=m;i++)   //找到票数的最高值
          pos=max(pos,vis[i]);
        ll res=0;
        for(int i=0,j=0;i<pos-vis[1]+1;j++)
          if(a[j].id!=1)
            res+=a[j].c,i++;
        ll ans=res;
        while(true)
        {
            if(blag)   //blag表示是否退出的判断变量
              break;
            pos--;      //pos表示i=1之外的每个选择的投票数的最高值
            res=0;      //res表示投pp票需要的最少收买金钱数
            memset(visited,0,sizeof(visited));
            int pp=vis[1];    //pp代表需要的票数,开始的时候值为vis[1]
            for(int i=2;i<=m;i++)
              if(vis[i]>pos)     //假如i的投票数超过当前最高值，那么就需要先收买投i的一些人
                for(int j=0;j<vec[i].size()&&j<vis[i]-pos;pp++,j++)
                  res+=vec[i][j].c,visited[vec[i][j].id]=1;
            if(pp>pos)   //如果所有需要提前收买的人收买了之后的票数已经超过了最高值，那么就不必要进行下一轮了
              blag=1;
            for(int i=0;i<n&&pp<=pos;i++)  //如果没有超过最高值，那么就需要收买其他人，让票数达到最高值
              if(!visited[i]&&a[i].id!=1)
                res+=a[i].c,pp++;
            ans=min(ans,res);
        }
        cout<<ans<<endl;
    }
    return 0;
}


#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
const int nn=3e3+5;
struct node
{
    int x,y;
}voter[nn];
int cmp(node a,node c)
{
    return a.y<c.y;
}
int main()
{
    int n,m;
    cin>>n>>m;
    int number[nn];int sumx=0;
    long long sum=0;
    int x,y;
    for(int i=0;i<n;i++)
    {
        cin>>x>>y;
        if(x!=1)
        {
            voter[i].x=x;
            number[x]++;
            voter[i].y=y;
        }
        else {sumx++;sum+=y;}
    }
    number[1]=sumx;
    long long sum1=0;
    sort(voter,voter+n,cmp);
    for(int i=0;i<=n/2-sumx;i++)
        sum1+=voter[i].y;
        if(n==1&&sumx!=1)sum1=voter[0].y;
        int mark=0,queuemax=-1;
        long long sum2=0;
        while(mark!=1)
    {for(int i=2;i<=m;i++)
    {
        if(queuemax<number[i])
        {mark=i;
        queuemax=number[i];}
    }
    if(queuemax<number[1])mark=1;
    else{
    for(int i=0;i<n;i++)if(voter[i].x==mark)
        {sum2+=voter[i].y;
         voter[i].x=1;
         break;}
        number[mark]--;number[1]++;
        queuemax=0;
    }
    }
    cout<<min(sum1,sum2)<<endl;
}


#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
const int nn=3e3+5;
struct node
{
    int x,y;
}voter[nn];
int cmp(node a,node c)
{
    return a.y<c.y;
}
int main()
{
    int n,m;
    cin>>n>>m;
    int number[nn];int sumx=0;
    long long sum=0;
    int x,y;
    for(int i=0;i+sumx<n;)
    {
        cin>>x>>y;
        if(x!=1)
        {
            voter[i].x=x;
            number[x]++;
            voter[i].y=y;
            i++;
        }
        else {sumx++;sum+=y;}
    }
    number[1]=sumx;
    long long sum1=0;
    sort(voter,voter+n-sumx,cmp);
    for(int i=0;i<=n/2-sumx;i++)
        sum1+=voter[i].y;
        if(n==1&&sumx!=1)sum1=voter[0].y;
        int mark=0,queuemax=-1;
        long long sum2=0;
        while(mark!=1)
    {for(int i=2;i<=m;i++)
    {
        if(queuemax<number[i])
        {mark=i;
        queuemax=number[i];}
    }
    if(queuemax<number[1])mark=1;
    else{
    for(int i=0;i<n;i++)if(voter[i].x==mark)
        {sum2+=voter[i].y;
         voter[i].x=1;
         break;}
        number[mark]--;number[1]++;
        queuemax=0;
    }
    }
    cout<<min(sum1,sum2)<<endl;
}


#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll nn=3e3+50;
struct node
{
    ll x,y;
}voter[nn];
ll cmp(node a,node c)
{
    return a.y<c.y;
}
int main()
{
    ll n,m;
    scanf("%lld%lld",&n,&m);
    ll number[nn];ll sumx=0;
    long long sum=0;
    ll x,y;
    for(ll i=0;i+sumx<n;)
    {
        scanf("%lld%lld",&x,&y);
        if(x!=1)
        {
            voter[i].x=x;
            number[x]++;
            voter[i].y=y;
            i++;
        }
        else {sumx++;sum+=y;}
    }
    number[1]=sumx;
    long long sum1=0;
    sort(voter,voter+n-sumx,cmp);
    for(ll i=0;i<=n/2-sumx;i++)
        sum1+=voter[i].y;
        if(n==1&&sumx!=1)sum1=voter[0].y;
        ll mark=0,queuemax=-1;
        long long sum2=0;
        long long cnt=0;
        while(mark!=1)
    {cnt++;
    assert(cnt<=3001);
    for(ll i=2;i<=m;i++)
    {
        if(queuemax<number[i])
        {mark=i;
        queuemax=number[i];}
    }
    if(queuemax<number[1])mark=1;
    else{
    for(ll i=0;i<n;i++)if(voter[i].x==mark)
        {sum2+=voter[i].y;
         voter[i].x=1;
         break;}
        number[mark]--;number[1]++;
        queuemax=0;
    }
    }
    printf("%lld\n",min(sum1,sum2));
}


#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll nn=3e3+50;
struct node
{
    ll x,y;
}voter[nn];
ll cmp(node a,node c)
{
    return a.y<c.y;
}
int main()
{
    ll n,m;
    scanf("%lld%lld",&n,&m);
    ll number[nn];ll sumx=0;
    long long sum=0;
    ll x,y;
    for(ll i=0;i+sumx<n;)
    {
        scanf("%lld%lld",&x,&y);
        if(x!=1)
        {
            voter[i].x=x;
            number[x]++;
            voter[i].y=y;
            i++;
        }
        else {sumx++;sum+=y;}
    }
    number[1]=sumx;
    long long sum1=0;
    sort(voter,voter+n-sumx,cmp);
    for(ll i=0;i<=n/2-sumx;i++)
        sum1+=voter[i].y;
        if(n==1&&sumx!=1)sum1=voter[0].y;
        ll mark=0,queuemax=-1;
        long long sum2=0;
        long long cnt=0;
        while(mark!=1)
    {cnt++;
    for(ll i=2;i<=m;i++)
    {
        if(queuemax<number[i])
        {mark=i;
        queuemax=number[i];}
    }
    if(queuemax<number[1])mark=1;
    else{
    for(ll i=0;i<n;i++)if(voter[i].x==mark)
        {sum2+=voter[i].y;
         voter[i].x=1;
         break;}
        number[mark]--;number[1]++;
        queuemax=0;
    }
    }
    assert(cnt<=3000);
    printf("%lld\n",min(sum1,sum2));
}


#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll nn=3e3+50;
struct node
{
    ll x,y;
}voter[nn];
ll cmp(node a,node c)
{
    return a.y<c.y;
}
int main()
{
    ll n,m;
    scanf("%lld%lld",&n,&m);
    ll number[nn];ll sumx=0;
    long long sum=0;
    ll x,y;
    for(ll i=0;i+sumx<n;)
    {
        scanf("%lld%lld",&x,&y);
        if(x!=1)
        {
            voter[i].x=x;
            number[x]++;
            voter[i].y=y;
            i++;
        }
        else {sumx++;sum+=y;}
    }
    number[1]=sumx;
    long long sum1=0;
    sort(voter,voter+n-sumx,cmp);
    for(ll i=0;i<=n/2-sumx;i++)
        sum1+=voter[i].y;
        if(n==1&&sumx!=1)sum1=voter[0].y;
        ll mark=0,queuemax=-1;
        long long sum2=0;
        while(mark!=1)
    {for(ll i=2;i<=m;i++)
    {
        if(queuemax<number[i])
        {mark=i;
        queuemax=number[i];}
    }
    if(queuemax<number[1])mark=1;
    else{
    for(ll i=0;i<n;i++)if(voter[i].x==mark)
        {sum2+=voter[i].y;
         voter[i].x=1;
         break;}
        number[mark]--;number[1]++;
        queuemax=0;
    }
    }
    printf("%lld\n",min(sum1,sum2));
}


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

using namespace std;

#define rep(ix, nx) for (int ix = 0; ix < nx; ix++)
#define all(x) x.begin(), x.end()

#define maxn 3000 + 5

typedef long long ll;

vector<int> costs[maxn];
vector<pair<int, int> > all_costs;
int n, m;

ll price_to_get_votes_and_win(int x) {
  ll res = 0;
  int cur_votes = costs[0].size();
  int diff = x - cur_votes;

  int touched[maxn];
  memset(touched, 0, sizeof touched);

  for (int i = 1; i < m; i++) {
    auto & v = costs[i];
    int num_to_take = max(0, (int) (v.size() - x + 1));
    if (diff < num_to_take) {
      return -1;
    }
    if (num_to_take > 0) {
      touched[i] += num_to_take;
    }
    diff -= num_to_take;
    for (int j = 0; j < num_to_take; j++) {
      res += v[j];
    }
  }

  for (auto c: all_costs) {
    if (diff == 0) {
      break;
    }
    if (touched[c.second]) {
      touched[c.second]--;
      continue;
    }
    diff--;
    res += c.first;
  }

  if (diff != 0) {
    return -1;
  }

  return res;
}

int main() {
  cin >> n >> m;
  rep(i, n) {
    int x, y;
    cin >> x >> y;
    costs[x - 1].push_back(y);
    if (x != 1) {
      pair<int, int> cost = {y, x - 1};
      all_costs.push_back(cost);
    }
  }
  sort(all(all_costs));
  rep(i, m) {
    sort(all(costs[i]));
  }
  int cur_votes = costs[0].size();
  ll min_price = -1;
  for (int votes = cur_votes; votes <= n; votes++) {
    ll result = price_to_get_votes_and_win(votes);
    // cout << "for votes: " << votes << " : " << result << " was the price" << endl;
    if (result == -1) continue;
    if (min_price == -1 || result < min_price) {
      min_price = result;
    }
  }
  cout << min_price << endl;
  return 0;
}


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

using namespace std;

#define rep(ix, nx) for (int ix = 0; ix < nx; ix++)
#define all(x) x.begin(), x.end()

#define maxn 3000 + 5

typedef long long ll;

vector<int> costs[maxn];
vector<pair<int, int> > all_costs;
int n, m;

ll price_to_get_votes_and_win(int x) {
  ll res = 0;
  int cur_votes = costs[0].size();
  int diff = x - cur_votes;

  char touched[maxn];
  memset(touched, 0, sizeof touched);

  for (int i = 1; i < m; i++) {
    auto & v = costs[i];
    int num_to_take = max(0, (int) (v.size() - x + 1));
    if (diff < num_to_take) {
      return -1;
    }
    if (num_to_take > 0) {
      touched[i] = 1;
    }
    diff -= num_to_take;
    for (int j = 0; j < num_to_take; j++) {
      res += v[j];
    }
  }

  for (auto c: all_costs) {
    if (diff == 0) {
      break;
    }
    if (touched[c.second]) {
      continue;
    }
    diff--;
    res += c.first;
  }

  if (diff != 0) {
    return -1;
  }

  return res;
}

int main() {
  cin >> n >> m;
  rep(i, n) {
    int x, y;
    cin >> x >> y;
    costs[x - 1].push_back(y);
    if (x != 1) {
      pair<int, int> cost = {y, x - 1};
      all_costs.push_back(cost);
    }
  }
  sort(all(all_costs));
  rep(i, m) {
    sort(all(costs[i]));
  }
  int cur_votes = costs[0].size();
  ll min_price = -1;
  for (int votes = cur_votes; votes <= n; votes++) {
    ll result = price_to_get_votes_and_win(votes);
    if (result == -1) continue;
    if (min_price == -1 || result < min_price) {
      min_price = result;
    }
  }
  cout << min_price << endl;
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define rep(ix, nx) for(int ix = 0; ix < nx; ix++)
typedef long long ll;

struct cpi {
  int cost, pref, index;

  bool operator < (const cpi& other) const {
    if (other.cost == cost && other.pref == pref) return index < other.index;
    if (other.cost == cost) return pref < other.pref;
    return cost < other.cost;
  }
};

int main() {
  int n, m;
  cin >> n >> m;
  vector<int> prices[m];
  for (int i = 0; i < n; i++) {
    int country, price;
    cin >> country >> price;
    prices[country - 1].push_back(price);
  }

  int indexes[m], cur_votes[m];
  for (int i = 0; i < m; i++) {
    indexes[i] = 0;
    cur_votes[i] = prices[i].size();
    sort(prices[i].begin(), prices[i].end());
  }

  int our_votes = prices[0].size();
  long long money_spent = 0;

  while (true) {
    set<int> iw; // indices_with_most_votes;
    int max_votes = -1;
    for (int i = 1; i < m; i++) {
      int cv = cur_votes[i];
      if (cv > max_votes && cv >= our_votes) max_votes = cv;
    }
    if (max_votes == -1) break;

    for (int i = 1; i < m; i++) {
      if (cur_votes[i] == max_votes) iw.insert(i);
    }

    vector<cpi> non_ideals;
    vector<cpi> ideals;
    for (int i = 1; i < m; i++) {
      for (int j = 0; j < 2 && (indexes[i] + j < prices[i].size()); j++) {
        int ni = indexes[i] + j;
        int pref = 1;
        if (iw.find(i) != iw.end()) pref = 0;
        cpi v = {prices[i][ni], pref, i};
        if (pref) {
          non_ideals.push_back(v);
        } else {
          ideals.push_back(v);
        }
      }
    }

    sort(non_ideals.begin(), non_ideals.end());
    sort(ideals.begin(), ideals.end());

    auto ii = ideals[0];

    if (non_ideals.size() > 0) {
      cpi ni = non_ideals[0];
      if (ni.cost * 2 < ii.cost) {
        int idx = ni.index;
        our_votes++;
        cur_votes[idx]--;
        indexes[idx]++;
        money_spent += (long long) ni.cost;
        continue;
      }
    }

    our_votes++;
    cur_votes[ii.index]--;
    indexes[ii.index]++;
    money_spent += (long long) ii.cost;
  }

  cout << money_spent << endl;
  return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

#define rep(ix, nx) for (int ix = 0; ix < nx; ix++)
#define all(x) x.begin(), x.end()

#define maxn 3000 + 5

typedef long long ll;

vector<int> costs[maxn];
vector<pair<int, int> > all_costs;
int n, m;

ll price_to_get_votes_and_win(int x) {
  ll res = 0;
  int cur_votes = costs[0].size();
  int diff = x - cur_votes;

  char touched[maxn];
  memset(touched, 0, sizeof touched);

  for (int i = 1; i < m; i++) {
    auto & v = costs[i];
    int num_to_take = max(0, (int) (v.size() - x + 1));
    if (diff < num_to_take) {
      return -1;
    }
    if (num_to_take > 0) {
      touched[i] = 1;
    }
    diff -= num_to_take;
    for (int j = 0; j < num_to_take; j++) {
      res += v[j];
    }
  }

  for (auto c: all_costs) {
    if (diff == 0) {
      break;
    }
    if (touched[c.second]) {
      continue;
    }
    diff--;
    res += c.first;
  }

  if (diff != 0) {
    return -1;
  }

  return res;
}

int main() {
  cin >> n >> m;
  rep(i, n) {
    int x, y;
    cin >> x >> y;
    costs[x - 1].push_back(y);
    if (x != 1) {
      pair<int, int> cost = {y, x - 1};
      all_costs.push_back(cost);
    }
  }
  sort(all(all_costs));
  rep(i, m) {
    sort(all(costs[i]));
  }
  int cur_votes = costs[0].size();
  ll min_price = -1;
  for (int votes = cur_votes; votes <= n; votes++) {
    ll result = price_to_get_votes_and_win(votes);
    if (result == -1) continue;
    if (min_price == -1 || result < min_price) {
      min_price = result;
    }
  }
  cout << min_price << endl;
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define rep(ix, nx) for(int ix = 0; ix < nx; ix++)
typedef long long ll;

struct cpi {
  int cost, pref, index;

  bool operator < (const cpi& other) const {
    if (other.cost == cost && other.pref == pref) return index < other.index;
    if (other.cost == cost) return pref < other.pref;
    return cost < other.cost;
  }
};

int main() {
  int n, m;
  cin >> n >> m;
  vector<int> prices[m];
  for (int i = 0; i < n; i++) {
    int country, price;
    cin >> country >> price;
    prices[country - 1].push_back(price);
  }

  int indexes[m], cur_votes[m];
  for (int i = 0; i < m; i++) {
    indexes[i] = 0;
    cur_votes[i] = prices[i].size();
    sort(prices[i].begin(), prices[i].end());
  }

  int our_votes = prices[0].size();
  long long money_spent = 0;

  while (true) {
    set<int> iw; // indices_with_most_votes;
    int max_votes = -1;
    for (int i = 1; i < m; i++) {
      int cv = cur_votes[i];
      if (cv > max_votes && cv >= our_votes) max_votes = cv;
    }
    if (max_votes == -1) break;

    for (int i = 1; i < m; i++) {
      if (cur_votes[i] == max_votes) iw.insert(i);
    }

    vector<cpi> non_ideals;
    vector<cpi> ideals;
    for (int i = 1; i < m; i++) {
      for (int j = 0; j < 2 && (indexes[i] + j < prices[i].size()); j++) {
        int ni = indexes[i] + j;
        int pref = 1;
        if (iw.find(i) != iw.end()) pref = 0;
        cpi v = {prices[i][ni], pref, i};
        if (pref) {
          non_ideals.push_back(v);
        } else {
          ideals.push_back(v);
        }
      }
    }

    sort(non_ideals.begin(), non_ideals.end());
    sort(ideals.begin(), ideals.end());

    auto ii = ideals[0];

    if (non_ideals.size() > 0) {
      cpi ni = non_ideals[0];
      if ((ni.cost * 2 < ii.cost) || ((iw.size() != 1) && (ni.cost < ii.cost))) {
        int idx = ni.index;
        our_votes++;
        cur_votes[idx]--;
        indexes[idx]++;
        money_spent += (long long) ni.cost;
        continue;
      }
    }

    our_votes++;
    cur_votes[ii.index]--;
    indexes[ii.index]++;
    money_spent += (long long) ii.cost;
  }

  cout << money_spent << endl;
  return 0;
}


#include <bits/stdc++.h>

#define INF 0x3f3f3f3f

using namespace std;
int n, m;
int num[3005];
int vis[3005];
struct people {
    int v, id;
    long long c;
    bool friend operator < (const people & a, const people & b) {
        return a.c < b.c;
    }
} p[3005], lis[3005][3005];
int main() {
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++)
        scanf("%d%I64d", &p[i].v, &p[i].c);
    sort(p + 1, p + 1 + n);
    for(int i = 1; i <= n; i++) {
        p[i].id = i;
        num[p[i].v]++;
        lis[p[i].v][num[p[i].v]].c = p[i].c;
        lis[p[i].v][num[p[i].v]].id = p[i].id;
        lis[p[i].v][num[p[i].v]].v = p[i].v;
    }
    for(int i = 1; i <= m; i++) {
        if(!num[i])
            continue;
        sort(lis[i] + 1, lis[i] + num[i]);
    }
    long long ans = INF;
    for(int i = num[1]; i <= n / 2 + 1; i++) {
        int t = num[1];
        long long money = 0;
        bool sign = 0;
        memset(vis, 0, sizeof(vis));
        for(int j = 2; j <= m; j++) {
            if(num[j] >= i) {
                for(int k = 1; 1; k++) {
                    money += lis[j][k].c;
                    vis[lis[j][k].id] = 1;
                    if(num[j] - k < i) {
                        t += k;
                        break;
                    }
                }
            }
            if(t > i) {
                sign = 1;
                break;
            }
        }
        if(sign)
            continue;
        for(int j = 1; j <= n && t < i; j++) {
            if(p[j].v == 1)
                continue;
            if(vis[p[j].id])
                continue;
            t++;
            money += p[j].c;
            vis[p[j].id] = 1;
        }
        ans = min(ans, money);
    }
    printf("%I64d", ans);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define N 3010
#define ll long long
#define Pli pair<ll ,int >
#define MPli(x,y) make_pair((ll)x,y)
vector<Pli> vec[N];
vector<Pli> svec;
bool v[N];
int n,m;
ll check(int x){
	memset(v,0,sizeof(v));
	ll sum=0;
	int num=0;
	for (int i=2;i<=n;i++)
		for (int j=vec[i].size()-x-1;j>=0;j--){
			num++;
			sum+=vec[i][j].first;
			v[vec[i][j].second]=true;
		}
	int s=x-num-vec[1].size();
	for (int i=0,snum=0;snum<=s&&i<svec.size();i++)
		if (!v[svec[i].second]) snum++,sum+=svec[i].first;
	return sum;
}
int main(){
	scanf("%d%d",&m,&n);
	for (int i=1,x,y;i<=m;i++){
		scanf("%d%d",&x,&y);
		vec[x].push_back(MPli(y,i));
		if (x!=1) svec.push_back(MPli(y,i));
	}
	sort(svec.begin(),svec.end());
	for (int i=2;i<=n;i++) sort(vec[i].begin(),vec[i].end());
	ll ans=2147483647LL*N;
	for (int i=0;i<=m;i++) ans=min(ans,check(i));
	printf("%I64d\n",ans);
    return 0;
}


//#include "pch.h"
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <queue>
#include <algorithm>
#include <map>
#include <cmath>
#include <iomanip>
#include <math.h>
#define INF 99999999
using namespace std;
typedef long long LL;
const int maxn = 3005;
bool v[maxn];
int n, m;
LL ans = 3 *1e13;
vector<pair<int, int> > s[maxn];
int vis[maxn];
vector<pair<int, int> > a;
int main() {
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		int x, y;
		cin >> x >> y;
		s[x].push_back(make_pair(y, i));
		if (x!=1 )  a.push_back(make_pair(y, i));
	}
	sort(a.begin(), a.end());
	int N = a.size();
	int s0 = s[1].size();
	for (int i = 1; i <= m; i++) {
		if (s[i].size() >= s0) sort(s[i].begin(), s[i].end());
	}
	for (int i = 0; i <= N; i++) {
		LL now = 0; memset(v, 0, sizeof(v));
		LL ret = 0;
		int f = 1;
		for (int k = 2; k <= m; k++) {
			if (s[k].size() >= s0+i) {
				if (s[k].size() - (i + s0) + 1 + ret > i) { f = 0; break; }
				ret += s[k].size() - (i + s0) + 1;
				for (int j = 0; j <s[k].size() - (i + s0)+1; j++) {
					int temp = s[k][j].second;
					now += s[k][j].first; v[temp] = 1;
				}
			}
		}
		if (f&&ret!=i) {
			int j = 0, k = 0;
			while (1)
			{
				if (j == N)
				{
					f = 0;
					break;
				}
				if (!v[a[j].second]) {
					now += a[j].first; k++;
					if (k == i - ret) break;
				}
				j++;
			}
		}
		if (f)  ans = min(ans, now);
	}
	cout << ans << endl;
}


#include <bits/stdc++.h>

#define INF 0x3f3f3f3f

using namespace std;
int n, m;
int num[3005];
int vis[3005];
struct people {
    int v, id;
    long long c;
    bool friend operator < (const people & a, const people & b) {
        return a.c < b.c;
    }
} p[3005], lis[3005][3005];
int main() {
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++)
        scanf("%d%I64d", &p[i].v, &p[i].c);
    sort(p + 1, p + 1 + n);
    for(int i = 1; i <= n; i++) {
        p[i].id = i;
        num[p[i].v]++;
        lis[p[i].v][num[p[i].v]].c = p[i].c;
        lis[p[i].v][num[p[i].v]].id = p[i].id;
        lis[p[i].v][num[p[i].v]].v = p[i].v;
    }
    for(int i = 1; i <= m; i++) {
        if(!num[i])
            continue;
        sort(lis[i] + 1, lis[i] + num[i]);
    }
    long long ans = INF;
    for(int i = num[1]; i <= n; i++) {
        int t = num[1];
        long long money = 0;
        bool sign = 0;
        memset(vis, 0, sizeof(vis));
        for(int j = 2; j <= m; j++) {
            if(num[j] >= i) {
                for(int k = 1; 1; k++) {
                    money += lis[j][k].c;
                    vis[lis[j][k].id] = 1;
                    if(num[j] - k < i) {
                        t += k;
                        break;
                    }
                }
            }
            if(t > i) {
                sign = 1;
                break;
            }
        }
        if(sign)
            continue;
        for(int j = 1; j <= n && t < i; j++) {
            if(p[j].v == 1)
                continue;
            if(vis[p[j].id])
                continue;
            t++;
            money += p[j].c;
        }
        ans = min(ans, money);
    }
    printf("%I64d", ans);
    return 0;
}


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
struct sss
{
    int id;
    int cost;
}a[3001];
int f[3001];
int g[3001];
int cmp(struct sss x,struct sss y)
{
    return x.cost<y.cost;
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&a[i].id,&a[i].cost);
        f[a[i].id]++;
    }
    long long sum=999999999999,sum2=0,ans;
    sort(a+1,a+n+1,cmp);
    for(int i=f[1];i<=n;i++)
    {
        sum2=0;
        ans=0;
        for(int j=2;j<=m;j++)
        {
            if(f[j]>=i)
            {
                g[j]=f[j]-i+1;
                sum2+=g[j];
            }
            else g[j]=0;
        }
        if(i-f[1]<sum2) continue;
        sum2=i-f[1]-sum2;
        for(int j=1;j<=n;j++)
        {
            if(g[a[j].id]!=0)
            {
                g[a[j].id]--;
                ans+=a[j].cost;
            }
            else{
                if(sum2!=0&&a[j].id!=1)
                {
                    sum2--;
                    ans+=a[j].cost;
                }
            }
        }
        sum=min(sum,ans);
    }
    cout<<sum;
}


#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>

using namespace std;

typedef long long ll;

const int MAXN = 3005;

struct voter{
	ll p;
	ll c;
}a[MAXN];

bool cmp(voter a, voter b){
	return a.c < b.c;
}

ll cnt[MAXN];
ll mcnt[MAXN];
bool vis[MAXN];

int main(){
	ios::sync_with_stdio(false);
	ll n, m;
	cin >> n >> m;
	for (ll i = 1; i <= n; ++i){
		cin >> a[i].p >> a[i].c;
		cnt[a[i].p]++;
	}
	sort(a + 1, a + n + 1, cmp);
	ll ans = 0x7fffffffffffffff;
	int flag = 0;
	for (ll i = cnt[1]; i <= (n - 1) / 2 + 1; ++i) {
		flag = 1;
		memset(vis, 0, sizeof vis);
		memset(mcnt, 0, sizeof mcnt);
		ll ci = 0;
		ll sum = 0;
		for (int j = 1; j <= n; ++j){
			ll np = a[j].p;
			ll nc = a[j].c;
			if (np == 1){
				ci++;
				vis[j] = 1;
				continue;
			}
			else{
				if (cnt[np] - mcnt[np] >= i){
					sum += nc;
					mcnt[np]++;
					vis[j] = 1;
					ci++;
				}
			}
		}
		if (ci < i){
			for (int j = 1; j <= n; ++j){
				if (!vis[j]){
					sum += a[j].c;
					ci++;
				}
				if (ci == i)
					break;
			}
		}
		if (ans>sum)
			ans = sum;
	}
	if (!flag)
		ans = 0;
	cout << ans << endl;
	return 0;
}


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

using namespace std;

const int MAXN = 3005;

struct voter{
	int p;
	int c;
}a[MAXN];

bool cmp(voter a, voter b){
	return a.c < b.c;
}

int cnt[MAXN];
int mcnt[MAXN];
bool vis[MAXN];

int main(){
	ios::sync_with_stdio(false);
	int n, m;
	cin >> n >> m;
	for (int i = 1; i <= n; ++i){
		cin >> a[i].p >> a[i].c;
		cnt[a[i].p]++;
	}
	sort(a, a + n, cmp);
	int ans = 0x3f3f3f3f;
	for (int i = cnt[1]; i <= (n - 1) / 2 + 1; ++i) {
		memset(vis, 0, sizeof vis);
		memset(mcnt, 0, sizeof mcnt);
		int ci = 0;
		int sum = 0;
		for (int j = 1; j <= n; ++j){
			int np = a[j].p;
			int nc = a[j].c;
			if (np == 1){
				ci++;
				vis[j] = 1;
			}
			else{
				if (cnt[np] - mcnt[np] >= i){
					sum += nc;
					mcnt[np]++;
					vis[j] = 1;
					ci++;
				}
			}
		}
		if (ci < i){
			for (int j = 1; j <= n; ++j){
				if (!vis[j]){
					sum += a[j].c;
					ci++;
				}
				if (ci == i)
					break;
			}
		}
		if (ans>sum)
			ans = sum;
	}
	cout << ans << endl;
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN = 10000 + 5;
vector<ll > a[MAXN];
ll cnt[MAXN],bk[MAXN];
pair<ll , ll> p[MAXN];
int main()
{
	int n,m;
	cin>>m>>n;
	for(int j = 0; j<n; j++) {
		scanf("%lld%lld",&p[j].second,&p[j].first);
		p[j].second--;cnt[p[j].second]++;
	}
	sort(p,p+n);
	ll ans = LLONG_MAX;
	for(int v = 1; v <=n; v++) {
		memset(cnt,0,sizeof(cnt));
		memset(bk,0,sizeof(bk));
		for(int j = 0; j<n; j++) cnt[p[j].second]++;
		ll chu = cnt[0],cost = 0;
		for(int i = 0; i<n; i++) {
			if(p[i].second !=0 && cnt[p[i].second ] >= v) {
				cost += p[i].first;
				chu++;
				cnt[p[i].second]--;
				bk[i] = 1;
			}
		}
		for(int i = 0; i<n; i++) {
			if(p[i].second !=0 && chu < v && bk[i] == 0) {
				chu++;
				cost += p[i].first;
			}
		}
		ans = min(ans,cost);
	}
	printf("%lld\n",ans);
	return 0 ;
}


#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <set>
#include <map>
#include <cctype>
#include <cmath>
#define eps 1e-8
#define INF 0x3f3f3f3f
#define MOD 1e9+7
#define PI acos(-1)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<11
#define mem(a) memset(a,0,sizeof(a))
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <cstring>
#include <string>
#include <set>
#include <queue>

#define ll long long
using namespace std;
bool vis[4000];
struct peo {
    int id;
    int cost;

    peo(int id, int cost) : id(id), cost(cost) {}
};
vector<peo> G[4000];
vector<peo> a;
int n, m;
bool cmp(peo &a, peo &b) {
    return a.cost < b.cost;
}
int main() {

    cin >> n >> m;
    ll sum = 0;
    for (int i = 1; i <= n; ++i) {
        int party, cost;
        cin >> party >> cost;
        if (party != 1) {
            a.push_back(peo(i, cost));
            G[party].push_back(peo(i, cost));
        } else {
            ++sum;
        }
    }
    sort(a.begin(), a.end(), cmp);
    for (int i = 1; i <= m; ++i) {
        sort(G[i].begin(), G[i].end(), cmp);
    }
    ll mincost = static_cast<long long int>(1e18 + 7);
    for (int k = 0; k < n; ++k) {
        memset(vis, 0, sizeof(vis));
        ll ans = 0;
        int t = 0;
        for (int i = 2; i <= m; ++i) {
            int newTicket = 0;
            while (G[i].size() - newTicket > k) {
                ans += G[i][newTicket].cost;
                vis[G[i][newTicket].id] = 1;
                ++newTicket;
            }
            t += newTicket;
        }
        int pos = 0;
        while (t + sum <= k) {
            if (!vis[a[pos].id]) {
                ans += a[pos].cost;
                ++t;
                vis[a[pos].id] = 1;
            }
            ++pos;
        }
        mincost = min(mincost, ans);
    }
    printf("%I64d\n", mincost);
    return 0;
}


#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int maxn=10000+5;
struct Vote{
	ll p;
	ll c;
	const bool operator <(const Vote &b)const{
		return c<b.c;
	}
};

map<ll,ll>cnt;
ll vis[maxn];
Vote p[maxn];
int n,m;
int main()
{
	cin>>m>>n;

	for(int i=0;i<n;i++){
		scanf("%lld%lld",&p[i].p,&p[i].c);
		p[i].p--;
	}

	sort(p,p+n);
	ll ans=LLONG_MAX;
	for(int v=1;v<=n;v++){
		cnt.clear();
		memset(vis,0,sizeof(vis));
		for(int i=0;i<n;i++)cnt[p[i].p]++;
		ll init=cnt[0],cost=0;
		for(int i=0;i<n;i++){
			if(p[i].p!=0 && cnt[p[i].p]>=v){
				cost+=p[i].c;
				cnt[p[i].p]--;
				init++;
				vis[i]=1;
			}
		}
		for(int i=0;i<n;i++){
			if(p[i].p!=0 && vis[i]==0 && init<v){
				cost+=p[i].c;
				init++;
			}
		}
		ans=min(ans,cost);
	}
	printf("%lld\n",ans);
	return 0;
}


#include<stdio.h>
#include<algorithm>
#include<queue>
#include<string.h>
#include<climits>
using namespace std;
int n,m;
int num[3005];
int vis[3005];
struct people
{
	int v,id;
	long long c;
	bool friend operator < (people a,people b){
		return a.c<b.c;
	}
}p[3005],lis[3005][3005];
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		scanf("%d%I64d",&p[i].v,&p[i].c);
	sort(p+1,p+1+n);
	for(int i=1;i<=n;i++)
	{
		p[i].id=i;
		num[p[i].v]++;
		lis[p[i].v][num[p[i].v]].c=p[i].c;
		lis[p[i].v][num[p[i].v]].id=p[i].id;
		lis[p[i].v][num[p[i].v]].v=p[i].v;
	}
	for(int i=1;i<=m;i++)
	{
		if(!num[i]) continue;
		sort(lis[i]+1,lis[i]+num[i]);
	}
	long long ans=LONG_LONG_MAX;
	for(int i=num[1];i<=n/2+1;i++)
	{
		int t=num[1];
		long long money=0;
		bool sign=0;
		memset(vis,0,sizeof(vis));
		for(int j=2;j<=m;j++)
		{
			if(num[j]>=i)
			{
				for(int k=1;1;k++)
				{
					money+=lis[j][k].c;
					vis[lis[j][k].id]=1;
					if(num[j]-k<i)
					{
						t+=k;
						break;
					}
				}
			}
			if(t>i)
			{
				sign=1;
				break;
			}
		}
		if(sign)continue;
		for(int j=1;j<=n&&t<i;j++)
		{
			if(p[j].v==1) continue;
			if(vis[p[j].id]) continue;
			t++;
			money+=p[j].c;
		}
		ans=min(ans,money);
	}
	printf("%I64d",ans);
	return 0;
}


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

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

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

long long ans = 1e18;

int n, m;

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

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

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


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

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

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

long long ans = 1e18;

int n, m;

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

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

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


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

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

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

long long ans = 1e18;

int n, m;

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

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

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


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

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

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

long long ans = 1e18;

int n, m;

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

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

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


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

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

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

long long ans = 1e18;

int n, m;

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

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

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


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

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

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

long long ans = 1e18;

int n, m;

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

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

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