Problem:
Score : 400 points

Problem Statement

There are N one-off jobs available. If you take the i-th job and complete it, you will earn the reward of B_i after A_i days from the day you do it.

You can take and complete at most one of these jobs in a day.

However, you cannot retake a job that you have already done.

Find the maximum total reward that you can earn no later than M days from today.

You can already start working today.

Constraints

All values in input are integers.

1 \leq N \leq 10^5

1 \leq M \leq 10^5

1 \leq A_i \leq 10^5

1 \leq B_i \leq 10^4

Input

Input is given from Standard Input in the following format:

N M
A_1 B_1
A_2 B_2
\vdots
A_N B_N

Output

Print the maximum total reward that you can earn no later than M days from today.

Sample Input 1

3 4
4 3
4 1
2 2

Sample Output 1

5

You can earn the total reward of 5 by taking the jobs as follows:

Take and complete the first job today. You will earn the reward of 3 after four days from today.

Take and complete the third job tomorrow. You will earn the reward of 2 after two days from tomorrow, that is, after three days from today.

Sample Input 2

5 3
1 2
1 3
1 4
2 1
2 3

Sample Output 2

10

Sample Input 3

1 1
2 1

Sample Output 3

0

Solution in Java7 (OpenJDK 1.7.0) (judge verdict: Wrong Answer)

import java.util.*;
import java.io.*;
import java.lang.*;
import java.math.*;
public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
        // int n = Integer.parseInt(bf.readLine());
        StringTokenizer st = new StringTokenizer(bf.readLine());
        // int[] a = new int[n]; for(int i=0; i<n; i++) a[i] = Integer.parseInt(st.nextToken());
        int n = Integer.parseInt(st.nextToken());
        int m = Integer.parseInt(st.nextToken());
        Pair[] a = new Pair[n];
        Map<Pair, Integer> counts = new HashMap<Pair, Integer>();
        TreeSet<Pair> vals = new TreeSet<Pair>();
        for(int i=0; i<n; i++) {
          st = new StringTokenizer(bf.readLine());
          int x = Integer.parseInt(st.nextToken());
          int y = Integer.parseInt(st.nextToken());
          a[i] = new Pair(x, y);
          //Pair rev= new Pair(y, x);

        }
        Arrays.sort(a);
        long ans = 0; int cur = 1;
        for(int i=0; i<n; i++) {
          //out.println(a[i].a + " " + a[i].b);
          while(a[i].a > cur) {
            if(!vals.isEmpty()) {
            Pair pp = vals.last();
          //  out.println(pp.a + " " + pp.b);
            counts.put(pp, counts.get(pp)-1);
            if(counts.get(pp)==0) vals.remove(pp);
            ans += pp.a;
            }
            if(cur > m) break;
            cur++;

          }

            Pair rr = new Pair(a[i].b, a[i].a);

            if(!counts.containsKey(rr)) counts.put(rr, 0);
            counts.put(rr, counts.get(rr)+1);
            vals.add(rr);



        }
        while((!vals.isEmpty()) && (cur <= m)) {
        Pair pp = vals.last();
        counts.put(pp, counts.get(pp)-1);
        if(counts.get(pp)==0) vals.remove(pp);
        ans += pp.a;
        cur++;
        //out.println(pp.a + " " + pp.b);
        }
        out.println(ans);
        out.close(); System.exit(0);
    }

}
class Pair implements Comparable<Pair> {
  public int a;
  public int b;
  public Pair(int a, int b) {
    this.a = a;
    this.b = b;
  }
  @Override
  public boolean equals(Object o) {
    Pair p = (Pair)o;
    return (this.compareTo(p) == 0);
  }

  @Override
  public int hashCode() {
    return (int)((1L*a*103948902382L+b) % 1000000007);
  }

  @Override
  public int compareTo(Pair p) {
    if(this.a > p.a) return 1;
    if(this.a < p.a) return -1;
    if(this.b < p.b) return 1;
    if(this.b > p.b) return -1;
    return 0;
  }
}