from collections import defaultdict





def burger(lv, x):

    if d[(lv, x)] >= 0:

        return d[(lv, x)]



    if x < 1 or x > cnt[lv]:

        d[(lv, x)] = 0

        return d[(lv, x)]



    # base case

    if (lv, x) == (0, 1):

        d[(lv, x)] = 1

        return d[(lv, x)]



    half = (cnt[lv] - 1) // 2

    if x <= half:

        d[(lv, x)] = burger(lv - 1, x - 1)

        return d[(lv, x)]

    else:

        d[(lv, x)] = burger(lv - 1, half - 1) + 1 + burger(lv - 1, min(x - 1 - half, half - 1))

        return d[(lv, x)]





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

cnt = [1]

for lv in range(1, 50 + 1):

    cnt.append(cnt[-1] * 2 + 3)

d = defaultdict(lambda: -1)



print((burger(n, x)))

# print(d)

def burger(n, x):

    if x < 1:

        return 0



    # base case

    if (n, x) == (0, 1):

        return 1



    if x <= 1 + size[n - 1]:

        return burger(n - 1, x - 1)

    else:

        return p_num[n - 1] + 1 + burger(n - 1, min(x - 2 - size[n - 1], size[n - 1]))

    # x-2-sizeだと前lvバーガー+バンのことがあり、バンを外す





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

size, p_num = [1], [1]

for i in range(1, 50 + 1):

    size.append(size[-1] * 2 + 3)

    p_num.append(p_num[-1] * 2 + 1)



print((burger(n, x)))

from collections import defaultdict


def burger(lv, x):
    if d[(lv, x)] >= 0:
        return d[(lv, x)]
    if x < 1 or x > cnt[lv]:
        d[(lv, x)] = 0
        return d[(lv, x)]
    # base case
    if (lv, x) == (0, 1):
        d[(lv, x)] = 1
        return d[(lv, x)]
    half = (cnt[lv] - 1) // 2
    if x <= half:
        d[(lv, x)] = burger(lv - 1, x - 1)
        return d[(lv, x)]
    else:
        d[(lv, x)] = (
            burger(lv - 1, half - 1) + 1 + burger(lv - 1, min(x - 1 - half, half - 1))
        )
        return d[(lv, x)]


n, x = list(map(int, input().split()))
cnt = [1]
for lv in range(1, 50 + 1):
    cnt.append(cnt[-1] * 2 + 3)
d = defaultdict(lambda: -1)
print((burger(n, x)))
# print(d)

def burger(n, x):
    if x < 1:
        return 0
    # base case
    if (n, x) == (0, 1):
        return 1
    if x <= 1 + size[n - 1]:
        return burger(n - 1, x - 1)
    else:
        return p_num[n - 1] + 1 + burger(n - 1, min(x - 2 - size[n - 1], size[n - 1]))
    # x-2-sizeだと前lvバーガー+バンのことがあり、バンを外す


n, x = list(map(int, input().split()))
size, p_num = [1], [1]
for i in range(1, 50 + 1):
    size.append(size[-1] * 2 + 3)
    p_num.append(p_num[-1] * 2 + 1)
print((burger(n, x)))

-from collections import defaultdict - - -def burger(lv, x): -    if d[(lv, x)] >= 0: -        return d[(lv, x)] -    if x < 1 or x > cnt[lv]: -        d[(lv, x)] = 0 -        return d[(lv, x)] +def burger(n, x): +    if x < 1: +        return 0 -    if (lv, x) == (0, 1): -        d[(lv, x)] = 1 -        return d[(lv, x)] -    half = (cnt[lv] - 1) // 2 -    if x <= half: -        d[(lv, x)] = burger(lv - 1, x - 1) -        return d[(lv, x)] +    if (n, x) == (0, 1): +        return 1 +    if x <= 1 + size[n - 1]: +        return burger(n - 1, x - 1) -        d[(lv, x)] = ( -            burger(lv - 1, half - 1) + 1 + burger(lv - 1, min(x - 1 - half, half - 1)) -        ) -        return d[(lv, x)] +        return p_num[n - 1] + 1 + burger(n - 1, min(x - 2 - size[n - 1], size[n - 1])) +    # x-2-sizeだと前lvバーガー+バンのことがあり、バンを外す -cnt = [1] -for lv in range(1, 50 + 1): -    cnt.append(cnt[-1] * 2 + 3) -d = defaultdict(lambda: -1) +size, p_num = [1], [1] +for i in range(1, 50 + 1): +    size.append(size[-1] * 2 + 3) +    p_num.append(p_num[-1] * 2 + 1) -# print(d)