Problem:
 Score : 400 points    Problem Statement In some other world, today is Christmas.  Mr. Takaha decides to make a multi-dimensional burger in his party. A level- L burger ( L is an integer greater than or equal to 0 ) is the following thing:   A level- 0 burger is a patty.  A level- L burger (L \geq 1) is a bun, a level- (L-1) burger, a patty, another level- (L-1) burger and another bun, stacked vertically in this order from the bottom.   For example, a level- 1 burger and a level- 2 burger look like BPPPB and BBPPPBPBPPPBB (rotated 90 degrees), where B and P stands for a bun and a patty.  The burger Mr. Takaha will make is a level- N burger. Lunlun the Dachshund will eat X layers from the bottom of this burger (a layer is a patty or a bun). How many patties will she eat?      Constraints  1 \leq N \leq 50  1 \leq X \leq ( the total number of layers in a level- N burger )  N and X are integers.         Input Input is given from Standard Input in the following format:  N  X       Output Print the number of patties in the bottom-most X layers from the bottom of a level- N burger.        Sample Input 1 2 7      Sample Output 1 4  There are 4 patties in the bottom-most 7 layers of a level- 2 burger ( BBPPPBPBPPPBB ).       Sample Input 2 1 1      Sample Output 2 0  The bottom-most layer of a level- 1 burger is a bun.       Sample Input 3 50 4321098765432109      Sample Output 3 2160549382716056  A level- 50 burger is rather thick, to the extent that the number of its layers does not fit into a 32 -bit integer.

Solution (Python):
from functools import lru_cache
n, x = map(int, input().split())

@lru_cache(None)
def d(k):
    if k == 0:
        return 1
    return 2 * d(k-1) + 3

@lru_cache(None)
def f(i, h):
    if h == 0:
        return i
    rv = 0
    if i >= 1:
        rv += f(min(i-1, d(h-1)), h-1)
    if i >= d(h-1) + 2:
        rv += 1 + f(min(i - d(h-1) - 2, d(h-1)), h-1)
    return rv

print(f(x, n))

Solution (Python):
n, x = map(int, input().split())
d = [1]
for _ in range(50):
    d.append(d[-1] * 2 + 3)
ans = 0
def f(i, h):
    if h == 0:
        return 1 if i == 1 else 0
    if i == 0:
        return 0
    mid = d[h-1] + 1
    if i <= mid:
        return f(i-1, h-1)
    if i == mid + 1:
        return 2 ** h
    if i <= d[h] - 1:
        return 2 ** h + f(i-mid-1, h-1)
    else:
        return 2 ** (h + 1) - 1
print(f(x, n))

Solution (Python):
n,x = map(int,input().split())
a = [1] 
p = [1] 
for i in range(n):
    a.append(a[i] * 2 + 3)
    p.append(p[i] * 2 + 1)
def f(n,x):
    
    if n == 0:
        if x <= 0:
            return 0
        else:
            return 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])
print(f(n,x))

Solution (Python):






from collections import namedtuple

def solve(n, x, burgers, total_eaten, patty_eaten):
    if n == 0:
        total_eaten += 1
        patty_eaten += 1
        return total_eaten, patty_eaten

    
    tmp_total = burgers[n].total
    tmp_patty = burgers[n].patty
    if total_eaten + tmp_total < x:
        return total_eaten + tmp_total, patty_eaten + tmp_patty

    
    total_eaten += 1
    if total_eaten == x:
        return total_eaten, patty_eaten

    
    total_eaten, patty_eaten = solve(n - 1, x, burgers, total_eaten, patty_eaten)
    if total_eaten == x:
        return total_eaten, patty_eaten

    
    total_eaten += 1
    patty_eaten += 1
    if total_eaten == x:
        return total_eaten, patty_eaten

    
    total_eaten, patty_eaten = solve(n - 1, x, burgers, total_eaten, patty_eaten)
    if total_eaten == x:
        return total_eaten, patty_eaten

    
    
    total_eaten += 1
    return total_eaten, patty_eaten

def main():
    N, X = map(int, input().split())
    Burger = namedtuple('Burger', ['total', 'patty'])
    burgers = [Burger(total=1, patty=1)]
    for i in range(N):
        total = burgers[i].total
        patty = burgers[i].patty
        burger = Burger(total=3 + total*2, patty=1 + 2*patty)
        burgers.append(burger)
    
    total_eaten, patty_eaten = 0, 0
    total_eaten, patty_eaten = solve(N, X, burgers, total_eaten, patty_eaten)
    print(patty_eaten)

if __name__ == '__main__':
    main()

Solution (Python):


import math



from collections import deque




N,X=map(int,input().split())
l=[1]*(N+1)
p=[1]*(N+1)
for i in range(1,N+1):
    l[i]=2*l[i-1]+3
    p[i]=2*p[i-1]+1
def ans(n,x):
    if n==0:
        return 1
    if x==1:
        return 0
    elif 1<x<=l[n-1]+1:
        return ans(n-1,x-1)
    elif x==l[n-1]+2:
        return p[n-1]+1
    elif l[n-1]+2<x<=2*l[n-1]+2:
        return p[n-1]+1+ans(n-1,x-l[n-1]-2)
    else:
        return p[n-1]*2+1
print(ans(N,X))

Solution (Python):
import sys
sys.setrecursionlimit(10000)  

n, x = map(int, input().split())
As = [1]  
Ps = [1]  

for i in range(n):
    As.append(As[i]*2 + 3)  
    Ps.append(Ps[i]*2 + 1)  

def f(n, x):
    """レベルnバーガーの下からx層食べたときの、食べたパティの総数"""
    if n == 0:
        return 0 if x <= 0 else 1

    median = (As[n]+1)//2

    if x < median:
        return f(n-1, x-1)
    elif x == median:
        return Ps[n-1] + 1
    elif x > median:
        return Ps[n-1] + 1 + f(n-1, x-median)

ans = f(n, x)

print(ans)

Solution (Python):
def main():
    n, x = list(map(int, input().split()))
    a, p = [1, ], [1, ]
    for i in range(n):
        a.append(a[i] * 2 + 3)
        p.append(p[i] * 2 + 1)
    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])

    print(f(n, x))

if __name__ == '__main__':
    main()

Solution (Python):
import sys
sys.setrecursionlimit(10**7)

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(int,input().split())
a,p=[1],[1]
for i in range(n):
  a.append(a[i]*2+3)
  p.append(p[i]*2+1)

print(f(n,x))

Solution (Python):
[n,x] = [int(i) for i in input().split()]
ls = [1]
pts = [1]

for i in range(50):
    ls.append(2 * ls[-1] + 3)
    pts.append(2 * pts[-1] + 1)

ans = 0

while n > 0 and x >= 0:
    if x < ls[n]//2:
        x -= 1
        n -= 1
    elif x == ls[n]//2:
        x = -1
        ans += pts[n-1]
    else:
        if x == ls[n]:
            x = 0
            ans += pts[n]
        else:
            x -= ls[n]//2
            ans += pts[n-1]+1
print(ans)

Solution (Python):
N, X = map(int, input().split())
a, p = [1], [1]
for i in range(N):
    a.append(a[i] * 2 + 3)
    p.append(p[i] * 2 + 1)

def paty(L, n):
    if L == 0:
        return 0 if n <= 0 else 1
    elif n <= 1 + a[L - 1]:
        return paty(L-1, n-1)
    else:
        return p[L-1] + 1 + paty(L-1, n-2-a[L-1])

print(paty(N, X))

Solution (Python):
N, X = map(int, input().split())
L_list = [1] * (N + 1)
for i in range(1, N+1):
    L_list[i] = 3+2*L_list[i-1]
paty_list = {(0, 1): 1}

def paty(L, n):
    if (L, n) in paty_list:
        return paty_list[L, n]
    ans = 0
    count = 0
    if count + 1 >= n:
        paty_list[(L, n)] = ans
        return ans
    count += 1
    if L_list[L-1] + count > n:
        ans += paty(L-1, n-count)
        paty_list[(L, n)] = ans
        return ans
    ans += paty(L-1, L_list[L-1])
    count += L_list[L-1]  
    if count + 1 > n:
        paty_list[(L, n)] = ans
        return ans
    ans += 1
    count += 1
    if L_list[L-1] + count > n:
        ans += paty(L-1, n-count)
        paty_list[(L, n)] = ans
        return ans
    ans += paty(L-1, L_list[L-1])
    paty_list[(L, n)] = ans
    return ans

print(paty(N, X))

Solution (Python):
from functools import lru_cache
import sys
sys.setrecursionlimit(10**6)


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

whole = [1]
putty = [1]
for _ in range(50):
    whole.append(whole[-1] * 2 + 3)
    putty.append(putty[-1] * 2 + 1)


@lru_cache(maxsize=None)
def rec(n, x):
    if n == 0:
        
        return 0 if x < 1 else 1

    
    med = (whole[n]+1) // 2

    
    if x < med:
        return rec(n - 1, x - 1)
    
    elif x == med:
        return putty[n - 1] + 1
    
    elif x > med:
        return putty[n - 1] + 1 + rec(n - 1, x - med)


ans = rec(n, x)

print(ans)

Solution (Python):
num = [1]
for i in range(1, 50):
  num.append(2 * num[i - 1] + 3)
def count_p(level, x):
  if x == 0:
    return 0
  if level == 1:
    if x == 5:
      return 3
    else:
      return x - 1
  if x < num[level - 1] + 1:
    return count_p(level - 1, x - 1)
  if x == num[level - 1] + 1:
    return 2 ** level - 1
  if x >= num[level - 1] * 2 + 2:
    return 2 ** (level + 1) - 1
  if x >= num[level - 1] + 2:
    return 2 ** level + count_p(level - 1, x - num[level - 1] - 2)


N, X = map(int, input().split())
print(count_p(N, X))

Solution (Python):
n, x = map(int, input().split())
L = [[1, 1]]
for i in range(1, n+1):
    L.append([L[i-1][0] * 2 + 3, L[i-1][1] * 2 + 1])
def f(n, x):
    if n == 0:
        return 0 if x <= 0 else 1
    elif x <= 1 + L[n-1][0]:
        return f(n-1, x-1)
    else:
        return L[n-1][1] + 1 + f(n-1, x-2-L[n-1][0])
print(f(n, x))

Solution (Python):


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

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


def calc(N, X):
    if X == 1:
        if N == 0:
            return 1
        else:
            return 0
    elif X <= 1+a[N-1]:
        return calc(N-1, X-1)
    elif X == 2+a[N-1]:
        return p[N-1]+1
    elif X <= 2*a[N-1]+2:
        return p[N-1]+1+calc(N-1, X-2-a[N-1])
    elif X == 2*a[N-1]+3:
        return 2*p[N-1]+1
    else:
        raise("Error")


print(calc(n, x))

Solution (Python):
N,X = map(int,input().split())
a,p =[1],[1]
for i in range(N):
    a.append(a[i]*2+3)
    p.append(p[i]*2+1)
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])
print(f(N,X))

Solution (Python):
def resolve():
    N, X = list(map(int, input().split()))
    level_len = [1]
    for i in range(1, N+1):
        level_len.append(2*level_len[i-1]+3)
    
    mem = {"0-0": 1}

    def get_cnt(level, pos):
        if "{}-{}".format(level, pos) in mem:
            return mem["{}-{}".format(level, pos)]

        result = None
        if pos == 0:
            result = 0
        elif 1 <= pos <= level_len[level-1]:
            result = get_cnt(level-1, pos-1)
        elif pos == 1+level_len[level-1]:
            result = get_cnt(level-1, level_len[level-1]-1)+1
        elif 1+level_len[level-1] < pos <= 1+2*level_len[level-1]:
            result = get_cnt(level-1, level_len[level-1]-1) + 1 + get_cnt(level-1, pos-level_len[level-1]-2)
        elif pos == 2*level_len[level-1]+2:
            result = 2*get_cnt(level-1, level_len[level-1]-1)+1

        if result is None:
            
            raise Exception("Invalid")
        mem.setdefault("{}-{}".format(level, pos), result)
        return result
    
    print(get_cnt(N, X-1))

    

if '__main__' == __name__:
    resolve()

Solution (Python):
n,x = map(int,input().split())
cnt = [0]*(n+1)
pcnt = [0]*(n+1)
cnt[0] = pcnt[0] = 1
for i in range(n):
    cnt[i+1] = cnt[i]*2+3
    pcnt[i+1] = pcnt[i]*2+1

def f(lv,x):
    if lv == 0: return 1
    elif x <= 1: return 0
    elif x <= cnt[lv-1] + 1: return f(lv-1,x-1)
    elif x == cnt[lv-1] + 2: return pcnt[lv-1]+1
    elif x <= 2*cnt[lv-1] + 2: return pcnt[lv-1]+1+f(lv-1,x-cnt[lv-1]-2)
    else: return pcnt[lv]

print(f(n,x))

Solution (Python):
def do(lv, dan):
    res = 0
    
    if lv == 0:
        if dan == 0:
            return 0
        elif dan == 1:
            return 1
        else:
            print("!!!!!!!!!!!!!!!!!!!!!!!!!!")
    if dan == 0:
        return 0

    dan -= 1

    if dan == 0:
        return 0

    if burgersize[lv-1] <= dan:
        res += pnum[lv-1]
        dan -= burgersize[lv-1]
    else:
        res = do(lv-1, dan)
        dan = 0

    if dan >= 1:
        res += 1
        dan -= 1
    else:
        return res

    if burgersize[lv-1] <= dan:
        res += pnum[lv-1]
        dan -= burgersize[lv-1]
    else:
        res += do(lv-1, dan)
        dan = 0


    return res

burgersize = [1] * 51
pnum = [1] * 51
for i in range(1, 51):
    burgersize[i] = burgersize[i-1] * 2 + 3
    pnum[i] = pnum[i-1] * 2 + 1


a,b = map(int, input().split())
print(do(a, b))

Solution (Python):
import sys
sys.setrecursionlimit(10**6)
input = sys.stdin.readline
N,X = map(int,input().split())
memo = {}
memo[(1,1)] = 1
def cost(N,X):
 L=2**(N+1)-3
 ans=0
 if X==1:
  ans=0
 elif X==2**(N+1)-3:
  ans=2**N-1
 elif X==(L+1)//2:
  if (N-1,X-2) in memo:
   ans=memo[(N-1,X-2)]+1
  else:
   ans=cost(N-1,X-2)+1
 elif X>(L+1)//2:
  if (N-1,X-((L+1)//2)) in memo:
   ans=2**(N-1)+memo[(N-1,X-((L+1)//2))]
  else:
   ans=2**(N-1)+cost(N-1,X-((L+1)//2))
 else:
  if (N-1,X-1) in memo:
   ans=memo[(N-1,X-1)]
  else:
   ans=cost(N-1,X-1)
 memo[(N,X)]=ans
 return ans
print(cost(N+1,X))

Solution (Python):
n,x=map(int,input().split())
p=[1]
a=[1]
for i in range(0,n):
  p.append(p[i]*2+1)
  a.append(a[i]*2+3)
def f(n,x):
  if n==0 and x<=0:
    return 0
  elif n==0:
    return 1
  elif x<=1+a[n-1]:
    return f(n-1,x-1)
  else:
    return p[n-1]+f(n-1,x-a[n-1]-2)+1
print(f(n,x))

Solution (Python):
n,x=map(int,input().split())

bp=[]
h=[]
for i in range(n+1):
    bp.append([2**(i+1)-2,2**(i+1)-1])
    h.append(2**(i+2)-3)


p=0
while x!=0:
    if n==0:
        p+=1
        x=0
    elif x<=h[n-1]+1:
        x=x-1
    elif x==h[n-1]+2:
        p+=1
        x=x-2
    elif x<=2*h[n-1]+2:
        p+=bp[n-1][1]+1
        x=x-h[n-1]-2
    else:
        p+=2*bp[n-1][1]+1
        x=0
    n=n-1

print(p)

Solution (Python):
import sys
readline = sys.stdin.readline

N, X = map(int,readline().split())

T = [0] * (N + 1) 
P = [0] * (N + 1) 

T[0] = 1
P[0] = 1

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


stack = [[N,X]]
ans = 0

while stack:
  n, x = stack.pop()
  if x <= 0:
    continue
  if x >= T[n]:
    ans += P[n]
    continue
  if n == 0:
    ans += P[n]
    continue
  stack.append([n - 1,x - 1])
  ans += (x >= T[n - 1] + 2) * 1
  stack.append([n - 1, x - (T[n - 1] + 2)])

print(ans)

Solution (Python):
import sys
readline = sys.stdin.readline

N, X = map(int,readline().split())

T = [0] * (N + 1) 
P = [0] * (N + 1) 

T[1] = 5
P[1] = 3

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


stack = [[N,X]]
ans = 0

while stack:
  n, x = stack.pop()
  if x <= 0:
    continue
  if x >= T[n]:
    ans += P[n]
    continue
  if n == 1:
    ans += min(x - 1,3)
    continue
  stack.append([n - 1,x - 1])
  ans += (x >= T[n - 1] + 2) * 1
  stack.append([n - 1, x - (T[n - 1] + 2)])

print(ans)

Solution (Python):
import sys
readline = sys.stdin.readline

N, X = map(int,readline().split())

T = [0] * (N + 1) 
P = [0] * (N + 1) 

T[1] = 5
P[1] = 3

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


stack = [[N,X]]
ans = 0

while stack:
  n, x = stack.pop()
  if n == 1:
    ans += min(x - 1,3)
    continue
  if x <= 1: 
    continue
  if x < 1 + T[n - 1]: 
    stack.append([n - 1, x - 1])
  elif x <= 1 + T[n - 1]:
    ans += P[n - 1]
  elif x == 2 + T[n - 1]:
    ans += P[n - 1]
    ans += 1
  elif x < 2 + T[n - 1] * 2:
    ans += P[n - 1]
    ans += 1
    stack.append([n - 1, x - (T[n - 1] + 2)])
  else:
    ans += P[n - 1] * 2
    ans += 1

print(ans)

Solution (Python):
def main():
    n, x = map(int, input().split())

    
    
    
    
    pl = [(0, 0)] * (n + 1)
    pl[0] = (1, 1)

    for i in range(1, n + 1):
        prv = pl[i - 1]
        pl[i] = (1 + 2 * prv[0], 3 + 2 * prv[1])

    res = 0

    while n and x > 0:
        x -= 1  
        p, l = pl[n - 1]
        if x == l * 2 + 2 or x == l * 2 + 1:
            res += 2 * p + 1
            break

        if x == l or x == l + 1:
            res += p + (x - l)
            break

        if x < l:
            n -= 1
        else:
            res += p + 1
            x -= l

    print(res)


if __name__ == '__main__':
    main()

Solution (Python):
def main():
    n, x = map(int, input().split())

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

    res = 0
    while n and x > 0:
        x -= 1  

        if x == l[n - 1] or x == l[n - 1] + 1:
            res += p[n - 1] + (x - l[n - 1])
            break
        if x == l[n - 1] * 2 + 2:
            res += 2 * p[n - 1] + 1
            break
        if x < l[n - 1]:
            n -= 1
        else:
            res += p[n - 1] + 1
            x -= l[n - 1]

    print(res)


if __name__ == '__main__':
    main()

Solution (Python):
from collections import deque
from heapq import heapify,heappop,heappush,heappushpop
from copy import copy,deepcopy
from itertools import product,permutations,combinations,combinations_with_replacement
from collections import defaultdict,Counter
from bisect import bisect_left,bisect_right


from functools import reduce
from pprint import pprint


INF = float("inf")

def mycol(data,col):
    return [ row[col] for row in data ]

def mysort(data,col,reverse_flag):
    data.sort(key=lambda x:x[col],reverse=reverse_flag)
    return data

def mymax(data):
    M = -1*float("inf")
    for i in range(len(data)):
        m = max(data[i])
        M = max(M,m)
    return M

def mymin(data):
    m = float("inf")
    for i in range(len(data)):
        M = min(data[i])
        m = min(m,M)
    return m

def mycount(ls,x):
    
    l = bisect_left(ls,x)
    r = bisect_right(ls,x)
    return (r-l)

def myoutput(ls,space=True):
    if space:
        if len(ls)==0:
            print(" ")
        elif type(ls[0])==str:
            print(" ".join(ls))
        elif type(ls[0])==int:
            print(" ".join(map(str,ls)))
        else:
            print("Output Error")
    else:
        if len(ls)==0:
            print("")
        elif type(ls[0])==str:
            print("".join(ls))
        elif type(ls[0])==int:
            print("".join(map(str,ls)))
        else:
            print("Output Error")

def I():
    return int(input())

def MI():
    return map(int,input().split())

def RI():
    return list(map(int,input().split()))

def CI(n):
    return [ int(input()) for _ in range(n) ]

def LI(n):
    return [ list(map(int,input().split())) for _ in range(n) ]

def S():
    return input()

def MS():
    return input().split()

def RS():
    return list(input().split())

def CS(n):
    return [ input() for _ in range(n) ]

def LS(n):
    return [ list(input().split()) for _ in range(n) ]

n,x = MI()

def mycalc(n,x):
    M = 4*(2**n) - 3
    m = (M//2) + 1
    if n==0:
        return 1
    if x==1:
        return 0
    elif x>=2 and x<m:
        return mycalc(n-1,x-1)
    elif x==m:
        return mycalc(n-1,x-2) + 1
    elif x>m and x<M:
        return mycalc(n-1,x-m) + ( 2**(n+1) - 2 )//2 + 1
    elif x==M:
        return 2**(n+1) - 1
    else:
        print("E")
ans = mycalc(n,x)
print(ans)

Solution (Python):
from collections import deque
from heapq import heapify,heappop,heappush,heappushpop
from copy import copy,deepcopy
from itertools import product,permutations,combinations,combinations_with_replacement
from collections import defaultdict,Counter
from bisect import bisect_left,bisect_right


from functools import reduce
from pprint import pprint
from statistics import mean,median,mode

INF = float("inf")

def mycol(data,col):
    return [ row[col] for row in data ]

def mysort(data,col,reverse_flag):
    data.sort(key=lambda x:x[col],reverse=reverse_flag)
    return data

def mymax(data):
    M = -1*float("inf")
    for i in range(len(data)):
        m = max(data[i])
        M = max(M,m)
    return M

def mymin(data):
    m = float("inf")
    for i in range(len(data)):
        M = min(data[i])
        m = min(m,M)
    return m

def mycount(ls,x):
    
    l = bisect_left(ls,x)
    r = bisect_right(ls,x)
    return (r-l)

def myoutput(ls,space=True):
    if space:
        if len(ls)==0:
            print(" ")
        elif type(ls[0])==str:
            print(" ".join(ls))
        elif type(ls[0])==int:
            print(" ".join(map(str,ls)))
        else:
            print("Output Error")
    else:
        if len(ls)==0:
            print("")
        elif type(ls[0])==str:
            print("".join(ls))
        elif type(ls[0])==int:
            print("".join(map(str,ls)))
        else:
            print("Output Error")

def I():
    return int(input())

def MI():
    return map(int,input().split())

def RI():
    return list(map(int,input().split()))

def CI(n):
    return [ int(input()) for _ in range(n) ]

def LI(n):
    return [ list(map(int,input().split())) for _ in range(n) ]

def S():
    return input()

def MS():
    return input().split()

def RS():
    return list(input().split())

def CS(n):
    return [ input() for _ in range(n) ]

def LS(n):
    return [ list(input().split()) for _ in range(n) ]

n,x = MI()

def mycalc(n,x):
    M = 4*(2**n) - 3
    m = (M//2) + 1
    if n==0:
        return 1
    if x==1:
        return 0
    elif x>=2 and x<m:
        return mycalc(n-1,x-1)
    elif x==m:
        return mycalc(n-1,x-2) + 1
    elif x>m and x<M:
        return mycalc(n-1,x-m) + ( 2**(n+1) - 2 )//2 + 1
    elif x==M:
        return 2**(n+1) - 1
    else:
        print("E")
ans = mycalc(n,x)
print(ans)

Solution (Python):
import sys
readline = sys.stdin.readline

N,X = map(int,readline().split())




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









def bargar(n,x):
  if n == 1:
    return min(x - 1, 3)
  t = T[n - 1] 
  if x == 1:
    return 0
  elif x <= t + 1:
    return bargar(n - 1, x - 1)
  elif x == t + 2:
    return bargar(n - 1, t) + 1
  elif x < t * 2 + 3:
    return bargar(n - 1,t) + 1 + bargar(n - 1, x - (t + 2))
  else:
    return bargar(n - 1,t) * 2 + 1

print(bargar(N,X))

Solution (Python):
n, x = map(int, input().split())
a, p = [1], [1]
for i in range(n):
    a.append(a[i] * 2 + 3)
    p.append(p[i] * 2 + 1)

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])
print(f(n, x))

Solution (Python):
n, x = map(int, input().split())
a, p = [1], [1]
for i in range(n):
    a.append(a[i] * 2 + 3)
    p.append(p[i] * 2 + 1)

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])
print(f(n, x))

Solution (Python):
import sys

readline = sys.stdin.readline
MOD = 10 ** 9 + 7
INF = float('INF')
sys.setrecursionlimit(10 ** 5)


def main():
    n, x = list(map(int, readline().split()))
    l = [0] * (n + 1)
    b = [0] * (n + 1)

    l[0] = 1
    b[0] = 1

    for i in range(1, n + 1):
        l[i] = 2 * l[i - 1] + 3
        b[i] = 2 * b[i - 1] + 1

    ans = 0
    rem = x
    level = n

    while rem and level > 0:
        if rem >= l[level - 1] + 2:
            ans += b[level - 1] + 1
            rem -= (l[level - 1] + 2)
            level -= 1
        elif rem == l[level - 1] + 1:
            rem -= (l[level - 1] + 1)
            ans += b[level - 1]
        else:
            rem -= 1
            level -= 1

    if level == 0 and rem:
        ans += 1

    print(ans)


if __name__ == '__main__':
    main()

Solution (Python):
n, x = map(int, input().split())
a, p = [1], [1]
for i in range(n):
    a.append(a[i] * 2 + 3)
    p.append(p[i] * 2 + 1)


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])


print(f(N=n, X=x))

Solution (Python):
N,X = map(int,input().split())

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

b = [1]
for i in range(N):
    b.append(2*b[-1]+1)

def solve(n,x):
    if n == 0:
        if x == 1:
            return 1
        return 0
    if x == a[n]:
        return b[n]
    if x >= a[n]//2+1:
        return b[n-1] + 1 + solve(n-1,x-a[n]//2-1)
    if x >= 1:
        return solve(n-1,x-1)
    return 0

print(solve(N,X))

Solution (Python):






import sys
input = sys.stdin.readline

import math

import bisect
from collections import defaultdict
from collections import deque
from functools import lru_cache






MOD = 10**9+7
INF = float('inf')






def I(): return int(input().strip())
def S(): return input().strip()
def IL(): return list(map(int,input().split()))
def SL(): return list(map(str,input().split()))
def ILs(n): return list(int(input()) for _ in range(n))
def SLs(n): return list(input().strip() for _ in range(n))
def ILL(n): return [list(map(int, input().split())) for _ in range(n)]
def SLL(n): return [list(map(str, input().split())) for _ in range(n)]


def P(arg): print(arg); return
def Y(): print("Yes"); return
def N(): print("No"); return
def E(): exit()
def PE(arg): print(arg); exit()
def YE(): print("Yes"); exit()
def NE(): print("No"); exit()


def DD(arg): return defaultdict(arg)



def inv(n): return pow(n, MOD-2, MOD)


kaijo_memo = []
def kaijo(n):
  if(len(kaijo_memo) > n):
    return kaijo_memo[n]
  if(len(kaijo_memo) == 0):
    kaijo_memo.append(1)
  while(len(kaijo_memo) <= n):
    kaijo_memo.append(kaijo_memo[-1] * len(kaijo_memo) % MOD)
  return kaijo_memo[n]

gyaku_kaijo_memo = []
def gyaku_kaijo(n):
  if(len(gyaku_kaijo_memo) > n):
    return gyaku_kaijo_memo[n]
  if(len(gyaku_kaijo_memo) == 0):
    gyaku_kaijo_memo.append(1)
  while(len(gyaku_kaijo_memo) <= n):
    gyaku_kaijo_memo.append(gyaku_kaijo_memo[-1] * pow(len(gyaku_kaijo_memo),MOD-2,MOD) % MOD)
  return gyaku_kaijo_memo[n]

def nCr(n,r):
  if(n == r):
    return 1
  if(n < r or r < 0):
    return 0
  ret = 1
  ret = ret * kaijo(n) % MOD
  ret = ret * gyaku_kaijo(r) % MOD
  ret = ret * gyaku_kaijo(n-r) % MOD
  return ret


def factorization(n):
  arr = []
  temp = n
  for i in range(2, int(-(-n**0.5//1))+1):
    if temp%i==0:
      cnt=0
      while temp%i==0: 
        cnt+=1 
        temp //= i
      arr.append([i, cnt])
  if temp!=1:
    arr.append([temp, 1])
  if arr==[]:
    arr.append([n, 1])
  return arr


def make_divisors(n):
  divisors = []
  for i in range(1, int(n**0.5)+1):
    if n % i == 0:
      divisors.append(i)
      if i != n // i: 
        divisors.append(n//i)
  return divisors


def gcd(a, b):
    while b:
        a, b = b, a % b
    return a


def lcm(a, b):
    return a * b // gcd (a, b)


def count_bit(n):
  count = 0
  while n:
    n &= n -1
    count += 1
  return count


def base_10_to_n(X, n):
  if X//n:
    return base_10_to_n(X//n, n)+[X%n]
  return [X%n]

def base_n_to_10(X, n):
  return sum(int(str(X)[-i-1])*n**i for i in range(len(str(X))))


def int_log(n, a):
  count = 0
  while n>=a:
    n //= a
    count += 1
  return count





N,X = IL()

width = [1]
beef = [1]
for i in range(50):
  width.append(width[-1]*2+3)
  beef.append(beef[-1]*2+1)
  

def count_beef(N,X):
  burger = width[N]
  ans = 0
  if X == 1:
    if N == 0:
      return 1
    else:
      return 0
  elif 2<=X<=1+width[N-1]:
    return count_beef(N-1,X-1)
  elif X == 2+width[N-1]:
    return beef[N-1]+1
  elif 3+width[N-1]<=X<=2+width[N-1]*2:
    return beef[N-1] + 1 + count_beef(N-1,X-2-width[N-1])
  else:
    return beef[N]
  
print(count_beef(N,X))

Solution (Python):






import sys
input = sys.stdin.readline

import math

import bisect
from collections import defaultdict
from collections import deque
from functools import lru_cache






MOD = 10**9+7
INF = float('inf')






def I(): return int(input().strip())
def S(): return input().strip()
def IL(): return list(map(int,input().split()))
def SL(): return list(map(str,input().split()))
def ILs(n): return list(int(input()) for _ in range(n))
def SLs(n): return list(input().strip() for _ in range(n))
def ILL(n): return [list(map(int, input().split())) for _ in range(n)]
def SLL(n): return [list(map(str, input().split())) for _ in range(n)]


def P(arg): print(arg); return
def Y(): print("Yes"); return
def N(): print("No"); return
def E(): exit()
def PE(arg): print(arg); exit()
def YE(): print("Yes"); exit()
def NE(): print("No"); exit()


def DD(arg): return defaultdict(arg)



def inv(n): return pow(n, MOD-2, MOD)


kaijo_memo = []
def kaijo(n):
  if(len(kaijo_memo) > n):
    return kaijo_memo[n]
  if(len(kaijo_memo) == 0):
    kaijo_memo.append(1)
  while(len(kaijo_memo) <= n):
    kaijo_memo.append(kaijo_memo[-1] * len(kaijo_memo) % MOD)
  return kaijo_memo[n]

gyaku_kaijo_memo = []
def gyaku_kaijo(n):
  if(len(gyaku_kaijo_memo) > n):
    return gyaku_kaijo_memo[n]
  if(len(gyaku_kaijo_memo) == 0):
    gyaku_kaijo_memo.append(1)
  while(len(gyaku_kaijo_memo) <= n):
    gyaku_kaijo_memo.append(gyaku_kaijo_memo[-1] * pow(len(gyaku_kaijo_memo),MOD-2,MOD) % MOD)
  return gyaku_kaijo_memo[n]

def nCr(n,r):
  if(n == r):
    return 1
  if(n < r or r < 0):
    return 0
  ret = 1
  ret = ret * kaijo(n) % MOD
  ret = ret * gyaku_kaijo(r) % MOD
  ret = ret * gyaku_kaijo(n-r) % MOD
  return ret


def factorization(n):
  arr = []
  temp = n
  for i in range(2, int(-(-n**0.5//1))+1):
    if temp%i==0:
      cnt=0
      while temp%i==0: 
        cnt+=1 
        temp //= i
      arr.append([i, cnt])
  if temp!=1:
    arr.append([temp, 1])
  if arr==[]:
    arr.append([n, 1])
  return arr


def make_divisors(n):
  divisors = []
  for i in range(1, int(n**0.5)+1):
    if n % i == 0:
      divisors.append(i)
      if i != n // i: 
        divisors.append(n//i)
  return divisors


def gcd(a, b):
    while b:
        a, b = b, a % b
    return a


def lcm(a, b):
    return a * b // gcd (a, b)


def count_bit(n):
  count = 0
  while n:
    n &= n -1
    count += 1
  return count


def base_10_to_n(X, n):
  if X//n:
    return base_10_to_n(X//n, n)+[X%n]
  return [X%n]

def base_n_to_10(X, n):
  return sum(int(str(X)[-i-1])*n**i for i in range(len(str(X))))


def int_log(n, a):
  count = 0
  while n>=a:
    n //= a
    count += 1
  return count





N,X = IL()

width = [1]
beef = [1]
for i in range(50):
  width.append(width[-1]*2+3)
  beef.append(beef[-1]*2+1)
  

def count_beef(N,X):
  burger = width[N]
  ans = 0
  if X == 1:
    if N == 0:
      return 1
    else:
      return 0
  elif 2<=X<=1+width[N-1]:
    return count_beef(N-1,X-1)
  elif X == 2+width[N-1]:
    return count_beef(N-1,X-2)+1
  elif 3+width[N-1]<=X<=2+width[N-1]*2:
    return beef[N-1] + 1 + count_beef(N-1,X-2-width[N-1])
  else:
    return beef[N]
  
print(count_beef(N,X))

Solution (Python):
n, x = map(int, input().split())

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

def f(n, x):
    if n == 1:
        if x == 1:
            return 0
        elif 2 <= x and x <= 4:
            return x-1
        else:
            return 3
    if x == 1:
        return 0
    elif 1 < x and x <= 1 + a[n-1]:
        return f(n-1, x-1)
    elif x == 2 + a[n-1]:
        return p[n-1] + 1
    elif 2 + a[n-1] < x and x < a[n]:
        return p[n-1] + 1 + f(n-1, x - (2 + a[n-1]))
    else:
        return p[n]
print(f(n, x))