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 Rust (1.15.1) (judge verdict: Accepted)

fn main() {
    const N_MAX: usize = 50;
    let mut layers = [1 as u64; N_MAX + 1];
    let mut patties = [1 as u64; N_MAX + 1];
    for i in 1..N_MAX + 1 {
        layers[i] = 2 * layers[i - 1] + 3;
        patties[i] = 2 * patties[i - 1] + 1;
    }

    let v = read_nums();
    let (N, X) = (v[0] as usize, v[1]);
    println!("{}", solve(N, X, &layers, &patties));

    fn solve(n: usize, x: u64, layers: &[u64], patties: &[u64]) -> u64 {
        if x == 0 {
            return 0;
        }
        if n == 0 {
            return 1;
        }
        let mut l = [0; 6];
        let mut p = [0; 6];
        l[0] = 0;
        p[0] = 0;
        l[1] = l[0] + 1;
        p[1] = p[0] + 0;
        l[2] = l[1] + layers[n - 1];
        p[2] = p[1] + patties[n - 1];
        l[3] = l[2] + 1;
        p[3] = p[2] + 1;
        l[4] = l[3] + layers[n - 1];
        p[4] = p[3] + patties[n - 1];
        l[5] = l[4] + 1;
        p[5] = p[4] + 0;
        if x <= l[1] {
            p[1]
        } else if x <= l[2] {
            p[1] + solve(n - 1, x - l[1], layers, patties)
        } else if x <= l[3] {
            p[3]
        } else if x <= l[4] {
            p[3] + solve(n - 1, x - l[3], layers, patties)
        } else {
            p[5]
        }
    };
}

fn read_str() -> String {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).expect("Failed to read input.");
    s
}

fn read_num() -> u64 {
    read_str().trim().parse().expect("Could not parse.")
}

fn read_nums() -> Vec<u64> {
    let s = read_str();
    let a: Vec<&str> = s.split(' ').collect();
    let mut v: Vec<u64> = Vec::new();
    for x in a {
        v.push(x.trim().parse().expect("Could not parse."));
    }
    v
}