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

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

int lowerBoundIdx(long[] data,long t){
	int l=0;
	int r=cast(int)data.length+1;
	while(r-l>1){
		int m = (r+l)/2;
		if(data[m-1] < t)
			l=m;
		else
			r=m;
	}
	return l;
}

static immutable long INF = 8108931919114514;

struct SegmentTree{
	long[] data;
	int s = 1;
	void Initiaize(long[] d){
		int h=1;
		while(s<d.length) s *= 2;
		data = new long[s*2];
		data[s..s+d.length] = d;
		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 main(){
	int n,d;
	scanf("%d%d",&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]);
	}

	int size = power3(n/2);
	long[] buf = new long[size*2];
	long[] vs = buf[0..size],ps = buf[size..size*2];
	
	for(int i=0;i<size;i++){
		int s=i;
		for(int j=0;j<n/2;j++){
			int t = s%3;
			s/=3;
			if(t==0){
				vs[i] -= vals[j];
				ps[i] -= pres[j];
			}else if(t==1){
				vs[i] += vals[j];
				ps[i] += pres[j];
			}
		}
	}
	
	sort(zip(vs,ps));
	
	SegmentTree seg;
	seg.Initiaize(ps);
	
	long ans=0;
	
	int size2 = power3(n-n/2);
	for(int i=0;i<size2;i++){
		long v=0,p=0;
		int s=i;
		for(int j=n/2;j<n;j++){
			int t = s%3;
			s/=3;
			if(t==0){
				v -= vals[j];
				p -= pres[j];
			}else if(t==1){
				v += vals[j];
				p += pres[j];
			}
		}
		if(abs(v)<=d){
			ans = max(ans,p);
		}
		int l = vs.lowerBoundIdx(-v-d);
		int r = vs.lowerBoundIdx(-v+d+1);
		long q = seg.RMQ(l,r);
		ans = max(ans,p+q);
	}
	
	printf("%lld\n",ans);
}