#include<stdio.h>
#include<stdlib.h>
#define NMAX 40
struct node {
  long long int value, weight;
};

int compare(const void *a, const void *b);

int main(void)
{
  int i, j, n, n2, c1 = 0, c2 = 1;
  long long int w, res = 0;
  struct node vw[NMAX], ps[NMAX];
  scanf("%d%lld", &n, &w);
  for (i = 0; i < n; i++) scanf("%lld%lld", &vw[i].value, &vw[i].weight);
  n2 = n / 2;
  for (i = 0; i < 1 << n2; i++) {
    long long int sv = 0, sw = 0;
    for (j = 0; j < n2; j++) {
      if (i >> j & 1) {
        sv += vw[j].value;
        sw += vw[j].weight;
      }
      ps[c1].value = sv;
      ps[c1++].weight = sw;
    }
  }
  qsort(ps, c1, sizeof(struct node), compare);
  for (i = 1; i < c1; i++) {
    if (ps[c2-1].value < ps[i].value) ps[c2++] = ps[i];
  }
  for (i = 0; i < 1 << (n - n2); i++) {
    long long int sv = 0, sw = 0;
    for (j = 0; j < n - n2; j++) {
      if (i >> j & 1) {
        sv += vw[n2+j].value;
        sw += vw[n2+j].weight;
      }
    }
    if (sw <= w) {
      int m, l = 0, r = c2;
      long long int x = w - sw;
      while (l < r) {
        m = (l + r) / 2;
        if (ps[m].weight <= x) l = m + 1;
        else r = m;
      }
      if (sv + ps[l-1].value > res) res = sv + ps[l-1].value;
    }
  }
  printf("%lld\n", res);
}

int compare(const void *a, const void *b)
{
  struct node ta = *(struct node*)a, tb = *(struct node*)b;
  if (ta.weight > tb.weight) return 1;
  else if (ta.weight < tb.weight) return -1;
  else if (ta.value > tb.value) return -1;
  else if (ta.value < tb.value) return 1;
  return 0;
}
