import std.stdio, std.string, std.range, std.conv, std.array, std.algorithm, std.math, std.typecons, std.bigint, std.functional;

void main() {

    // A(n) = B A(n-1) P A(n-1) B

    // A(0) = P
    // A(1) = BPPPB
    // A(2) = BBPPPBPBPPPBB

    //レベル n のバーガーは何層か？
    // l(n) とすると、
    // l(n) = 1 + l(n-1) + 1 + l(n-1) + 1
    //      = 2 l(n-1) + 3
    // (l(n)+3) = 2 (l(n-1)+3)
    // m(n) = l(n)+3 とすると、
    // m(n) = 2 m(n-1)
    // m(0) = l(0) + 3 = 4 なので、
    // m(n) = 2^(n+2)
    // l(n) = 2^(n+2)-3 となる。

    const tmp = readln.split.to!(BigInt[]);
    const N = tmp[0], X = tmp[1];

    BigInt pow(BigInt a, BigInt b) {
        if (b == 0) return BigInt(1);
        if (b == 1) return a;
        auto t = memoize!pow(a, b / 2);
        return t * t * memoize!pow(a, b-b/2*2);
    }

    // level lのバーガーの層数
    BigInt _layer(BigInt l) {
        return pow(BigInt(2), (l+2))-3;
    }
    alias layer = memoize!_layer;

    // level lのバーガーをx層食べたときのパティの数
    BigInt func(BigInt l, BigInt x) {
        if (l == 0) return BigInt(1);
        if (x <= 1) return BigInt(0);
        if (x <= 1 + layer(l-1)) return memoize!func(l-1, x-1);
        if (x == 2 + layer(l-1)) return memoize!func(l-1, layer(l-1)) + 1;
        if (x <= 2 + layer(l-1) * 2) return memoize!func(l-1, layer(l-1)) + 1 + memoize!func(l-1, x-layer(l-1)-2);
        if (x == 3 + layer(l-1) * 2) return memoize!func(l-1, layer(l-1)) * 2 + 1;
        assert(false);
    }
    writeln(func(N,X));
}
