import std.stdio;
import std.algorithm;
import core.stdc.stdio;
import std.range;
import std.math;
import core.memory;
import std.datetime;

int power3(int k){
	if(k==0)
		return 1;
	else
		return 3*power3(k-1);
}

static immutable long INF = 1L<<60;

struct vp{
	long v;
	long p;
	int opCmp(const ref vp rhs)const{
		if(v<rhs.v)
			return -1;
		if(v>rhs.v)
			return 1;
		return 0;
	}
}

struct SegmentTree{
	long[] data;
	int s = 1;
	void Initiaize(vp[] d){
		int h=1;
		while(s<d.length) s *= 2;
		data = new long[s*2];
		for(int i=0;i<d.length;i++)
			data[s+i] = d[i].p;
		data[s+d.length..$] = -INF;
		for(int i=s-1;i>=1;i--){
			data[i] = max(data[i*2],data[i*2+1]);
		}
	}
	long _rmq(int b,int e,int l,int r,int i){
		if(r<=b || e<=l)
			return -INF;
		if(b<=l && r<=e)
			return data[i];
		return max(_rmq(b,e,l,(l+r)/2,i*2),_rmq(b,e,(l+r)/2,r,i*2+1));
	}
	long RMQ(int b,int e){
		if(e<=b)
			return -INF;
		return _rmq(b,e,0,s,1);
	}
}

void Calc(ref vp[] vps,long[] vals,long[] pres){
	int size = power3(cast(int)vals.length);
	vps = new vp[size];
	
	void _calc(int c,int idx,long v,long p){
		if(c==cast(int)vals.length){
			vps[idx] = vp(v,p);
		}else{
			_calc(c+1,idx*3,v-vals[c],p-pres[c]);
			_calc(c+1,idx*3+1,v+vals[c],p+pres[c]);
			_calc(c+1,idx*3+2,v,p);
		}
	}
	
	_calc(0,0,0,0);
	
	//sort(vps);
}

static immutable long noMinus = 1L<<55;
void BaseSort(int bits,int mask)(ref vp[] data,ref vp[] buf,int len){
	static int[mask+1] si;
	for(int i=0;i<56;i+=bits){
		si[] = 0;
		for(int j=0;j<len;j++){
			si[(data[j].v+noMinus>>i)&mask]++;
		}
		int last=0;
		for(int j=0;j<mask+1;j++){
			swap(si[j],last);
			last += si[j];
		}
		for(int j=0;j<len;j++){
			buf[si[(data[j].v+noMinus>>i)&mask]++] = data[j];
		}
		swap(data,buf);
	}
}

void main(){
	GC.disable;

	int n;
	long d;
	scanf("%d%lld",&n,&d);
	long[] vals = new long[n];
	long[] pres = new long[n];

	for(int i=0;i<n;i++){
		scanf("%lld%lld",&vals[i],&pres[i]);
	}

	vp[] avp,bvp;
	Calc(avp,vals[n/2..$],pres[n/2..$]);
	Calc(bvp,vals[0..n/2],pres[0..n/2]);
	
	vp[] buf = new vp[max(avp.length,bvp.length)];
	
	BaseSort!(14,(1<<14)-1)(avp,buf,cast(int)avp.length);
	BaseSort!(14,(1<<14)-1)(bvp,buf,cast(int)bvp.length);
	
	SegmentTree seg;
	seg.Initiaize(bvp);
	
	long ans=0;
	
	int l=0;
	int r=0;
	for(int i=cast(int)avp.length-1;i>=0;i--){
		if(abs(avp[i].v)<=d){
			ans = max(ans,avp[i].p);
		}
		while(l<bvp.length && bvp[l].v + avp[i].v < -d) l++;
		while(r<bvp.length && bvp[r].v + avp[i].v <= d) r++;
		long q = seg.RMQ(l,r);
		ans = max(ans,avp[i].p+q);
	}
	printf("%lld\n",ans);
}