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 Java8 (OpenJDK 1.8.0) (judge verdict: Accepted)

import java.awt.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.StringTokenizer;
import java.io.PrintWriter;
import java.util.TreeSet;

public class Main {
    static class Scanner {
        BufferedReader br;
        StringTokenizer tk = new StringTokenizer("");

    public Scanner(InputStream is) {
        br = new BufferedReader(new InputStreamReader(is));
    }

    public int nextInt() throws IOException {
        if (tk.hasMoreTokens())
            return Integer.parseInt(tk.nextToken());
        tk = new StringTokenizer(br.readLine());
        return nextInt();
    }

    public long nextLong() throws IOException {
        if (tk.hasMoreTokens())
            return Long.parseLong(tk.nextToken());
        tk = new StringTokenizer(br.readLine());
        return nextLong();
    }

    public String next() throws IOException {
        if (tk.hasMoreTokens())
            return (tk.nextToken());
        tk = new StringTokenizer(br.readLine());
        return next();
    }

    public String nextLine() throws IOException {
        tk = new StringTokenizer("");
        return br.readLine();
    }

    public double nextDouble() throws IOException {
        if (tk.hasMoreTokens())
            return Double.parseDouble(tk.nextToken());
        tk = new StringTokenizer(br.readLine());
        return nextDouble();
    }

    public char nextChar() throws IOException {
        if (tk.hasMoreTokens())
            return (tk.nextToken().charAt(0));
        tk = new StringTokenizer(br.readLine());
        return nextChar();
    }

    public int[] nextIntArray(int n) throws IOException {
        int a[] = new int[n];
        for (int i = 0; i < n; i++)
            a[i] = nextInt();
        return a;
    }

    public long[] nextLongArray(int n) throws IOException {
        long a[] = new long[n];
        for (int i = 0; i < n; i++)
            a[i] = nextLong();
        return a;
    }

    public int[] nextIntArrayOneBased(int n) throws IOException {
        int a[] = new int[n + 1];
        for (int i = 1; i <= n; i++)
            a[i] = nextInt();
        return a;
    }

    public long[] nextLongArrayOneBased(int n) throws IOException {
        long a[] = new long[n + 1];
        for (int i = 1; i <= n; i++)
            a[i] = nextLong();
        return a;
    }


}

    public static void main(String args[]) throws IOException {
        new Thread(null, new Runnable() {
            public void run() {
                try {
                    solve();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, "1", 1 << 26).start();

    }

    static void solve() throws IOException {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        TreeSet<Integer> rd=new TreeSet<>();
        int n=in.nextInt(), m=in.nextInt();
        for(int i=0;i<m;i++)
            rd.add(i);
        ArrayList<Point> ar=new ArrayList<>();
        for(int i=0;i<n;i++){
            int a=in.nextInt();
            int b=in.nextInt();
            ar.add(new Point(a,b));
        }
        Collections.sort(ar, (a,b)->a.y>b.y?-1:a.y<b.y?1:a.x>b.x?-1:a.x<b.x?1:0);
        int ans=0;
        for(Point p:ar){
            int tm=m-p.x;
            Integer c=rd.floor(tm);
            if(c!=null){
                ans+=p.y;
                rd.remove(c.intValue());
            }
        }
        out.println(ans);

        out.close();

    }
}