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 Go (1.6) (judge verdict: Time Limit Exceeded)

// by https://atcoder.jp/contests/abc070/tasks/abc070_c
package main

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

var sc = bufio.NewScanner(os.Stdin)

func main() {
	var headTmp = nextLine()
	// fmt.Println(headTmp)
	var head = strings.Split(headTmp, " ")
	// fmt.Println(head)

	var N int
	var M int
	N, _ = strconv.Atoi(head[0])
	M, _ = strconv.Atoi(head[1])
	var A []int
	var B []int
	// var BB []int
	for i := 0; i < N; i++ {
		var bodyTmp = nextLine()
		// fmt.Println(bodyTmp)

		var body = strings.Split(bodyTmp, " ")
		var a, _ = strconv.Atoi(body[0])
		var b, _ = strconv.Atoi(body[1])
		A = append(A, a)
		B = append(B, b)
		// i=1~Mまでaがiより小さいか確かめる
		// １より小さいならばbを取得
		// その中で一番大きいbを取得
	}
	// fmt.Println(B)
	// sort.Sort(sort.Reverse(sort.IntSlice(B)))
	// fmt.Println(B)
	// var resA []int
	// var resB []int
	var totalMoney int

	for j := 1; j < M+1; j++ {
		// fmt.Println("j", j)

		var maxIndex int
		var maxB int

		for i := 0; i < N; i++ {
			// fmt.Println("i", i)

			// j日後より短い中で
			if A[i] <= j {
				//　価値が最大の仕事を探す
				if B[i] > maxB {
					maxIndex = i
					// fmt.Println("maxIndex", maxIndex)

					maxB = B[i]
					// fmt.Println("maxB", maxB)
				}
				// var bb = B[i]
				// BB = append(BB, bb)
			}

		}
		// resA = append(resA, A[maxIndex])
		// resB = append(resB, maxB)

		if maxB > 0 {
			totalMoney += maxB

			B[maxIndex] = 0
			// fmt.Println("maxIndex", maxIndex)

			// fmt.Println("B", B)
		}

		// A[maxIndex] = 0
		// fmt.Println("A[maxIndex]", A[maxIndex])

		// A = delete(A, maxIndex)
		// B = delete(B, maxIndex)
		//N--
		// fmt.Println(M)
		// fmt.Println("B:", B)
		// // sort.Sort(sort.Reverse(sort.IntSlice(B)))
		// // fmt.Println("sort:", B)
		// fmt.Println("BB:", BB)
		// fmt.Println("max=", maxInt(BB))

		// B = B[1:]
		// B = append(B, 0)

		// fmt.Println("B:", B)
		// BB = nil

		// fmt.Println("A:", A)
		// fmt.Println("s:", delete(A, 0))
		// fmt.Println(totalMoney)

	}
	// fmt.Println("A:", resA)
	// fmt.Println("B:", resB)
	fmt.Println(totalMoney)

	// fmt.Println("A:", A[0])
	// fmt.Println("B:", B)

	// fmt.Println("N:", N)
	// fmt.Println("M:", M)
}

func delete(s []int, i int) []int {
	x := append(s[:i], s[i+1:]...)
	return x
}

func maxInt(a []int) int {
	sort.Sort(sort.IntSlice(a))
	return a[len(a)-1]
}

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