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)

// -----------------------------------------------
// Framework <https://github.com/vain0x/procon>
//
// See the bottom of file for solution.
// -----------------------------------------------

#![allow(unused_imports)]
#![allow(non_snake_case)]

use std::cell::RefCell;
use std::cmp::{max, min, Ordering};
use std::collections::*;
use std::fmt::{Debug, Formatter, Write as FmtWrite};
use std::io::{stderr, stdin, BufRead, Write};
use std::mem::{replace, swap};
use std::ops::*;
use std::rc::Rc;

#[allow(unused_macros)]
macro_rules! debug {
    ($($e:expr),*) => {
        #[cfg(debug_assertions)]
        $({
            let (e, mut err) = (stringify!($e), stderr());
            writeln!(err, "\x1B[33m{}\x1B[0m = {:?}", e, $e).unwrap()
        })*
    };
}

#[allow(unused_macros)]
macro_rules! read {
    ([$t:ty] ; $n:expr) =>
        ((0..$n).map(|_| read!([$t])).collect::<Vec<_>>());
    ($($t:ty),+ ; $n:expr) =>
        ((0..$n).map(|_| read!($($t),+)).collect::<Vec<_>>());
    ([$t:ty]) =>
        (rl().split_whitespace().map(|w| w.parse().unwrap()).collect::<Vec<$t>>());
    ($($t:ty),*) => {{
        let buf = rl();
        let mut w = buf.split_whitespace();
        ($(w.next().unwrap().parse::<$t>().unwrap()),*)
    }};
}

#[allow(dead_code)]
fn rl() -> String {
    let mut buf = String::new();
    stdin().read_line(&mut buf).unwrap();
    buf.trim_right().to_owned()
}

// -----------------------------------------------
// Solution
// -----------------------------------------------

// レベル l バーガーの下から x 層を食べる
fn dfs(mut x: i64, l: usize, p: &mut i64, xs: &[i64], ps: &[i64]) {
    // パン
    if x == 0 {
        return;
    }
    x -= 1;

    // l-1 バーガー
    if x < xs[l - 1] {
        return dfs(x, l - 1, p, xs, ps);
    }
    x -= xs[l - 1];
    *p += ps[l - 1];

    // パティ
    if x == 0 {
        return;
    }
    x -= 1;
    *p += 1;

    // l-1 バーガー
    if x == 0 {
        return;
    }
    if x < xs[l - 1] {
        return dfs(x, l - 1, p, xs, ps);
    }
    x -= xs[l - 1];
    *p += ps[l - 1];

    // パン
    if x == 0 {
        return;
    }
    x -= 1;
}

fn main() {
    let (N, X) = read!(usize, i64);

    let mut ps = vec![0; N + 1];
    let mut xs = vec![0; N + 1];
    ps[0] = 1;
    xs[0] = 1;

    for l in 0..N {
        ps[1 + l] = ps[l] * 2 + 1;
        xs[1 + l] = xs[l] * 2 + 3;
    }

    let mut p = 0_i64;
    dfs(X, N, &mut p, &xs, &ps);

    println!("{}", p)
}