#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: 977904