function Main(input) {
  input = input.trim()
  input = input.split(" ").map(Number);
  if(Math.abs(input[0]-input[1])>Math.abs(input[0]-input[2])) console.log("B");
  else console.log("A")
}Main(require("fs").readFileSync("/dev/stdin", "utf8"));


function Main(input) {
  const numbers = input.split(' ').map(n => Number(n));
  const x = numbers[0];
  const a = numbers[1];
  const b = numbers[2];

  if (Math.abs(x - a) > Math.abs(x - b)) {
    console.log('B');
  } else {
    console.log('A');
  }
}

Main(require("fs").readFileSync("/dev/stdin", "utf8"));


'use strict'

const main = input => {
	const args = input.split('\n').map(arg => arg.split(' '))
	const x = parseInt(args[0][0], 10)
	const a = parseInt(args[0][1], 10)
	const b = parseInt(args[0][2], 10)
	if (Math.abs(a - x) < Math.abs(b - x)) console.log('A')
	else console.log('B')
}

main(require('fs').readFileSync('/dev/stdin', 'utf8'))


function main(input) {
  input = input.trim();
  const a = input.split(" ").map(Number);
  const b = a[2] - a[0];
  const c = a[1] - a[0];
  if(a[0]>a[1]){
    c = c*(-1);
  }
  if(c<b){
    console.log("A");
  }else{
    console.log("B");
  }

}
main(require("fs").readFileSync("/dev/stdin", "utf8"));


function main(input) {
  input=input.trim();
  const x = parseInt(input.split(" ")[0], 10);
  const a = parseInt(input.split(" ")[1], 10);
  const b = parseInt(input.split(" ")[2], 10);

  if(Math.abs(x-a)>Math.abs(x-b)){
    console.log("B");
  }else{
    console.log("A");
  }

main(require('fs').readFileSync('/dev/stdin', 'utf8'));


function main(input) {
  input=input.trim();
  const x = parseInt(input.split(" ")[0], 10);
  const a = parseInt(input.split(" ")[1], 10);
  const b = parseInt(input.split(" ")[2], 10);

  console.log(Math.min.apply(null, [Math.abs(x-a),Math.abs(x-b)]));
}

main(require('fs').readFileSync('/dev/stdin', 'utf8'));


package main

import "fmt"

func abs(x int) int {
	if x < 0 {
		return -x
	}
	return x
}

func main() {
	var x, a, b int
	fmt.Scan(&x, &a, &b)

	if abs(x-a) < abs(x-b) {
		fmt.Println("A")
	} else {
		fmt.Println("B")
	}
}


package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

func out(x ...interface{}) {
	fmt.Println(x...)
}

var sc = bufio.NewScanner(os.Stdin)

func getInt() int {
	sc.Scan()
	i, e := strconv.Atoi(sc.Text())
	if e != nil {
		panic(e)
	}
	return i
}

func getString() string {
	sc.Scan()
	return sc.Text()
}

func asub(a, b int) int {
	if a > b {
		return a - b
	}
	return b - a
}

func main() {
	sc.Split(bufio.ScanWords)
	sc.Buffer([]byte{}, 1000000)

	x, a, b := getInt(), getInt(), getInt()

	if asub(x, a) >= asub(x, b) {
		out("B")
	} else {
		out("A")
	}

}


package main

import (
	"fmt"
	"math"
)

func AbsInt(n1 int, n2 int) int {
	return int(math.Abs(float64(n1 - n2)))
}

func main() {
	var x, a, b int
	fmt.Scan(&x, &a, &b)
	if AbsInt(x, a) < AbsInt(x, b) {
		fmt.Println("A")
	} else {
		fmt.Println("B")
	}
}


package main

import "fmt"

func abs(a int) int {
	if a > 0 {
		return a
	}
	return (-1) * a
}

func main() {
	var x, a, b int
	fmt.Scan(&x, &a, &b)

	if abs(x-a) > abs(x-b) {
		fmt.Println("A")
	} else {
		fmt.Println("B")
	}
}


package main

import (
        "bufio"
        "fmt"
        "os"
        "strings"
)

func solution(s string) string {
        var memo [26]int

        for _, r := range s {
                memo[r-'a']++
        }
        for i := range memo {
                if memo[i] == 0 {
                        return string(i + 'a')
                }
        }
        return "None"
}

func main() {
        reader := bufio.NewReaderSize(os.Stdin, 1024)
        str, _, _ := reader.ReadLine()
        fmt.Println(solution(strings.TrimRight(string(str), "\r\n")))
}


package main

import "fmt"

func main() {
	var x, a, b int
	fmt.Scan(&x, &a, &b)
	if x-a > x-b {
		fmt.Println("B")
	} else {
		fmt.Println("A")
	}
}


x,a,b = gets.chomp.split.map(&:to_i)

c = (a-x).abs
d = (b-x).abs

if c <= d
  puts "A"
else
  puts "B"
end


x, a, b = gets.split.map(&:to_i)
if (x-a).abs - (x-b).abs > 0
  puts "B"
else
  puts "A"
end


x,a,b=gets.split(" ").map(&:to_i)

if (a-x).abs<(b-x).abs then
  print("A")
else
  print("B")
end


x,a,b = gets.chomp.split(' ').map(&:to_i)
puts [(x-a).abs,(x-b).abs].min


# すぬけ君は，数直線上の位置 x に住んでいます．
# また，位置 a,b にはそれぞれ出前を行っている店 A,B が存在します．
# すぬけ君は，店 A,B のうち，より近いほうから出前をとることにしました．
# どちらの店がすぬけ君の住んでいる位置により近いかを求めてください．
# ただし，数直線上の 2 点 s,t の間の距離は |s−t| で表されます．

input = gets.chomp.split
x = input[0].to_i
a = input[1].to_i
b = input[2].to_i

(x - a).abs < (x - b).abs ? puts "A" : puts "B"


x,a,b = gets.split.map(&:to_i)

if (x - a).abs > (x - b).abs
  puts "a"
else
  puts "b"
end


use std::io;

fn procon_read<T: std::str::FromStr>() ->  Vec<T> {
	let mut buf = String::new();
	io::stdin().read_line(&mut buf).expect("");
	let iter = buf.split_whitespace();
	let mut v: Vec<T> = Vec::new();
	for i in iter {
		v.push(i.parse().ok().unwrap());
	}
	v
}

fn main() {
	let v:Vec<i32> = procon_read();
	let x = v[0];
	let a = v[1];
	let b = v[2];
	if (a-x).abs() < (b-x).abs() {
		println!("A");
	}else{
		println!("B");
	}
}


use std::io::*;
use std::str::FromStr;

pub fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

fn main() {
    let x: i64 = read();
    let a: i64 = read();
    let b: i64 = read();

    if (x - a).abs() > (x - b).abs() {
        println!("B")
    } else {
        println!("A")
    }
}


fn main(){
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    let v:Vec<i32> = s.trim().split_whitespace().map(|e| e.parse().ok().unwrap()).collect();
    let mut x = v[0];
    let mut a = v[1];
    let mut b = v[2];

    if (a-x).abs() < (b-x).abs(){
        println!("A");
    }
    else{
        println!("B");
    }
}


use proconio::{input, fastout};

#[fastout]
fn main() {
    input! {
        (x, a, b): (i32, i32, i32)
    }

    if (x-a).abs()>(x-b).abs() {
        println!("A");
    } else {
        println!("B");
    }
}


use std::str::FromStr;
use std::fmt::Debug;
use std::cmp;

#[allow(dead_code)]
fn read_as_vec<T>() -> Vec<T>
where T: FromStr, <T as FromStr>::Err : Debug{
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    s.trim().split_whitespace().map(|c| T::from_str(c).unwrap()).collect()

}

#[allow(dead_code)]
fn read_as_string() -> String{
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    s.trim().to_string()
}

fn is_X(s: &Vec<Vec<(char, u64)>>, i: usize) -> bool{
    return s[0][i].0 == s[1][i].0;
}

fn is_Y(s: &Vec<Vec<(char, u64)>>, i: usize) -> bool{
    return !is_X(s, i);
}

fn main(){
    let n: usize = read_as_vec()[0];

    let mut s: Vec<Vec<(char, u64)>> = Vec::new();

    s.push(read_as_string().chars().zip(vec![0;n].into_iter()).collect::<Vec<(char, u64)>>());
    s.push(read_as_string().chars().zip(vec![0;n].into_iter()).collect::<Vec<(char, u64)>>());

    //init
    let mut i = 0;
    let mut ans: u64;
    let mut is_prev_x: bool;

    if is_X(&s, i){
        ans = 3;
        i += 1;
        is_prev_x = true;
    }else{
        ans = 6;
        i += 2;
        is_prev_x = false;
    }

    while i < n{
        if is_X(&s, i){
            if is_prev_x{
                ans *= 2;
            }else{
                ans *= 1;
            }
            i += 1;
            is_prev_x = true;
        }else{
            if is_prev_x{
                ans *= 2;
            }else{
                ans *= 3;
            }
            i += 2;
            is_prev_x = false;
        }
        ans %= 1_000_000_007;
    }

    println!("{:?}", ans);
}


#[allow(unused_imports)]
use std::cmp::{max, min};
#[allow(unused_imports)]
use std::collections::{HashMap, HashSet};
#[allow(unused_imports)]
use std::io::*;
#[allow(unused_imports)]
use std::str::*;

macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        let mut next = || { iter.next().unwrap() };
        input_inner!{next, $($r)*}
    };
    ($($r:tt)*) => {
        let stdin = std::io::stdin();
        let mut bytes = std::io::Read::bytes(std::io::BufReader::new(stdin.lock()));
        let mut next = move || -> String{
            bytes
                .by_ref()
                .map(|r|r.unwrap() as char)
                .skip_while(|c|c.is_whitespace())
                .take_while(|c|!c.is_whitespace())
                .collect()
        };
        input_inner!{next, $($r)*}
    };
}

macro_rules! input_inner {
    ($next:expr) => {};
    ($next:expr, ) => {};

    ($next:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($next, $t);
        input_inner!{$next $($r)*}
    };
}

macro_rules! read_value {
    ($next:expr, ( $($t:tt),* )) => {
        ( $(read_value!($next, $t)),* )
    };

    ($next:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($next, $t)).collect::<Vec<_>>()
    };

    ($next:expr, chars) => {
        read_value!($next, String).chars().collect::<Vec<char>>()
    };

    ($next:expr, usize1) => {
        read_value!($next, usize) - 1
    };

    ($next:expr, $t:ty) => {
        $next().parse::<$t>().expect("Parse error")
    };
}

#[allow(dead_code)]
fn read<T: FromStr>() -> T {
    let cin = stdin();
    let cin = cin.lock();
    let s: String = cin
        .bytes() // Bytes
        .map(|c| c.expect("failed reading char") as char)
        .skip_while(|c| c.is_whitespace()) // c が whitespace である限り skip
        .take_while(|c| !c.is_whitespace()) // c が whitespace でない限り要素を返す
        .collect();
    s.parse().ok().expect("failed parsing")
}

fn main() {
    input! {x:usize, a:usize, b:usize}
    println!("{}", min((x - a).abs(), (x - b).abs()))
}


let i=readLine()!.characters.split(" ").map{Int(String($0))!};print(abs(i[1]-i[0])<abs(i[2]-i[0]) ?"A":"B")


import Glibc
extension String: CollectionType {}

var xab = readLine()!.split(" ").map { Int($0)! }
if abs(xab[0] - xab[1]) > abs(xab[0] - xab[2]) {
	print("B")
} else {
  print("A")
}


//: Playground - noun: a place where people can play

import Foundation
/*
 func readInt(str : String) -> Int{
 return Int(str)  ?? 0
 }

 func splitInt(str : String,array :inout [Int]) ->(){
 var temp : String = ""
 for itr in str{
 if itr == " "{
 array.append(Int(temp) ?? 0)
 print(temp)
 temp =  ""
 } else {
 temp += String(itr)
 }
 }
 array.append(Int(temp) ?? 0)
 }
 */

var str: String = readLine() ?? ""
var array :[Int] = []
let startindex = str.startIndex
var temp:String = ""
var index = startindex
for itr in str.characters{
    if itr == " "{
        array.append(Int(temp) ?? 0)
        temp = "";
    } else {
        temp += String(itr);
    }
}
array.append(Int(temp) ?? 0)
if  abs(array[0]-array[1]) < abs(array[0]-array[2]){
    print("A")
}else{
    print("B")
}


let i=readLine()!.characters.split(" ").map{Int(String($0))!};print((i[1]-i[0])<(i[2]-i[0]) ?"A":"B")


let i=readLine()!.characters.split(" ").map{Int(String($0))!};print(i[1]-i[0]<i[2]-i[0] ?"A":"B")


let i=readLine()!.characters.split(" ").map{Int(String($0))!};print(i[1]-i[0]>i[2]-i[0] ?"A":"B")


const main = (input) => {
  input = input.split(' ');
  const x = parseInt(input[0], 10);
  const a = parseInt(input[1], 10);
  const b = parseInt(input[2], 10);

  if (Math.abs(x-a)>=Math.abs(x-b)) {
    console.log("B");
  }else{
    console.log("A");
  }

}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));


const stdin = require('fs').readFileSync('/dev/stdin', 'utf8')

const [x, a, b] = stdin.split('\n')[0].split(' ').map(Number)

console.log(Math.abs(x-a) > Math.abs(x-b) ? 'B' : 'A')


const t={input:require('fs').readFileSync('/dev/stdin','utf8').split(/[\s]/),n:(arg:number=0):any=>{if(arg){const a=[];for(let i=0;i<arg;i++){a.push(t.n())}return a}else{const a=t.input[0];t.input.shift();return Number(a)}},s:(arg:number=0):string|string[]=>{if(arg){const a=[];for(let i=0;i<arg;i++){a.push(t.s())}return a}else{const a=t.input[0];t.input.shift();return String(a)}},c:(arg:number=0):string|string[]=>{if(arg){const a=[];for(let i=0;i<arg;i++){a.push(t.c())}return a}else{let a=t.input[0].split('');const b=a[0];a.shift();if(a.length>0){t.input[0]=a.join('')}else{t.input.shift()}return String(b)}},o:(...arg)=>{console.log(...arg)},abs:(a)=>{return Math.abs(a)},min:(...a)=>{return Math.min(...a)},max:(...a)=>{return Math.max(...a)},floor:(a)=>{return Math.floor(a)},asc:(ar:number[])=>{return ar.sort((a,b)=>{return a-b})},desc:(ar:number[])=>{return ar.sort((a,b)=>{return b-a})},sw:(a,arr:any[],op:'=='|'>='|'>'|'<='|'<'='==')=>{for(let i=0;i<arr.length;i+=2){if(eval(a+op+arr[i]))return arr[i+1];}return arr[arr.length-1]}};
const main=()=>{
  let [x,a,b] = t.n(3)
  a-=x;
  b-=x;
  t.o(t.abs(a)<t.abs(b)?'A':'B')
}
main()


const main = (input) => {
  input = input.split(' ');
  const a = parseInt(input[0], 10);
  const b = parseInt(input[1], 10);

  if (a>b) {
    console.log("A");
  }else{
    console.log("B");
  }

}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));


const main = (input) => {
  input = input.split(' ');
  const x = parseInt(input[0], 10);
  const a = parseInt(input[1], 10);
  const b = parseInt(input[2], 10);

  if (x-a>=x-b) {
    console.log("B");
  }else{
    console.log("A");
  }

}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));


const main = (input) => {
  input = input.split(' ');
  const x = parseInt(input[0], 10);
  const a = parseInt(input[1], 10);
  const b = parseInt(input[2], 10);

  if (x-a>=x-b) {
    console.log("A");
  }else{
    console.log("B");
  }

}
main(require('fs').readFileSync('/dev/stdin', 'utf8'));


# ABC137D - Summer Vacation
from heapq import heappush, heappushpop

def main():
    N, M, *A = map(int, open(0).read().split())
    # T[i] := candidates of values on i-th deadline
    T = [[] for _ in range(M + 1)]
    for a, b in zip(*[iter(A)] * 2):
        if a <= M:
            T[M - a] += [b]
    q = []  # heapq
    for i in range(M + 1):
        for v in T[i]:
            # keep i worthwhile tasks in i-th day
            if len(q) <= i:
                heappush(q, v)
            else:
                heappushpop(q, v)
    print(sum(q))

if __name__ == "__main__":
    main()


import sys
from heapq import heappop, heappush

input = sys.stdin.readline

def main():
    MAX_A = 10 ** 5
    N, M = map(int, input().split())
    AB = [[] for _ in range(MAX_A + 1)]
    for i in range(N):
        A, B = map(int, input().split())
        AB[A].append(-B)

    p_queue = []
    ans = 0
    for m in range(1, M + 1):
        for b in AB[m]:
            heappush(p_queue, b)
        if p_queue:
            x = heappop(p_queue)
            x *= -1
            ans += x

    print(ans)

if __name__ == "__main__":
    main()


def main():
    import sys
    sys.setrecursionlimit(10**9)
    input = sys.stdin.readline
    from heapq import heappush, heappop

    N, M = map(int, input().split())
    AB = [ [] for _ in range(100000) ]

    for _ in range(N):
        a, b = map(int, input().split())
        AB[a-1].append(-b)

    ans = 0
    heap = []
    for a in range(M):
        for b in AB[a]:
            heappush(heap, b)
        if heap:
            ans -= heappop(heap)

    print(ans)

main()


import math
from math import gcd,pi,sqrt
INF = float("inf")
MOD = 10**9 + 7

import sys
sys.setrecursionlimit(10**6)
import itertools
import bisect
from collections import Counter,deque
def i_input(): return int(input())
def i_map(): return map(int, input().split())
def i_list(): return list(i_map())
def i_row(N): return [i_input() for _ in range(N)]
def i_row_list(N): return [i_list() for _ in range(N)]
def s_input(): return input()
def s_map(): return input().split()
def s_list(): return list(s_map())
def s_row(N): return [s_input for _ in range(N)]
def s_row_str(N): return [s_list() for _ in range(N)]
def s_row_list(N): return [list(s_input()) for _ in range(N)]

def main():
    n,M = i_map()
    l = [i_list() for _ in range(n)]
    l.sort(reverse = True)

    dp = [0]*(M+1)
    for i,k in l:
        if i > M:
            continue
        m = min(dp[:(-i)])
        d = dp.index(m)
        if k > m:
            dp[d] = k
    print(sum(dp))

if __name__=="__main__":
    main()


import heapq

n,m=map(int,input().split())
mm=10**5+5
c=[[0] for i in range(mm)]

for i in range(n):
  a,b=map(int,input().split())
  c[a].append(b)

#print(c)

ans=0
h=[]
for i in reversed(range(m)):
  d=m-i
  h+=list(map(lambda x:-x, c[d]))
  heapq.heapify(h)
  ans+=-heapq.heappop(h)

print(ans)


import heapq

n,m=map(int,input().split())
mm=10*5+1
c=[[0] for i in range(mm)]

for i in range(n):
  a,b=map(int,input().split())
  c[a].append(b)

#print(c)

ans=0
h=[]
for i in reversed(range(m)):
  d=m-i
  h+=list(map(lambda x:-x, c[d]))+[0]
  heapq.heapify(h)
  ans+=-heapq.heappop(h)

print(ans)


import java.util.*;
import java.io.*;
import java.awt.Point;

public class Main {

    public static void main(String[] args) {
      MyWriter out = new MyWriter(System.out);

      MyScanner sc = new MyScanner(System.in);
      int N = sc.nextInt();
      int M = sc.nextInt();
      LinkedList<Integer>[] list = new LinkedList[100001];

      for (int i = 0; i < N; i++) {
        int a = sc.nextInt();
      	int b = sc.nextInt();
        if (list[a] == null) {
          list[a] = new LinkedList<Integer>();
        }
        list[a].add(b);
      }

      int res = 0;
      PriorityQueue <Integer> pqueue = new PriorityQueue<Integer>(Collections.reverseOrder());
      for (int i = 1; i <= M; i++) {
        if (list[i] != null) {
          pqueue.addAll(list[i]);
        }
        if (!pqueue.isEmpty())
        	res += pqueue.poll();
      }

      out.println(res);
      out.flush();
    }

    static final class MyScanner {
        static final int BUFFER_SIZE = 8192;
        private final InputStream in;
        private final byte[] buffer = new byte[BUFFER_SIZE];
        private int point;
        private int readLength;
        MyScanner(InputStream in) {
            this.in = in;
        }
        private int readByte() {
            if (point < readLength) {
                int result = buffer[point];
                point += 1;
                return result;
            }
            try {
                readLength = in.read(buffer);
            } catch (IOException e) {
                throw new AssertionError(null, e);
            }
            if (readLength == -1) {
                return -1;
            }
            point = 1;
            return buffer[0];
        }
        private static boolean isPrintableCharExceptSpace(int c) {
            return 33 <= c && c <= 126;
        }
        String next() {
            int c = readByte();
            while (!(c == -1 || isPrintableCharExceptSpace(c))) {
                c = readByte();
            }
            if (c == -1) {
                throw new NoSuchElementException();
            }
            StringBuilder b = new StringBuilder();
            do {
                b.appendCodePoint(c);
                c = readByte();
            } while (c != -1 && isPrintableCharExceptSpace(c));
            return b.toString();
        }
        long nextLong() {
            int c = readByte();
            while (!(c == -1 || isPrintableCharExceptSpace(c))) {
                c = readByte();
            }
            if (c == -1) {
                throw new NoSuchElementException();
            }
            boolean minus = false;
            if (c == '-') {
                minus = true;
                c = readByte();
            }
            long result = 0L;
            do {
                if (c < '0' || c > '9') {
                    throw new InputMismatchException();
                }
                result = result * 10L + (c - '0');
                c = readByte();
            } while (c != -1 && isPrintableCharExceptSpace(c));
            return minus ? -result : result;
        }
        int nextInt() {
            long n = nextLong();
            if (n < Integer.MIN_VALUE || n > Integer.MAX_VALUE) {
                throw new InputMismatchException();
            }
            return (int)n;
        }
        double nextDouble() {
            return Double.parseDouble(next());
        }
        int[] nextIntArray(int n) {
            int[] result = new int[n];
            for (int i = 0; i < n; i++) {
                result[i] = nextInt();
            }
            return result;
        }
        private static boolean allSameLength(int[] a, int[] b, int[]... c) {
            if (a.length != b.length) {
                return false;
            }
            for (int[] element : c) {
                if (a.length != element.length) {
                    return false;
                }
            }
            return true;
        }
        private static boolean allSameLength(char[] a, char[] b, char[]... c) {
            if (a.length != b.length) {
                return false;
            }
            for (char[] element : c) {
                if (a.length != element.length) {
                    return false;
                }
            }
            return true;
        }
        void nextVerticalIntArrays(int[] a, int[] b, int[]... c) {
            if (!allSameLength(a, b, c)) {
                throw new IllegalArgumentException();
            }
            for (int i = 0; i < a.length; i++) {
                a[i] = nextInt();
                b[i] = nextInt();
                for (int[] d : c) {
                    d[i] = nextInt();
                }
            }
        }
        long[] nextLongArray(int n) {
            long[] result = new long[n];
            for (int i = 0; i < n; i++) {
                result[i] = nextLong();
            }
            return result;
        }
        char nextChar() {
            int c = readByte();
            while (!(c == -1 || isPrintableCharExceptSpace(c))) {
                c = readByte();
            }
            if (c == -1) {
                throw new NoSuchElementException();
            }
            return (char)c;
        }
        char[] nextCharArray(int n) {
            char[] result = new char[n];
            for (int i = 0; i < n; i++) {
                result[i] = nextChar();
            }
            return result;
        }
        char[][] next2dCharArray(int n, int m) {
            char[][] result = new char[n][m];
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    result[i][j] = nextChar();
                }
            }
            return result;
        }
        void nextVerticalCharArrays(char[] a, char[] b, char[]... c) {
            if (!allSameLength(a, b, c)) {
                throw new IllegalArgumentException();
            }
            for (int i = 0; i < a.length; i++) {
                a[i] = nextChar();
                b[i] = nextChar();
                for (char[] d : c) {
                    d[i] = nextChar();
                }
            }
        }
    }
    static final class MyWriter extends PrintWriter {
        MyWriter(OutputStream out) {
            super(out);
        }
        void joinAndPrintln(int[] x) {
            joinAndPrintln(x, " ");
        }
        void joinAndPrintln(int[] x, String delimiter) {
            StringBuilder b = new StringBuilder();
            if (x.length > 0) {
                b.append(x[0]);
                for (int i = 1; i < x.length; i++) {
                    b.append(delimiter).append(x[i]);
                }
            }
            println(b.toString());
        }
        void joinAndPrintln(long[] x) {
            joinAndPrintln(x, " ");
        }
        void joinAndPrintln(long[] x, String delimiter) {
            StringBuilder b = new StringBuilder();
            if (x.length > 0) {
                b.append(x[0]);
                for (int i = 1; i < x.length; i++) {
                    b.append(delimiter).append(x[i]);
                }
            }
            println(b.toString());
        }
        void joinAndPrintln(Iterable<?> iterable) {
            joinAndPrintln(iterable, " ");
        }
        void joinAndPrintln(Iterable<?> iterable, String delimiter) {
            StringBuilder b = new StringBuilder();
            for (Iterator<?> i = iterable.iterator(); i.hasNext();) {
                b.append(i.next());
                while (i.hasNext()) {
                    b.append(delimiter).append(i.next());
                }
            }
            println(b.toString());
        }
    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.BufferedWriter;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.util.Collections;
import java.util.ArrayList;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        DSummerVacation solver = new DSummerVacation();
        solver.solve(1, in, out);
        out.close();
    }

    static class DSummerVacation {
        static final int MASK = (1 << 17) - 1;

        public void solve(int testNumber, InputReader in, OutputWriter out) {
            int n = in.nextInt(), m = in.nextInt();
            int[] a = new int[n];
            int[] b = new int[n];
            boolean[] filled = new boolean[m + 2];
            DisjointSets ds = new DisjointSets(m + 1);
            ArrayList<Integer> al = new ArrayList<>();
            for (int i = 0; i < n; i++) {
                b[i] = in.nextInt();
                a[i] = in.nextInt();
                al.add((a[i] << 17) | b[i]);
            }
            Collections.sort(al);
            int ans = 0;
            for (int i = 0; i < n; i++) {
                int x = al.get(n - 1 - i);
                int _a = x >> 17;
                int _b = x & MASK;
                if (_b > m) continue;
                int pos = !filled[m - _b] ? m - _b : ds.root(m - _b) - 1;
                if (pos < 0) continue;
                if (pos + 1 <= m && filled[pos + 1]) {
                    ds.unite(pos, pos + 1);
                }
                if (pos - 1 >= 0 && filled[pos - 1]) ds.unite(pos, pos - 1);
                filled[pos] = true;
                ans += _a;
            }
            out.println(ans);
        }

        public class DisjointSets {
            int[] p;

            DisjointSets(int size) {
                p = new int[size];
                for (int i = 0; i < size; i++)
                    p[i] = i;
            }

            public int root(int x) {
                return x == p[x] ? x : (p[x] = root(p[x]));
            }

            boolean unite(int a, int b) {
                a = root(a);
                b = root(b);
                if (a < b) {
                    int temp = a;
                    a = b;
                    b = temp;
                }
                if (a != b) {
                    p[a] = b;
                    return true;
                }
                return false;
            }

        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void println(Object... objects) {
            for (int i = 0; i < objects.length; i++) {
                if (i != 0) {
                    writer.print(' ');
                }
                writer.print(objects[i]);
            }
            writer.print('\n');
        }

        public void close() {
            writer.close();
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private InputReader.SpaceCharFilter filter;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars == -1) {
                throw new InputMismatchException();
            }
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (numChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }

        public int nextInt() {
            int c = read();
            while (isSpaceChar(c)) c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);

        }

    }
}


import java.util.*;
import java.io.*;

public class Main {
	public static void main(String[] args) {
		FastScanner sc = new FastScanner();
		PrintWriter out = new PrintWriter(System.out);

		int n = sc.nextInt();
		int m = sc.nextInt();
		List<Integer>[] candidate = new ArrayList[m];
		for(int i = 0; i < candidate.length; i++) {
			candidate[i] = new ArrayList<>();
		}
		for(int i = 0; i < n; i++) {
			int a = sc.nextInt();
			int b = sc.nextInt();
			int limit = m - a;
			if (limit < 0) continue;
			candidate[limit].add(b);
		}
		Queue<Integer> que = new PriorityQueue<>();

		for(int i = 0; i < candidate.length; i++) {
			List<Integer> list = candidate[i];
			for(int j = 0; j < list.size(); j++) {
				que.offer(list.get(j));
				if (que.size() > i + 1) {
					que.poll();
				}
			}
		}
		long sum = 0;
		while(que.size() > 0) {
			sum += (long)que.poll();
		}

		out.println(sum);

		out.close();
	}

public static class Pair implements Comparable<Pair> {
    int from; int to; long cost;
    Pair(int from,int to, long cost) {
    	this.from = from;
        this.to = to;
        this.cost = cost;
    }
    public int compareTo(Pair p) {
        return Long.compare(cost, p.cost);
    }
}

static class FastScanner {
    private final InputStream in = System.in;
    private final byte[] buffer = new byte[1024];
    private int ptr = 0;
    private int buflen = 0;
    private boolean hasNextByte() {
        if (ptr < buflen) {
            return true;
        }else{
            ptr = 0;
            try {
                buflen = in.read(buffer);
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (buflen <= 0) {
                return false;
            }
        }
        return true;
    }
    private int readByte() { if (hasNextByte()) return buffer[ptr++]; else return -1;}
    private static boolean isPrintableChar(int c) { return 33 <= c && c <= 126;}
    public boolean hasNext() { while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++; return hasNextByte();}
    public String next() {
        if (!hasNext()) throw new NoSuchElementException();
        StringBuilder sb = new StringBuilder();
        int b = readByte();
        while(isPrintableChar(b)) {
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }
    public long nextLong() {
        if (!hasNext()) throw new NoSuchElementException();
        long n = 0;
        boolean minus = false;
        int b = readByte();
        if (b == '-') {
            minus = true;
            b = readByte();
        }
        if (b < '0' || '9' < b) {
            throw new NumberFormatException();
        }
        while(true){
            if ('0' <= b && b <= '9') {
                n *= 10;
                n += b - '0';
            }else if(b == -1 || !isPrintableChar(b)){
                return minus ? -n : n;
            }else{
                throw new NumberFormatException();
            }
            b = readByte();
        }
    }
    public int nextInt() {
        long nl = nextLong();
        if (nl < Integer.MIN_VALUE || nl > Integer.MAX_VALUE) throw new NumberFormatException();
        return (int) nl;
    }
    public double nextDouble() { return Double.parseDouble(next());}
}
}


// template for atcode
import java.util.*;
import java.io.*;
import static java.lang.Math.*;

public class Main {

    private static final int MOD = (int)1e9 + 7; //998244353;
    // private static final long INF = (long)1e17;
    private static final int INF = (int)1e9;

    public Main(FastScanner in, PrintWriter out) {
        int N = in.nextInt();
        int M = in.nextInt();
        int[][] AB = new int[N][];
        Map<Integer, List<Integer>> urgent = new HashMap<>();
        for (int i = 0; i < N; i++) {
            int a = in.nextInt(), b = in.nextInt();
            AB[i] = new int[]{a, b};
            urgent.computeIfAbsent(a, k -> new ArrayList<>()).add(b);
        }
        // Arrays.sort(AB, Comparator.<int[]>comparingInt(a -> a[1]).reversed());
        for (var l : urgent.values()) Collections.sort(l);
        Arrays.sort(AB, (x, y) -> {
            if (x[1] == y[1]) return Integer.compare(y[0], x[0]);
            return Integer.compare(y[1], x[1]);
        });
        int res = 0, i = 0;
        while (M > 0) {
            List<Integer> l = urgent.get(M);
            if (l == null) {
                while (i < N && (AB[i][0] > M || !urgent.containsKey(AB[i][0]))) i++;
                if (i == N) break;
                l = urgent.get(AB[i][0]);
                res += l.remove(l.size() - 1);
                if (l.isEmpty()) urgent.remove(AB[i][0]);
                i++;
            } else {
                res += l.get(l.size() - 1);
                urgent.remove(M);
            }
            M--;
        }
        out.println(res);
    }

    private int gcd(int a, int b) {
        while (true) {
            if (b == 0) return a;
            int tmp = a;
            a = b;
            b = tmp % b;
        }
    }

    private long gcd(long a, long b) {
        while (true) {
            if (b == 0) return a;
            long tmp = a;
            a = b;
            b = tmp % b;
        }
    }

    private long powm(long x, long p) {
        long res = 1;
        while (p > 0) {
            if (p % 2 == 1)
                res = res * x % MOD;
            x = x * x % MOD;
            p /= 2;
        }
        return res;
    }

    public static void main(String[] args) {
        PrintWriter out = new PrintWriter(System.out);
        // Scanner in = new Scanner(
                // new BufferedReader(new InputStreamReader(System.in)));
        FastScanner in = new FastScanner(System.in);

        Main sol = new Main(in, out);
        out.close();
    }
}

// Pair
class Pair<T extends Comparable<? super T>, U extends Comparable<? super U>> implements Comparable<Pair<T, U>> {
    T a;
    U b;
    Pair() { }
    Pair(T a, U b) {
        this.a = a;
        this.b = b;
    }

    @Override
    public String toString() { return "("+a.toString()+", "+b.toString()+")"; }

    @Override
    public int hashCode() { return Objects.hash(a, b); }

    @Override
    public boolean equals(Object obj) {
        if(this == obj) return true;
        if(obj == null) return false;
        if(this.getClass() != obj.getClass()) return false;
        Pair that = (Pair) obj;
        if(this.a.getClass() != that.a.getClass()) return false;
        if(this.b.getClass() != that.b.getClass()) return false;
        if(!this.a.equals(that.a)) return false;
        if(!this.b.equals(that.b)) return false;
        return true;
    }

    @Override
    public int compareTo(Pair<T, U> that) {
        int c = (this.a).compareTo(that.a);
        if(c == 0) c = (this.b).compareTo(that.b);
        return c;
    }
}

class FastScanner{
    private InputStream stream;
    private byte[] buf = new byte[1024];
    private int curChar;
    private int numChars;

    public FastScanner(InputStream stream)
    {
        this.stream = stream;
    }

    int read()
    {
        if (numChars == -1)
            throw new InputMismatchException();
        if (curChar >= numChars){
            curChar = 0;
            try{
                numChars = stream.read(buf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (numChars <= 0)
                return -1;
        }
        return buf[curChar++];
    }

    boolean isSpaceChar(int c)
    {
        return c==' '||c=='\n'||c=='\r'||c=='\t'||c==-1;
    }

    boolean isEndline(int c)
    {
        return c=='\n'||c=='\r'||c==-1;
    }

    int nextInt()
    {
        return Integer.parseInt(next());
    }

    long nextLong()
    {
        return Long.parseLong(next());
    }

    double nextDouble()
    {
        return Double.parseDouble(next());
    }

    String next(){
        int c = read();
        while (isSpaceChar(c))
            c = read();
        StringBuilder res = new StringBuilder();
        do{
            res.appendCodePoint(c);
            c = read();
        }while(!isSpaceChar(c));
        return res.toString();
    }

    String nextLine(){
        int c = read();
        while (isEndline(c))
            c = read();
        StringBuilder res = new StringBuilder();
        do{
            res.appendCodePoint(c);
            c = read();
        }while(!isEndline(c));
        return res.toString();
    }
}


// template for atcode
import java.util.*;
import java.io.*;
import static java.lang.Math.*;

public class Main {

    private static final int MOD = (int)1e9 + 7; //998244353;
    // private static final long INF = (long)1e17;
    private static final int INF = (int)1e9;

    public Main(FastScanner in, PrintWriter out) {
        int N = in.nextInt();
        int M = in.nextInt();
        int[][] AB = new int[N][];
        Map<Integer, List<Integer>> urgent = new HashMap<>();
        for (int i = 0; i < N; i++) {
            int a = in.nextInt(), b = in.nextInt();
            AB[i] = new int[]{a, b};
            urgent.computeIfAbsent(a, k -> new ArrayList<>()).add(b);
        }
        Arrays.sort(AB, Comparator.<int[]>comparingInt(a -> a[1]).reversed());
        for (var l : urgent.values()) Collections.sort(l);
        // Arrays.sort(AB, (x, y) -> {
            // if (x[1] == y[1]) return Integer.compare(y[0], x[0]);
            // return Integer.compare(y[1], x[1]);
        // });
        int res = 0, i = 0;
        while (M > 0) {
            List<Integer> l = urgent.get(M);
            if (l == null) {
                while (i < N && (AB[i][0] > M || !urgent.containsKey(AB[i][0]))) i++;
                if (i == N) break;
                l = urgent.get(AB[i][0]);
                res += l.remove(l.size() - 1);
                if (l.isEmpty()) urgent.remove(AB[i][0]);
                i++;
            } else {
                res += l.get(l.size() - 1);
                urgent.remove(M);
            }
            M--;
        }
        out.println(res);
    }

    private int gcd(int a, int b) {
        while (true) {
            if (b == 0) return a;
            int tmp = a;
            a = b;
            b = tmp % b;
        }
    }

    private long gcd(long a, long b) {
        while (true) {
            if (b == 0) return a;
            long tmp = a;
            a = b;
            b = tmp % b;
        }
    }

    private long powm(long x, long p) {
        long res = 1;
        while (p > 0) {
            if (p % 2 == 1)
                res = res * x % MOD;
            x = x * x % MOD;
            p /= 2;
        }
        return res;
    }

    public static void main(String[] args) {
        PrintWriter out = new PrintWriter(System.out);
        // Scanner in = new Scanner(
                // new BufferedReader(new InputStreamReader(System.in)));
        FastScanner in = new FastScanner(System.in);

        Main sol = new Main(in, out);
        out.close();
    }
}

// Pair
class Pair<T extends Comparable<? super T>, U extends Comparable<? super U>> implements Comparable<Pair<T, U>> {
    T a;
    U b;
    Pair() { }
    Pair(T a, U b) {
        this.a = a;
        this.b = b;
    }

    @Override
    public String toString() { return "("+a.toString()+", "+b.toString()+")"; }

    @Override
    public int hashCode() { return Objects.hash(a, b); }

    @Override
    public boolean equals(Object obj) {
        if(this == obj) return true;
        if(obj == null) return false;
        if(this.getClass() != obj.getClass()) return false;
        Pair that = (Pair) obj;
        if(this.a.getClass() != that.a.getClass()) return false;
        if(this.b.getClass() != that.b.getClass()) return false;
        if(!this.a.equals(that.a)) return false;
        if(!this.b.equals(that.b)) return false;
        return true;
    }

    @Override
    public int compareTo(Pair<T, U> that) {
        int c = (this.a).compareTo(that.a);
        if(c == 0) c = (this.b).compareTo(that.b);
        return c;
    }
}

class FastScanner{
    private InputStream stream;
    private byte[] buf = new byte[1024];
    private int curChar;
    private int numChars;

    public FastScanner(InputStream stream)
    {
        this.stream = stream;
    }

    int read()
    {
        if (numChars == -1)
            throw new InputMismatchException();
        if (curChar >= numChars){
            curChar = 0;
            try{
                numChars = stream.read(buf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (numChars <= 0)
                return -1;
        }
        return buf[curChar++];
    }

    boolean isSpaceChar(int c)
    {
        return c==' '||c=='\n'||c=='\r'||c=='\t'||c==-1;
    }

    boolean isEndline(int c)
    {
        return c=='\n'||c=='\r'||c==-1;
    }

    int nextInt()
    {
        return Integer.parseInt(next());
    }

    long nextLong()
    {
        return Long.parseLong(next());
    }

    double nextDouble()
    {
        return Double.parseDouble(next());
    }

    String next(){
        int c = read();
        while (isSpaceChar(c))
            c = read();
        StringBuilder res = new StringBuilder();
        do{
            res.appendCodePoint(c);
            c = read();
        }while(!isSpaceChar(c));
        return res.toString();
    }

    String nextLine(){
        int c = read();
        while (isEndline(c))
            c = read();
        StringBuilder res = new StringBuilder();
        do{
            res.appendCodePoint(c);
            c = read();
        }while(!isEndline(c));
        return res.toString();
    }
}


// template for atcode
import java.util.*;
import java.io.*;
import static java.lang.Math.*;

public class Main {

    private static final int MOD = (int)1e9 + 7; //998244353;
    // private static final long INF = (long)1e17;
    private static final int INF = (int)1e9;

    public Main(FastScanner in, PrintWriter out) {
        int N = in.nextInt();
        int M = in.nextInt();
        int[][] AB = new int[N][];
        for (int i = 0; i < N; i++) {
            int a = in.nextInt(), b = in.nextInt();
            AB[i] = new int[]{a, b};
        }
        Arrays.sort(AB, (x, y) -> {
            if (x[1] == y[1]) return Integer.compare(y[0], x[0]);
            return Integer.compare(y[1], x[1]);
        });
        int res = 0;
        for (int i = 0; i < N && M > 0; i++) {
            int a = AB[i][0], b = AB[i][1];
            if (a <= M) {
                M--;
                res += b;
            }
        }
        out.println(res);
    }

    private int gcd(int a, int b) {
        while (true) {
            if (b == 0) return a;
            int tmp = a;
            a = b;
            b = tmp % b;
        }
    }

    private long gcd(long a, long b) {
        while (true) {
            if (b == 0) return a;
            long tmp = a;
            a = b;
            b = tmp % b;
        }
    }

    private long powm(long x, long p) {
        long res = 1;
        while (p > 0) {
            if (p % 2 == 1)
                res = res * x % MOD;
            x = x * x % MOD;
            p /= 2;
        }
        return res;
    }

    public static void main(String[] args) {
        PrintWriter out = new PrintWriter(System.out);
        // Scanner in = new Scanner(
                // new BufferedReader(new InputStreamReader(System.in)));
        FastScanner in = new FastScanner(System.in);

        Main sol = new Main(in, out);
        out.close();
    }
}

// Pair
class Pair<T extends Comparable<? super T>, U extends Comparable<? super U>> implements Comparable<Pair<T, U>> {
    T a;
    U b;
    Pair() { }
    Pair(T a, U b) {
        this.a = a;
        this.b = b;
    }

    @Override
    public String toString() { return "("+a.toString()+", "+b.toString()+")"; }

    @Override
    public int hashCode() { return Objects.hash(a, b); }

    @Override
    public boolean equals(Object obj) {
        if(this == obj) return true;
        if(obj == null) return false;
        if(this.getClass() != obj.getClass()) return false;
        Pair that = (Pair) obj;
        if(this.a.getClass() != that.a.getClass()) return false;
        if(this.b.getClass() != that.b.getClass()) return false;
        if(!this.a.equals(that.a)) return false;
        if(!this.b.equals(that.b)) return false;
        return true;
    }

    @Override
    public int compareTo(Pair<T, U> that) {
        int c = (this.a).compareTo(that.a);
        if(c == 0) c = (this.b).compareTo(that.b);
        return c;
    }
}

class FastScanner{
    private InputStream stream;
    private byte[] buf = new byte[1024];
    private int curChar;
    private int numChars;

    public FastScanner(InputStream stream)
    {
        this.stream = stream;
    }

    int read()
    {
        if (numChars == -1)
            throw new InputMismatchException();
        if (curChar >= numChars){
            curChar = 0;
            try{
                numChars = stream.read(buf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (numChars <= 0)
                return -1;
        }
        return buf[curChar++];
    }

    boolean isSpaceChar(int c)
    {
        return c==' '||c=='\n'||c=='\r'||c=='\t'||c==-1;
    }

    boolean isEndline(int c)
    {
        return c=='\n'||c=='\r'||c==-1;
    }

    int nextInt()
    {
        return Integer.parseInt(next());
    }

    long nextLong()
    {
        return Long.parseLong(next());
    }

    double nextDouble()
    {
        return Double.parseDouble(next());
    }

    String next(){
        int c = read();
        while (isSpaceChar(c))
            c = read();
        StringBuilder res = new StringBuilder();
        do{
            res.appendCodePoint(c);
            c = read();
        }while(!isSpaceChar(c));
        return res.toString();
    }

    String nextLine(){
        int c = read();
        while (isEndline(c))
            c = read();
        StringBuilder res = new StringBuilder();
        do{
            res.appendCodePoint(c);
            c = read();
        }while(!isEndline(c));
        return res.toString();
    }
}


//#include<bits/stdc++.h>
#include<cstdio>
#include<queue>

using namespace std;
typedef long long ll;
#define rep(i, n) for(int i = 0; i < (n); i++)
#define rep1(i, n) for(int i = 1; i <= (n); i++)
#define co(x) cout << (x) << "\n"
#define cosp(x) cout << (x) << " "
#define ce(x) cerr << (x) << "\n"
#define cesp(x) cerr << (x) << " "
#define pb push_back
#define mp make_pair
#define Would
#define you
#define please

//そっかー

const int cm = 1 << 17;
char cn[cm], * ci = cn + cm, ct;
inline char getcha() {
	if (ci - cn == cm) { fread(cn, 1, cm, stdin); ci = cn; }
	return *ci++;
}
inline int getint() {
	int A = 0;
	if (ci - cn + 16 > cm) while ((ct = getcha()) >= '0') A = A * 10 + ct - '0';
	else while ((ct = *ci++) >= '0') A = A * 10 + ct - '0';
	return A;
}

int main() {
	//cin.tie(0);
	//ios::sync_with_stdio(false);

	int N = getint(), M = getint();
	int E[100001], H[100001] = {}, n[100001];
	int k = 1;
	rep(i, N) {
		int a = getint();
		E[k] = getint();
		n[k] = H[a];
		H[a] = k++;
	}
	priority_queue<int> que;

	int kotae = 0;
	int j = 0;
	rep1(i, M) {
		for (int j = H[i]; j; j = n[j]) que.push(E[j]);
		if (que.size()) {
			kotae += que.top();
			que.pop();
		}
	}

	printf("%d", kotae);

	Would you please return 0;
}


//#include<bits/stdc++.h>
#include<cstdio>
#include<queue>

using namespace std;
typedef long long ll;
#define rep(i, n) for(int i = 0; i < (n); i++)
#define rep1(i, n) for(int i = 1; i <= (n); i++)
#define co(x) cout << (x) << "\n"
#define cosp(x) cout << (x) << " "
#define ce(x) cerr << (x) << "\n"
#define cesp(x) cerr << (x) << " "
#define pb push_back
#define mp make_pair
#define Would
#define you
#define please

void sugoi_sort(int N, int A[], int B[]) {
	const int b = 8;
	int tmpA[100001], tmpB[100001];
	rep(k, 4) {
		int kazu[1 << b] = {}, kazu2[1 << b] = {};
		rep(i, N) kazu[A[i] >> k * b & ((1 << b) - 1)]++;
		rep(i, (1 << b) - 1) kazu[i + 1] += kazu[i];
		for (int i = N - 1; i >= 0; i--) {
			tmpA[--kazu[A[i] >> k * b & ((1 << b) - 1)]] = A[i];
			tmpB[kazu[A[i] >> k * b & ((1 << b) - 1)]] = B[i];
		}
		k++;
		rep(i, N) kazu2[tmpA[i] >> k * b & ((1 << b) - 1)]++;
		rep(i, (1 << b) - 1) kazu2[i + 1] += kazu2[i];
		for (int i = N - 1; i >= 0; i--) {
			A[--kazu2[tmpA[i] >> k * b & ((1 << b) - 1)]] = tmpA[i];
			B[kazu2[tmpA[i] >> k * b & ((1 << b) - 1)]] = tmpB[i];
		}
	}
}

const int cm = 1 << 17;
char cn[cm], * ci = cn + cm, ct;
inline char getcha() {
	if (ci - cn == cm) { fread(cn, 1, cm, stdin); ci = cn; }
	return *ci++;
}
inline int getint() {
	int A = 0;
	if (ci - cn + 16 > cm) while ((ct = getcha()) >= '0') A = A * 10 + ct - '0';
	else while ((ct = *ci++) >= '0') A = A * 10 + ct - '0';
	return A;
}

int main() {
	//cin.tie(0);
	//ios::sync_with_stdio(false);

	int N = getint(), M = getint();
	int A[100000], B[100000];
	rep(i, N) {
		A[i] = getint();
		B[i] = getint();
	}
	sugoi_sort(N, A, B);
	priority_queue<int> que;

	int kotae = 0;
	int j = 0;
	rep1(i, M) {
		while (j < N && A[j] <= i) {
			que.push(B[j++]);
		}
		if (que.size()) {
			kotae += que.top();
			que.pop();
		}
	}

	printf("%d", kotae);

	Would you please return 0;
}


#pragma GCC optimize ("Ofast")
#include<bits/stdc++.h>
using namespace std;
void *wmem;
template<class T> inline void walloc1d(T **arr, int x, void **mem = &wmem){
  static int skip[16]={0, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
  (*mem) = (void*)( ((char*)(*mem)) + skip[((unsigned long long)(*mem)) & 15] );
  (*arr)=(T*)(*mem);
  (*mem)=((*arr)+x);
}
inline void rd(int &x){
  int k, m=0;
  x=0;
  for(;;){
    k = getchar_unlocked();
    if(k=='-'){
      m=1;
      break;
    }
    if('0'<=k&&k<='9'){
      x=k-'0';
      break;
    }
  }
  for(;;){
    k = getchar_unlocked();
    if(k<'0'||k>'9'){
      break;
    }
    x=x*10+k-'0';
  }
  if(m){
    x=-x;
  }
}
inline void wt_L(char a){
  putchar_unlocked(a);
}
inline void wt_L(int x){
  char f[10];
  int m=0, s=0;
  if(x<0){
    m=1;
    x=-x;
  }
  while(x){
    f[s++]=x%10;
    x/=10;
  }
  if(!s){
    f[s++]=0;
  }
  if(m){
    putchar_unlocked('-');
  }
  while(s--){
    putchar_unlocked(f[s]+'0');
  }
}
template<class T> struct Heap_max{
  T *val;
  int size;
  void malloc(const int N){
    val = (T*) std::malloc(N*sizeof(T));
    size = 0;
  }
  void walloc(const int N, void **mem = &wmem){
    walloc1d(&val, N, mem);
    size = 0;
  }
  void free(){
    std::free(val);
  }
  void init(){
    size = 0;
  }
  void up(){
    int m, n=size - 1;
    while(n){
      m = (n-1) / 2;
      if(val[m] >= val[n]){
        break;
      }
      swap(val[m], val[n]);
      n = m;
    }
  }
  void down(){
    int m, n=0;
    for(;;){
      m=2*n+1;
      if(m>=size){
        break;
      }
      if(m+1<size && val[m] < val[m+1]){
        m++;
      }
      if(val[m] <= val[n]){
        break;
      }
      swap(val[m], val[n]);
      n=m;
    }
  }
  T top(){
    return val[0];
  }
  T pop(){
    T res=val[0];
    size--;
    if(size > 0){
      val[0] = val[size];
      down();
    }
    return res;
  }
  void push(const T x){
    val[size++] = x;
    up();
  }
}
;
template<class S> void wAdjEdge_L(const int N, const int M, const int *A, const S *B, int **res_sz, S ***res_B, void **mem = &wmem){
  int i, j, k;
  walloc1d(res_sz, N, mem);
  for(i=0;i<(N);i++){
    (*res_sz)[i] = 0;
  }
  for(i=0;i<(M);i++){
    (*res_sz)[A[i]]++;
  }
  walloc1d(res_B, N, mem);
  for(i=0;i<(N);i++){
    walloc1d(&((*res_B)[i]), (*res_sz)[i], mem);
  }
  for(i=0;i<(N);i++){
    (*res_sz)[i] = 0;
  }
  for(i=0;i<(M);i++){
    (*res_B)[A[i]][(*res_sz)[A[i]]++] = B[i];
  }
}
char memarr[96000000];
int N;
int M;
int A[100000];
int B[100000];
int *sz;
int **val;
int main(){
  Heap_max<int> h;
  int i, j, res=0;
  wmem = memarr;
  rd(N);
  rd(M);
  {
    int Lj4PdHRW;
    for(Lj4PdHRW=0;Lj4PdHRW<(N);Lj4PdHRW++){
      rd(A[Lj4PdHRW]);A[Lj4PdHRW] += (-1);
      rd(B[Lj4PdHRW]);
    }
  }
  wAdjEdge_L(100000, N, A, B, &sz, &val);
  h.walloc(N);
  for(i=0;i<(M);i++){
    for(j=0;j<(sz[i]);j++){
      h.push(val[i][j]);
    }
    if(h.size){
      res += h.pop();
    }
  }
  wt_L(res);
  wt_L('\n');
  return 0;
}
// cLay varsion 20190822-2

// --- original code ---
// int N, M, A[1d5], B[1d5];
// int *sz, **val;
// {
//   int i, j, res = 0;
//   Heap_max<int> h;
//
//   rd(N,M,(A--,B)(N));
//   wAdjEdge(1d5, N, A, B, &sz, &val);
//
//   h.walloc(N);
//
//   rep(i,M){
//     rep(j,sz[i]) h.push(val[i][j]);
//     if(h.size) res += h.pop();
//   }
//
//   wt(res);
// }


#include <bits/stdc++.h>

#include <algorithm>

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

// @param n `0 <= n`
// @return minimum non-negative `x` s.t. `n <= 2**x`
int ceil_pow2(int n) {
    int x = 0;
    while ((1U << x) < (unsigned int)(n)) x++;
    return x;
}

// @param n `1 <= n`
// @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`
int bsf(unsigned int n) {
#ifdef _MSC_VER
    unsigned long index;
    _BitScanForward(&index, n);
    return index;
#else
    return __builtin_ctz(n);
#endif
}

}  // namespace internal

}  // namespace atcoder

#include <cassert>
#include <vector>

namespace atcoder {

template <class S, S (*op)(S, S), S (*e)()> struct segtree {
  public:
    segtree() : segtree(0) {}
    segtree(int n) : segtree(std::vector<S>(n, e())) {}
    segtree(const std::vector<S>& v) : _n(int(v.size())) {
        log = internal::ceil_pow2(_n);
        size = 1 << log;
        d = std::vector<S>(2 * size, e());
        for (int i = 0; i < _n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) {
            update(i);
        }
    }

    void set(int p, S x) {
        assert(0 <= p && p < _n);
        p += size;
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }

    S get(int p) {
        assert(0 <= p && p < _n);
        return d[p + size];
    }

    S prod(int l, int r) {
        assert(0 <= l && l <= r && r <= _n);
        S sml = e(), smr = e();
        l += size;
        r += size;

        while (l < r) {
            if (l & 1) sml = op(sml, d[l++]);
            if (r & 1) smr = op(d[--r], smr);
            l >>= 1;
            r >>= 1;
        }
        return op(sml, smr);
    }

    S all_prod() { return d[1]; }

    template <bool (*f)(S)> int max_right(int l) {
        return max_right(l, [](S x) { return f(x); });
    }
    template <class F> int max_right(int l, F f) {
        assert(0 <= l && l <= _n);
        assert(f(e()));
        if (l == _n) return _n;
        l += size;
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!f(op(sm, d[l]))) {
                while (l < size) {
                    l = (2 * l);
                    if (f(op(sm, d[l]))) {
                        sm = op(sm, d[l]);
                        l++;
                    }
                }
                return l - size;
            }
            sm = op(sm, d[l]);
            l++;
        } while ((l & -l) != l);
        return _n;
    }

    template <bool (*f)(S)> int min_left(int r) {
        return min_left(r, [](S x) { return f(x); });
    }
    template <class F> int min_left(int r, F f) {
        assert(0 <= r && r <= _n);
        assert(f(e()));
        if (r == 0) return 0;
        r += size;
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!f(op(d[r], sm))) {
                while (r < size) {
                    r = (2 * r + 1);
                    if (f(op(d[r], sm))) {
                        sm = op(d[r], sm);
                        r--;
                    }
                }
                return r + 1 - size;
            }
            sm = op(d[r], sm);
        } while ((r & -r) != r);
        return 0;
    }

  private:
    int _n, size, log;
    std::vector<S> d;

    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
};

}  // namespace atcoder

#define _overload3(_1,_2,_3,name,...) name
#define _rep(i,n) repi(i,0,n)
#define repi(i,a,b) for(int i=int(a);i<int(b);++i)
#define rep(...) _overload3(__VA_ARGS__,repi,_rep,)(__VA_ARGS__)
using namespace std;
using namespace atcoder;
using ll = long long;
using P = pair<int,int>;
constexpr int INF = 1001001001;
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }

P op(P a, P b) { return a.second < b.second ? b : a; }
P e() { return make_pair(-1, -1); }
P target;
bool f(P v) { return v.second < target.second; }

int main() {
    int n, m;
    cin >> n >> m;
    vector<P> p(n);
    rep (i, n) {
        int a, b;
        cin >> a >> b;
        p[i] = make_pair(a, b);
    }
    sort(p.begin(), p.end(), greater<P>());
    //for (auto q : p) cout << "(" << q.first << ", " << q.second << ")" << endl;
    vector<int> l(m+1, -1);
    for (int i = n-1; i >= 0; i--) l[p[i].first] = i;
    //rep (i, m+1) cout << "l[" << i << "]:" << l[i] << endl;

    segtree<P, op, e> seg(p);
    int pre = -1;
    ll ans = 0;
    rep (i, m+1) {
        int li = l[i];
        //cout << "i:" << i << endl;
        if (li < 0) {
            if (pre < 0) continue;
            else li = pre;
        }
        //cout << "[" << li << "," << n << "] ";
        target = seg.prod(li, n);
        //cout << " target:" << target.second << " ";
        if (target == e()) continue;
        int id = seg.max_right<f>(li);
        //cout << "id:" << id << endl;
        seg.set(id, e());
        ans += target.second;
        pre = li;
    }

    cout << ans << endl;

    return 0;
}


#include <bits/stdc++.h>
#include <atcoder/segtree>
#define _overload3(_1,_2,_3,name,...) name
#define _rep(i,n) repi(i,0,n)
#define repi(i,a,b) for(int i=int(a);i<int(b);++i)
#define rep(...) _overload3(__VA_ARGS__,repi,_rep,)(__VA_ARGS__)
using namespace std;
using namespace atcoder;
using ll = long long;
using P = pair<int,int>;
constexpr int INF = 1001001001;
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }

P op(P a, P b) { return a.second < b.second ? b : a; }
P e() { return make_pair(-1, -1); }
P target;
bool f(P v) { return v.second < target.second; }

int main() {
    int n, m;
    cin >> n >> m;
    vector<P> p(n);
    rep (i, n) {
        int a, b;
        cin >> a >> b;
        p[i] = make_pair(a, b);
    }
    sort(p.begin(), p.end(), greater<P>());
    //for (auto q : p) cout << "(" << q.first << ", " << q.second << ")" << endl;
    vector<int> l(m+1, -1);
    for (int i = n-1; i >= 0; i--) l[p[i].first] = i;
    //rep (i, m+1) cout << "l[" << i << "]:" << l[i] << endl;

    segtree<P, op, e> seg(p);
    int pre = -1;
    ll ans = 0;
    rep (i, m+1) {
        int li = l[i];
        //cout << "i:" << i << endl;
        if (li < 0) {
            if (pre < 0) continue;
            else li = pre;
        }
        //cout << "[" << li << "," << n << "] ";
        target = seg.prod(li, n);
        //cout << " target:" << target.second << " ";
        if (target == e()) continue;
        int id = seg.max_right<f>(li);
        //cout << "id:" << id << endl;
        seg.set(id, e());
        ans += target.second;
        pre = li;
    }

    cout << ans << endl;

    return 0;
}


#include <iostream> // cout, endl, cin
#include <string> // string, to_string, stoi
#include <vector> // vector
#include <algorithm> // min, max, swap, sort, reverse, lower_bound, upper_bound
#include <utility> // pair, make_pair
#include <tuple> // tuple, make_tuple
#include <map> // map
#include <queue> // queue, priority_queue
#include <set> // set
#include <stack> // stack
#include <deque> // deque
#define ll long long
#define ALL(x) (x).begin(),(x).end()
#define rep(i, n) for(int i = 0; i < (int)(n); i++)
#define vi vector<int>
#define vvi vector<vector<int>>
using namespace std;

class UnionFind {
protected:
    vector<vector<int>> Graph;// {ID,Value,ParentID,Height}
    vector<bool> isClosed;
public:
    void push(int x) {
        int i = Graph.size();
        Graph.push_back({ i,x,i,1 });
        isClosed.push_back(false);
    }
    void unite(int x, int y) {
        if (root(x) == root(y)) {
            isClosed[root(x)] = true;
            isClosed[root(y)] = true;
        }
        int hx = Graph[root(x)][3];
        int hy = Graph[root(y)][3];
        if (hx < hy) {
            Graph[root(x)][2] = root(y);
            flatten(x, root(y));
        }
        else if (hx == hy) {
            Graph[root(y)][2] = root(x);
            Graph[root(x)][3]++;
            flatten(y, root(x));
        }
        else {
            Graph[root(y)][2] = root(x);
            flatten(y, root(x));
        }
    }
    bool same(int x, int y) {
        return root(x) == root(y);
    }

    void flatten(int x, int rootid) {
        int parentid = Graph[x][0];
        while (Graph[parentid][0] != Graph[parentid][2]) {
            Graph[parentid][2] = rootid;
            int next = Graph[parentid][2];
            parentid = next;
        }
    }
    int root(int x) {
        int parentid = Graph[x][0];
        while (Graph[parentid][0] != Graph[parentid][2]) {
            int next = Graph[parentid][2];
            parentid = next;
        }

        return parentid;
    }
    int count_groups() {
        int cnt = 0;
        for (int i = 0; i < Graph.size(); i++) {
            if (Graph[i][2] == Graph[i][0]) {
                cnt++;
            }
        }
        return cnt;
    }
    vector<vector<int>> group_indices() {
        vector<vector<int>> groups(Graph.size());
        for (int i = 0; i < Graph.size(); i++) {
            groups[root(i)].push_back(i);
        }
        return groups;
    }
    void unite_x_parentize(int x, int y) {
        if (root(x) == root(y)) {
            isClosed[root(x)] = true;
            isClosed[root(y)] = true;
        }
        Graph[root(y)][2] = root(x);
        int val = rand() % 53;
        if (val == 0) {
            flatten(y, root(x));
        }
    }
};

bool comp(vi& lhs, vi& rhs) {
    if (lhs[1] != rhs[1]) {
        return lhs[1] > rhs[1];
    }
    else {
        return lhs[0] < rhs[0];
    }
}
int main() {
    int N, M; cin >> N >> M;
    vector<vector<int>> pjobs(N, vi(2));
    rep(i, N) cin >> pjobs[i][0] >> pjobs[i][1];
    sort(ALL(pjobs), comp);
    ll score = 0;
    UnionFind uf;
    for (int i = 0; i < M+2; i++) {
        uf.push(i);
    }
    for (int i = 0; i < N; i++) {
        if (pjobs[i][0] < M + 1) {
            int day = uf.root(pjobs[i][0]);
            if (day != M + 1) {
                uf.unite_x_parentize(day + 1, day);
                score += pjobs[i][1];
            }
        }
        else {
            continue;
        }
    }
    cout << score << endl;
}


#include <float.h>
#include <inttypes.h>
#include <limits.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <math.h>
#ifdef __cplusplus
#include <bits/stdc++.h>
#endif

int a[100000];
int s=0;

void push(int x){
	int c=s++, p=(c-1)/2;
	while(c>0 && x>a[p]){
		a[c]=a[p];
		c=p, p=(c-1)/2;
	}
	a[c]=x;
}
int pop(void){
	int t=a[0], x=a[--s];
	int p=0, c=p*2+1;
	while(c<s && a[c=(c+1<s&&a[c+1]>a[c])?c+1:c]>x){
		a[p]=a[c];
		p=c, c=p*2+1;
	}
	a[p]=x;
	return t;
}

uint32_t nextpint(void){ char c=getchar_unlocked(); while(c<'0'||'9'<c) c=getchar_unlocked(); uint32_t x=0; while('0'<=c && c<='9'){ x=x*10+c-'0'; c=getchar_unlocked(); } return x; }
void rsort_u32(void *base, const int count);

uint32_t b[100000][2];
int main(void){
	uint32_t n=nextpint();
	uint32_t m=nextpint();
	for(uint32_t i=0; i<n; i++){
		b[i][0]=nextpint();
		b[i][1]=nextpint();
	}
	rsort_u32(b, n);
	uint32_t ans=0;
	uint32_t p=0;
	for(uint32_t i=1; i<=m; i++){
		for(; p<n&&b[p][0]<=i; p++){
			push(b[p][1]);
		}
		if(s>0) ans+=pop();
	}
	printf("%"PRIu32"\n", ans);
}

void rsort_u32(void *base, const int count){
	uint64_t *a=base;
	uint64_t *b=malloc(count*sizeof(uint64_t));
	int c[0x100];
	memset(c, 0, sizeof(c)); for(int i=0; i<count; i++){ c[(a[i]>>(0<<3))&0xFF]++; } for(int i=1; i<0x100; i++) c[i]+=c[i-1]; for(int i=count-1; i>=0; i--){ b[--c[(a[i]>>(0<<3))&0xFF]]=a[i]; }{void *t=a; a=b; b=t;}
	memset(c, 0, sizeof(c)); for(int i=0; i<count; i++){ c[(a[i]>>(1<<3))&0xFF]++; } for(int i=1; i<0x100; i++) c[i]+=c[i-1]; for(int i=count-1; i>=0; i--){ b[--c[(a[i]>>(1<<3))&0xFF]]=a[i]; }{void *t=a; a=b; b=t;}
	memset(c, 0, sizeof(c)); for(int i=0; i<count; i++){ c[(a[i]>>(2<<3))&0xFF]++; } for(int i=1; i<0x100; i++) c[i]+=c[i-1]; for(int i=count-1; i>=0; i--){ b[--c[(a[i]>>(2<<3))&0xFF]]=a[i]; }{void *t=a; a=b; b=t;}
	memset(c, 0, sizeof(c)); for(int i=0; i<count; i++){ c[(a[i]>>(3<<3))&0xFF]++; } for(int i=1; i<0x100; i++) c[i]+=c[i-1]; for(int i=count-1; i>=0; i--){ b[--c[(a[i]>>(3<<3))&0xFF]]=a[i]; }{void *t=a; a=b; b=t;}
	free(b);
}


#include <stdio.h>
#define SIZE 100006
typedef struct mk{
    int b;
    struct mk *next;
}data;
data *input[SIZE],node[SIZE];
int id = 0;
data *New(int b){
    data *tm = &node[id++];
    tm->b = b;
    tm->next = NULL;
    return tm;
}
data *insert(data *root, int b){
    if(root==NULL) return New(b);
    data *tm = New(b);
    tm->next = root;
    return tm;
}
int len = 0,heap[SIZE];
void swap(int *x,int *y){
    int t = *x;
    *x = *y;
    *y = t;
}
int minChild(int *ar,int len,int r,int lf,int rt){
    if(lf<len && ar[r]<ar[lf]) r = lf;
    if(rt<len && ar[r]<ar[rt]) r = rt;
    return r;
}
void heapify(int *ar, int len,int r){
    int c = minChild(ar,len,r,r*2+1,r*2+2);
    if(c!=r){
        swap(&ar[r],&ar[c]);
        heapify(ar,len,c);
    }
}
int getTop(int len){
    int ret = heap[0];
    heap[0] = heap[len];
    heapify(heap,len, 0);
    return ret;
}
void Insert(int v,int len){
    heap[len]=v;
    while(len>0 && heap[(len-1)/2]<heap[len]){
        swap(&heap[len],&heap[(len-1)/2]);
        len = (len-1)/2;
    }
}
void MRoy(){
    int n,m,a,b,length = 0;
    for(int i = 0;i<SIZE;i++) input[i] = NULL;
    scanf("%d%d",&n,&m);
    for(int i = 0;i<n;i++){
        scanf("%d %d",&a,&b);
        input[a] = insert(input[a],b);
    }
    int Ans = 0;
    for(int i = 0;i<m;i++){
        data *tm = input[i+1];
        while(tm!=NULL){
            // printf("%d ",tm->b);
            Insert(tm->b,length);
            length++;
            tm=tm->next;
        }
        if(length){
            Ans += getTop(--length);
        }
            // printf("%d\n",Ans);
    }
    printf("%d\n",Ans);
    return;
}
int main(){
    MRoy();
    return 0;
}


#include<stdio.h>
#include<stdlib.h>
long long int a[100005], b[100005];
int asc(const void* x, const void* y)
{
	if (b[*(int*)x] < b[*(int*)y])return 1;
	if (b[*(int*)x] > b[*(int*)y])return -1;
	return 0;
}
int q[100005];
void qq()
{
	int i;
	for (i = 0; i < 100005; i++)
		q[i] = i;
	return;
}
int r(int n)
{
	if (n < 0)
		return -1;
	if (q[n] == n)
		return n;
	if (q[n] < 0)
		return -1;
	return q[n] = r(q[n]);
}
int main()
{
	long long int n, m;
	scanf("%lld %lld", &n, &m);
	long long int i, j;
	for (i = 0; i < n; i++)
		scanf("%lld %lld", &a[i], &b[i]);
	int p[100005];
	for (i = 0; i < m; i++)
		p[i] = 0;
	long long int ans = 0;
	int c[100005];
	for (i = 0; i < n; i++)
		c[i] = i;
	qsort(c, n, sizeof(int), asc);
	qq();

	for (i = 0; i < n; i++)
	{
		j = r(m - a[c[i]]);
		if (j >= 0)
		{
			p[j] = 1;
			q[j]--;
			ans += b[c[i]];
		}
	}
	printf("%lld\n", ans);
	return 0;
}


#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>

enum Color {red, black};
typedef struct RBT_Node{
	int key;
	enum Color color;
	struct RBT_Node *left, *right, *parent;
} Node;
Node *nil, *T;
Node* tree_minimum(Node *x){
	Node *res = x;
	while((*res).left != nil)res = (*res).left;
	return res;
}
Node* tree_maximum(Node *x){
	Node *res = x;
	while((*res).right != nil)res = (*res).right;
	return res;
}
void left_lotate(Node *x){
	Node *y = (*x).right;
	(*x).right = (*y).left;
	if((*y).left != nil){
		(*(*y).left).parent = x;
	}
	(*y).parent = (*x).parent;
	if((*x).parent == nil){
		T = y;
	}else if(x == (*(*x).parent).left){
		(*(*x).parent).left = y;
	}else {
		(*(*x).parent).right = y;
	}
	(*y).left = x;
	(*x).parent = y;
	return;
}
void right_lotate(Node *x){
	Node *y = (*x).left;
	(*x).left = (*y).right;
	if((*y).right != nil){
		(*(*y).right).parent = x;
	}
	(*y).parent = (*x).parent;
	if((*x).parent == nil){
		T = y;
	}else if(x == (*(*x).parent).right){
		(*(*x).parent).right = y;
	}else {
		(*(*x).parent).left = y;
	}
	(*y).right = x;
	(*x).parent = y;
	return;
}
void insert_fixup(Node *z){
	while((*(*z).parent).color == red){
		if((*z).parent == (*(*(*z).parent).parent).left){
			Node *y = (*(*(*z).parent).parent).right;
			if((*y).color == red){
				(*(*z).parent).color = black;
				(*y).color = black;
				(*(*(*z).parent).parent).color = red;
				z = (*(*z).parent).parent;
			}else {
				if(z == (*(*z).parent).right){
					z = (*z).parent;
					left_lotate(z);
				}
				(*(*z).parent).color = black;
				(*(*(*z).parent).parent).color = red;
				right_lotate((*(*z).parent).parent);
			}
		}else{
			Node *y = (*(*(*z).parent).parent).left;
			if((*y).color == red){
				(*(*z).parent).color = black;
				(*y).color = black;
				(*(*(*z).parent).parent).color = red;
				z = (*(*z).parent).parent;
			}else {
				if(z == (*(*z).parent).left){
					z = (*z).parent;
					right_lotate(z);
				}
				(*(*z).parent).color = black;
				(*(*(*z).parent).parent).color = red;
				left_lotate((*(*z).parent).parent);
			}
		}
	}
	(*T).color = black;
	return;
}
void insert(Node *z){
	Node *y = nil;
	Node *x = T;
	while(x != nil){
		y = x;
		if((*z).key < (*x).key){
			x = (*x).left;
		}else {
			x = (*x).right;
		}
	}
	(*z).parent = y;
	if(y == nil){
		T = z;
	}else if((*z).key < (*y).key){
		(*y).left = z;
	}else {
		(*y).right = z;
	}
	insert_fixup(z);
	return;
}
void push(int x){
	Node *z = (Node*)malloc(sizeof(Node));
	(*z).key = x;
	(*z).parent = (*z).left = (*z).right = nil;
	(*z).color = red;
	insert(z);
	return;
}
void transplant(Node *u, Node *v){
	if((*u).parent == nil){
		T = v;
	}else if(u == (*(*u).parent).left){
		(*(*u).parent).left = v;
	}else {
		(*(*u).parent).right = v;
	}
	(*v).parent = (*u).parent;
	return;
}
void delete_fixup(Node *x){
	while(x != T && (*x).color == black){
		if(x == (*(*x).parent).left){
			Node *w = (*(*x).parent).right;
			if((*w).color == red){
				(*w).color = black;
				(*(*x).parent).color = red;
				left_lotate((*x).parent);
				w = (*(*x).parent).right;
			}
			if((*(*w).left).color == black && (*(*w).right).color == black){
				(*w).color = red;
				x = (*x).parent;
			}else {
				if((*(*w).right).color == black){
					(*(*w).left).color = black;
					(*w).color = red;
					right_lotate(w);
					w = (*(*x).parent).right;
				}
				(*w).color = (*(*x).parent).color;
				(*(*x).parent).color = black;
				(*(*w).right).color = black;
				left_lotate((*x).parent);
				x = T;
			}
		}else{
			Node *w = (*(*x).parent).left;
			if((*w).color == red){
				(*w).color = black;
				(*(*x).parent).color = red;
				right_lotate((*x).parent);
				w = (*(*x).parent).left;
			}
			if((*(*w).right).color == black && (*(*w).left).color == black){
				(*w).color = red;
				x = (*x).parent;
			}else {
				if((*(*w).left).color == black){
					(*(*w).right).color = black;
					(*w).color = red;
					left_lotate(w);
					w = (*(*x).parent).left;
				}
				(*w).color = (*(*x).parent).color;
				(*(*x).parent).color = black;
				(*(*w).left).color = black;
				right_lotate((*x).parent);
				x = T;
			}
		}
	}
	(*x).color = black;
	return;
}
bool delete(int t){
	Node *z = T;
	while((*z).key != t && z != nil){
		if((*z).key > t){
			z = (*z).left;
		}else {
			z = (*z).right;
		}
	}
	if(z == nil) return false;
	Node *x;
	Node *y = z;
	enum Color y_original_color = (*y).color;
	if((*z).left == nil){
		x = (*z).right;
		transplant(z, (*z).right);
	}else if((*z).right == nil){
		x = (*z).left;
		transplant(z, (*z).left);
	}else {
		y = tree_minimum((*z).right);
		y_original_color = (*y).color;
		x = (*y).right;
		if((*y).parent == z){
			(*x).parent = y;
		}else {
			transplant(y, (*y).right);
			(*y).right = (*z).right;
			(*(*y).right).parent = y;
		}
		transplant(z, y);
		(*y).left = (*z).left;
		(*(*y).left).parent = y;
		(*y).color = (*z).color;
	}
		free(z);
	if(y_original_color == black){
		delete_fixup(x);
	}
	return true;
}
void nil_init(){
	nil = (Node*)malloc(sizeof(Node));
	(*nil).color = black;
	(*nil).key = -1;
	(*nil).left = (*nil).right = (*nil).parent = nil;
	return;
}
int N, M, A[1<<17], B[1<<17], idx[1<<17], ans = 0;
int cmp(const void *a, const void *b){
	return A[*(int*)a] - A[*(int*)b];
}
int main(){
	nil_init(); T = nil;
	scanf("%d%d", &N, &M);
	for(int i=0; i<N; i++){
		scanf("%d%d", A+i, B+i);
		idx[i] = i;
	}
	qsort(idx, N, 4, cmp);
	int j = 0;
	for(int i=1; i>=M; i++){
		for(;A[idx[j]] <= i && j < N; j++){
			push(B[idx[j]]);
		}
		if(T != nil){
			Node *t = tree_maximum(T);
			ans += (*t).key;
			delete((*t).key);
		}
	}
	printf("%ld\n", ans);
	return 0;
}


#include <stdio.h>
#include <stdlib.h>

typedef struct {
	int key, id;
} data;

void merge_sort(data x[], int n)
{
	static data y[100001] = {};
	if (n == 1) return;
	merge_sort(&(x[0]), n/2);
	merge_sort(&(x[n/2]), (n+1)/2);

	int i, p, q;
	for (i = 0, p = 0, q = n/2; i < n; i++) {
		if (p >= n/2) y[i] = x[q++];
		else if (q >= n) y[i] = x[p++];
		else y[i] = (x[p].key < x[q].key)? x[p++]: x[q++];
	}
	for (i = 0; i < n; i++) x[i] = y[i];
}

typedef struct {
	data *obj;
	int size;
} min_heap;

void push(data x, min_heap* h)
{
	int i = h->size;
	data tmp;
	h->obj[(h->size)++] = x;
	while (1) {
		if (i == 0) break;
		else if (h->obj[i].key < h->obj[(i-1)/2].key) {
			tmp = h->obj[(i-1)/2];
			h->obj[(i-1)/2] = h->obj[i];
			h->obj[i] = tmp;
			i = (i - 1) / 2;
		} else break;
	}
}

data pop(min_heap* h)
{
	int i = 0, j;
	data output = h->obj[0], tmp;
	h->obj[0] = h->obj[--(h->size)];
	while (1) {
		if (i * 2 + 1 >= h->size) break;
		else if (i * 2 + 2 >= h->size) j = i * 2 + 1;
		else if (h->obj[i*2+1].key < h->obj[i*2+2].key) j = i * 2 + 1;
		else j = i * 2 + 2;
		if (h->obj[j].key < h->obj[i].key) {
			tmp = h->obj[j];
			h->obj[j] = h->obj[i];
			h->obj[i] = tmp;
			i = j;
		} else break;
	}
	return output;
}

int main()
{
	int i, N, M;
	data d[100001];
	scanf("%d %d", &N, &M);
	for (i = 0; i < N; i++) scanf("%d %d", &(d[i].key), &(d[i].id));
	merge_sort(d, N);

	int j, ans = 0;
	min_heap h;
	h.size = 0;
	h.obj = (data*)malloc(sizeof(data) * (N + 1));
	for (i = M, j = N - 1; i >= 1; i--) {
		for (; j >= 0 && d[j].key == i; j--) {
			d[j].key += d[j].id;
			d[j].id = d[j].key - d[j].id;
			d[j].key -= d[j].id;
			push(d[j], &h);
		}
		while (h.size > M - i + 1) pop(&h);
	}
	while (h.size > 0) ans += pop(&h).key;

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


#include <stdio.h>
#include <stdlib.h>

typedef struct {
	int key, id;
} data;

void merge_sort(data x[], int n)
{
	static data y[100001] = {};
	if (n == 1) return;
	merge_sort(&(x[0]), n/2);
	merge_sort(&(x[n/2]), (n+1)/2);

	int i, p, q;
	for (i = 0, p = 0, q = n/2; i < n; i++) {
		if (p >= n/2) y[i] = x[q++];
		else if (q >= n) y[i] = x[p++];
		else y[i] = (x[p].key < x[q].key)? x[p++]: x[q++];
	}
	for (i = 0; i < n; i++) x[i] = y[i];
}

typedef struct {
	int *par, *size, *max;
} UF_forest;

void UF_initialize(UF_forest *F, int n)
{
	int i;
	F->par = (int*)malloc(sizeof(int) * (n + 1));
	F->size = (int*)malloc(sizeof(int) * (n + 1));
	F->max = (int*)malloc(sizeof(int) * (n + 1));
	for (i = 1; i <= n; i++) {
		F->par[i] = i;
		F->size[i] = 1;
		F->max[i] = i;
	}
}

void UF_merge(UF_forest *F, int u, int v)
{
	for (; F->par[u] != u; u = F->par[u]);
	for (; F->par[v] != v; v = F->par[v]);
	if (u == v) return;
	else if (F->size[u] > F->size[v]) {
		F->par[v] = u;
		F->size[u] += F->size[v];
		F->max[u] = (F->max[u] < F->max[v])? F->max[v]: F->max[u];
	} else {
		F->par[u] = v;
		F->size[v] += F->size[u];
		F->max[v] = (F->max[u] < F->max[v])? F->max[v]: F->max[u];
	}
}

int UF_root(UF_forest *F, int v)
{
	for (; F->par[v] != v; v = F->par[v]);
	return v;
}

int UF_size(UF_forest *F, int v)
{
	for (; F->par[v] != v; v = F->par[v]);
	return F->size[v];
}

int UF_max(UF_forest *F, int v)
{
	for (; F->par[v] != v; v = F->par[v]);
	return F->max[v];
}

int main()
{
	int i, N, M;
	data d[100001];
	scanf("%d %d", &N, &M);
	for (i = 0; i < N; i++) scanf("%d %d", &(d[i].id), &(d[i].key));
	merge_sort(d, N);

	int ans = 0, tmp;
	UF_forest F;
	UF_initialize(&F, M + 1);
	for (i = N - 1; i >= 0; i--) {
		tmp = UF_max(&F, d[i].id);
		if (tmp <= M) {
			ans += d[i].key;
			UF_merge(&F, d[i].id, tmp + 1);
		}
	}

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


module.exports=function(t){var e={};function i(r){if(e[r])return e[r].exports;var s=e[r]={i:r,l:!1,exports:{}};return t[r].call(s.exports,s,s.exports,i),s.l=!0,s.exports}return i.m=t,i.c=e,i.d=function(t,e,r){i.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},i.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},i.t=function(t,e){if(1&e&&(t=i(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(i.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var s in t)i.d(r,s,function(e){return t[e]}.bind(null,s));return r},i.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(e,"a",e),e},i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},i.p="",i(i.s=0)}([function(t,e,i){"use strict";var r=i(1);i(2)(r.readFileSync("/dev/stdin","utf8"))},function(t,e){t.exports=require("fs")},function(t,e,i){"use strict";var r=i(3),s=i(5);t.exports=function(t){var e=new r(t);s(e)}},function(t,e,i){"use strict";var r=i(4);t.exports=class{constructor(t){var e=t.trim().split(/\s+/g);this.inp=new r(e)}inr(){return this.inp.deq()}in(){return parseInt(this.inp.deq(),10)}fin(){this.inp.clear()}}},function(t,e,i){"use strict";t.exports=class{constructor(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[];this.size=t.length,this.items=t,this.ind=0}enq(t){this.size+=1,this.items.push(t)}deq(){var t=this.items[this.ind];return this.size-=1,this.ind+=1,t}clear(){this.items=[],this.size=0,this.ind=0}}},function(t,e,i){"use strict";var r=i(6);t.exports=function(t){for(var e=t.in(),i=t.in(),s=new Array(e),n=0;n<e;n++){var o=t.in(),h=t.in();s[n]={a:o,b:h}}s.sort(function(t,e){return t.a-e.a});for(var a=new r,u=0,p=0,f=1;f<=i;f++){for(;p<e&&s[p].a<=f;)a.pushItem(s[p].b),p++;if(0!=a.size){var c=a.getTop();a.removeTop(),u+=c}}console.log(u)}},function(t,e,i){"use strict";function r(t,e){return t<=e}function s(t,e){return t>=e}t.exports=class{constructor(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0;this.cf=e?r:s,i&&(this.cf=i),this.heap=t,this.size=this.heap.length,this.heapify()}heapify(){for(var t=0,e=this.size;2*t+1<=e;)t=2*t+1;for(var i=t-1;i>=0;)2*i+1>e-1?i--:(this.downHeap(i),i--)}downHeap(t){for(var e=this.size,i=t;2*i+1<e;){var r=this.heap[2*i+1],s=2*i+2<e?this.heap[2*i+2]:r,n=this.cf(s,r)?r:s,o=this.cf(s,r)?2*i+1:2*i+2;if(this.cf(n,this.heap[i]))break;var h=n;this.heap[o]=this.heap[i],this.heap[i]=h,i=o}}upHeap(t){for(var e=t;0!=e;){var i=Math.floor((e-1)/2);if(this.cf(this.heap[e],this.heap[i]))break;var r=this.heap[i];this.heap[i]=this.heap[e],this.heap[e]=r,e=i}}pushItem(t){this.size+=1,this.heap.push(t),this.upHeap(this.size-1)}getTop(){return this.heap[0]}removeTop(){return 0!=this.size&&(1==this.size?(this.size=0,this.heap=[],!0):(this.size-=1,this.heap[0]=this.heap.pop(),this.downHeap(0),!0))}getValuesList(){return this.heap}}}]);


function main(input) {
    var args = input.trim().split("\n");
    var info = args[0].split(" ").map((v) => parseInt(v));
    var N = info[0];
    var M = info[1];
    var jobs = args.filter((v, i) => i !== 0).map((v) => {
        return v.split(" ").map(v2 => parseInt(v2));
    });

    jobs.sort((a, b) => {
        return a[0] - b[0];
    });

    var pq = new PriorityQueue();
    var result = 0;
    var j = 0;
    for(var i = 1; M >= i; i++) {
        while(!!jobs[j] && jobs[j][0] <= i) {
            pq.push(-jobs[j][1]);
            j++;
        }

        if(pq.size()) result += -pq.pop();
    }

    console.log(result);
}

function PriorityQueue(){
    this.heap = [];
}
PriorityQueue.prototype = {
    push : function(x){
        var h = this.heap, i = h.length++, j;
        while(i){
            j = i-1 >> 1;
            if(h[j] <= x)break;
            h[i] = h[j];
            i = j;
        }
        h[i] = x;
    },
    pop : function(){
        var h = this.heap, r = h[0], x = h.pop();
        var i = 0, k = h.length >> 1, j;
        while (i < k) {
            j = (i << 1) + 1;
            if(h[j+1] < h[j])++j;
            if(x <= h[j])break;
            h[i] = h[j];
            i = j;
        }
        if(h.length)h[i] = x;
        return r;
    },
    size : function(){return this.heap.length;},
    top : function(){return this.heap[0];},
};

main(require("fs").readFileSync("/dev/stdin", "utf8"));


var GET=(function(){function f(s){return new g(s);}function g(s){this._s=s.trim().split("\n");this._y=0;}g.prototype.a=function(f){var s=this._s, y=this._y, r;if(typeof s[y]==="string")s[y]=s[y].split(" ").reverse();r=s[y].pop();if(!s[y].length)this._y++;return f?r:+r;};g.prototype.l=function(f){var s=this._s[this._y++].split(" ");return f?s:s.map(a=>+a);};g.prototype.m=function(n,f){var r=this._s.slice(this._y,this._y+=n).map(a=>a.split(" "));return f?r:r.map(a=>a.map(a=>+a));};g.prototype.r=function(n,f){var r=this._s.slice(this._y,this._y+=n);return f?r:r.map(a=>+a);};return f;})();
var o=GET(require("fs").readFileSync("/dev/stdin","utf8"));
function xArray(v){var a=arguments,l=a.length,r="Array(a["+--l+"]).fill(0).map(x=>{return "+v+";})";while(--l)r="Array(a["+l+"]).fill(0).map(x=>"+r+")";return eval(r);}
function PriorityQueue(n){
  this.heap=Array(n||1e5);
  this.size=0;
}
PriorityQueue.prototype = {
  push:function(x){
    var h=this.heap,i=this.size++,j;
    while(i){
      j=i-1>>1;
      if(h[j]<=x)break;
      h[i]=h[j],i=j;
    }
    h[i]=x;
  },
  pop:function(){
    var h=this.heap,s=this.size-1,x=h[s];h[s]=undefined;
    if(s<1)if(s)return;else return --this.size,x;
    var r=h[0],i=0,k=s>>1,j;--this.size;
    while(i<k){
      j=(i<<1)+1;
      if(h[j+1]<h[j])++j;
      if(x<=h[j])break;
      h[i]=h[j],i=j;
    }
    return h[i]=x,r;
  },
  top:function(){return this.heap[0];},
};

console.log(main());
function main(){
  var n = o.a();
  var m = o.a();
  var a = o.m(n);
  a.push([1e9,0]);
  a.sort((a,b)=>a[0]-b[0]);
  var ans = 0, j = 0;
  var pq = new PriorityQueue();
  for(var i = 1; i <= m; i++){
    while(a[j][0] <= i){
      pq.push(-a[j++][1]);
    }
    if(pq.size)ans -= pq.pop();
  }
  return ans;
}


using System;
using System.Collections.Generic;
using static System.Math;
using System.Linq;
using System.Text;

class DandA {
    static void Main(string[] args) {
        int[] nm = ReadLineIntArray();
        int[] aArr = new int[nm[0]];
        int[] bArr = new int[nm[0]];
        for (int i = 0;i < nm[0];i++) {
            int[] ab = ReadLineIntArray();
            aArr[i] = ab[0];
            bArr[i] = ab[1];
        }
        Array.Sort(aArr, bArr);
        Array.Sort(bArr, aArr);

        List<int> cntList = new List<int>();
        long rtn = 0;
        int max = nm[1];
        for (int i = nm[0] -1;i >= 0;i--) {
            if (aArr[i] <= max) {
                rtn += bArr[i];
                cntList.Add(aArr[i]);
                if (cntList.Count == nm[1]) {break;}
                cntList.Sort();
                for (int j = nm[1] - max; j < cntList.Count; j++) {
                    if (cntList[cntList.Count - (j + 1)] == (nm[1] - j)) {
                        max = cntList[cntList.Count - (j + 1)] - 1;
                    }
                }
            }
        }
        Console.WriteLine(rtn);
    }

    static string Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ";
    static string[] strAry = new string[] {"L", "R", "U", "D"};
    static int[] intArray = new int[10];
    static List<int> intList = new List<int>();

    static private string ReadLineStr() {return Console.ReadLine();}
    static private int ReadLineInt() {return int.Parse(Console.ReadLine());}
    static private long ReadLineLong() {return long.Parse(Console.ReadLine());}
    static private double ReadLineDouble() {return double.Parse(Console.ReadLine());}
    static private string[] ReadLineStrArray() {return Console.ReadLine().Trim().Split();}
    static private int[] ReadLineIntArray() {return Console.ReadLine().Trim().Split().Select(a => int.Parse(a)).ToArray();}
    static private long[] ReadLineLongArray() {return Console.ReadLine().Trim().Split().Select(a => long.Parse(a)).ToArray();}
    static private double[] ReadLineDoubleArray() {return Console.ReadLine().Trim().Split().Select(a => double.Parse(a)).ToArray();}
    static private decimal[] ReadLineDecimalArray() {return Console.ReadLine().Trim().Split().Select(a => decimal.Parse(a)).ToArray();}
    static private List<int> ReadLineIntList() {return Console.ReadLine().Trim().Split().Select(a => int.Parse(a)).ToList();}
    static private List<long> ReadLineLongList() {return Console.ReadLine().Trim().Split().Select(a => long.Parse(a)).ToList();}
    static private string[][] ReadMLineStrArray(int arg) { return new int[arg].Select(_ => Console.ReadLine().Split()).ToArray();}
    static private int[][] ReadMLineIntArray(int arg) { return new int[arg].Select(_ => Console.ReadLine().Split().Select(int.Parse).ToArray()).ToArray();}

    static private bool IsPrime(int num) {
        if (num < 2) return false;
        if (num == 2) return true;
        else if (num % 2 == 0) return false;
        double sqrtNum = Math.Sqrt(num);
        for (int i = 3; i <= sqrtNum; i += 2) {
            if (num % i == 0) return false;
        }
        return true;
    }

    static private string IntToNString(int x, int n) {
        var nstring = "";
        var numbers = new string[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
        int r = 1;
        int q = x;
        while (q > 0) {
            r = q % n;
            nstring += numbers[r];
            q = q / n;
        }
        return string.Join("",nstring.Reverse());
     }
}


function Main(input) {
  input = input.split("\n");
  var N = parseInt(input[0].split(" ")[0]);
  var M = parseInt(input[0].split(" ")[1]);
  input.shift();
  input.splice(N,input.length);
  var x = input.map(i => i.split(" ").map(i=> parseInt(i)));
  var dp=new Array(Math.pow(10,4)*N+1);
  for(var i=0;i<dp.length;i++){
    if(i==0){
      var sub = new Array(M+1).fill(1);
    }else{
      var sub = new Array(M+1).fill(0);
    }
    dp[i]=sub;
  }
  x.sort(function(a,b){
    if (a[0] < b[0]) return -1;
    if (a[0] > b[0]) return 1;
    if (a[1] < b[1]) return -1;
    if (a[1] > b[1]) return 1;
    return 0;
  })
  dp[0][0]=1;
  for(k=0;k<N;k++){
    for(i=M;i>=1;i--){
      for(j=dp.length-1;j>=0;j--){
        if(dp[j][i-1]==1){
          dp[j][i]=1;
          if(i>=x[k][0]){
            dp[j+x[k][1]][i]=1;
          }
        }
      }
    }
  }
  for(var i=dp.length-1;i>=0;i--){
    if(dp[i][M]==1){
      var ans = i;
      break;
    }
  }

  console.log('%s', ans);
  return ans;
}

function debug(n){
  var input = document.getElementById("input"+n).value;
  var ans=Main(input);
  var result="WA";
  if(ans==document.getElementById("output"+n).value.split("\n")[0]){
    result="AC";
  }
  document.getElementById("result"+n).innerHTML=result;
}
Main(require("fs").readFileSync("/dev/stdin", "utf8"));


function Main(input) {
  input = input.split("\n");
  var N = parseInt(input[0].split(" ")[0]);
  var M = parseInt(input[0].split(" ")[1]);
  input.shift();
  input.splice(N,input.length);
  var x = input.map(i => i.split(" ").map(i=> parseInt(i)));
  var dp=new Array(Math.pow(10,5)*N+1);
  for(var i=0;i<dp.length;i++){
    if(i==0){
      var sub = new Array(M+1).fill(1);
    }else{
      var sub = new Array(M+1).fill(0);
    }
    dp[i]=sub;
  }
  x.sort(function(a,b){
    if (a[0] < b[0]) return -1;
    if (a[0] > b[0]) return 1;
    if (a[1] < b[1]) return -1;
    if (a[1] > b[1]) return 1;
    return 0;
  })
  dp[0][0]=1;
  for(k=0;k<N;k++){
    for(i=M;i>=1;i--){
      for(j=dp.length-1;j>=0;j--){
        if(dp[j][i-1]==1){
          dp[j][i]=1;
          if(i>=x[k][0]){
            dp[j+x[k][1]][i]=1;
          }
        }
      }
    }
  }
  for(var i=dp.length-1;i>=0;i--){
    if(dp[i][M]==1){
      var ans = i;
      break;
    }
  }

  console.log('%s', ans);
  return ans;
}

function debug(n){
  var input = document.getElementById("input"+n).value;
  var ans=Main(input);
  var result="WA";
  if(ans==document.getElementById("output"+n).value.split("\n")[0]){
    result="AC";
  }
  document.getElementById("result"+n).innerHTML=result;
}
Main(require("fs").readFileSync("/dev/stdin", "utf8"));


package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

const (
	initialBufSize = 100000
	maxBufSize     = 10000000
)

var (
	sc = bufio.NewScanner(os.Stdin)
	wt = bufio.NewWriter(os.Stdout)
)

func next() string {
	sc.Scan()
	return sc.Text()
}

func nextInt() int {
	i, _ := strconv.Atoi(next())
	return i
}

func puts(a ...interface{}) {
	fmt.Fprintln(wt, a...)
}

type Job struct {
	a, b int
}

type Jobs []Job

func (a Jobs) Len() int           { return len(a) }
func (a Jobs) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a Jobs) Less(i, j int) bool { return a[i].a < a[j].a }

type Heap struct {
	size  int
	elems [100000]int
}

type MyHeap interface {
	Size() int
	Push(int)
	Pop() int
}

func (heap *Heap) Size() int {
	return heap.size
}

func (heap *Heap) Push(x int) {
	i := heap.size

	for i > 0 {
		// 親ノードの番号
		p := (i - 1) / 2

		// 逆転していないなら抜ける
		if heap.elems[p] >= x {
			break
		}

		// 親ノードの数字を下ろして、自分は上に
		heap.elems[i] = heap.elems[p]
		i = p
	}

	heap.elems[i] = x
	heap.size++
}

func (heap *Heap) Pop() int {
	// 最小値
	ret := heap.elems[0]
	heap.size--
	// rootに持ってくる値
	x := heap.elems[heap.size]

	// rootから下ろしていく
	i := 0
	for i*2+1 < heap.size {
		// 子同士を比較
		a, b := i*2+1, i*2+2
		if b < heap.size && heap.elems[b] > heap.elems[a] {
			a = b
		}
		if heap.elems[a] <= x {
			break
		}

		// 子の数字を持ち上げる
		heap.elems[i] = heap.elems[a]
		i = a
	}

	heap.elems[i] = x

	return ret
}

func (heap *Heap) Top() int {
	return heap.elems[0]
}

func main() {
	sc.Split(bufio.ScanWords)
	sc.Buffer(make([]byte, initialBufSize), maxBufSize)
	defer wt.Flush()

	n, m := nextInt(), nextInt()
	jobs := make(Jobs, n)
	for i := 0; i < n; i++ {
		a, b := nextInt(), nextInt()
		jobs[i] = Job{a, b}
	}
	sort.Sort(jobs)

	ans := 0
	pq := new(Heap)
	for day, id := m-1, 0; day >= 0; day-- {
		for id < n && day+jobs[id].a <= m {
			pq.Push(jobs[id].b)
			id++
		}
		if pq.size > 0 {
			ans += pq.Pop()
		}
	}

	puts(ans)
}


// Template: https://github.com/maitaken/atcoder-template
package main

import (
	"bufio"
	"container/heap"
	"fmt"
	"math"
	"os"
	"strconv"
	"strings"
)

const (
	BUFSIZE = 10000000
	MOD     = 1000000007
	INT_INF = math.MaxInt32
)

var rdr *bufio.Reader

func main() {
	rdr = bufio.NewReaderSize(os.Stdin, BUFSIZE)
	solve()
}

func solve() {
	N, M := readint2()

	queue := &IntHeap{}
	A := make([][]int, int(1e5+1))
	for i := 0; i < N; i++ {
		a, b := readint2()
		if A[a] == nil {
			A[a] = make([]int, 0)
		}
		A[a] = append(A[a], b)
	}

	ans := 0
	for i := 0; i <= M; i++ {
		for _, v := range A[i] {
			heap.Push(queue, v)
		}

		if len(*queue) == 0 {
			continue
		}
		ans += heap.Pop(queue).(int)
	}
	fmt.Println(ans)
}

func readline() string {
	buf := make([]byte, 0, 16)
	for {
		l, p, e := rdr.ReadLine()
		if e != nil {
			fmt.Println(e.Error())
			panic(e)
		}
		buf = append(buf, l...)
		if !p {
			break
		}
	}
	return string(buf)
}

func readIntSlice() []int {
	slice := make([]int, 0)
	lines := strings.Split(readline(), " ")
	for _, v := range lines {
		slice = append(slice, s2i(v))
	}
	return slice
}

func readint() int {
	return s2i(readline())
}

func readint2() (int, int) {
	lines := strings.Split(readline(), " ")
	return s2i(lines[0]), s2i(lines[1])
}

func readint3() (int, int, int) {
	lines := strings.Split(readline(), " ")
	return s2i(lines[0]), s2i(lines[1]), s2i(lines[2])
}

func readint4() (int, int, int, int) {
	lines := strings.Split(readline(), " ")
	return s2i(lines[0]), s2i(lines[1]), s2i(lines[2]), s2i(lines[3])
}

// For int
func b2i(b bool) int {
	if b {
		return 1
	}
	return 0
}

func abs(v int) int {
	if v < 0 {
		return -v
	}
	return v
}

func pow(x, y int) int {
	return int(math.Pow(float64(x), float64(y)))
}

func mod(x, y int) int {
	m := x % y
	if m < 0 {
		return m + y
	}
	return m
}

func modpow(x, y int) int {
	ret := 1
	for ; y != 0; y >>= 1 {
		if y&1 == 1 {
			ret = mod((ret * x), MOD)
		}
		x = mod(x*x, MOD)
	}
	return ret
}

func min(values ...int) int {
	ret := INT_INF
	for _, v := range values {
		if ret > v {
			ret = v
		}
	}
	return ret
}

func max(values ...int) int {
	ret := -INT_INF
	for _, v := range values {
		if ret < v {
			ret = v
		}
	}
	return ret
}

func s2i(s string) int {
	v, ok := strconv.Atoi(s)
	if ok != nil {
		panic("Faild : " + s + " can't convert to int")
	}
	return v
}

func i2s(i int) string {
	return strconv.Itoa(i)
}

func gcd(v1, v2 int) int {
	if v1 > v2 {
		v1, v2 = v2, v1
	}
	for v1 != 0 {
		v1, v2 = v2%v1, v1
	}
	return v2
}

func lcm(v1, v2 int) int {
	return v1 * v2 / gcd(v1, v2)
}

func extgcd(a, b, c int) (int, int, int) {
	if a < b {
		a, b = b, a
	}
	if b == 0 {
		return a, 1, 0
	}
	d, x, y := extgcd(b, mod(a, b), c)
	return d, y, x - int(a/b)*y
}

func bit(size int) [][]bool {
	bSize := int(math.Pow(2, float64(size)))
	b := make([][]bool, bSize)
	for i := 0; i < bSize; i++ {
		b[i] = make([]bool, size)
		for j := 0; j < size; j++ {
			if i>>j&1 == 1 {
				b[i][j] = true
			} else {
				b[i][j] = false
			}
		}
	}
	return b
}

/* ------------------------------------------------ */
/* Data stracture                                   */
/* ------------------------------------------------ */
// 簡易的なDeque (PushLeftが非常に遅い)
type Deque []interface{}

func (q *Deque) PopRight() (r interface{}) {
	l := len(*q)
	r = (*q)[l-1]
	*q = (*q)[:l-1]
	return
}

func (q *Deque) PopLeft() (r interface{}) {
	r = (*q)[0]
	*q = (*q)[1:]
	return
}

func (q *Deque) PushRight(x interface{}) {
	*q = append(*q, x)
}

func (q *Deque) PushLeft(x interface{}) {
	*q = append([]interface{}{x}, *q...)
}

type IntHeap []int

func (h *IntHeap) Push(x interface{}) {
	*h = append(*h, x.(int))
}

func (h *IntHeap) Pop() interface{} {
	old := *h
	n := len(old)
	x := old[n-1]
	*h = old[0 : n-1]
	return x
}

func (h IntHeap) Len() int           { return len(h) }
func (h IntHeap) Less(i, j int) bool { return h[i] > h[j] }
func (h IntHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }

// BIT Tree
type FenwickTree []int

func NewFenwickTree(size int) *FenwickTree {
	var t FenwickTree
	t = make([]int, size+1)
	return &t
}

func (t FenwickTree) add(index, v int) {
	for i := index + 1; i < len(t); i += (i & -i) {
		t[i] += v
	}
}

func (t FenwickTree) sum(index int) int {
	total := 0
	for i := index + 1; i != 0; i -= (i & -i) {
		total += t[i]
	}
	return total
}

type Comb struct {
	length int
	fac    []int
	inv    []int
	finv   []int
}

func NewComb() *Comb {
	return &Comb{
		length: 2,
		fac:    []int{1, 1},
		inv:    []int{1, 1},
		finv:   []int{1, 1},
	}
}

func (c Comb) calc(n, k int) int {
	if n < k {
		return 0
	}
	if n < 0 || k < 0 {
		return 0
	}

	if c.length <= n {
		for i := c.length; i <= n; i++ {
			c.fac = append(c.fac, mod(c.fac[i-1]*i, MOD))
			c.inv = append(c.inv, MOD-mod(c.inv[mod(MOD, i)]*(MOD/i), MOD))
			c.finv = append(c.finv, mod(c.finv[i-1]*c.inv[i], MOD))
		}
	}
	return mod(c.fac[n]*mod(c.finv[k]*c.finv[n-k], MOD), MOD)
}