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):
import sys
from collections import deque
stdin = sys.stdin

ni = lambda: int(ns())
na = lambda: list(map(int, stdin.readline().split()))
ns = lambda: stdin.readline().rstrip()  

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

print(f(n,x))

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

a,p=[1],[1]

for i in range(N):
  a.append(2*a[i]+3)
  p.append(2*p[i]+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())

def dp(a, b):
    if a == 1:
        if 1 <= b <= 4:
            return b-1
        else:
            return 3
    elif b == 1:
        return 0
    elif 1 < b < 2**(a+1)-1:
        return dp(a-1, b-1)
    elif b == 2**(a+1)-1:
        return dp(a-1, 2**(a+1)-3) + 1
    elif 2**(a+1)-1 < b < 2**(a+2)-3:
        return dp(a-1, 2**(a+1)-3) + 1 + dp(a-1, b+1-2**(a+1))
    elif b == 2**(a+2)-3:
        return dp(a-1, 2**(a+1)-3) * 2 + 1
    
print(dp(n, x))

Solution (Python):

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

nlen = [0] * (N+1)
nlen[0] = 1

for i in range(N):
    i += 1

    nlen[i] = 3 + nlen[i-1] * 2

    
    
num = [0] * (N+1)

p = 0
b = 0

amari = X


for i in range(N):

    i = N-i

    num[i-1] += 2 * num[i]
    p += num[i]
    b += num[i] * 2

    if 3 + 2 * nlen[i-1]  == amari :

        num[i-1] += 2

        p += 1
        b += 2

        amari = 0

    elif 2 + 2 * nlen[i-1] == amari:

        num[i-1] += 2

        p += 1
        b += 1

        amari = 0

    elif 2 + nlen[i-1] <= amari:

        num[i-1] += 1

        p += 1
        b += 1

        amari -= 2 + nlen[i-1]

    elif 1 + nlen[i-1] == amari:

        num[i-1] += 1

        b += 1

        amari = 0

    elif 1 <= amari:

        b += 1
        amari -= 1

print (p + num[0])

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:
    return 0 if x<= 0 else 1
  elif n == 1:
    return "BPPPB"[:x].count("P")
  else: 
    if x <= 0:
      return 0
    elif x <= 1 + a[n-1]:
      return f(n-1, x-1)  
    else:
      return p[n-1] + f(n - 1,x - 2 - a[n-1]) + 1
print (f(N, X))

Solution (Python):



import sys
sys.setrecursionlimit(10**6)
readline = sys.stdin.readline



n,x = [int(i) for i in readline().split()]

sou = [1]*51
pat = [1]*51
for i in range(50):
    sou[i+1] = 2*sou[i]+3
    pat[i+1] = 2*pat[i]+1




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

    if x <= sou[n-1]+1:
        return solve(n-1,x-1)
    elif x == sou[n-1]+2:
        return pat[n-1]+1
    elif x == sou[n]:
        return pat[n]
    else:
        return pat[n-1] + 1 + solve(n-1,x-sou[n-1]-2)
        
print(solve(n,x))

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

n_all = [1] + [0] * N
n_p = [1] + [0] * N
for i in range(1, N + 1):
    n_all[i] = n_all[i - 1] * 2 + 3
    n_p[i] = n_p[i - 1] * 2 + 1
    
def f(l, x):
    if l == 0:
        return 0 if x <= 0 else 1
    if x <= 1:
        return 0
    elif x < n_all[l - 1] + 1:
        return f(l - 1, x - 1)
    elif x == n_all[l - 1] + 1:
        return n_p[l - 1]
    elif x < n_all[l - 1] * 2 + 2:
        return n_p[l - 1] + 1 + f(l - 1, x - n_all[l - 1] - 2)
    else:
        return n_p[l - 1] * 2 + 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):
n, x = list(map(int, input().split()))

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

p = [1]
for _ in range(n):
  p.append(2 * p[-1] + 1)





def f(l, y):
  
  global a, p
  if l == 0:
    return 1
  if y <= 1:
    return 0
  elif y <= a[l - 1] + 1:
    return f(l - 1, y - 1)
  elif y <= a[l - 1] + 2:
    return p[l - 1] + 1
  else:
    return p[l - 1] + 1 + f(l - 1, y - 1 - a[l - 1] - 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
sys.setrecursionlimit(1000000)

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

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


def L(i, X):
    if i == 0:
        if X == 0:
            return 0
        else:
            return 1
    else:
        if X == 0:
            return 0
        elif 1 <= X < l[i-1]+2:
            return L(i-1, X-1)
        elif X == l[i-1]+2:
            return p[i-1]+1
        elif l[i-1]+2 < X < l[i]:
            return p[i-1]+1+L(i-1, X-l[i-1]-2)
        else:
            return p[i]


print(L(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 = 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__":
    resolve()

Solution (Python):

import sys

memo = [{} for _ in range(51)]

def rec(x, k):
    """レベルxバーガーを下からk枚食べた時のパティの枚数"""
    M = 2 ** (x+2) - 3
    if k in memo[x].keys():
        return memo[x][k]
    if k <= x:
        return 0
    if x == 1:
        if k in [2, 3, 4]:
            return k - 1
        elif k == 5:
            return 3
        elif k == 1:
            return 0
        else:
            return 3
    else:
        if k < (M+1) // 2:
            ret = rec(x-1, k-1)
            memo[x][k] = ret
        elif k > (M+1) // 2:
            ret = rec(x-1, (M-3)//2) + 1 + rec(x-1, k-2-(M-3)//2)
            memo[x][k] = ret
        else:
            ret = rec(x-1, (M-3)//2) + 1
            memo[x][k] = ret
        return ret

def solve(N: int, X: int):
    print(rec(N, X))
    
    return



def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  
    X = int(next(tokens))  
    solve(N, X)

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:
    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):
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())

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

def solve(cur, level):
    if level == 0:
        return 1 if cur > 0 else 0
    elif (layers[level] // 2) >= cur:
        return solve(cur - 1, level - 1)
    else:
        return solve(cur - layers[level-1] - 2, level - 1) + patties[level-1] + 1

print(solve(x,n))

Solution (Python):
from bisect import bisect_left

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

L = [1]
P = [1]
l = 1
p = 1
for _ in range(N):
    l = 2*l+3
    p = 2*p+1
    L.append(l)
    P.append(p)
L.sort(reverse=True)
P.sort(reverse=True)


A = X
ans = 0
for n in range(0, N+1):
    if n == N:
        if A == 1:
            ans += 1
        break
    l0 = L[n]//2-1
    p0 = P[n]//2
    
    if A == 1:
        break
    elif  A == l0 + 2:
        ans += p0+1
        break
    elif A == 2*l0+3:
        ans += 2*p0+1
        break
    elif A < l0+2:
        A = A - 1
    elif A > l0+2:
        ans += p0+1
        A = A-l0-2
print(ans)

Solution (Python):
def pat(n, x):
    if x == 0:
        return 0
    if n == 0:
        return 1
    a = 2 ** (n + 2) - 3
    if a // 2 + 1 <= x:
        return 2 ** n + pat(n - 1, x - a // 2 - 1)
    elif a // 2 == x:
        return 2 ** n - 1
    else:
        return pat(n - 1, x - 1)


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

Solution (Python):
def f(N, X):
  m = 2 ** (N + 1) - 1
  if X <= N:
    return 0
  elif N == 0:
    return 1
  elif X < m:
    return f(N-1, X-1)
  else:
    return 2 ** N + f(N-1, X-m)

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

Solution (Python):
Tmp = []
Tmp = input().rstrip().split(' ')
 
nN = int(Tmp[0])
nX = int(Tmp[1])


nA = 1
nP = 1
 
nAnsA = []
nAnsP = []

nAnsA.append(1)
nAnsP.append(1)
 
for i in range(nN):
  nTmpA = nA * 2 +3
  nTmpP = nP * 2 +1
  nAnsA.append(nTmpA)
  nAnsP.append(nTmpP)
  nA = nTmpA
  nP = nTmpP

nAnsA.sort(reverse=True)  
nAnsP.sort(reverse=True)  
nN += 1

nMaxA = nAnsA[0]
nMaxP = nAnsP[0]
 
nTmpA = nMaxA
nTmpP = nMaxP
 
nAns = 0





for i in range(nN):

  if i == nN - 1:
    nAns += 1
    break
  else:
    nTmpA = nAnsA[i+1] + 2
    nTmpP = nAnsP[i+1] + 1



  
  if nTmpA > nX:
    nX -= 1
    if (nX == 0):
      break
  elif nTmpA == nX:
    nAns += nTmpP
    break
  else:
    nAns += nTmpP
    nX -= nTmpA

    
print(nAns)

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 f(n, x):
    if n == 0:
        return 0 if x <= 0 else 1
    elif x <= a[n-1] + 1:
        return f(n - 1, x - 1)
    else:
        return p[n-1] + 1 + f(n-1, x-a[n-1]-2)

print(f(n, x))

Solution (Python):
n,x= list(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 rec(N,X):


    if X == 0:
        return 0
    if N == 0:
        return 1
    if X == 1:
        return 0
    if 1 < X <=As[N-1] + 1:
        return rec(N-1,X-1)

    if X == As[N-1] + 2:
        return Ps[N-1] + 1

    if As[N-1] + 2 < X < 2 * As[N-1] + 3:
        return Ps[N-1] + 1 + rec(N-1,X -As[N-1] -2)

    if X == 2*As[N-1] + 3:
        return 2 * Ps[N-1] + 1


ans = rec(n,x)
print(ans)

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):
n, x = map(int, input().split())

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

def count_putties(N, X):
        if N == 0:
                return 1 if X > 0 else 0
        elif X <= layers[N-1] + 1:
                return count_putties(N-1, X-1)
        else:
                l = putties[N-1] + 1
                return l + count_putties(N-1, X-(layers[N-1] + 2))

print(count_putties(n, x))

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

bc = [0] * 51
pc = [0] * 51
l = [0] * 51
pc[0] = 1
l[0] = 1
for i in range(1, 51):
    bc[i] = bc[i-1] * 2 + 2
    pc[i] = pc[i-1] * 2 + 1
    l[i] = bc[i] + pc[i]

def ans(nn, xx):
    if nn == 0:
        return 1
    if xx == 1:
        return 0
    elif xx < (l[nn] + 1) //2:
        return ans(nn-1, xx-1)
    elif xx == (l[nn] + 1) //2:
        return pc[nn-1] + 1
    else:
        return pc[nn-1] + 1 + ans(nn-1, xx-((l[nn]+1)//2) )

print(ans(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 main():

    """ convenient functions
    
    
    
    
    
    """

    """convenient decorator
    
    
        
        
        
        
        
        
        
        
        
        
    """
    
    
    import sys
    sys.setrecursionlimit(10**7)
    from itertools import accumulate, combinations, permutations, product 
    
    from math import factorial, ceil, floor, sqrt
    def factorize(n):
        """return the factors of the Arg and count of each factor
        
        Args:
            n (long): number to be resolved into factors
        
        Returns:
            list of tuples: factorize(220) returns [(2, 2), (5, 1), (11, 1)]
        """
        fct = []  
        b, e = 2, 0  
        while b * b <= n:
            while n % b == 0:
                n = n // b
                e = e + 1
            if e > 0:
                fct.append((b, e))
            b, e = b + 1, 0
        if n > 1:
            fct.append((n, 1))
        return fct
    def combinations_count(n, r):
        """Return the number of selecting r pieces of items from n kinds of items.
        
        Args:
            n (long): number
            r (long): number
        
        Raises:
            Exception: not defined when n or r is negative
        
        Returns:
            long: number
        """
        
        if n < 0 or r < 0:
            raise Exception('combinations_count(n, r) not defined when n or r is negative')
        if n - r < r: r = n - r
        if r < 0: return 0
        if r == 0: return 1
        if r == 1: return n
        numerator = [n - r + k + 1 for k in range(r)]
        denominator = [k + 1 for k in range(r)]
        for p in range(2,r+1):
            pivot = denominator[p - 1]
            if pivot > 1:
                offset = (n - r) % p
                for k in range(p-1,r,p):
                    numerator[k - offset] /= pivot
                    denominator[k] /= pivot
        result = 1
        for k in range(r):
            if numerator[k] > 1:
                result *= int(numerator[k])
        return result
    def combinations_with_replacement_count(n, r):
        """Return the number of selecting r pieces of items from n kinds of items allowing individual elements to be repeated more than once.
        
        Args:
            n (long): number
            r (long): number
        
        Raises:
            Exception: not defined when n or r is negative
        
        Returns:
            long: number
        """
        if n < 0 or r < 0:
            raise Exception('combinations_with_replacement_count(n, r) not defined when n or r is negative')
        elif n == 0:
            return 1
        else:
            return combinations_count(n + r - 1, r)
    from bisect import bisect_left, bisect_right
    from collections import deque, Counter, defaultdict 
    from heapq import heapify, heappop, heappush, heappushpop, heapreplace,nlargest,nsmallest 
    from copy import deepcopy, copy 
    import operator
    from operator import itemgetter 
    
    
    from functools import reduce, lru_cache
    def chmin(x, y):
        """change minimum
        if x > y, x = y and return (x, True).
        convenient when solving problems of dp[i]
        
        Args:
            x (long): current minimum value
            y (long): potential minimum value
        
        Returns:
            (x, bool): (x, True) when updated, else (x, False)
        """
        if x > y:
            x = y
            return (x, True)
        else:
            return (x, False)
    def chmax(x, y):
        """change maximum
        if x < y, x = y and return (x, True).
        convenient when solving problems of dp[i]
        
        Args:
            x (long): current maximum value
            y (long): potential maximum value
        
        Returns:
            (x, bool): (x, True) when updated, else (x, False)
        """
        if x < y:
            x = y
            return (x, True)
        else:
            return (x, False)

    from fractions import gcd 
    def gcds(numbers):
        return reduce(gcd, numbers)
    def lcm(x, y):
        return (x * y) // gcd(x, y)
    def lcms(numbers):
        return reduce(lcm, numbers, 1)

    
    
    INF = 10 ** 18
    MOD = 10 ** 9 + 7
    modpow = lambda a, n, p = MOD: pow(a, n, p) 
    def modinv(a, p = MOD):
        
        
        return modpow(a, p-2, p)
    def modinv_list(n, p = MOD):
        if n <= 1:
            return [0,1][:n+1]
        else:
            inv_t = [0,1]
            for i in range(2, n+1):
                inv_t += [inv_t[p % i] * (p - int(p / i)) % p]
            return inv_t
    def modfactorial_list(n, p = MOD):
        if n == 0:
            return [1]
        else:
            l = [0] * (n+1)
            tmp = 1
            for i in range(1, n+1):
                tmp = tmp * i % p
                l[i] = tmp
            return l
    def modcomb(n, k, fac_list = [], p = MOD):
        
        
        from math import factorial
        if n < 0 or k < 0 or n < k: return 0
        if n == 0 or k == 0: return 1
        if len(fac_list) <= n:
            a = factorial(n) % p
            b = factorial(k) % p
            c = factorial(n-k) % p
        else:
            a = fac_list[n]
            b = fac_list[k]
            c = fac_list[n-k]
        return (a * modpow(b, p-2, p) * modpow(c, p-2, p)) % p
    def modadd(a, b, p = MOD):
        return (a + b) % MOD
    def modsub(a, b, p = MOD):
        return (a - b) % p
    def modmul(a, b, p = MOD):
        return ((a % p) * (b % p)) % p
    def moddiv(a, b, p = MOD):
        return modmul(a, modpow(b, p-2, p))

    class UnionFindTree:
        """union find tree class
        TODO: fix this description...
        how to use (example):
        >>  uf = UnionFindTree(N) 
        >>  if uf.find_root(a) == uf.find_root(b):
        >>      do something
        >>  else:
        >>      do something
        >>      uf.unite(a, b)
        """
        def __init__(self, N):
            self.root = [-1] * (N+1)
            self.rank   = [0]  * (N+1)
            self.connected_num = [1] * (N+1)
    
        def find_root(self,x):
            root = self.root
            while root[x] != -1:
                x = root[x]
            return x
    
        def unite(self,x,y):
            root = self.root
            rank = self.rank
            connected_num = self.connected_num
            find_root = self.find_root
    
            rx = find_root(x)
            ry = find_root(y)
            if rx != ry:
                if rank[rx] < rank[ry]:
                    root[rx] = ry
                    rx,ry = ry,rx
                else:
                    if rank[rx] == rank[ry]:
                        rank[rx] += 1
                    root[ry] = rx       
                connected_num[rx] += connected_num[ry]

    """ initialize variables and set inputs
    
        
        
    
        
        
        
        
        
        
        
    
        
        
        
        
    
        
        
    """

    
    r = lambda: sys.stdin.readline().strip()
    r_int = lambda: int(r())
    R = lambda: list(map(int, r().split()))
    Rmap = lambda: map(int, r().split())
    Rfloat = lambda: list(map(float, r().split()))
    Rtuple = lambda: tuple(map(int, r().split()))

    """ how to treat input
    
    
    
    
    
    
    
    """

    if __name__ != '__main__':
        
        sys.stdin = open('sample.txt')
        
    
    

    N, X = R()
    """
    A_n = 2A_(n-1) + 3, A_0 = 1
    B_n = 2B_n-1 + 1, B_0 = 0
    """
    A = [1] * 50
    B = [1] * 50
    for i in range(1, 50):
        A[i] = 2 * A[i-1] + 3
    for i in range(1, 50):
        B[i] = 2 * B[i-1] + 1
    
    @lru_cache(maxsize=None)
    def burg(l, x):
        if x == 1:
            if l == 0:
                return 1
            return 0
        elif x <= 1 + A[l-1]:
            return 0 + burg(l-1, x-1)
        elif x == 2 + A[l-1]:
            return 1 + B[l-1]
        elif x <= 2 + 2*A[l-1]:
            return 1 + B[l-1] + burg(l-1, x-2-A[l-1])
        else:
            return 2 * B[l-1] + 1
    
    
    print(burg(N, X))
    
    
    
    
    
    
    
    
    
    

    """memo: how to use defaultdict of list
    
    Dic = defaultdict(list)
    
    Dic[x].append(y)
    
    for k, v in Dic.items():
    """
    
    """memo: how to solve binary problems
    
    >>> a = 5
    >>> bin_str_a = format(a, '
    >>> print(bin_str_a)
    0b0101 
    """
    
    """memo: how to solve the problem
    creating simple test/answer
    greed
    simple dp
    graph
    """

if __name__ == '__main__':
    main()

Solution (Python):
N, X = map(int, input().split())
a,p = [1],[1]

for i in range(N):
  a.append(2 * a[i] + 3)
  p.append(2 * p[i] + 1)
  
def runrun(N,X):
  if N == 0:
    return 0 if X <= 0 else 1
  elif X<= 1 + a[N-1]:
    return runrun(N-1, X-1)
  else:
    return p[N-1] + 1 + runrun(N-1, X-a[N-1]-2)
    
    
print(runrun(N,X))

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



def f(n, x):
    return (
        0 if x <= 0 else
        2**(n + 1) - 1 if x >= 2**(n + 2) - 3 else
        f(n - 1, x - 1) +
        f(0, x - (2**(n + 1) - 2)) +
        f(n - 1, x - (2**(n + 1) - 1))
    )


ans = f(N, X)

print(ans)

Solution (Python):
import sys
input = sys.stdin.readline
from functools import lru_cache

size = [0] * 51

@lru_cache(100000)
def rec(l, x):
	global size
	
	if l == 0:
		
		return x
	mid = size[l] // 2 + 1
	if x == size[l]:
		return 2 * rec(l-1, size[l-1]) + 1
	elif x == mid:
		return rec(l-1, size[l-1]) + 1
	elif x == 1:
		return 0
	elif x > mid:
		return rec(l-1, size[l-1]) + rec(l-1, x-size[l-1]-2) + 1
	else:
		return rec(l-1, x-1)

def main():
	global size
	n, x = map(int, input().strip().split())
	size[0] = 1
	for i in range(1, 51):
		size[i] = 2 * size[i-1] + 3
	
	print(rec(n, x))

if __name__ == '__main__':
	main()

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

a = [1] * (N + 1)
p = [1] * (N + 1)
for i in range(N):
    a[i + 1] = a[i] * 2 + 3
    p[i + 1] = 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())

burger_list = []
for i in range(N+1):
    if i == 0:
        burger_list.append([0,1])
    else:
        burger_list.append([2+burger_list[-1][0]*2,1+burger_list[-1][1]*2])

def pty(x,k,List):
    if x == 1:
        y = 0
    elif 1 < x <= sum(List[k-1])+1:
        y = 1
    elif x == 2+sum(List[k-1]):
        y = 2
    elif x == sum(List[k]):
        y = 4
    elif 2+sum(List[k-1]) < x <= 2+sum(List[k-1])*2:
        y = 3
    return y
        
ans = 0
k = N
while X > 0:
    n = pty(X,k,burger_list)
    if n == 0:
        if k == 0:
            ans += 1
        X = 0
    elif n == 2:
        ans += (burger_list[k-1][1]+1)
        X = 0
    elif n == 4:
        ans += burger_list[k][1]
        X = 0
    elif n == 1:
        X -= 1
        k -= 1
    elif n == 3:
        ans += (burger_list[k-1][1]+1)
        X -= (sum(burger_list[k-1])+2)
        k -= 1
print(ans)

Solution (Python):
def len_burger(L):
    return 2**(L+2)-3
def num_ban(L):
    return 2**(L+1)-1

def eat(L,X):
    if L == 0: return 1
    if X == 1: return 0
    elif X <= len_burger(L-1)+1: return eat(L-1,X-1)
    elif X == len_burger(L-1)+2: return num_ban(L-1)+1
    elif X < 2*len_burger(L-1)+3: return num_ban(L-1)+1+eat(L-1,X-len_burger(L-1)-2)
    elif X == len_burger(L): return num_ban(L)

def solve():
    N,X = [int(s) for s in input().split() if s]
    
    print(eat(N,X))
    
solve()

Solution (Python):
A,P=[1],[1]
for i in range(50):
    A.append(A[i]*2+3)
    P.append(P[i]*2+1)

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

print(n(*list(map(int, input().split()))))

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

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

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

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

print (calc(N, X))

Solution (Python):
import numpy as np

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


def num_p(x,n):
    if n == 0:
        return 1
    burg = size[n-1]
    if x == 1:
        return 0
    elif x == burg+2:
        return full_p[n-1]+1
    elif x < burg +2:
        return num_p(x-1,n-1)
    elif x > burg+2:
        return full_p[n-1]+1+num_p(x-(burg+2),n-1)


ans = num_p(x,n)

print(ans)

Solution (Python):
def calc(n,x):
  ans=0
  while 1:
    if x==1:
      break
    elif 2<=x<=lb[n-1]:
      x-=1
      n-=1
    elif x==1+lb[n-1]:
      ans+=pb[n-1]
      break
    elif x==2+lb[n-1]:
      ans+=1+pb[n-1]
      break
    elif 3+lb[n-1]<=x<=1+2*lb[n-1]:
      ans+=1+pb[n-1]
      x-=2+lb[n-1]
      n-=1
    elif x==2+2*lb[n-1]:
      ans+=1+2*pb[n-1]
      break
    elif x==3+2*lb[n-1]:
      ans+=1+2*pb[n-1]
      break
  return ans

n,x=map(int,input().split())
lb=[1]
pb=[1]
for i in range(1,51):
  lb.append(lb[i-1]*2+3)
for i in range(1,51):
  pb.append(pb[i-1]*2+1)
print(calc(n,x))

Solution (Python):
def f(i, X):
    if i == 0:
        return 1

    elif X == 1:
        return 0

    elif X <= 1 + a[i-1]:
        return f(i-1, X-1)

    elif X == 2 + a[i-1]:
        return p[i-1] + 1

    elif X <= 2 + 2 * a[i-1]:
        return f(i-1, X-2-a[i-1]) + 1 + p[i-1]

    else:
        return p[i]

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

print(f(N, X))

Solution (Python):



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

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

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

Solution (Python):
import sys
sys.setrecursionlimit(10**7)
def LI(): return [int(x) for x in sys.stdin.readline().split()]
def LI_(): return [int(x) - 1 for x in sys.stdin.readline().split()]
def LF(): return [float(x) for x in sys.stdin.readline().split()]
def LS(): return sys.stdin.readline().split()
def II(): return int(sys.stdin.readline())
def SI(): return sys.stdin.readline().strip()
INF = 10 ** 18
MOD = 10 ** 9 + 7

N, X = LI()

def solve():
  
  lenl = [0 for i in range(N+1)]
  for i in range(N+1):
    if i == 0:
      lenl[i] = 1
    else:
      lenl[i] = 2 * lenl[i-1] + 3
  
  npl = [0 for i in range(N+1)]
  for i in range(N+1):
    if i == 0:
      npl[i] = 1
    else:
      npl[i] = 2 * npl[i-1] + 1

  def np(l, x):
    if x <= 0:
      return 0
    if l == 0:
      return 1
    
    if x < lenl[l] // 2:
      return np(l-1, x-1)
    elif x == lenl[l] // 2:
      return npl[l-1]
    elif x == (lenl[l] // 2) + 1:
      return npl[l-1] + 1
    else:
      return npl[l-1] + 1 + np(l-1, x-(lenl[l]//2)-1)
  
  print(np(N, X))
solve()