#include <bits/stdc++.h>
using namespace std;
const long long int MOD = 1000000007;
const long long int INF = LONG_MAX;
const vector<vector<long long int> > adj4({{0, 1}, {0, -1}, {1, 0}, {-1, 0}});
const vector<vector<long long int> > adj8(
    {{0, 1}, {0, -1}, {1, 0}, {-1, 0}, {-1, -1}, {1, -1}, {-1, 1}, {1, 1}});
struct DisjointSet {
  vector<long long int> roots;
  vector<long long int> sizes;
  DisjointSet(long long int n) {
    sizes = vector<long long int>(n, 1);
    roots = vector<long long int>(n);
    for (long long int i = 0; i < (n); ++i) roots[i] = i;
  }
  long long int root(long long int a) {
    return roots[a] == a ? a : root(roots[a]);
  }
  void join(long long int a, long long int b) {
    long long int ra = root(a);
    long long int rb = root(b);
    if (sizes[a] > sizes[b]) {
      roots[rb] = ra;
      sizes[ra] += sizes[rb];
    } else {
      roots[ra] = rb;
      sizes[rb] += sizes[ra];
    }
  }
};
long long int gcd(long long int a, long long int b) {
  return b == 0 ? a : gcd(b, a % b);
}
bool isprime(long long int n) {
  if (n == 2 || n == 3) return true;
  if (n < 2 || n % 2 == 0 || n % 3 == 0) return false;
  for (long long int i = 6; (i - 1) * (i - 1) <= n; i += 6) {
    if (n % (i - 1) == 0 || n % (i + 1) == 0) {
      return false;
    }
  }
  return true;
}
vector<bool> sprime;
void genPrime(long long int sz) {
  sprime = vector<bool>(sz, true);
  sprime[0] = false;
  sprime[1] = false;
  for (long long int i = (2); i < (sz); ++i) {
    for (long long int j = i * i; j < sz; j += i) {
      sprime[j] = false;
    }
  }
}
vector<long long int> facts;
bool factGenFlag = false;
void genFact(long long int n) {
  factGenFlag = true;
  facts = vector<long long int>(n + 1);
  facts[0] = 1;
  for (long long int i = (1); i < (n + 1); ++i) {
    facts[i] = facts[i - 1] * i;
  }
}
void genFactMod(long long int n, long long int mod) {
  factGenFlag = true;
  facts = vector<long long int>(n + 1);
  facts[0] = 1;
  for (long long int i = (1); i < (n + 1); ++i) {
    facts[i] = facts[i - 1] * i % mod;
  }
}
long long int fact(long long int a, long long int n) {
  if (factGenFlag && a < 3) return facts[n];
  long long int r = 1;
  for (long long int i = (a); i < (n + 1); ++i) {
    r *= i;
  }
  return r;
}
long long int factMod(long long int a, long long int n, long long int mod) {
  if (factGenFlag && a < 3) return facts[n];
  long long int r = 1;
  for (long long int i = (a); i < (n + 1); ++i) {
    r *= i;
    r %= mod;
  }
  return r;
}
long long int powMod(long long int a, long long int b, long long int mod) {
  long long int n = 1;
  long long int p = a;
  while (b > 0) {
    if (b % 2 == 1) {
      n *= p;
      n %= mod;
    }
    p *= p;
    p %= mod;
    b /= 2;
  }
  return n;
}
long long int modularInverse(long long int a, long long int mod) {
  return powMod(a, mod - 2, mod);
}
long long int ent(long long int a, long long int b) {
  long long int r = fact(a - b + 1, a);
  long long int d = fact(2, b);
  long long int ent = r / d;
  return ent;
}
long long int entMod(long long int a, long long int b, long long int mod) {
  long long int r = factMod(a - b + 1, a, mod);
  long long int d = factMod(2, b, mod);
  long long int ent = r * modularInverse(d, mod) % mod;
  return ent;
}
long long int bsfunction(long long int n) { return 0; }
long long int binarysearch(long long int left, long long int right,
                           long long int target) {
  if (left == right) {
    return left;
  }
  long long int mid =
      (left + right > 0) ? (left + right) / 2 : (left + right - 1) / 2;
  long long int val = bsfunction(mid);
  if (val > target) {
    return binarysearch(left, mid, target);
  } else if (val == target) {
    return mid;
  } else {
    return binarysearch(mid + 1, right, target);
  }
}
vector<long long int> topores;
vector<bool> topovisperm;
vector<bool> topovistemp;
vector<vector<long long int> > topograph;
bool topoimp;
void toposortvisit(long long int step) {
  if (topovisperm[step]) return;
  if (topovistemp[step]) {
    topoimp = true;
    return;
  }
  topovistemp[step] = true;
  for (long long int p : topograph[step]) {
    toposortvisit(p);
    if (topoimp) return;
  }
  topovisperm[step] = true;
  topores.push_back(step);
}
void toposort() {
  long long int n = topograph.size();
  topoimp = false;
  topovistemp = vector<bool>(n, false);
  topovisperm = vector<bool>(n, false);
  topores = vector<long long int>();
  topores.reserve(n);
  for (long long int i = 0; i < (n); ++i) {
    if (!topovisperm[i]) {
      toposortvisit(i);
      if (topoimp) {
        return;
      }
    }
  }
}
stringstream sss;
void MAIN() {
  long long int n, q;
  cin >> n >> q;
  --q;
  string s = "";
  for (long long int i = 0; i < (n); ++i) {
    s.push_back(q % 2 + '0');
    q /= 2;
  }
  reverse((s).begin(), (s).end());
  long long int r = 0;
  long long int b = 1LL << (n - 1);
  if (s[0] == '1') {
    r += 1LL << n;
  } else {
    r += 1;
  }
  for (long long int i = 0; i < (n - 1); ++i) {
    if (s[i] == s[i + 1]) {
      r += b;
    } else {
      r += 1;
    }
    b >>= 1LL;
  }
  cout << (r) << endl;
}
const long long int TESTCASEN = 1;
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  sss << R"(
1 2
2 3
3 6
10 1024
    )";
  for (long long int i = 0; i < (TESTCASEN); ++i) {
    MAIN();
  }
  return 0;
}
