#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
#include <utility>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <deque>
#include <functional>

using namespace std;

#define int long long

#define fst first
#define scd second
#define PB push_back
#define MP make_pair
#define all(a) a.begin(),a.end()
#define rall(a) a.rbegin(),a.rend()
#define omajinai ios::sync_with_stdio(false);cin.tie(0)
#define rep(i,x) for(int i=0;i<(int)(x);++i)
#define rep1(i,x) for(int i=1;i<=(int)(x);++i)

typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int, int> pii;
typedef vector<pii> vpii;

template<typename T>T& max(T&a,T&b){if(a>=b)return a;return b;}
template<typename T>T& min(T&a,T&b){if(a<b)return a;return b;}
template<typename T>bool chmax(T&a,T b){if(a<b){a=b;return true;}return false;}
template<typename T>bool chmin(T&a,T b){if(a>b){a=b;return true;}return false;}
template<typename T>T get(){T a;cin>>a;return a;}
template<typename T>T rev(T a){reverse(all(a));return a;}
template<typename T>vector<T>&sort(vector<T>&a){sort(all(a));return a;}

const int inf = 3e18;
const double eps = 1e-9;

struct Data {
	int fst, scd;
	Data(int fst, int scd) : fst(fst), scd(scd) {}
	bool operator<(const Data &d) const {
		if (fst == d.fst) return scd < d.scd;
		return fst < d.fst;
	}
	bool operator>(const Data& d) const {
		if (fst == d.fst) return scd > d.scd;
		return fst > d.fst;
	}
};

struct RMQ {
	vi dat;
	int n;

	RMQ(int n_) {
		n = 1;

		while (n < n_) n *= 2;
		dat.resize(2 * n, -inf);
	}

	inline void update(int i, int v) {
		i += n - 1;

		dat[i] = v;

		while (i > 0) {
			i = (i - 1) / 2;
			dat[i] = max(dat[i * 2 + 1], dat[i * 2 + 2]);
		}
	}

	inline int query(int a, int b, int k = 0, int l = 0, int r = -1) {
		if (r == -1) r = n;
		if (r <= a || b <= l) return -inf;
		if (a <= l && r <= b) return dat[k];
		
		int vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
		int vr = query(a, b, k * 2 + 2, (l + r) / 2, r);

		return max(vl, vr);
	}
};

vector<Data> treasures;
vector<Data> half1, half2;
int A[15000000];
int B[15000000];

signed main()
{ // #define int long long ?????????????????§scanf???????????¨???????????????????????\?????????????????????
	omajinai;
	int N, D; cin >> N >> D;

	rep(i, N) {
		int X, Y; cin >> X >> Y;
		treasures.PB(Data(X, Y));
	}

	for (int i = 0, n = N / 2 + N % 2, len = pow(3, n); i < len; ++i) {
		int diff1 = 0, diff2 = 0;

		for (int j = 0, I = i; j < n; ++j) {
			switch (I % 3) {
				case 0:
					break;
				case 1:
					diff1 += treasures[N / 2 + j].fst;
					diff2 -= treasures[N / 2 + j].scd;
					break;
				case 2:
					diff1 -= treasures[N / 2 + j].fst;
					diff2 += treasures[N / 2 + j].scd;
					break;
			}

			I /= 3;
		}

		half2.PB(Data(diff1, diff2));
	}

	RMQ rmq(half2.size());

	sort(all(half2));

	rep(i, half2.size()) {
		A[i] = half2[i].fst;
		B[i] = half2[i].scd;

		rmq.update(i, B[i]);
	}

	int ans = -inf;

	for (int i = 0, n = N / 2, len = pow(3, n); i < len; ++i) {
		int diff1 = 0, diff2 = 0;

		for (int j = 0, I = i; j < n; ++j) {
			switch (I % 3) {
				case 0:
					break;
				case 1:
					diff1 += treasures[j].fst;
					diff2 -= treasures[j].scd;
					break;
				case 2:
					diff1 -= treasures[j].fst;
					diff2 += treasures[j].scd;
					break;
			}

			I /= 3;
		}

		half1.PB(Data(diff1, diff2));
	}

	sort(all(half1), greater<Data>());

	int lidx = 0, ridx = 0;

	rep(i, half1.size()) {
		Data &da = half1[i];

		int lv = min(-D - da.fst, D - da.fst);
		int rv = max(-D - da.fst, D - da.fst);
		
		while (A[lidx] < lv && lidx + 1 < half2.size()) lidx++;
		while ((lidx > ridx) || (A[ridx] <= rv && ridx + 1 < half2.size())) ridx++;
		ridx--;

		if (lidx > ridx) continue;

		ans = max(ans, da.scd + rmq.query(lidx, ridx + 1));
	}

	cout << ans << endl;
}

Measured memory_bytes: 977684