/*
* Problem :: 14585 / 사수빈탕
*
* Kind :: Dynamic Programming
*
* Insight
* - DP 인데 시간도 고려해야한다
* + 그런데 수빈이가 1만큼 움직일 때, 시간은 1만큼 지나간다
* 즉, 현재 수빈이의 현재 좌표가 (i,j) 면 i+j 만큼의 시간이 지나간 것이다
* 현재 좌표만으로 흐른 시간을 알 수 있으니 딱히 시간의 흐름을 확인하기 위한
* 코딩은 없어도 될 듯 하다
* # 점화식 / dp[i][j] = max(dp[i-1][j], dp[i][j-1])
* -> 만약 (i,j) 에 사탕바구니가 있다면
* 남아있는 사탕의 개수 / max(0, M-(i+j))
* 점화식 / if (A[i][j]) { dp[i][j] += max(0, M-(i+j)); }
*
* Point
* - 사실 이 문제의 낚시(?)포인트는
* NxN 좌표폄면이 아니라는 것이다!
* + 문제를 잘 읽어보면 수빈이는 좌표평면에 앉아있을 뿐이지
* 그 크기에 대해서는 딱히 언급이 없다
* # 입력에서 0 <= x_i, y_i <= 300 을 통해
* 301x301 좌표평면에 앉아있는 것을 알아내야 한다
* -> 아마도 많은 사람들이 dp[N+1][N+1] 으로 선언했다가 틀리지 않았을까 싶다
*
* - max(N)=3*10^2, max(M)=10^6
* N^2*M = 9*10^10 이므로
* dp[300+1][300+1] 을 int 자료형으로 선언하면
* Overflow 가 일어나므로 long 자료형으로 선언해주자
*/
//
// BOJ
// ver.C++
//
// Created by GGlifer
//
// Open Source
#include <iostream>
#include <cstring>
using namespace std;
#define endl '\n'
// Set up : Global Variables
/* None */
// Set up : Functions Declaration
/* None */
int main()
{
// Set up : I/O
ios::sync_with_stdio(false);
cin.tie(nullptr);
// Set up : Input
int N, M;
cin >> N >> M;
bool A[300+1][300+1];
memset(A, false, sizeof(A));
for (int i=0; i<N; i++) {
int x, y;
cin >> x >> y;
A[x][y] = true; /* 사탕바구니 위치 저장 */
}
// Process
long dp[300+1][300+1]; /* 좌표평면: 301x301 */
memset(dp, 0, sizeof(dp));
for (int i=0; i<=300; i++) {
for (int j=0; j<=300; j++) {
dp[i][j] = max((i > 0) ? dp[i-1][j] : 0, (j > 0) ? dp[i][j-1] : 0);
if (A[i][j]) {
/* 흐른 시간: i+j
* 사탕바구니에서 남은 사탕의 개수: max(0, M-(i+j)) */
dp[i][j] += max(0, M-(i+j));
}
}
}
// Control : Output
cout << dp[300][300] << endl;
}
// Helper Functions
/* None */