using System;
using System.Collections.Generic;
using System.Linq;

namespace CSharpSample01
{

    //優先度付きキューのクラス
    class PriorityQueue
    {
        int H;
        int[] heap;
        const int MAX = 2000000;

        public PriorityQueue()
        {
            H = 0;
            heap = new int[MAX];
        }

        public PriorityQueue(int size)
        {
            H = size;
            heap = new int[H + 1];
        }

        public void MaxHeapfy(int p)
        {
            while (2 * p <= H)
            {
                int son_n = 2 * p;
                int son = heap[2 * p];
                if (2 * p + 1 <= H && son < heap[2 * p + 1])
                {
                    son = heap[2 * p + 1];
                    son_n++;
                }

                if (son > heap[p])
                {
                    int tmp = heap[p];
                    heap[p] = son;
                    heap[son_n] = tmp;
                }
                else
                {
                    break;
                }

                p = son_n;
            }
        }

        public void BuildMaxHeap()
        {
            for (int s = H / 2; s >= 1; s--)
            {
                MaxHeapfy(s);
            }
        }

        //キューに値を入れる
        public void Insert(int key)
        {
            H++;
            heap[H] = key;

            int son = H;

            while (son != 1)
            {
                int p = son / 2;
                if (heap[son] > heap[p])
                {
                    int tmp = heap[p];
                    heap[p] = heap[son];
                    heap[son] = tmp;
                    son /= 2;
                }
                else
                {
                    break;
                }
            }

        }

        //キュー内の最大値を取り出して削除
        public int ExtractMax()
        {
            int max = heap[1];
            heap[1] = heap[H];
            H--;

            MaxHeapfy(1);

            return max;
        }

        //キュー内の最大値を見るだけ
        //キュー内が空なら-1を返す
        public int GetMax()
        {
            if (H == 0) return -1;
            return heap[1];
        }

    }



    class Program
    {

        static long Solve(int N, int M, List<int>[] job)
        {
            //報酬の最大値
            long cnt = 0;

            PriorityQueue pq = new PriorityQueue();

            //i日後に報酬を受け取れるバイトの報酬値を優先度付きキューに入れていく
            //各iの時の最大報酬値を足す
            for (int i = 1; i <= M; i++)
            {
                foreach(int reward in job[i])
                {
                    pq.Insert(reward);
                }
                if(pq.GetMax() != -1)  //-1の時はキューが空
                {
                    cnt += pq.ExtractMax();  //取り出して消す
                }
            }

            return cnt;
        }

        static void Main(string[] args)
        {
            string[] input = Console.ReadLine().Split(' ');
            int N = int.Parse(input[0]);
            int M = int.Parse(input[1]);
           
            //job[a] := a日後に払われるバイトの報酬リスト
            List<int>[] job = new List<int>[M + 1];

            for (int i = 0; i <= M; i++)
            {
                job[i] = new List<int>();
            }

            for (int i = 0; i < N; i++)
            {
                input = Console.ReadLine().Split(' ');
                int a = int.Parse(input[0]);
                int b = int.Parse(input[1]);
                if (a <= M) job[a].Add(b);
            }

            Console.WriteLine(Solve(N, M, job));

        }
    }
}

Measured memory_bytes: 25748