#include<map>
#include<set>
#include<iostream>
#include<cstdio>
#include<vector>
#include<deque>
#include<algorithm>
#include<unordered_map>
#include<climits>
#include<vector>
#include<cstring>
#include<cassert>
#include<cmath>

#define REP(i,s,n) for(int i=s;i<n;++i)
#define rep(i,n) REP(i,0,n)
#define ALL(x) x.begin(),x.end()

using namespace std;

typedef long long ll;

#define MAX 31
#define IINF LLONG_MAX


class RMQ{
private:
  int limit,N;
  vector<ll> dat;
public:
  void init(int n_){
    N = n_;
    limit = 1LL;
    while(limit<n_)limit*=2;
    dat.clear();
    dat.resize(2*limit,-IINF);
  }
  
  ll _build(int cur,int L,int R,const vector<ll> &buf){
    if( !( 0 <= cur && cur < 2*limit ) ) return -IINF;
    if( L == R-1 ) {
      if( L >= N ) return -IINF;
      dat[cur] = buf[L];
    } else {
      ll vl = _build(cur*2+1,L,(L+R)/2,buf);
      ll vr = _build(cur*2+2,(L+R)/2,R,buf);
      dat[cur] = max(vl,vr);
    }
    return dat[cur];
  }

  void build(const vector<ll> &buf){ _build(0,0,limit,buf); };

  ll _query(int a,int b,int k,int l,int r){
    if(r<=a || b<=l)return -IINF;
    else if(a<=l && r<=b)return dat[k];
    ll vl = _query(a,b,k*2+1,l,(l+r)/2);
    ll vr = _query(a,b,k*2+2,(l+r)/2,r);
    return max(vl,vr);
  }

  ll query(int a,int b){ return _query(a,b,0,0,limit); }
};

int N;
ll D,X[MAX],Y[MAX];
struct Data {
  ll v,w;
  bool operator == ( const Data &data ) const {
    return v == data.v && w == data.w;
  }
  bool operator < ( const Data &data ) const {
    if( v != data.v ) return v < data.v;
    return w > data.w;
  }
};
vector<Data> v1,v2;

void dfs(vector<Data> &vec,int base,int cur,int rem,ll v,ll w) {
  if( rem <= 0 ) {
    //mp[v] = max(mp[v],w);
    vec.push_back((Data){v,w});
    return;
  }
  int ID = base + cur;
  assert( ID < N );
  dfs(vec,base,cur+1,rem-1,v,w);
  dfs(vec,base,cur+1,rem-1,v-X[ID],w-Y[ID]); // Anna
  dfs(vec,base,cur+1,rem-1,v+X[ID],w+Y[ID]); // Bruno
}

void compute() {
  {
  int M = N / 2;
  dfs(v1,0,0,M,0,0);
  //puts("-");
  sort(ALL(v1));
  //puts("--");
  v1.erase(unique(ALL(v1)),v1.end());
  //puts("---");
  vector<Data> tvec;
  ll cur = -IINF;
  rep(i,(int)v1.size()) if( v1[i].v != cur ) {
    cur = v1[i].v;
    tvec.push_back(v1[i]);
  }
  v1 = tvec;
  tvec.clear();
  cur = -IINF;
  //puts("-----");
  dfs(v2,M,0,N-M,0,0);
  //puts("------");
  sort(ALL(v2));
  //puts("-------");
  v2.erase(unique(ALL(v2)),v2.end());
  //puts("--------");
  rep(i,(int)v2.size()) if( v2[i].v != cur ) {
    cur = v2[i].v;
    tvec.push_back(v2[i]);
  }
  v2 = tvec;
  //puts("---------");
  }
  RMQ rmq;
  vector<ll> vec;
  {
    vector<ll> buf;
    for(auto v : v2) {
      vec.push_back(v.v);
      buf.push_back(v.w);
    }
    rmq.init((int)buf.size());
    rmq.build(buf);
  }

  ll ans = 0;
  for(auto v : v1) {
    int ptr_L = lower_bound(vec.begin(),vec.end(),-D-v.v) - vec.begin();
    int ptr_R = upper_bound(vec.begin(),vec.end(), D-v.v) - vec.begin();
    if( llabs(v.v + vec[ptr_L]) > D ) continue;
    ans = max(ans,v.w+rmq.query(ptr_L,ptr_R));
  }
  cout << ans << endl;
}

int main() {
  if( 0 ) {
    N = 30;
    D = 1000000000000000LL;
    cout << N << " " << D << endl;
    rep(i,N) {
      cout << rand() << " " << rand() << endl;
    }
    return 0;
  }
  cin >> N >> D;
  rep(i,N) cin >> X[i] >> Y[i];
  compute();
  return 0;
}

Measured memory_bytes: 871440