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)

#![allow(unused_imports)]
#![allow(unused_variables)]
#![allow(non_snake_case)]
#![allow(dead_code)]
#![allow(deprecated)]

use std::cell::{Cell, Ref, RefCell, RefMut};
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;
use std::usize;

const MOD_10_9_7: u64 = 1_000_000_007;
const INF: i64 = 1_000_000_000_000;
const MIN_INF: i64 = -1_000_000_000_000;

/// FYI: https://github.com/vain0x/scan-bench
#[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) =>
        (rl().parse::<$t>().unwrap());
    ($($t:ty),*) => {{
        let buf = rl();
        let mut w = buf.split_whitespace();
        ($(w.next().unwrap().parse::<$t>().unwrap()),*)
    }};
}

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

#[allow(unused_macros)]
macro_rules! debug {
    ($($a:expr),*) => {
        eprintln!(concat!($(stringify!($a), " = {:?}, "),*), $($a),*);
    }
}

fn main() {
    let (n, x): (usize, usize) = read!(usize, usize);

    let mut l = Vec::with_capacity(n + 1); // レベルiバーガーの層の数
    let mut p = Vec::with_capacity(n + 1); // レベルiバーガーのパティの数
    l.push(1usize);
    p.push(1usize);
    for i in 1..(n + 1) {
        let l_prev = l[i - 1];
        let p_prev = p[i - 1];
        l.push(l_prev * 2 + 3);
        p.push(p_prev * 2 + 1);
    }

    let mut ans = 0usize;
    let mut i = 0usize;
    let mut i_in_d = 0usize;
    let mut cur_level = n;
    while i < x {
        if i_in_d == 0 {
            // レベルcur_levelバーガーの一番下を見ているとき
            if cur_level == 0 {
                i_in_d = 0;
                i += 1;
                ans += 1;
                continue;
            } else {
                i_in_d += 1;
                i += 1;
                continue;
            }
        }
        if i_in_d == l[cur_level - 1] + 1 {
            // レベルcur_levelバーガーの中央にあるパティを見ているとき
            i_in_d += 1;
            i += 1;
            ans += 1;
            continue;
        }
        if i_in_d == l[cur_level - 1] * 2 + 2 {
            // レベルcur_levelバーガーの一番上を見ているとき
            i_in_d += 1;
            i += 1;
            continue;
        }
        if i + l[cur_level - 1] < x {
            // レベルcur_level - 1バーガーを全部食べても大丈夫なとき
            i_in_d += l[cur_level - 1];
            i += l[cur_level - 1];
            ans += p[cur_level - 1];
            continue;
        }

        // レベルcur_level - 1バーガーを全部食べることができない場合
        i_in_d = 0;
        cur_level -= 1;
    }
    println!("{}", ans);
}