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 in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Practice
{
    class Program
    {
        static void Main(string[] args)
        {
            Solve();
        }
        private const int MOD = 1000000007;
        private static List<long> ps = null;
        static void Solve()
        {
            var nk = ReadAndParseLongArr();
            long n = nk[0];
            long x = nk[1];
            long length = powNoMod(2, n + 2) - 3;

            ps = new List<long>();
            for(int i=0;i<=n;++i)
            {
                ps.Add(powNoMod(2, i + 1) - 1);
            }
            long ans = CalcP(x-1, 0, length - 1, (int)n);
            Console.WriteLine(ans);
        }
        private static long CalcP( long x, long a, long b, int n)
        {
            if(a == b) { return 1; }
            long halfP = (b-a) / 2 + a;
            if( x == a)
            {
                return 0;
            }
            else if( x < halfP)
            {
                return CalcP(x, a + 1, halfP - 1, n-1);
            }else if( x == halfP)
            {
                return ps[n-1] + 1;
            }
            else // (x <= b)
            {
                return ps[n-1] + 1 + CalcP(x, halfP + 1, b - 1, n-1);
            }
        }

        private static long powNoMod(long x, long n)
        {
            if (n == 0) { return 1; }
            long res = powNoMod(x * x , n / 2);
            if (n % 2 == 1)
            {
                res = res * x;
            }
            return res;
        }

        #region よく使う便利関数
        private static bool isPrime(long x)
        {
            if (x == 2) { return true; }
            if (x < 2 || x % 2 == 0) { return false; }
            long i = 3;
            while (i * i <= x)
            {
                if (x % i == 0) { return false; }
                i = i + 2;
            }
            return true;
        }
        private static long lcm(long x, long y)
        {
            return x / gcd(x, y) * y;
        }
        private static long gcd(long x, long y)
        {
            return y > 0 ? gcd(y, x % y) : x;
        }
        private static long pow(long x, long n)
        {
            if (n == 0) { return 1; }
            long res = pow(x * x % MOD, n / 2);
            if (n % 2 == 1)
            {
                res = res * x % MOD;
            }
            return res;
        }
        private static int ReadAndParseInt()
        {
            return int.Parse(Console.ReadLine());
        }
        private static int[] ReadAndParseIntArr()
        {
            return Array.ConvertAll(Console.ReadLine().Split(' '), int.Parse);
        }
        private static long ReadAndParseLong()
        {
            return long.Parse(Console.ReadLine());
        }
        private static long[] ReadAndParseLongArr()
        {
            return Array.ConvertAll(Console.ReadLine().Split(' '), long.Parse);
        }
        #endregion
    }
}