// Slower C++ solution:
#include<iostream>

#include<vector>

#include<queue>



using namespace std;



vector<int>ve[120000];



int main(){

	ios::sync_with_stdio(false);

	cin.tie(0);cout.tie(0);

	int n,k;

	cin>>n>>k;

	int x,y;

	for(int i=0;i<n;i++){

		cin>>x>>y;

		if(x>k) continue;

		int tt=k-x+1;

		ve[tt].push_back(y);

	}

	

	priority_queue<int>q;

	int ans=0;

	for(int i=k;i>=1;i--){

		for(int j=0;j<ve[i].size();j++) q.push(ve[i][j]);

		if(!q.empty()){

			ans+=q.top();

			q.pop();	

		}

	}

	cout<<ans<<"\n";

	

	return 0;

} 

// Faster C++ solution for the same problem (measured speedup: 1.1428313091594384x):
/*بِسْمِ اللَّهِ الرَّحْمَنِ الرَّحِيم*/

#include <bits/stdc++.h>

using namespace std;

#define FASTIO ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);

typedef long long ll;

const double PI = acos(-1.0);

const ll mod = 1e9 + 7;



inline void normal(ll &a) { a %= mod; (a < 0) && (a += mod); }

inline ll modMul(ll a, ll b) { a %= mod, b %= mod; normal(a), normal(b); return (a * b) % mod; }

inline ll modAdd(ll a, ll b) { a %= mod, b %= mod; normal(a), normal(b); return (a + b) % mod; }

inline ll modSub(ll a, ll b) { a %= mod, b %= mod; normal(a), normal(b); a -= b; normal(a); return a; }

inline ll modPow(ll b, ll p) { ll r = 1; while (p) { if (p & 1) r = modMul(r, b); b = modMul(b, b); p >>= 1; } return r; }

inline ll modInverse(ll a) { return modPow(a, mod - 2); }

inline ll modDiv(ll a, ll b) { return modMul(a, modInverse(b)); }





/* for Random Number generate

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

*/

///**

template < typename F, typename S >

ostream& operator << ( ostream& os, const pair< F, S > & p ) {

  return os << "(" << p.first << ", " << p.second << ")";

}



template < typename T >

ostream &operator << ( ostream & os, const vector< T > &v ) {

  os << "{";

  for (auto it = v.begin(); it != v.end(); ++it) {

    if ( it != v.begin() ) os << ", ";

    os << *it;

  }

  return os << "}";

}



template < typename T >

ostream &operator << ( ostream & os, const set< T > &v ) {

  os << "[";

  for (auto it = v.begin(); it != v.end(); ++it) {

    if ( it != v.begin()) os << ", ";

    os << *it;

  }

  return os << "]";

}



template < typename F, typename S >

ostream &operator << ( ostream & os, const map< F, S > &v ) {

  os << "[";

  for (auto it = v.begin(); it != v.end(); ++it) {

    if ( it != v.begin() ) os << ", ";

    os << it -> first << " = " << it -> second ;

  }

  return os << "]";

}



#define dbg(args...) do {cerr << #args << " : "; faltu(args); } while(0)



clock_t tStart = clock();

#define timeStamp dbg("Execution Time: ", (double)(clock() - tStart)/CLOCKS_PER_SEC)



void faltu () { cerr << endl; }



template <typename T>

void faltu( T a[], int n ) {

  for (int i = 0; i < n; ++i) cerr << a[i] << ' ';

  cerr << endl;

}



template <typename T, typename ... hello>

void faltu( T arg, const hello &... rest) { cerr << arg << ' '; faltu(rest...); }

// Program showing a policy-based data structure.

#include <ext/pb_ds/assoc_container.hpp> // Common file 

#include <ext/pb_ds/tree_policy.hpp>

#include <functional> // for less 

#include <iostream>

using namespace __gnu_pbds;

using namespace std;

// GNU link : https://goo.gl/WVDL6g

typedef tree<int, null_type, less_equal<int>, rb_tree_tag,

        tree_order_statistics_node_update>

        new_data_set;



// find_by_order(k) – ফাংশনটি kth ordered element এর একটা পয়েন্টার রিটার্ন করে। অর্থাৎ তুমি চাইলেই kth ইন্ডেক্সে কি আছে, সেটা জেনে ফেলতে পারছো!

// order_of_key(x) – ফাংশনটি x এলিমেন্টটা কোন পজিশনে আছে সেটা বলে দেয়।



//*//**___________________________________________________**/



const int N = 1e5 + 5;

vector<int> idx[N];



int main()

{

  FASTIO

  /*

#ifndef ONLINE_JUDGE

  freopen("in.txt", "r", stdin);

  freopen("out.txt", "w", stdout);

  freopen("error.txt", "w", stderr);

#endif

//*/

  int n, m;

  cin >> n >> m;

  priority_queue<int> PQ;

  for (int i = 0; i < n; i++) {

    int a, b;

    cin >> a >> b;

    if (m - a >= 0) idx[m - a].push_back(b);

  }

  int ans = 0;

  for (int i = m; i >= 0; i--) {

    for (auto x : idx[i])PQ.push(x);

    if ((int)PQ.size()) {

      ans += PQ.top();

      PQ.pop();

    }

  }

  cout << ans << endl;

  return 0;

}