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++14 (Clang 3.8.0) (judge verdict: Accepted)

#include <cmath>
#include <iostream>
#include <vector>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <stack>
#include <tuple>
#include <bitset>
#include <algorithm>
#include <functional>
#include <utility>
#include <iomanip>

#define int long long int
#define rep(i, n) for(int i = 0; i < (n); ++i)
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((int)(x).size())
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() )

using namespace std;

typedef pair<int, int> P;

const int INF = 1e15;
const int MOD = 1e9+7;

int solve(const vector<vector<int>>& b, const vector<int>& s, const vector<int>& p, int n, int x){
    int res = 0;
    rep(i, 5){
        if(x < b[n][i]){
            break;
        }
        x -= b[n][i];
        if(i % 2 == 1){
            res += p[n-1];
        }
        if(i == 2){
            res += 1;
        }
    }

    if(x != 0){
        res += solve(b, s, p, n-1, x);
    }

    return res;
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);

    int n, x;
    cin >> n >> x;

    vector<vector<int>> b(51, vector<int>(5));
    vector<int> s(51);
    vector<int> p(51);
    b[0][0] = 1;
    s[0] = 1;
    p[0] = 1;

    rep(i, 50){
        b[i+1][0] = 1;
        b[i+1][1] = s[i];
        b[i+1][2] = 1;
        b[i+1][3] = s[i];
        b[i+1][4] = 1;

        rep(j, 5){
            s[i+1] += b[i+1][j];
        }
        p[i+1] = 1 + p[i] * 2;
    }

    cout << solve(b, s, p, n, x) << endl;

    return 0;
}