package main

import (
    "bufio"
    "os"
    "strings"
    "strconv"
    "fmt"
    "sort"
    "container/heap"
    "math"
)

var sc = bufio.NewScanner(os.Stdin)

func readLineToInt() []int {
    sc.Scan()
    line := strings.Split(sc.Text(), " ")
    var intLine []int
    for _, str := range line {
        n, _ := strconv.Atoi(str)
        intLine = append(intLine, n)
    }
    return intLine
}


/****************** Pair ********************/
type Pair struct {
    a int
    b int
}

type SortablePairs struct {
    arr []*Pair
    lessfunc []lessFunc
}

type lessFunc func(i, j *Pair) bool

func (sp SortablePairs) Len() int {
    return len(sp.arr)
}

func (sp SortablePairs) Swap(i, j int) {
    sp.arr[i], sp.arr[j] = sp.arr[j], sp.arr[i]
}

func (sp SortablePairs) Less(i, j int) bool {
    p, q := sp.arr[i], sp.arr[j]
    for k := 0; k < len(sp.lessfunc); k++ {
        less := sp.lessfunc[k]
        if less(p, q) {
            return true
        } else if less(q, p) {
            return false
        }
    }
    return false
}

/***************** HeapQue *****************/

type PriorityQueue struct {
    arr []*Pair
    size int
}
/** sort **/
func (pq PriorityQueue) Len() int {
    return len(pq.arr)
}

func (pq PriorityQueue) Swap(i, j int) {
    pq.arr[i], pq.arr[j] = pq.arr[j], pq.arr[i]
}

func (pq PriorityQueue) Less(i, j int) bool{
    return pq.arr[i].a < pq.arr[j].a
}

/**** pq ****/
func (pq *PriorityQueue) Push(x interface{}) {
    item := x.(*Pair)
    pq.arr = append(pq.arr, item)
    pq.size++
}

func (pq *PriorityQueue) Pop() interface{} {
    n := pq.size
    item := pq.arr[n - 1]
    pq.arr = pq.arr[:n - 1]
    pq.size--
    return item
}

func max(a, b int) int {
    return int(math.Max(float64(a), float64(b)))
}

func main() {
    nk := readLineToInt()
    n, k := nk[0], nk[1]
    var dic map[int][]int = map[int][]int{}
    var keys []int
    for i := 0; i < n; i++ {
        td := readLineToInt()
        t, d := td[0], td[1]
        _, ok := dic[t]
        if !ok {
            keys = append(keys, t)
        }
        dic[t] = append(dic[t], d)
    }

    var sp SortablePairs
    less := func(p, q *Pair) bool {
        return p.a >= q.a
    }
    sp.lessfunc = append(sp.lessfunc, less)
    for _, key := range keys {
        sort.Ints(dic[key])
        length := len(dic[key])
        sp.arr = append(sp.arr, &Pair{dic[key][length - 1], key})
        dic[key] = dic[key][:length - 1]
    }
    sort.Sort(sp)
    var que PriorityQueue
    heap.Init(&que)
    queScore := 0
    defaultScore := 0
    cnt := 0
    ans := 0
    for _, p := range sp.arr {
        defaultScore += p.a + cnt * 2 + 1
        cnt++
        if cnt >= k {
            ans = max(ans, defaultScore)
            break
        }
        for _, add := range dic[p.b] {
            heap.Push(&que, &Pair{add, p.b})
            queScore += add
        }
        for que.size > k - cnt {
            item := heap.Pop(&que).(*Pair)
            queScore -= item.a
        }
        ans = max(ans, defaultScore + queScore)
    }
    fmt.Println(ans)

}

### FIXED CODE ###

from collections import defaultdict
from heapq import heappush, heappop


n, k = map(int, input().split())
dic = defaultdict(list)
for _ in range(n):
    t, d = map(int, input().split())
    dic[t].append(d)

maxs = []
for key in dic:
    dic[key].sort()
    maxs.append((dic[key].pop(), key))

maxs.sort(reverse=True)
queSize = 0
que = []
queScore = 0
defaultScore = 0
cnt = 0
ans = 0
for v, key in maxs:
    defaultScore += v + cnt * 2 + 1
    cnt += 1
    if cnt >= k:
        ans = max(ans, defaultScore)
        break
    for add in dic[key]:
        heappush(que, add)
        queSize += 1
        queScore += add
    while queSize > k - cnt:
        queScore -= heappop(que)
        queSize -= 1
    ans = max(ans, defaultScore + queScore)

print(ans)