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: Wrong Answer)

package main

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

const MaxInt = int(^uint(0) >> 1)
const MinInt = -MaxInt - 1

var sc = bufio.NewScanner(os.Stdin)

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

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

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

type QueueItem struct {
	key, value int
}

func (q Queue) isPrior(i, j int) bool {
	return q.body[i].key > q.body[j].key
}
func (q Queue) swap(i, j int) {
	q.body[i], q.body[j] = q.body[j], q.body[i]
}

type Queue struct {
	body []QueueItem
	size int
}

func NewQueue() *Queue {
	return &Queue{[]QueueItem{}, 0}
}

func (q *Queue) Push(item QueueItem) {
	q.body = append(q.body, item)
	index := q.size
	q.size++
	for index > 0 {
		parentIndex := ((index + 1) >> 1) - 1
		if q.isPrior(index, parentIndex) {
			q.swap(index, parentIndex)
			index = parentIndex
		} else {
			break
		}
	}
}

func (q *Queue) Peek() QueueItem {
	return q.body[0]
}

func (q *Queue) Pop() QueueItem {
	result := q.body[0]
	q.body[0] = q.body[q.size-1]
	q.size--
	q.body = q.body[:q.size]
	for index := 0; index < q.size; {
		lIndex := ((index + 1) << 1) - 1
		if lIndex >= q.size || q.isPrior(index, lIndex) {
			break
		}
		rIndex := lIndex + 1
		if rIndex < q.size && !q.isPrior(lIndex, rIndex) {
			q.swap(index, rIndex)
			index = rIndex
		} else {
			q.swap(index, lIndex)
			index = lIndex
		}
	}
	return result
}

func (q *Queue) Size() int {
	return q.size
}

func main() {
	sc.Split(bufio.ScanWords)

	n := nextInt()
	m := nextInt()

	dateMap := make(map[int][]int)
	for i := 0; i < n; i++ {
		date, salary := nextInt(), nextInt()
		dateMap[date] = append(dateMap[date], salary)
	}
	//fmt.Printf("%v\n", dateMap)

	total := 0
	q := NewQueue()
	for d := m - 1; d >= 0; d-- {
		if salaries, ok := dateMap[m-d]; ok {
			for _, v := range salaries {
				q.Push(QueueItem{v, m - d})
			}
		}
		//fmt.Printf("%v\n", q)
		if q.Size() > 0 {
			total += q.Pop().key
		}
	}

	fmt.Printf("%d\n", total)
}