#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

#define HUGE_NUM 999999999999999999

enum Type{
	One,
	Two,
};

enum Which{
	A,
	B,
	Skip,
};

struct Data{
	ll market_value,precious_degree;
};

struct Info{
	Info(ll arg_market_value_diff,ll arg_precious_degree_diff){
		market_value_diff = arg_market_value_diff;
		precious_degree_diff = arg_precious_degree_diff;
	}
	bool operator<(const struct Info &arg) const{ //市場価値の差の降順
		return market_value_diff > arg.market_value_diff;
	}
	bool operator==(const struct Info &arg) const{
		return market_value_diff == arg.market_value_diff
				&&precious_degree_diff == arg.precious_degree_diff;
	}

	ll market_value_diff,precious_degree_diff;
};

ll N,DIFF;
Data data[30];
int start_index[2],end_index[2];
vector<Info> V[2];
ll* table;
int SIZE = 1;

//簡易化のため、要素数を2のべき乗にする関数
void init(int first_N){
	while(SIZE < first_N)SIZE *= 2;
}

void update(int loc,ll value){
	loc += SIZE-1;

	table[loc] = value;

	if(N == 1)return;

	int parent = (loc-1)/2;

	while(true){
		table[parent] = max(table[2*parent+1],table[2*parent+2]); //親は左右の子の大きい方の値を持つ

		if(parent == 0)break;
		else{
			parent = (parent-1)/2;
		}
	}
}


ll query(int search_left,int search_right,int node_id,int node_left,int node_right){

	if(search_right < node_left || search_left > node_right)return -HUGE_NUM;

	if(search_left <= node_left && search_right >= node_right){
		return table[node_id];
	}

	ll left_max = query(search_left,search_right,2*node_id+1,node_left,(node_left+node_right)/2);
	ll right_max = query(search_left,search_right,2*node_id+2,(node_left+node_right)/2+1,node_right);

	return max(left_max,right_max);
}


bool rangeCheck(ll value){
	if(value >= -DIFF && value <= DIFF){
		return true;
	}else{
		return false;
	}
}

void make_group(Which array[30],int index,Type type){
	if(index == end_index[type]+1){

		ll A_market = 0,A_precious = 0,B_market = 0,B_precious = 0;
		for(int i = start_index[type]; i <= end_index[type]; i++){
			if(array[i] == Skip)continue;

			if(array[i] == A){
				A_market += data[i].market_value;
				A_precious += data[i].precious_degree;
			}else{
				B_market += data[i].market_value;
				B_precious += data[i].precious_degree;
			}
		}

		V[type].push_back(Info(B_market-A_market,B_precious-A_precious));
		return;
	}

	Which next_array[3][30];
	for(int i = 0; i < 3; i++){
		for(int k = start_index[type]; k < index; k++){
			next_array[i][k] = array[k];
		}
	}

	next_array[0][index] = A;
	next_array[1][index] = B;
	next_array[2][index] = Skip;

	for(int i = 0; i < 3; i++){
		make_group(next_array[i],index+1,type);
	}
}

int main(){

	scanf("%lld %lld",&N,&DIFF);

	for(int i = 0; i < N; i++){
		scanf("%lld %lld",&data[i].market_value,&data[i].precious_degree);
	}

	if(N == 1){
		if(data[0].market_value <= DIFF){
			printf("%lld\n",data[0].precious_degree);
		}else{
			printf("0\n");
		}
		return 0;
	}

	V[One].push_back(Info(0,0));
	V[Two].push_back(Info(0,0));

	//0～N-1の財宝を2つに分割する
	start_index[One] = 0;
	end_index[One] = (N-1)/2;

	start_index[Two] = end_index[One]+1;
	end_index[Two] = N-1;


	Which first_array[30];

	make_group(first_array,start_index[One],One);
	make_group(first_array,start_index[Two],Two);

	sort(V[One].begin(),V[One].end()); //Oneは降順に
	V[One].erase(unique(V[One].begin(),V[One].end()),V[One].end());

	sort(V[Two].begin(),V[Two].end());
	V[Two].erase(unique(V[Two].begin(),V[Two].end()),V[Two].end());
	reverse(V[Two].begin(),V[Two].end()); //Twoは昇順に

	ll ans = -HUGE_NUM;

	int left,right,start_index = 0;
	int calc_left,calc_right,m;
	int One_num = (int)V[One].size(),Two_num = (int)V[Two].size();

	//2分探索で、range制約を満たす左端と右端を求める
	while(start_index < One_num){

		left = BIG_NUM; //左端を求める
		calc_left = 0, calc_right = Two_num-1,m = (calc_left+calc_right);
		while(calc_left<=calc_right){
			if(V[One][start_index].market_value_diff+V[Two][m].market_value_diff >= -DIFF){
				left = m;
				calc_right = m-1; //より左へ

			}else{
				calc_left = m+1;
			}
			m = (calc_left+calc_right)/2;
		}

		if(left == BIG_NUM){
			start_index++;
			continue;
		}

		right = BIG_NUM; //右端を求める
		calc_left = 0, calc_right = Two_num-1,m = (calc_left+calc_right);
		while(calc_left<=calc_right){
			if(V[One][start_index].market_value_diff+V[Two][m].market_value_diff <= DIFF){
				right = m;
				calc_left = m+1; //より右へ

			}else{
				calc_right = m-1;
			}
			m = (calc_left+calc_right)/2;
		}
		if(right == BIG_NUM || left > right){
			start_index++;
			continue;
		}
		break;
	}

	if(start_index == One_num){
		printf("0\n");
		return 0;
	}

	init(Two_num);
	table = new ll[2*SIZE-1];

	for(int i = 0; i <= 2*SIZE-2; i++)table[i] = -HUGE_NUM;
	for(int i = 0; i < Two_num; i++)update(i,V[Two][i].precious_degree_diff);

	ans = V[One][start_index].precious_degree_diff+query(left,right,0,0,SIZE-1);

	for(int i = start_index+1; i < One_num; i++){
		while(left < Two_num && V[One][i].market_value_diff+V[Two][left].market_value_diff < -DIFF)left++;
		if(left == Two_num)break;
		while(right < Two_num && V[One][i].market_value_diff+V[Two][right].market_value_diff <= DIFF)right++;
		right--;

		if(left > right)continue;

		ans = max(ans,V[One][i].precious_degree_diff+query(left,right,0,0,SIZE-1));
	}

	if(ans == -HUGE_NUM){
		printf("0\n");
	}else{
		printf("%lld\n",ans);
	}

	return 0;
}



Measured memory_bytes: 713372