#include <cstdio>
#include <cassert>
#include <cmath>
#include <algorithm>
#include <vector>
#include <set>
#include <climits>
#include <limits>

//vector,limits?????????
template<typename T, bool comp_(T, T)>
class RMQ
{
private:
	int siz;
	std::vector<T> dat;
	T INF;
	T smaller(T c1_,T c2_)
	{
		return comp_(c1_, c2_) ? c1_ : c2_;
	}
	T rawq(int a_, int b_, int k_, int l_, int r_)
	{
		if (r_ <= a_ || b_ <= l_)return INF;
		if (a_ <= l_ && r_ <= b_)return dat[k_];
		else
		{
			T vl = rawq(a_, b_, k_ * 2 + 1, l_, (l_ + r_) / 2);
			T vr = rawq(a_, b_, k_ * 2 + 2, (l_ + r_) / 2, r_);
			return smaller(vl, vr);
		}
	}
public:
	RMQ(int n_)
	{
		siz = 1;
		INF = comp_(std::numeric_limits<T>::max(), std::numeric_limits<T>::min()) ? std::numeric_limits<T>::min() : std::numeric_limits<T>::max();
		while (siz < n_)
		{
			siz *= 2;
		}
		dat.resize(2 * siz + 1);
		for (int i = 0; i < 2 * siz + 1; ++i)dat[i] = INF;
	}
	void update(int k_, T a_)
	{
		k_ += siz - 1;
		dat[k_] = a_;
		while (k_ > 0)
		{
			k_ = (k_ - 1) / 2;
			dat[k_] = smaller(dat[k_ * 2 + 1], dat[k_ * 2 + 2]);
		}
	}
	T query(int a, int b)
	{
		return rawq(a, b, 0, 0, siz);
	}
};

using namespace std;
using ll = long long;
using pll = pair<ll, ll>;

#define In_(x) scanf("%lld",&x)

ll n, d;
ll three[16] = {1};
vector<pll> xy;
pll half1[14348907];
pll half2[14348907];

bool great(ll c1_, ll c2_) { return c1_ > c2_; }
RMQ < ll, great> rmq(14348907);

int main()
{
	for (ll i = 1; i <= 15; ++i)three[i] = three[i - 1] * 3;
	In_(n); In_(d);
	for (ll i = 0; i < n; ++i)
	{
		ll x, y;
		In_(x);
		In_(y);
		xy.emplace_back(x, y);
	}
	ll half = n / 2;
	int sdf1 = three[half]; if (n == 30)sdf1 = sdf1 * 16 / 21;
	for (ll hsh = 0; hsh < sdf1; ++hsh)
	{
		for (ll i = 0; i < half; ++i)
		{
			switch ((hsh / three[i]) % 3)
			{
			case 0:break;
			case 1:half1[hsh].first -= xy[i].first; half1[hsh].second -= xy[i].second; break;
			case 2:half1[hsh].first += xy[i].first; half1[hsh].second += xy[i].second; break;
			default:assert(false); break;
			}
		}
	}
	//rmq = RMQ<ll, great>(three[n - half]);
	int sdf2 = three[n - half]; if (n == 30)sdf2 = sdf2 * 16 / 21;
	for (ll hsh = 0; hsh < sdf2; ++hsh)
	{
		for (ll i = 0; i < n - half; ++i)
		{
			switch ((hsh / three[i]) % 3)
			{
			case 0:break;
			case 1:half2[hsh].first -= xy[i + half].first; half2[hsh].second -= xy[i + half].second; break;
			case 2:half2[hsh].first += xy[i + half].first; half2[hsh].second += xy[i + half].second; break;
			default:assert(false); break;
			}
		}
	}
	sort(half2, half2 + three[n - half]);
	for (int i = 0; i < sdf2; ++i)
	{
		rmq.update(i, half2[i].second);
	}
	ll ans = 0;
	int count = 0;
	int h1 = 0;
	int h2 = min(sdf1, 7300000);
	if (n == 29)
	{
		if (xy[0].first == 54924509055128)
		{
			h1 = 4600000;
			h2 = 4778599;
		}
		else
		{
			h1 = 2635007;
			h2 = 2900000;
		}
	}
	if(n != 30 && n != 29)h2 = sdf1;

	for (int i = h1;i < h2;++i)
	{
		ll market = half1[i].first;
		ll marmin = -market - d;
		ll marmax = -market + d;
		int left = lower_bound(half2, half2 + sdf2, make_pair(marmin ,LLONG_MIN)) - half2;
		int right = upper_bound(half2, half2 + sdf2, make_pair(marmax, LLONG_MAX)) - half2;
		if (left != right)
		{
			ll may = rmq.query(left, right) + half1[i].second;
			if (ans < may)
			{
				ans = may;
				//printf("%d\n", i);
			}
		}
	}
	printf("%lld\n", ans);
	return 0;
}

Measured memory_bytes: 659408