CodeEff/ECCO huggingface dataset:
# Original solution
n,x=list(map(int,input().split()))
l=[0]
for i in range(n+1):
  l.append(2**(i+1)-1)
m=[0]
for i in range(n+1):
  m.append(2**(i+2)-3)
c=0
for i in range(n,-1,-1):
  if x<2**(i+1)-1:
    x-=1
  elif x==2**(i+1)-1:
    c+=l[i]+1
    x=0
  elif x>2**(i+1)-1:
    c+=l[i]+1
    if x==m[i+1]:
      x-=1
    x=x-(2**(i+1)-1)
print(c)

# Optimized solution
n,x=list(map(int,input().split()))
l=[0]
for i in range(n):
  l.append(2**(i+1)-1)
m=[0]
for i in range(n+1):
  m.append(2**(i+2)-3)
c=0
for i in range(n,-1,-1):
  t=2**(i+1)-1
  if x<t:
    x-=1
  elif x==t:
    c+=l[i]+1
    x=0
  else:
    c+=l[i]+1
    if x==m[i+1]:
      x-=1
    x=x-t
print(c)
# Original solution
# -*- coding: utf-8 -*-
"""
Created on Mon Apr 27 21:30:42 2020
"""

import sys
#import numpy as np

sys.setrecursionlimit(10 ** 9)
#def input():
#    return sys.stdin.readline()[:-1]
mod = 10**9+7

#N = int(input())
N, X = list(map(int,input().split()))
#A = list(map(int,input().split()))

n = N
eat = X

def dfs(x):
    x

ans = 0
#print(ans,eat,n)
while eat > 0:
    if eat == (pow(2,n+2) - 3 + 1) //2:
        ans += pow(2,n) - 1 + 1
        eat = 0
        n -= 1
    elif eat > (pow(2,n+2) - 3 + 1) //2:
        ans += pow(2,n) - 1 + 1
        eat -= (pow(2,n+2) - 2) //2
        n -= 1
    else:
        eat -= 1
        n -= 1
#    print(ans,eat,n)

print(ans)
    


# Optimized solution
# -*- coding: utf-8 -*-
"""
Created on Mon Apr 27 21:30:42 2020
"""

import sys
#import numpy as np

sys.setrecursionlimit(10 ** 9)
#def input():
#    return sys.stdin.readline()[:-1]
mod = 10**9+7

#N = int(input())
N, X = list(map(int,input().split()))
#A = list(map(int,input().split()))

n = N
eat = X

def dfs(x):
    x

ans = 0
#print(ans,eat,n)
while eat > 0 and n >= 0:
    if eat == (pow(2,n+2) - 3 + 1) //2:
        ans += pow(2,n) - 1 + 1
        eat = 0
        n -= 1
    elif eat > (pow(2,n+2) - 3 + 1) //2:
        ans += pow(2,n) - 1 + 1
        eat -= (pow(2,n+2) - 2) //2
        n -= 1
    else:
        eat -= 1
        n -= 1
#    print(ans,eat,n)

print(ans)
# Original solution
N, X = list(map(int, input().split()))

# レベルLバーガーの厚さ, レベルLバーガーに含まれるパティの数
thick, patti = [1], [1]
for i in range(N):
    thick.append(2 * thick[-1] + 3)
    patti.append(2 * patti[-1] + 1)


def solve(n, x):
    if n == 0:
        return 0 + (x >= 1)

    # レベルL-1バーガー
    elif x <= 1 + thick[n - 1]:
        return solve(n - 1, x - 1)

    # 2つ目のレベルL-1バーガーにかかる
    else:
        return patti[n - 1] + 1 + solve(n - 1, x - 1 - thick[n - 1] - 1)


print((solve(N, X)))


# Optimized solution
N, X = list(map(int, input().split()))


Patti = [1]  # レベルLバーガーに含まれているパティの数
Size = [1]   # レベルLバーガーの大きさ
for i in range(50):
    Patti.append(Patti[-1] * 2 + 1)
    Size.append(Size[-1] * 2 + 3)


def solve(n, x):
    # 一番下のバンのみ（ただしレベル0バーガーはPになる）
    if x == 1:
        return 0 + (n == 0)

    # 一番下のバン + レベルL-1バーガーのどこかまで
    if 1 < x <= 1 + Size[n - 1]:
        return solve(n - 1, x - 1)

    # 一番下のバン + レベルL-1バーガー + 真ん中のパティまで
    if x == 1 + Size[n - 1] + 1:
        return Patti[n - 1] + 1

    # 一番下のバン + レベルL-1バーガー + 真ん中のパティ + レベルL-1バーガーの途中まで
    if 1 + Size[n - 1] + 1 < x < Size[n]:
        return 1 + Patti[n - 1] + solve(n - 1, x - (1 + Size[n - 1] + 1))

    # レベルLバーガーすべて
    if x == Size[n]:
        return Patti[n]


print((solve(N, X)))
# Original solution
n, x = list(map(int, input().split()))

pate, slice = [1], [1]
for _ in range(n+1):
    pate.append(2 * pate[-1] + 1)
    slice.append(2 * slice[-1] + 3)

ans = 0
while n >= 0 and x > 0:
    if n == 0 and x > 0:
        ans += 1
        x -= 1
    elif x >= slice[n - 1] + 2:
        ans += pate[n - 1] + 1
        x -= slice[n - 1] + 2
    elif x < slice[n - 1] + 2:
        x -= 1
    n -= 1
print(ans)


# Optimized solution
n, x = list(map(int, input().split()))

pate, slice = [1], [1]
for _ in range(n + 1):
    pate.append(2 * pate[-1] + 1)
    slice.append(2 * slice[-1] + 3)

ans = 0
while n > 0 and x > 0:
    if x >= slice[n - 1] + 2:
        ans += pate[n - 1] + 1
        x -= slice[n - 1] + 2
    elif x < slice[n - 1] + 2:
        x -= 1
    n -= 1
print((ans + (x > 0)))
# Original solution
import sys, re
from collections import deque, defaultdict, Counter
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, tan, asin, acos, atan, radians, degrees, log2, gcd
from itertools import accumulate, permutations, combinations, combinations_with_replacement, product, groupby
from operator import itemgetter, mul
from copy import deepcopy
from string import ascii_lowercase, ascii_uppercase, digits
from bisect import bisect, bisect_left, insort, insort_left
from heapq import heappush, heappop
from functools import reduce
def input(): return sys.stdin.readline().strip()
def INT(): return int(eval(input()))
def MAP(): return list(map(int, input().split()))
def LIST(): return list(map(int, input().split()))
def ZIP(n): return list(zip(*(MAP() for _ in range(n))))
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
mod = 10 ** 9 + 7 
#mod = 998244353
from decimal import *
#import numpy as np
#decimal.getcontext().prec = 10

N, X = MAP()

p = [0]*(N+1) #レベルNバーガーのパティ枚数
p[0] = 1
q = [0]*(N+1) #レベルNバーガーの総枚数
q[0] = 1

for i in range(1, N+1):
	p[i] = 2*p[i-1] + 1
	q[i] = 2*q[i-1] + 3

ans = 0
i = N
while 0 < X:
	while 0 < X < q[i]:
		i -= 1
		X -= 1
	if 0 < X:
		X -= q[i]
		ans += p[i]
	if 0 < X:
		X -= 1
		ans += 1

print(ans)

# Optimized solution
import sys, re
from collections import deque, defaultdict, Counter
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, tan, asin, acos, atan, radians, degrees, log2, gcd
from itertools import accumulate, permutations, combinations, combinations_with_replacement, product, groupby
from operator import itemgetter, mul
from copy import deepcopy
from string import ascii_lowercase, ascii_uppercase, digits
from bisect import bisect, bisect_left, insort, insort_left
from heapq import heappush, heappop
from functools import reduce
def input(): return sys.stdin.readline().strip()
def INT(): return int(eval(input()))
def MAP(): return list(map(int, input().split()))
def LIST(): return list(map(int, input().split()))
def ZIP(n): return list(zip(*(MAP() for _ in range(n))))
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
mod = 10 ** 9 + 7 
#mod = 998244353
from decimal import *
#import numpy as np
#decimal.getcontext().prec = 10

N, X = MAP()

L = [0]*(N+1) #レベルiバーガーの全体の層数
L[0] = 1
for i in range(1, N+1):
	L[i] = 2*L[i-1] + 3

P = [0]*(N+1) #レベルiバーガーのパティの数
P[0] = 1
for i in range(1, N+1):
	P[i] = 2*P[i-1] + 1

def solve(i, x): #レベルiバーガーの下からx個
	if i == 0:
		if x <= 0:
			return 0
		else:
			return 1
	if x <= L[i-1] + 1:
		ret = solve(i-1, x-1)
	else:
		ret = P[i-1] + 1 + solve(i-1, x - L[i-1] - 2)
	return ret


print((solve(N, X)))
# Original solution
def main():
    N, X = (int(i) for i in input().split())

    A = [1] * (N+1)
    P = [1] * (N+1)
    for i in range(1, N+1):
        A[i] = 2*A[i-1] + 3
        P[i] = 2*P[i-1] + 1

    def f(N, X):
        if N == 0:
            return 0 if X <= 0 else 1
        elif X == 1:
            return 0
        elif X <= 1 + A[N-1]:
            return f(N-1, X-1)
        elif X == 2 + A[N-1]:
            return P[N-1] + 1
        elif X <= 2 + 2 * A[N-1]:
            return P[N-1] + 1 + f(N-1, X-2-A[N-1])
        elif X == 3 + 2 * A[N-1]:
            return 2 * P[N-1] + 1

    print((f(N, X)))


if __name__ == '__main__':
    main()


# Optimized solution
def main():
    N, X = (int(i) for i in input().split())
    ans = 0

    def dfs(n, x, ans):
        a = 1 + 4*(2**(n-1) - 1)
        if n == 1:
            return 1
        elif (n-1) >= x:
            return 0
        elif x == a//2:
            return 1 + 2*(2**(n-2) - 1)
        elif x == a//2 + 1:
            return 1 + 2*(2**(n-2) - 1) + 1
        elif x < a//2:
            ans += dfs(n-1, x-1, ans)
        elif x > a//2 + 1:
            ans += dfs(n-1, x-(a//2)-1, ans) + (1 + 2*(2**(n-2) - 1) + 1)
        return ans

    print((dfs(N+1, X, ans)))


if __name__ == '__main__':
    main()
# Original solution
N, X = list(map(int, input().split()))
pcnt = [0] * (N+1)
fcnt = [0] * (N+1)
pcnt[0] = fcnt[0] = 1
for i in range(N):
	pcnt[i+1] = pcnt[i]*2+1
	fcnt[i+1] = fcnt[i]*2+3

def func(l=N, x=X):
	if (l == 0):
		if (x >= 1):
			return 1
		else:
			return 0
	if (x <= 1):
		return 0
	if (x < fcnt[l-1]+2):
		return func(l-1, x-1)
	elif (x == fcnt[l - 1] + 2):
		return pcnt[l-1]+1
	else:
		return pcnt[l-1]+1+func(l-1, x-fcnt[l-1]-2)

print((func()))


# Optimized solution
N, X = list(map(int, input().split()))
pcnt = [0] * (N+1)
fcnt = [0] * (N+1)
pcnt[0] = fcnt[0] = 1
for i in range(N):
	pcnt[i+1] = pcnt[i]*2+1
	fcnt[i+1] = fcnt[i]*2+3

def func(l=N, x=X):
	if (l == 0):
		if (x >= 1):
			return 1
		else:
			return 0
	if (x < fcnt[l-1]+2):
		return func(l-1, x-1)
	else:
		return pcnt[l-1]+1+func(l-1, x-fcnt[l-1]-2)

print((func()))
# Original solution
from functools import lru_cache

N, X = list(map(int, input().split()))

@lru_cache(maxsize=None)
def length(level):
    if level <= 0:
        return 1
    return length(level - 1) * 2 + 3

@lru_cache(maxsize=None)
def search(level, right):
    if level == 0:
        return 1

    ret = 0
    right -= 1
    if length(level - 1) <= right:
        ret += search(level - 1, length(level - 1))
        right -= length(level - 1)

        if right > 0:
            ret += 1
        right -= 1

    if 0 < right:
        ret += search(level - 1, right)
    return ret

print((search(N, X)))


# Optimized solution
from functools import lru_cache

N, X = list(map(int, input().split()))

@lru_cache(maxsize=None)
def size(level):
    return 1 if level == 0 else size(level - 1) * 2 + 3

@lru_cache(maxsize=None)
def calc(level, N):
    if level == 0:
        return 1 if N > 0 else 0

    N = min(N, size(level))

    ret = 0
    N -= 1

    if N >= size(level - 1):
        ret += calc(level - 1, size(level - 1))
        N -= size(level - 1)

        if N >= 1:
            ret += 1
            N -= 1

    return ret + calc(level - 1, N)

print((calc(N, X)))
# Original solution
def do(level,x):
    if x<=0:
        return 0
    elif x>=j[level]:
        return k[level]
    res=0
    x-=1
    if x>=j[level-1]+1:
        x-=j[level-1]+1
        res+=k[level-1]+1
    return res+do(level-1,x)

n,x=list(map(int,input().split()))
j=[1]+[0]*50
k=[1]+[0]*50
for i in range(1,n+1):
    j[i]=j[i-1]*2+3
    k[i]=k[i-1]*2+1
res=0
print((do(n,x)))

# Optimized solution
def do(level,x):
    if x<=0: #1層も手を付けないとき
        return 0
    elif x>=whole[level]: #完食できるとき
        return patty[level]
    #それ以外、途中まで食べるときはlevel>=1の場合のみあり得る
    x-=1 #このとき1層目は必ずバンズ
    res=0 #食べたパティの総数を記録する
    if x>=whole[level-1]+1: #真ん中のパティまで到達できるとき
        x-=whole[level-1]+1
        res+=patty[level-1]+1
    return res+do(level-1,x)

n,x=list(map(int,input().split()))
whole=[1]+[0]*50
patty=[1]+[0]*50
for i in range(1,n+1):
    whole[i]=whole[i-1]*2+3
    patty[i]=patty[i-1]*2+1
res=0
print((do(n,x)))
# Original solution
#再帰の深さが1000を超えそうなときはこれをやっておく
import sys
sys.setrecursionlimit(10**7)

n,x=list(map(int,input().split()))
a=[0]*(n+1)
p=[0]*(n+1)
a[0]=1
p[0]=1
for i in range(n):
  a[i+1]=2*a[i]+3
  p[i+1]=2*p[i]+1
  
def func(i,x):
  if i==0:
    if x<=0:
      return 0
    elif x>=1:
      return 1
  mid=(a[i]+1)//2
  if mid==x:
    return p[i-1]+1
  elif mid>x:
    return func(i-1,x-1)
  else:
    return p[i-1]+1+func(i-1,x-mid)


print((func(n,x)))  

# Optimized solution
n,x=list(map(int,input().split()))

#lレベルバーガーの下からx層に含まれるパティーの数
a=[1]*(n+1)
p=[1]*(n+1)
for i in range(1,n+1):
  a[i]=a[i-1]*2+3
  p[i]=p[i-1]*2+1

def count(l,x):
  if l==0:
    if x>=1:
      return 1
    else:
      return 0
  else:
    if x==1:
      return 0
    elif x<a[l-1]+2:
      return count(l-1,x-1)
    elif x==a[l-1]+2:
      return p[l-1]+1
    elif a[l]>x:
      return count(l-1,x-a[l-1]-2)+p[l-1]+1
    else:
      return p[l]
    
print((count(n,x)))
# Original solution
def m(n): # n次元バーガーの層数
    if n == 0:
        return 1
    else:
        a = 1
        for i in range(n):
            a = a * 2 + 3
        return a

def paty(n): # n次元バーガーのパティの数
    a = 1
    if n >= 1:
        for i in range(n):
            a = a * 2 + 1
    return a

def a(n, x): #これが答えを返す
    x = x - 1
    if x == 0 and n == 0:
        return 1
    elif x == 0:
        return 0
    elif x == m(n-1) + 1:
        return paty(n-1) + 1
    elif x == m(n):
        return paty(n)
    elif x > m(n-1):
        return paty(n-1) + 1 + a(n - 1, x - m(n-1) - 1)
    else:
        n = n - 1
        return a(n, x)

n, x= list(map(int, input().split()))
print((a(n, x)))

# Optimized solution
n, x = list(map(int, input().split()))
def patty(L):
# レベルLバーガーにパティがいくらあるか
    p = 1
    for i in range(L):
        p = 2 * p + 1
    return (p)
def vol(L):
# レベルLバーガーが何層か
    m = 1
    for i in range(L):
        m  = m * 2 + 3
    return (m)
def eated(L, X):
# レベルLバーガーを下からX層に何枚パティがあるか
    if L == 0:
        return 1
    m = vol(L)
    if X == 1 or X == 0:
        #print("下から１枚")
        return 0
    elif X == (m + 1) / 2:
        #print("ちょうど真ん中")
        #print(str(L-1) + "バーガーのパティ＋１枚")
        return patty(L-1) + 1
    elif X < (m + 1) / 2:
        #print("下半分")
        #print(str(L-1) + "バーガーを考える")
        return eated(L-1, X-1)
    else:
        #print("上半分")
        #print(str(L) + "バーガーのパティを上から" + str(X) + "枚食べたと考える")
        return patty(L) - eated(L, m - X)
print((eated(n, x)))
# Original solution
from math import ceil,floor,factorial,gcd,sqrt,log2,cos,sin,tan,acos,asin,atan,degrees,radians,pi,inf,comb
from itertools import accumulate,groupby,permutations,combinations,product,combinations_with_replacement
from collections import deque,defaultdict,Counter
from bisect import bisect_left,bisect_right
from operator import itemgetter
from heapq import heapify,heappop,heappush
from queue import Queue,LifoQueue,PriorityQueue
from copy import deepcopy
from time import time
from functools import reduce
import string
import sys
sys.setrecursionlimit(10 ** 7)
def input() : return sys.stdin.readline().strip()
def INT()   : return int(eval(input()))
def MAP()   : return list(map(int,input().split()))
def LIST()  : return list(MAP())

# レベルnバーガー
def dfs(k):
    global count, ans
    # バン
    count += 1
    if k == 0:
        ans += 1
    elif count < x:
        # レベルn-1バーガー
        if count + b[k-1] > x:
            dfs(k-1)
        else:
            count += b[k-1]
            ans += p[k-1]
        if count < x:
            # パティ
            count += 1
            ans += 1
            if count < x:
                # レベルn-1バーガー
                if count + b[k-1] > x:
                    dfs(k-1)
                else:
                    count += b[k-1]
                    ans += p[k-1]

n, x = MAP()
b = [0]*n
p = [0]*n
b[0] = 1
p[0] = 1
for i in range(1, n):
    b[i] = b[i-1]*2 + 3
    p[i] = p[i-1]*2 + 1

count = 0
ans = 0
dfs(n)
print(ans)

# Optimized solution
from math import ceil,floor,factorial,gcd,sqrt,log2,cos,sin,tan,acos,asin,atan,degrees,radians,pi,inf,comb
from itertools import accumulate,groupby,permutations,combinations,product,combinations_with_replacement
from collections import deque,defaultdict,Counter
from bisect import bisect_left,bisect_right
from operator import itemgetter
from heapq import heapify,heappop,heappush
from queue import Queue,LifoQueue,PriorityQueue
from copy import deepcopy
from time import time
from functools import reduce
import string
import sys
sys.setrecursionlimit(10 ** 7)
def input() : return sys.stdin.readline().strip()
def INT()   : return int(eval(input()))
def MAP()   : return list(map(int,input().split()))
def LIST()  : return list(MAP())

# レベルnバーガー
def f(n, x):
    if n == 0:
        return 0 if x <= 0 else 1
    elif x <= 1 + a[n-1]:
        return f(n-1, x-1)
    else:
        return p[n-1] + 1 + f(n-1, x-2-a[n-1])

n, x = MAP()
a = [0]*n
p = [0]*n
a[0] = 1
p[0] = 1
for i in range(1, n):
    a[i] = a[i-1]*2 + 3
    p[i] = p[i-1]*2 + 1

print((f(n, x)))
# Original solution
N, X = list(map(int, input().split(' ')))

p = [1]
pb = [1]
np = 0
nx = X

for _ in range(N):
    p.append(p[-1] * 2 + 1)
    pb.append(pb[-1] * 2 + 3)


def dfs(level):
    global np, nx

    if nx == 0:
        return

    if nx >= pb[level]:
        nx -= pb[level]
        np += p[level]
        return

    nx -= 1
    if nx == 0:
        return

    dfs(level - 1)

    if nx == 0:
        return

    nx -= 1
    np += 1

    if nx == 0:
        return

    dfs(level - 1)

    if nx == 0:
        return

    nx -= 1


dfs(N)

print(np)


# Optimized solution
N, X = list(map(int, input().split(' ')))

level2p = [1] * (N + 1)
level2pb = [1] * (N + 1)

for i in range(N):
    level2p[i + 1] = level2p[i] * 2 + 1
    level2pb[i + 1] = level2pb[i] * 2 + 3


def dfs(n, x):
    if n == 0:
        return 1

    if x <= 1:
        return 0
    elif x <= 1 + level2pb[n - 1]:
        return dfs(n - 1, x - 1)
    elif x <= 1 + level2pb[n - 1] + 1:
        return level2p[n - 1] + 1
    elif x <= 1 + level2pb[n - 1] + 1 + level2pb[n - 1]:
        return level2p[n - 1] + 1 + dfs(n - 1, x - 1 - level2pb[n - 1] - 1)
    else:
        return level2p[n]


print((dfs(N, X)))
# Original solution
import sys
stdin = sys.stdin
 
sys.setrecursionlimit(10**5) 
 
def li(): return list(map(int, stdin.readline().split()))
def li_(): return [int(x)-1 for x in stdin.readline().split()]
def lf(): return list(map(float, stdin.readline().split()))
def ls(): return stdin.readline().split()
def ns(): return stdin.readline().rstrip()
def lc(): return list(ns())
def ni(): return int(stdin.readline())
def nf(): return float(stdin.readline())

n,x = li()

top = [4*pow(2,i) - 3 for i in range(n+1)]
med = [pow(2,i+1) - 1 for i in range(n+1)]
bot = [1 for _ in range(n+1)]

def findPattyNum(level:int, lay: int):
    if level == 0 and lay == 1:
        return 1
    
    if lay == 4*pow(2,level)-3:
        return pow(2,level+1) - 1
    
    elif pow(2,level+1)-1 < lay < 4*pow(2,level)-3:
        return pow(2,level) + findPattyNum(level-1, lay - (pow(2,level+1)-1))
    
    elif lay == pow(2,level+1)-1:
        return pow(2,level)
    
    elif 1 < lay < pow(2,level+1)-1:
        return findPattyNum(level-1, lay-1)
    
    elif lay == 1:
        return 0
    
print((findPattyNum(n,x)))

# Optimized solution
import sys
stdin = sys.stdin

sys.setrecursionlimit(10 ** 7)

def li(): return list(map(int, stdin.readline().split()))
def li_(): return [int(x) - 1 for x in stdin.readline().split()]
def lf(): return list(map(float, stdin.readline().split()))
def ls(): return stdin.readline().split()
def ns(): return stdin.readline().rstrip()
def lc(): return list(ns())
def ni(): return int(stdin.readline())
def nf(): return float(stdin.readline())


def rec(n: int, x: int, a: list, p: list) -> int:
    if x <= 0:
        raise ValueError

    elif n == 0:
        return 1

    elif x == 1:
        return 0

    elif 1 < x < a[n-1] + 2:
        return rec(n-1, x-1, a, p)

    elif x == a[n-1] + 2:
        return p[n-1] + 1

    elif a[n-1] + 2 < x < 2*a[n-1] + 3:
        return p[n-1] + 1 + rec(n-1, x - a[n-1] - 2, a, p)

    elif x == 2*a[n-1] + 3:
        return 2 * p[n-1] + 1

n,x = li()
a = [1]
p = [1]

for i in range(n):
    a.append(2*a[-1]+3)
    p.append(2*p[-1]+1)

print((rec(n, x, a, p)))
# Original solution
from collections import Counter,defaultdict,deque
from heapq import heappop,heappush,heapify
import sys,bisect,math,itertools,string,queue
sys.setrecursionlimit(10**8)
mod = 10**9+7
def inp(): return int(sys.stdin.readline())
def inpl(): return list(map(int, sys.stdin.readline().split()))
def inpl_str(): return list(sys.stdin.readline().split())
def inpln(n): return list(int(sys.stdin.readline()) for i in range(n))

n,x = inpl()
h = [1] * (n+1)
b = [0] * (n+1)
p = [1] * (n+1)
for i in range(1,n+1):
    h[i] = 3 + h[i-1] * 2
    b[i] = 2 + b[i-1] * 2
    p[i] = h[i] - b[i]
# print(h,p)
def sol(n,x):
    if n == 0 :
        return 0 if x <= 0 else 1
    elif x == 1:
        return 0
    elif x <= 1 + h[n-1]:
        return sol(n-1, x-1)
    elif x == 2 + h[n-1]:
        return p[n-1] + 1
    elif x < h[n]:
        return p[n-1] + 1 + sol(n-1, x-(h[n-1]+2))
    else:
        return p[n-1] * 2 + 1
print((sol(n,x)))



# Optimized solution
from collections import Counter,defaultdict,deque
from heapq import heappop,heappush,heapify
import sys,bisect,math,itertools,string,queue
sys.setrecursionlimit(10**8)
mod = 10**9+7
def inp(): return int(sys.stdin.readline())
def inpl(): return list(map(int, sys.stdin.readline().split()))
def inpl_str(): return list(sys.stdin.readline().split())
def inpln(n): return list(int(sys.stdin.readline()) for i in range(n))

n,x = inpl()
h = [1] * (n+1)
b = [0] * (n+1)
p = [1] * (n+1)
for i in range(1,n+1):
    h[i] = 3 + h[i-1] * 2
    b[i] = 2 + b[i-1] * 2
    p[i] = h[i] - b[i]
# print(h,p)
def sol(n,x):
    if n == 0 :
        return 1
    elif x == 1:
        return 0
    elif x <= 1 + h[n-1]:
        return sol(n-1, x-1)
    elif x == 2 + h[n-1]:
        return p[n-1] + 1
    elif x < h[n]:
        return p[n-1] + 1 + sol(n-1, x-(h[n-1]+2))
    else:
        return p[n-1] * 2 + 1
print((sol(n,x)))
# Original solution
def solve(n, x):
    if x == 1:
        if n == 0:
            return 1
        else:
            return 0
    elif 1 < x <= 1 + layer[n-1]:
        return solve(n-1, x-1)
    elif x == 2 + layer[n-1]:
        return patty[n-1] + 1
    elif 2 + layer[n-1] < x <= 2 + 2 * layer[n-1]:
        return solve(n-1, x-layer[n-1]-2) + patty[n-1] + 1
    else:
        return 2 * patty[n-1] + 1


N, X = list(map(int, input().split()))

layer, patty = [1], [1]
for _ in range(N):
    layer.append(layer[-1] * 2 + 3)
    patty.append(patty[-1] * 2 + 1)

print((solve(N, X)))

# Optimized solution
def solve(n, x):
    if x == 1:
        if n == 0:
            return 1
        else:
            return 0
    elif 1 < x < layer[n] // 2 + 1:
        return solve(n-1, x-1)
    elif x == layer[n] // 2 + 1:
        return patty[n-1] + 1
    elif layer[n] // 2 + 1 < x < layer[n]:
        return solve(n-1, x-layer[n-1]-2) + patty[n-1] + 1
    else:
        return patty[n]


N, X = list(map(int, input().split()))

layer, patty = [1], [1]
for _ in range(N):
    layer.append(layer[-1] * 2 + 3)
    patty.append(patty[-1] * 2 + 1)

print((solve(N, X)))