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: Time Limit Exceeded)

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

public class Main {

    void solve() {
        Scanner sc = new Scanner(System.in);
        int numOfJob = sc.nextInt(); // N
        int deadline = sc.nextInt(); // M
        // List<Job> jobs = new LinkedList<>();
        List<Job> jobs = new ArrayList<>();
        for (int i = 0; i < numOfJob; i++) {
            int delay = sc.nextInt(); // A[i]
            int reward = sc.nextInt(); // B[i]
            jobs.add(new Job(delay, reward));
        }
        // delay の昇順に並び替え
        jobs.sort((a, b) -> a.delay - b.delay);

        int ans = 0;
        // 制約の厳しい後ろの日程から見ていく。
        // こういう問題では制約の大きい方から見ていくのが定石らしい。
        // 制約が大きい方が決まりやすいからかな。
        for (int day = deadline - 1; day >= 0; day--) {
            int havingDay = deadline - day;
            // jobsを引数で渡せば、ローカル変数で済む。
            Job bestJob = findBestJob(jobs, havingDay);
            if (bestJob == null) continue;
            ans += bestJob.getReward();
            // 一度使ったjobは使用できないので、削除する。
            // removeの引数には、jobオブジェクトを指定できる。
            jobs.remove(bestJob);
        }

        System.out.print(ans);
    }

    Job findBestJob(List<Job> jobs, int havingDay) {
        if (jobs.size() == 0) return null;
        // 初期値として最低なJobを設定する。
        Job bestJob = new Job(0 ,0);
        for (Job job : jobs) {
            if (job.getDelay() <= havingDay) {
                if (job.getReward() > bestJob.getReward()) {
                    bestJob = job;
                }
            }
            else {
                break;
            }
        }
        if (bestJob.getReward() == 0) {
            return null;
        }
        else {
            return bestJob;
        }
    }

    class Job {
        private int delay;
        private int reward;

        Job(int delay, int reward) {
            this.delay = delay;
            this.reward = reward;
        }
        int getDelay() {
            return delay;
        }
        int getReward() {
            return reward;
        }
    }

    // Main
    public static void main(String[] args) {
        new Main().solve();
    }
}