object Main {

  def main(args: Array[String]): Unit = {
    val sc = new java.util.Scanner(System.in)

    val N = sc.nextInt()
    val X = sc.nextLong()
    // レベルnのハンバーガーの層数はf(n)で表され,f(n) = 2f(n-1) + 3, f(0) = 1である.
    // つまり, レベルNのハンバーガーの場合f(N)枚であり, このうちX層食べた時のパティの枚数を知りたい.

    // もし, X < f(N) / 2 + 1 の時, ハンバーガーの真ん中の途中まで食べているので,
    // レベル N - 1 のハンバーガーを X - 1 層食べた時の パティの枚数 が答えになる.

    // X == f(N) / 2 + 1 の時, ハンバーガーの真ん中まで食べているので,
    // レベルN - 1のハンバーガーに含まれるパティの数だけ食べていることになる.

    // X > f(n) / 2 + 1 の時, ハンバーガーの真ん中よりも食べているので,
    // レベル N - 1 のハンバーガーに含まれるパティの数 +
    // レベル N - 1 のハンバーガーを X - (f(N) / 2 + 1) 層食べた時の パティの枚数 が答えになる.

    // こうして再帰的に求めていけるが, レベル 0 の ハンバーガーに含まれるパティの数は 当然 1 である.

    def solve(): Long = {
      val f = new Array[Long](N+1)
      f(0) = 1
      var i = 1
      while (i <= N) {
        f(i) = 2 * f(i-1) + 3
        i += 1
      }

      val dp = new Array[Long](N+1)
      dp(0) = 1

      // 5 枚 ,3 枚目 が半分, 4枚まで食べたい時,
      def dfs(level: Int, X: Long): Long =
        if (level > 0) {
          val center = f(level) / 2 + 1
          if (X >= 1 && X < center) {
            dfs(level - 1, X - 1)
          } else if (X >= center) {
            val miniBarger =
              if (dp(level - 1) != 0)
                dp(level - 1)
              else {
                dp(level - 1) = dfs(level - 1, f(level - 1))
                dp(level - 1)
              }
            if (X == center)
              miniBarger + 1
            else if (X > center && X < f(level))
              miniBarger + 1 + dfs(level - 1, X - center)
            else if (X == f(level))
              miniBarger + 1 + miniBarger
            else 0
          } else 0
        } else 0

      dfs(N, X)
    }

    println(solve())
  }

}
