import std.stdio, std.string, std.conv, std.algorithm;
import std.typecons;
import std.array, std.range, std.container;
 
void main() {
	auto data = readln.split;
	auto N = data[0].to!ulong, K = data[1].to!ulong;
	Tuple!(ulong, ulong)[] sushi;
	foreach (i; 0 .. N) {
		data = readln.split;
		sushi ~= tuple(data[0].to!ulong, data[1].to!ulong);
	}
	sushi = sushi.sort!( (a,b) => a[1] > b[1] || (a[1]==b[1] && a[0] > b[0]) ).array;
	
	ulong result;
	foreach (number; 1 .. K+1) {
		ulong result2 = 0;
		// the indexes of sushi to be eaten
		bool[100007] sushi_list;
		bool[100007] t_list;
		ulong count;
		
		// add "number" types of sushi;
		foreach (index, s; sushi) {
			if (count == number) break;
			// new type of sushi
			if (!t_list[s[0]] && count < number) {
				t_list[s[0]] = true;
				sushi_list[index] = true; 
				result2 += s[1];
				count++;
			}
			
		}
		// there are no "number" types of sushi given
		if (count < number) break;
		
		//writeln(sushi_list);
		
		foreach (index, s; sushi) {
			if (count == K) break;
			if (!sushi_list[index] && t_list[s[0]]) {
				sushi_list[index] = true;
				result2 += s[1];
				count++;
			}
		}
		
		result2 += number * number;
		//writeln(sushi_list, sushi_list.map!(x => sushi[x][1]), sushi_list.map!(x => sushi[x][1]).reduce!("a+b"));
		
		result = max(result, result2);
	}
	writeln(result);
}

