Amr bought a new video game "Guess Your Way Out!". The goal of the game is to find an exit from the maze that looks like a perfect binary tree of height h. The player is initially standing at the root of the tree and the exit from the tree is located at some leaf node. Let's index all the leaf nodes from the left to the right from 1 to 2h. The exit is located at some node n where 1 ≤ n ≤ 2h, the player doesn't know where the exit is so he has to guess his way out!Amr follows simple algorithm to choose the path. Let's consider infinite command string "LRLRLRLRL..." (consisting of alternating characters 'L' and 'R'). Amr sequentially executes the characters of the string using following rules:  Character 'L' means "go to the left child of the current node";  Character 'R' means "go to the right child of the current node";  If the destination node is already visited, Amr skips current command, otherwise he moves to the destination node;  If Amr skipped two consecutive commands, he goes back to the parent of the current node before executing next command;  If he reached a leaf node that is not the exit, he returns to the parent of the current node;  If he reaches an exit, the game is finished. Now Amr wonders, if he follows this algorithm, how many nodes he is going to visit before reaching the exit?

Input consists of two integers h, n (1 ≤ h ≤ 50, 1 ≤ n ≤ 2h).

Output a single integer representing the number of nodes (excluding the exit node) Amr is going to visit before reaching the exit by following this algorithm.

NoteA perfect binary tree of height h is a binary tree consisting of h + 1 levels. Level 0 consists of a single node called root, level h consists of 2h nodes called leaves. Each node that is not a leaf has exactly two children, left and right one. Following picture illustrates the sample test number 3. Nodes are labeled according to the order of visit.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;

public class C507 {

	public static long find(long h,long n,boolean flag){
		//System.out.println(h+" "+n);
		if(h == 1){
			if(n == 1){
				if(flag)
					return 1;
				return 2;
			}else{
				if(flag)
					return 2;
				return 1;
			}
		}
		long a = (long) Math.pow(2, h);
		if(n > a/2){
			if(flag)
				return a + find(h-1,n-a/2,flag);
			else return 1 + find(h-1,n-a/2,!flag);
		}
		else {
			if(flag)
				return  1+find(h-1,n,!flag);
			else return a + find(h-1,n,flag);
		}
	}
	public static void main(String[] args) throws NumberFormatException, IOException{
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] a = br.readLine().split(" ");
		long h = Long.parseLong(a[0]);
		long n = Long.parseLong(a[1]);
		System.out.println(find(h,n,true));
	}
}

import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskC solver = new TaskC();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskC {
    public void solve(int testNumber, InputReader in, PrintWriter out) {
        long h = in.nextInt();
        long n = in.nextLong();
        long max = (1L << (h));
        long ans = ways(1L, max, h, n, true);
        out.println(ans);
    }

    private long ways(long min, long max, long h, long n, boolean left) {
        if (min == max) {
            return 0L;
        }
        long mid = (min + max) / 2L;
        if (left) {
            if (n <= mid) {
                return 1L + ways(min, mid, h - 1, n, !left);
            } else {
                long rest = h > 0 ? ((1L << h) - 1L) : 0L;
                return 1L + rest + ways(1L + mid, max, h - 1, n, left);
            }
        } else {
            if (n<=mid){
                long rest = h > 0 ? ((1L << h) - 1L) : 0L;
                return 1L + rest + ways(min, mid, h - 1, n, left);
            } else {
                return 1L + ways(mid+1L, max, h-1, n, !left);
            }
        }

    }
}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }
}

import java.io.*;
import java.util.*;

public class c{
	private static long getans(int h, long n, boolean dir){ //dir is TRUE if LEFT
		System.err.printf("getans(%d, %d, ", h, n);
		System.err.print(dir);
		System.err.println(")");
		if (h == 0)
			return 0l;
		if (dir){
			if (n <= 1l << (h - 1))
				return 1l + getans(h - 1, n, !dir);
			else
				return (1l << h) + getans(h - 1, n - (1l << (h - 1)), dir);
		}
		else{
			if (n <= 1l << (h - 1))
				return (1l << h) + getans(h - 1, n, dir);
			else
				return 1l + getans(h - 1, n - (1l << (h - 1)), !dir);
		}
	}

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int h = in.nextInt();
		long n = in.nextLong();
		System.out.println(getans(h, n, true));
	}
}

import java.util.Scanner;

public class CMain {
    public void solve() {
        Parser parser = new Parser();
        int h = parser.nextInteger();
        long n = parser.nextLong() - 1;

        long currHalfChildren = 1l << (h-1);
        boolean currMoveToLeft = true;

        long count = 0;

        while(currHalfChildren > 1){
            if(currMoveToLeft){
                if(n < currHalfChildren){
                    ++count;
                    currMoveToLeft = false;
                } else {
                    count += currHalfChildren * 2;
                    n -= currHalfChildren;
                }
            } else {
                if(n < currHalfChildren){
                    count += currHalfChildren * 2;
                } else {
                    ++count;
                    n -= currHalfChildren;
                    currMoveToLeft = true;
                }
            }
            currHalfChildren >>= 1;
        }

        ++count;

        if(currMoveToLeft && n == 1 || !currMoveToLeft && n ==0){
            ++count;
        }

        System.out.print(count);

    }

    public static void main(String[] args) {
        new CMain().solve();
    }

    static public class Parser{
        Scanner scanner;

        public Parser() {
            scanner = new Scanner(System.in);
        }

        public Parser(String str) {
            scanner = new Scanner(str);
        }

        long nextLong(){
            return scanner.nextLong();
        }

        int nextInteger(){
            return scanner.nextInt();
        }

        double nextDouble(){
            return scanner.nextDouble();
        }

        String nextLine(){
            return scanner.nextLine();
        }

        int[] nextIntegers(int count){
            int[] result = new int[count];
            for(int i = 0; i < count; ++i){
                result[i] = nextInteger();
            }
            return result;
        }

        long[] nextLongs(int count){
            long[] result = new long[count];
            for(int i = 0; i < count; ++i){
                result[i] = nextLong();
            }
            return result;
        }

        int[][] nextIntegers(int fields, int count){
            int[][] result = new int[fields][];
            for(int i = 0; i < fields; ++i){
                result[i] = new int[count];
            }
            for(int c = 0; c < count; ++c){
                for(int i = 0; i < fields; ++i){
                    result[i][c] = nextInteger();
                }
            }
            return result;
        }
    }

    static public class Matrix{
        static public final int size = 101;
        static public final long base = 1000000007;

        static public class Vector{
            long[] data = new long[size];
        }
        private long[] data;

        public Matrix() {
            data = new long[size * size];
        }

        long get(int row, int column){
            return data[row * size + column];
        }

        long set(int row, int column, long value){
            int index = row * size + column;
            long result = data[index];
            data[index] = value;
            return result;
        }

        public Matrix mul(Matrix other){
            Matrix result = new Matrix();
            for(int r = 0; r < size; ++r){
                for(int c = 0; c < size; ++c){
                    long value = 0;
                    for(int i = 0; i < size; ++i){
                        value += get(r, i) * other.get(i, c);
                        value %= base;
                    }
                    result.set(r, c, value);
                }
            }
            return result;
        }

    }
}

import java.util.*;
import java.io.*;
import java.math.*;
@SuppressWarnings("unchecked")
public class Main {
    InputReader ir = new InputReader(System.in);
    PrintWriter out = new PrintWriter(System.out);
    final long mod = 993960000099397l;

    void solve() {

        int h = ir.readInt();
        long n = (long)Math.pow(2, h) + ir.readLong() - 1;
        long temp = n;
        String path = "";
        while(temp != 1) {
            long prev = temp;
            temp /= 2;
            if(temp*2 + 1 == prev) {
                path = "1"+path;
            } else {
                path = "0"+path;
            }
        }

        char cur = '0';
        long ans = 0;
        int i = 0;
        int j = 0;
        while(true) {
            if(path.charAt(j) != cur) {
                int l = h - i;
                ans += ((1l << l) - 1);
            } else {
                ans += 1;
                j++;
                i++;
            }
            if(j == path.length()) {
                break;
            }
            cur = (cur == '0' ? '1' : '0');
        }
        out.println(ans);
    }
    void run() {
        solve();
        out.close();
    }

    public static void main(String args[]){
        new Main().run();
    }
}

class InputReader {

    private InputStream stream;
    private byte[] buf = new byte[1024];
    private int curChar;
    private int numChars;
    private SpaceCharFilter filter;

    public InputReader(InputStream stream) {
        this.stream = stream;
    }

    public int read() {
        if (numChars == -1)
            throw new InputMismatchException();
        if (curChar >= numChars) {
            curChar = 0;
            try {
                numChars = stream.read(buf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (numChars <= 0)
                return -1;
        }
        return buf[curChar++];
    }
    public final int readInt() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
    }
    public long readLong() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        long res = 0;
        do {
            if (c < '0' || c > '9')
                throw new InputMismatchException();
            res *= 10;
            res += c - '0';
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }

    public String readString() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        StringBuilder res = new StringBuilder();
        do {
            res.appendCodePoint(c);
            c = read();
        } while (!isSpaceChar(c));
        return res.toString();
    }

    public boolean isSpaceChar(int c) {
        if (filter != null)
            return filter.isSpaceChar(c);
        return isWhitespace(c);
    }
        public double readDouble() {
        return Double.parseDouble(readString());
    }

    public static boolean isWhitespace(int c) {
        return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
    }

    public String next() {
        return readString();
    }

    public interface SpaceCharFilter {
        public boolean isSpaceChar(int ch);
    }
}

import java.util.Scanner;
public class Main {
	static long pow(long a, long n)
	{
		if(n==1)
			return a;
		if(n==0)
			return 1;
		if(n%2==0)
		{
			long p=pow(a, n/2);
			return p*p;
		}
		else
		{
			long p=pow(a, n/2);
			return a*p*p;
		}
	}
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		long h=sc.nextLong();
		long n=sc.nextLong();
		n=n+pow(2,h)-1;
		String path="";
		while(n>1)
		{
			if(n%2==1)
				path="R"+path;
			else
				path="L"+path;
			n=n/2;
		}
		long ans=0;
		int indd=0;
		for(int i = 0; i<path.length(); i++)
		{
			if(indd%2==0 && path.charAt(i)=='R')
			{
				ans=ans+pow(2,h-i)-1;
				indd=(indd+1)%2;
			}
			else
				if(indd%2==1 && path.charAt(i)=='L')
				{
					ans=ans+pow(2,h-i)-1;
					indd=(indd+1)%2;
				}
			indd=(indd+1)%2;
		}
		System.out.println(ans+path.length());
	}
}

//package Round287_Div2;

import java.util.Scanner;
//import java.util.Stack;

public class Solution3 {
  /*
  public static void main(String[] args) {
    Scanner scan = new Scanner(System.in);
    int h = scan.nextInt();
    int n = scan.nextInt();
    boolean[] visited = new boolean[(1 << (h + 1)) - 1];
    n = (1 << h) + n - 2;
    boolean isLeft = true;
    int curr = 0, next = 0;
    Stack<Integer> stack = new Stack<>();
    int step = 0;
    boolean firstSkip = false;
    while (curr != n) {
      next = isLeft ? curr*2 + 1 : curr*2 + 2;
      if (next < visited.length) {
          if (!visited[next]) {
            visited[next] = true;
            stack.push(curr);
            step++;
            curr = next;
            isLeft = !isLeft;
          } else {
            isLeft = !isLeft;
            if (!firstSkip) {
              firstSkip = true;
            } else {
              firstSkip = false;
              curr = stack.pop();
            }
          }
        } else { // null children
          curr = stack.pop();
        }
    }
    System.out.println(step);
    scan.close();
  }*/
  public static void main(String[] args) {
    Scanner scan = new Scanner(System.in);
    long h = scan.nextLong();
    long n = scan.nextLong();
    long start = 1, end = 1L << h, mid = 0, step = 0;
    boolean isLeft = true;
    while (start <= end) {
      if (start == end) break;
      mid = start + ((end -start) >> 1);
      if (isLeft) {
        if (n > mid) {
          step += 1L << h;
          start = mid + 1;
        } else {
          step++;
          isLeft = false;
          end = mid;
        }
      } else {
        if (n <= mid) {
          step += 1L << h;
          end = mid;
        } else {
          step++;
          isLeft = true;
          start = mid + 1;
        }
      }
      h--;
    }
    scan.close();
    System.out.println(step);
  }
}

import java.util.*;
public class KnightTemplar {
public static void main(String [] args){
	Scanner in=new Scanner(System.in);
	int h=in.nextInt();
	long n=in.nextLong()+(long)Math.pow(2,h)-1;
	Stack<Long>st=new Stack<Long>();
	long temp=n;
	while(temp>1){
	st.push(temp);
	temp/=2;
	}
	long ans=1;
	long cnt=0;
	boolean flag=true;
	long prev=2;
	int level=0;
	//System.out.print(st);
	while(!st.isEmpty()){
	long node=st.pop();
	cnt++;level++;
	if(node==prev){
		ans+=1;
		if(cnt%2==0)prev=2*node;
		else prev=2*node+1;
	}
		else {
		ans+=(long)Math.pow(2,h-level +1)-1;
		st.push(node);level--;
		prev=node;
	}
	//System.out.println(prev + " "+node+" "+ans+" "+cnt+ " "+level);
}
System.out.print(ans-1);
}
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class GuessYourWayOut {

	static long solve(int h, long n, int c) { // 1 right, 0 left
		if (h == 0)
			return 0;
		long node = (1L << h) / 2;
		long sum = ((1L << (h + 1)) - 1) / 2;
		if (c == 1) { // right
			if (n <= node) { // in left
				return 1 + sum + solve(h - 1, n, c);
			}
			return 1 + solve(h - 1, n - node, c ^ 1);
		}
		if (c == 0) { // left
			if (n <= node) { // in left
				return 1 + solve(h - 1, n, c ^ 1);
			}
			return 1 + sum + solve(h - 1, n - node, c);
		}
		return 0;
	}

	public static void main(String[] args) throws IOException {
		MyScanner sc = new MyScanner(System.in);
		PrintWriter pw = new PrintWriter(System.out);
		int h = sc.nextInt();
		long n = sc.nextLong();
		pw.println(solve(h, n, 0));
		pw.close();
	}

	static class MyScanner {
		StringTokenizer st;
		BufferedReader br;

		public MyScanner(InputStream s) {
			br = new BufferedReader(new InputStreamReader(s));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public String nextLine() throws IOException {
			return br.readLine();
		}

		public boolean ready() throws IOException {
			return br.ready();
		}

	}
}

import java.io.PrintWriter;
import java.util.Scanner;
import java.util.Stack;

public class Solution {
    public static void main(String[] args) throws Exception{
        Scanner sc = new Scanner(System.in);
        PrintWriter pw = new PrintWriter(System.out);
        long h = sc.nextLong(), n = sc.nextLong();
        Stack<Long> st = new Stack();
        st.push((long) -1);
        long k = (long) (n+Math.pow(2, h)-1);
        while (k != 1) {
            st.push(k);
            k/=2;
        }
        long tek = 1, flag = 0, yr = 0;
        long sum = 0;
        long next = st.pop();
        while (next != -1) {
            if (flag == 0) {
                if (next == tek*2) {
                    sum++;
                    flag = 1;
                } else {
                    sum += Math.pow(2, h-yr);
                }
            } else {
                if (next == tek*2+1) {
                    sum++;
                    flag = 0;
                } else {
                    sum += Math.pow(2, h-yr);
                }
            }
            yr++;
            tek = next;
            next = st.pop();
        }
        pw.println(sum);
        pw.close();
    }
}

import java.util.*;
public class GuessYourWayOut {
public static Scanner scn = new Scanner (System.in);
	public static void main(String[] args) {
		int h = scn.nextInt();
		long n = scn.nextLong();
		solver(h,n);
	}
	private static void solver(int h, long n) {
		long limit = (long)Math.pow(2, h);
		String ans = PathFinder(h,n,1,limit);
	//	System.out.println(ans);
		String algo = "";
		for(int i = 0;i<2*ans.length();i++){
			if(i%2==0){
				algo+="L";
			}else{
				algo+="R";
			}
		}
		long nc =0;
		int ansi = 0;
		int algoi = 0;
		int curr_h = h;
		while(ansi<ans.length()){
			if(ans.charAt(ansi)==algo.charAt(algoi)){
				ansi++;
				algoi++;
				nc++;
				curr_h--;
			}else{
				algoi++;
				long inc = (long)Math.pow(2, curr_h)-1;
				nc +=inc;
			}
		}
		System.out.println(nc);
	}
	private static String PathFinder(int h, long key,long rs, long re) {
		if(rs>re){
			return "";
		}
		if(rs==re && re==key){
			return "";
		}
		long mid = (rs+re)/2;
		String res = "";
		if(key>mid){
			res = "R"+PathFinder(h, key, mid+1, re);
		}else{
			res = "L"+PathFinder(h, key, rs, mid);
		}
		return res;
	}

}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class round_507_C {

	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		int h = sc.nextInt();
		long n = sc.nextLong() + (1L << h) - 1;
		long [] nodes = new long[h + 1];
		long curr = n;
		for (int i = h; i >= 0; i--) {
			nodes[i] = curr;
			curr >>= 1;
		}
		long answer = 0;
		long direction = 0;   // 0 for left , 1 for right
		for (int i = 0; i < nodes.length - 1; i++) {
			long nextNode = (nodes[i] << 1) + direction;
			if(nextNode != nodes[i + 1])
				answer += (1L << (h - i)) - 1;
			else
				direction ^=1;
		}
		System.out.println(answer + h);
	}

	static class Scanner {
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s) {
			br = new BufferedReader(new InputStreamReader(s));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public double nextDouble() throws IOException {
			return Double.parseDouble(next());
		}

		public long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public String nextLine() throws IOException {
			return br.readLine();
		}

		public boolean ready() throws IOException {
			return br.ready();
		}
	}
}

import java.io.*;
import java.util.*;
import java.util.Map.Entry;

public class Main {
	static long solve(long l,long r,long e,int dir) {//dir=0 ->left
		if(l==r) {
			return 0l;
		}
		long mid=(l+r)>>1;
		if(e<=mid) {
			if(dir==0) {
				return 1l+solve(l,mid,e,1);
			}
			else {
				long nodes=((r-l+1)*2-1)/2;
				return nodes+1l+solve(l,mid,e,1);
			}
		}
		else {
			if(dir==0) {
				long nodes=((r-l+1)*2-1)/2;
				return nodes+1l+solve(mid+1,r,e,0);
			}
			else {
				return 1l+solve(mid+1,r,e,0);
			}
		}
	}
	public static void main(String[] args) throws IOException {
		MScanner sc=new MScanner(System.in);
		PrintWriter pw=new PrintWriter(System.out);
		int n=sc.nextInt();long e=sc.nextLong();
		pw.println(solve(1,1l<<n,e,0));
		pw.flush();
	}
    static class MScanner {
		StringTokenizer st;
		BufferedReader br;

		public MScanner(InputStream system) {
			br = new BufferedReader(new InputStreamReader(system));
		}

		public MScanner(String file) throws Exception {
			br = new BufferedReader(new FileReader(file));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public String nextLine() throws IOException {
			return br.readLine();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public double nextDouble() throws IOException {
			return Double.parseDouble(next());
		}

		public char nextChar() throws IOException {
			return next().charAt(0);
		}

		public Long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public boolean ready() throws IOException {
			return br.ready();
		}

		public void waitForInput() throws InterruptedException {
			Thread.sleep(3000);
		}
	}
}

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class GuessYouWayOut {

	public static void main(String args[] ) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	    PrintWriter w = new PrintWriter(System.out);

	    StringTokenizer st1 = new StringTokenizer(br.readLine());
	    long h = Long.parseLong(st1.nextToken());
	    long n = Long.parseLong(st1.nextToken());

	    long ans = solve(h,n,true);
	    w.println(ans-1);
	    w.close();
	}

	public static long solve(long h,long n,boolean direction){
		//System.out.println(h + " " + n);

		if(h==0)
			return 1;

		long total = (long)Math.pow(2,h+1) - 1;
		long lastlevel = (long)Math.pow(2, h);

		if(direction){
			if(n<=lastlevel/2)
				return 1 + solve(h-1,n,!direction);
			else
				return 1 + total/2 + solve(h-1,n - (long)Math.pow(2,h-1),direction);
		}
		else{
			if(n<=lastlevel/2)
				return 1 + total/2 + solve(h-1,n,direction);
			else
				return 1 + solve(h-1,n - (long)Math.pow(2,h-1),!direction);
		}
	}
	public static int ip(String s){
		return Integer.parseInt(s);
	}
}

import java.io.IOException;
import java.lang.Math;

public class GuessYourWayOut507C {

    private static long nodeVisitCount = 0;
    private static char nextNode = 'L';
    private static long exitNodeIndex = -1;
    private static long maxIndex = -1;

    public static void main(String[] args) {

        java.io.BufferedReader r = new java.io.BufferedReader (new java.io.InputStreamReader (System.in));

        String s = null;

        try {
            s=r.readLine();

        } catch (IOException e) {
            e.printStackTrace();
        }
        String str[] = s.split(" ");

        /*long startTime = System.currentTimeMillis();*/

        long h,n;

        h = Long.parseLong(str[0]);
        n = Long.parseLong(str[1]);

        exitNodeIndex = calculateExitNodeIndex(h, n);
        maxIndex = calculateMaxIndex(h);

        findExit(0);

        System.out.println(nodeVisitCount);

        /*
        long stopTime = System.currentTimeMillis();
          long elapsedTime = stopTime - startTime;
          System.out.println(elapsedTime +"ms");
        */
    }

    public static long leftMostChildIndex(long currentIndex){
        long leftChildIndex = LChild(currentIndex);
        if(leftChildIndex <= maxIndex){
            return leftMostChildIndex(leftChildIndex);
        }
        return currentIndex;
    }

    public static long rightMostChildIndex(long currentIndex){
        long rightChildIndex = RChild(currentIndex);
        if(rightChildIndex <= maxIndex){
            return rightMostChildIndex(rightChildIndex);
        }
        return currentIndex;
    }

    static long parent(long index){
        if(index == 0){
            return -1;
        }
        return (index-1)/2;
    }

    static long LChild(long index){
        return (index*2+1);
    }

    static long RChild(long index){
        return (index*2 + 2);
    }

    static long calculateMaxIndex(long height){
        return (long)(Math.pow(2,height+1)-2);
    }

    public static long calculateExitNodeIndex(long h, long n){
        return (long)(Math.pow(2,h) - 2 + n);
    }

    public static boolean findExit(long currentIndex){
        if(currentIndex == exitNodeIndex){
            return true;
        }

        long LChildIndex = LChild(currentIndex);
        long RChildIndex = RChild(currentIndex);
        nodeVisitCount++;

        boolean exitNodeFoundFlag = false;

        if(nextNode == 'L'){
            nextNode = 'R';

            if(LChildIndex <= maxIndex){
                long leftChildLeftMostIndex = leftMostChildIndex(LChildIndex);
                long leftChildRightMostIndex = rightMostChildIndex(LChildIndex);
                if(leftChildLeftMostIndex <= exitNodeIndex && exitNodeIndex <= leftChildRightMostIndex){
                    exitNodeFoundFlag = findExit(LChildIndex);
                }else{
                    nextNode = 'L';
                    nodeVisitCount += 2*(leftChildRightMostIndex - leftChildLeftMostIndex) + 1;
                }

                if(exitNodeFoundFlag == false){
                    long rightChildLeftMostIndex = leftMostChildIndex(RChildIndex);
                    long rightChildRightMostIndex = rightMostChildIndex(RChildIndex);
                    if(rightChildLeftMostIndex <= exitNodeIndex && exitNodeIndex <= rightChildRightMostIndex){
                        exitNodeFoundFlag = findExit(RChildIndex);
                    }
                    else{
                        nextNode = 'R';
                        nodeVisitCount += 2*(rightChildRightMostIndex - rightChildLeftMostIndex) + 1;
                    }
                }
            }
        }
        else{
            nextNode = 'L';
            if(RChildIndex <= maxIndex){
                long rightChildLeftMostIndex = leftMostChildIndex(RChildIndex);
                long rightChildRightMostIndex = rightMostChildIndex(RChildIndex);
                if(rightChildLeftMostIndex <= exitNodeIndex && exitNodeIndex <= rightChildRightMostIndex){
                    exitNodeFoundFlag = findExit(RChildIndex);
                }
                else{
                    nextNode = 'R';
                    nodeVisitCount += 2*(rightChildRightMostIndex - rightChildLeftMostIndex) + 1;
                }

                if(exitNodeFoundFlag == false){
                    long leftChildLeftMostIndex = leftMostChildIndex(LChildIndex);
                    long leftChildRightMostIndex = rightMostChildIndex(LChildIndex);
                    if(leftChildLeftMostIndex <= exitNodeIndex && exitNodeIndex <= leftChildRightMostIndex){
                        exitNodeFoundFlag = findExit(LChildIndex);
                    }else{
                        nextNode = 'L';
                        nodeVisitCount += 2*(leftChildRightMostIndex - leftChildLeftMostIndex) + 1;
                    }
                }
            }
        }

        return exitNodeFoundFlag;
    }

}

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

import java.util.Scanner;

/**
 *
 * @author fz
 */
public class CF_287C {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        long h = sc.nextLong();
        long k = sc.nextLong();
        System.out.println(recur(h, k, true));

    }
    public static long recur(long h, long k, boolean left) {
        if(h == 1) {
            if(k == 1 && left)
                return 1L;
            else if(k == 2 && !left)
                return 1L;
            else
                return 2L;
        }
        long val = pow2(h - 1);
        if(k > val) {
            if(left)
                return 2 * val + recur(h - 1, k - val, left);
            else
                return 1 + recur(h - 1, k - val, !left);
        }
        else {
            if(left)
                return 1 + recur(h - 1, k, !left);
            else
                return 2 * val + recur(h - 1, k, left);

        }

    }
    public static long pow2(long h) {
        long res = 1;
        for(long i = 0; i < h; i++)
            res = res * 2;
        return res;
    }
}

//package round287;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class C {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int h = ni();
		long n = nl()-1;
		long lr = 0;
		long ved = 0;
		for(int i = h-1;i >= 0;i--){
			ved++;
			long b = n>>>i&1;
			if(lr == b){
			}else{
				ved += (1L<<i+1)-1;
			}
			lr = b^1;
		}
		out.println(ved);
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new C().run(); }

	private byte[] inbuf = new byte[1024];
	private int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class Main {

    public void solve(){

        int h = in.nextInt();
        long n = in.nextLong();

        int go = 0; // right = 1, left = 0;
        Long n1 = (long)n-1;
        long total = 0;
        long d = (1L << h-1);

        while(h > 0){
            if((n1 & d) == d ){
                if(go == 1){
                    total +=1;
                    go = 0;
                }
                else{
                    total += Math.pow(2, h) ;
                    go = 0;
                }

            }
            else{
                if(go == 0){
                    total += 1;
                    go =1;
                }
                else{
                    total += Math.pow(2, h) ;
                    go = 1;
                }
            }

            h--;
            d = d >> 1;
        }
        out.println(total);

    }

    public static void main(String[] args){
        Main m = new Main();
        m.solve();
        m.out.flush();
        m.out.close();
    }

    InputStream inputStream;
    OutputStream outputStream;
    InputReader in;
    PrintWriter out;

    public Main(){
        inputStream = System.in;
        outputStream = System.out;
        in = new InputReader(inputStream);
        out = new PrintWriter(outputStream);
    }

}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        return tokenizer.nextToken();
    }
    public String nextLine(){
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        String s = "";
        while(tokenizer.hasMoreTokens()){
            s += tokenizer.nextToken();
            if(tokenizer.hasMoreTokens()){
                s+=" ";
            }
        }

        return s;

    }

    public int nextInt() {
        return Integer.parseInt(next());
    }
    public double nextDouble(){
        return Double.parseDouble(next());
    }

    public long nextLong(){
        return Long.parseLong(next());
    }

    public float nextFloat(){
        return Float.parseFloat(next());
    }

}

import java.io.*;
import java.util.*;
import java.math.*;

public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		OutputWriter out = new OutputWriter(outputStream);
		Task solver = new Task();
		solver.solve(1, in, out);
		out.close();
	}
}

class Task {

	public void solve(int testNumber, InputReader in, OutputWriter out) {
		int h=in.readInt(), x=0;
		long n=in.readLong(), ret=0;
		for (; h>0; h--) {
			ret++;
//			out.printLine(h, x, n);
			if ((n>1L<<(h-1) && x==0) || (x==1 && n<=1L<<(h-1))) {
				ret+=(1L<<h)-1;
			}else x=1-x;
			n=(n-1)%(1L<<(h-1))+1;
//			out.printLine(ret);
		}
		out.printLine(ret);
	}
}

class InputReader {
	private boolean finished = false;

	private InputStream stream;
	private byte[] buf = new byte[1024];
	private int curChar;
	private int numChars;
	private SpaceCharFilter filter;

	public InputReader(InputStream stream) {
		this.stream = stream;
	}

	public int read() {
		if (numChars == -1)
			throw new InputMismatchException();
		if (curChar >= numChars) {
			curChar = 0;
			try {
				numChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (numChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}

	public int peek() {
		if (numChars == -1)
			return -1;
		if (curChar >= numChars) {
			curChar = 0;
			try {
				numChars = stream.read(buf);
			} catch (IOException e) {
				return -1;
			}
			if (numChars <= 0)
				return -1;
		}
		return buf[curChar];
	}

	public int readInt() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public long readLong() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		long res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public String readString() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		StringBuilder res = new StringBuilder();
		do {
			if (Character.isValidCodePoint(c))
				res.appendCodePoint(c);
			c = read();
		} while (!isSpaceChar(c));
		return res.toString();
	}

	public boolean isSpaceChar(int c) {
		if (filter != null)
			return filter.isSpaceChar(c);
		return isWhitespace(c);
	}

	public static boolean isWhitespace(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}

	private String readLine0() {
		StringBuilder buf = new StringBuilder();
		int c = read();
		while (c != '\n' && c != -1) {
			if (c != '\r')
				buf.appendCodePoint(c);
			c = read();
		}
		return buf.toString();
	}

	public String readLine() {
		String s = readLine0();
		while (s.trim().length() == 0)
			s = readLine0();
		return s;
	}

	public String readLine(boolean ignoreEmptyLines) {
		if (ignoreEmptyLines)
			return readLine();
		else
			return readLine0();
	}

	public BigInteger readBigInteger() {
		try {
			return new BigInteger(readString());
		} catch (NumberFormatException e) {
			throw new InputMismatchException();
		}
	}

	public char readCharacter() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		return (char) c;
	}

	public double readDouble() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		double res = 0;
		while (!isSpaceChar(c) && c != '.') {
			if (c == 'e' || c == 'E')
				return res * Math.pow(10, readInt());
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		}
		if (c == '.') {
			c = read();
			double m = 1;
			while (!isSpaceChar(c)) {
				if (c == 'e' || c == 'E')
					return res * Math.pow(10, readInt());
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				m /= 10;
				res += (c - '0') * m;
				c = read();
			}
		}
		return res * sgn;
	}

	public boolean isExhausted() {
		int value;
		while (isSpaceChar(value = peek()) && value != -1)
			read();
		return value == -1;
	}

	public String next() {
		return readString();
	}

	public SpaceCharFilter getFilter() {
		return filter;
	}

	public void setFilter(SpaceCharFilter filter) {
		this.filter = filter;
	}

	public interface SpaceCharFilter {
		public boolean isSpaceChar(int ch);
	}
}

class OutputWriter {
	private final PrintWriter writer;

	public OutputWriter(OutputStream outputStream) {
		writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
				outputStream)));
	}

	public OutputWriter(Writer writer) {
		this.writer = new PrintWriter(writer);
	}

	public void print(char[] array) {
		writer.print(array);
	}

	public void print(Object... objects) {
		for (int i = 0; i < objects.length; i++) {
			if (i != 0)
				writer.print(' ');
			writer.print(objects[i]);
		}
	}

	public void print(int[] array) {
		for (int i = 0; i < array.length; i++) {
			if (i != 0)
				writer.print(' ');
			writer.print(array[i]);
		}
	}

	public void print(long[] array) {
		for (int i = 0; i < array.length; i++) {
			if (i != 0)
				writer.print(' ');
			writer.print(array[i]);
		}
	}

	public void printLine(int[] array) {
		print(array);
		writer.println();
	}

	public void printLine(long[] array) {
		print(array);
		writer.println();
	}

	public void printLine() {
		writer.println();
	}

	public void printLine(Object... objects) {
		print(objects);
		writer.println();
	}

	public void print(char i) {
		writer.print(i);
	}

	public void printLine(char i) {
		writer.println(i);
	}

	public void printLine(char[] array) {
		writer.println(array);
	}

	public void printFormat(String format, Object... objects) {
		writer.printf(format, objects);
	}

	public void close() {
		writer.close();
	}

	public void flush() {
		writer.flush();
	}

	public void print(long i) {
		writer.print(i);
	}

	public void printLine(long i) {
		writer.println(i);
	}

	public void print(int i) {
		writer.print(i);
	}

	public void printLine(int i) {
		writer.println(i);
	}
}

class IOUtils {

	public static int[] readIntArray(InputReader in, int size) {
		int[] array = new int[size];
		for (int i = 0; i < size; i++)
			array[i] = in.readInt();
		return array;
	}

	public static long[] readLongArray(InputReader in, int size) {
		long[] array = new long[size];
		for (int i = 0; i < size; i++)
			array[i] = in.readLong();
		return array;
	}

	public static double[] readDoubleArray(InputReader in, int size) {
		double[] array = new double[size];
		for (int i = 0; i < size; i++)
			array[i] = in.readDouble();
		return array;
	}

	public static String[] readStringArray(InputReader in, int size) {
		String[] array = new String[size];
		for (int i = 0; i < size; i++)
			array[i] = in.readString();
		return array;
	}

	public static char[] readCharArray(InputReader in, int size) {
		char[] array = new char[size];
		for (int i = 0; i < size; i++)
			array[i] = in.readCharacter();
		return array;
	}

	public static void readIntArrays(InputReader in, int[]... arrays) {
		for (int i = 0; i < arrays[0].length; i++) {
			for (int j = 0; j < arrays.length; j++)
				arrays[j][i] = in.readInt();
		}
	}

	public static void readLongArrays(InputReader in, long[]... arrays) {
		for (int i = 0; i < arrays[0].length; i++) {
			for (int j = 0; j < arrays.length; j++)
				arrays[j][i] = in.readLong();
		}
	}

	public static void readDoubleArrays(InputReader in, double[]... arrays) {
		for (int i = 0; i < arrays[0].length; i++) {
			for (int j = 0; j < arrays.length; j++)
				arrays[j][i] = in.readDouble();
		}
	}

	public static char[][] readTable(InputReader in, int rowCount,
			int columnCount) {
		char[][] table = new char[rowCount][];
		for (int i = 0; i < rowCount; i++)
			table[i] = readCharArray(in, columnCount);
		return table;
	}

	public static int[][] readIntTable(InputReader in, int rowCount,
			int columnCount) {
		int[][] table = new int[rowCount][];
		for (int i = 0; i < rowCount; i++)
			table[i] = readIntArray(in, columnCount);
		return table;
	}

	public static double[][] readDoubleTable(InputReader in, int rowCount,
			int columnCount) {
		double[][] table = new double[rowCount][];
		for (int i = 0; i < rowCount; i++)
			table[i] = readDoubleArray(in, columnCount);
		return table;
	}

	public static long[][] readLongTable(InputReader in, int rowCount,
			int columnCount) {
		long[][] table = new long[rowCount][];
		for (int i = 0; i < rowCount; i++)
			table[i] = readLongArray(in, columnCount);
		return table;
	}

	public static String[][] readStringTable(InputReader in, int rowCount,
			int columnCount) {
		String[][] table = new String[rowCount][];
		for (int i = 0; i < rowCount; i++)
			table[i] = readStringArray(in, columnCount);
		return table;
	}

	public static String readText(InputReader in) {
		StringBuilder result = new StringBuilder();
		while (true) {
			int character = in.read();
			if (character == '\r')
				continue;
			if (character == -1)
				break;
			result.append((char) character);
		}
		return result.toString();
	}

	public static void readStringArrays(InputReader in, String[]... arrays) {
		for (int i = 0; i < arrays[0].length; i++) {
			for (int j = 0; j < arrays.length; j++)
				arrays[j][i] = in.readString();
		}
	}

	public static void printTable(OutputWriter out, char[][] table) {
		for (char[] row : table)
			out.printLine(new String(row));
	}
}

class SumIntervalTree extends LongIntervalTree {
	public SumIntervalTree(int size) {
		super(size);
	}

	@Override
	protected long joinValue(long left, long right) {
		return left + right;
	}

	@Override
	protected long joinDelta(long was, long delta) {
		return was + delta;
	}

	@Override
	protected long accumulate(long value, long delta, int length) {
		return value + delta * length;
	}

	@Override
	protected long neutralValue() {
		return 0;
	}

	@Override
	protected long neutralDelta() {
		return 0;
	}
}

abstract class IntervalTree {
	protected int size;

	protected IntervalTree(int size) {
		this(size, true);
	}

	public IntervalTree(int size, boolean shouldInit) {
		this.size = size;
		int nodeCount = Math.max(1, Integer.highestOneBit(size) << 2);
		initData(size, nodeCount);
		if (shouldInit)
			init();
	}

	protected abstract void initData(int size, int nodeCount);

	protected abstract void initAfter(int root, int left, int right, int middle);

	protected abstract void initBefore(int root, int left, int right, int middle);

	protected abstract void initLeaf(int root, int index);

	protected abstract void updatePostProcess(int root, int left, int right,
			int from, int to, long delta, int middle);

	protected abstract void updatePreProcess(int root, int left, int right,
			int from, int to, long delta, int middle);

	protected abstract void updateFull(int root, int left, int right, int from,
			int to, long delta);

	protected abstract long queryPostProcess(int root, int left, int right,
			int from, int to, int middle, long leftResult, long rightResult);

	protected abstract void queryPreProcess(int root, int left, int right,
			int from, int to, int middle);

	protected abstract long queryFull(int root, int left, int right, int from,
			int to);

	protected abstract long emptySegmentResult();

	public void init() {
		if (size == 0)
			return;
		init(0, 0, size - 1);
	}

	private void init(int root, int left, int right) {
		if (left == right) {
			initLeaf(root, left);
		} else {
			int middle = (left + right) >> 1;
			initBefore(root, left, right, middle);
			init(2 * root + 1, left, middle);
			init(2 * root + 2, middle + 1, right);
			initAfter(root, left, right, middle);
		}
	}

	public void update(int from, int to, long delta) {
		update(0, 0, size - 1, from, to, delta);
	}

	protected void update(int root, int left, int right, int from, int to,
			long delta) {
		if (left > to || right < from)
			return;
		if (left >= from && right <= to) {
			updateFull(root, left, right, from, to, delta);
			return;
		}
		int middle = (left + right) >> 1;
		updatePreProcess(root, left, right, from, to, delta, middle);
		update(2 * root + 1, left, middle, from, to, delta);
		update(2 * root + 2, middle + 1, right, from, to, delta);
		updatePostProcess(root, left, right, from, to, delta, middle);
	}

	public long query(int from, int to) {
		return query(0, 0, size - 1, from, to);
	}

	protected long query(int root, int left, int right, int from, int to) {
		if (left > to || right < from)
			return emptySegmentResult();
		if (left >= from && right <= to)
			return queryFull(root, left, right, from, to);
		int middle = (left + right) >> 1;
		queryPreProcess(root, left, right, from, to, middle);
		long leftResult = query(2 * root + 1, left, middle, from, to);
		long rightResult = query(2 * root + 2, middle + 1, right, from, to);
		return queryPostProcess(root, left, right, from, to, middle,
				leftResult, rightResult);
	}
}

class TreapSet<K> implements NavigableSet<K> {
	protected static final Random rnd = new Random(239);

	protected final Node nullNode;
	protected final Comparator<? super K> comparator;
	protected Node root;
	private final K from;
	private final K to;
	private final boolean fromInclusive;
	private final boolean toInclusive;

	public TreapSet() {
		this((Comparator<? super K>) null);
	}

	public TreapSet(Comparator<? super K> comparator) {
		this(null, null, false, false, comparator, null, null);
	}

	public TreapSet(Iterable<? extends K> collection) {
		this(collection, null);
	}

	public TreapSet(Iterable<? extends K> collection,
			Comparator<? super K> comparator) {
		this(comparator);
		addAll(collection);
	}

	protected TreapSet(K from, K to, boolean fromInclusive,
			boolean toInclusive, Comparator<? super K> comparator, Node root,
			Node nullNode) {
		this.comparator = comparator;
		this.from = from;
		this.to = to;
		this.fromInclusive = fromInclusive;
		this.toInclusive = toInclusive;
		if (nullNode == null)
			nullNode = new NullNode();
		if (root == null)
			root = nullNode;
		this.root = root;
		this.nullNode = nullNode;
	}

	public boolean addAll(Iterable<? extends K> collection) {
		boolean result = false;
		for (K element : collection)
			result |= add(element);
		return result;
	}

	public K lower(K k) {
		Node target = root.lower(k);
		if (target == nullNode)
			return null;
		if (belongs(target.key))
			return target.key;
		return null;
	}

	private boolean belongs(K key) {
		int valueFrom = compare(from, key);
		int valueTo = compare(key, to);
		return (valueFrom < 0 || valueFrom == 0 && fromInclusive)
				&& (valueTo < 0 || valueTo == 0 && toInclusive);
	}

	public K floor(K k) {
		Node target = root.floor(k);
		if (target == nullNode)
			return null;
		if (belongs(target.key))
			return target.key;
		return null;
	}

	public K ceiling(K k) {
		Node target = root.ceil(k);
		if (target == nullNode)
			return null;
		if (belongs(target.key))
			return target.key;
		return null;
	}

	public K higher(K k) {
		Node target = root.higher(k);
		if (target == nullNode)
			return null;
		if (belongs(target.key))
			return target.key;
		return null;
	}

	public K pollFirst() {
		K first = first();
		if (first == null)
			throw new NoSuchElementException();
		root.erase(first);
		return first;
	}

	public K pollLast() {
		K last = last();
		if (last == null)
			throw new NoSuchElementException();
		root.erase(last);
		return last;
	}

	public int size() {
		if (from == null && to == null)
			return root.size;
		if (from == null) {
			Node to = toInclusive ? root.floor(this.to) : root.lower(this.to);
			if (to == nullNode)
				return 0;
			return root.indexOf(to) + 1;
		}
		if (to == null) {
			Node from = fromInclusive ? root.ceil(this.from) : root
					.higher(this.from);
			if (from == nullNode)
				return 0;
			return root.size - root.indexOf(from);
		}
		Node from = fromInclusive ? root.ceil(this.from) : root
				.higher(this.from);
		if (from == nullNode || !belongs(from.key))
			return 0;
		Node to = toInclusive ? root.floor(this.to) : root.lower(this.to);
		return root.indexOf(to) - root.indexOf(from) + 1;
	}

	public boolean isEmpty() {
		return size() == 0;
	}

	@SuppressWarnings({ "unchecked" })
	public boolean contains(Object o) {
		return belongs((K) o) && root.search((K) o) != nullNode;
	}

	public Iterator<K> iterator() {
		return new Iterator<K>() {
			private K current = first();

			public boolean hasNext() {
				return current != null;
			}

			public K next() {
				K result = current;
				current = higher(current);
				return result;
			}

			public void remove() {
				TreapSet.this.remove(current);
			}
		};
	}

	public Object[] toArray() {
		Object[] array = new Object[size()];
		int index = 0;
		for (K key : this)
			array[index++] = key;
		return array;
	}

	@SuppressWarnings({ "unchecked" })
	public <T> T[] toArray(T[] a) {
		if (a.length < size())
			throw new IllegalArgumentException();
		int index = 0;
		for (K key : this)
			a[index++] = (T) key;
		return a;
	}

	public boolean add(K k) {
		if (k == null)
			throw new NullPointerException();
		if (contains(k))
			return false;
		root = root.insert(createNode(k));
		return true;
	}

	protected Node createNode(K k) {
		return new Node(k, rnd.nextLong());
	}

	public boolean remove(Object o) {
		if (!contains(o))
			return false;
		// noinspection unchecked
		root = root.erase((K) o);
		return true;
	}

	public boolean containsAll(Collection<?> c) {
		for (Object o : c) {
			if (!contains(o))
				return false;
		}
		return true;
	}

	public boolean addAll(Collection<? extends K> c) {
		return addAll((Iterable<? extends K>) c);
	}

	public boolean retainAll(Collection<?> c) {
		List<K> toRemove = new ArrayList<K>();
		for (K key : this) {
			if (!c.contains(key))
				toRemove.add(key);
		}
		return removeAll(toRemove);
	}

	public boolean removeAll(Collection<?> c) {
		boolean result = false;
		for (Object o : c)
			result |= remove(o);
		return result;
	}

	public void clear() {
		retainAll(Collections.<Object> emptySet());
	}

	public NavigableSet<K> descendingSet() {
		throw new UnsupportedOperationException();
	}

	public Iterator<K> descendingIterator() {
		return new Iterator<K>() {
			private K current = last();

			public boolean hasNext() {
				return current != null;
			}

			public K next() {
				K result = current;
				current = lower(current);
				return result;
			}

			public void remove() {
				TreapSet.this.remove(current);
			}
		};
	}

	public NavigableSet<K> subSet(K fromElement, boolean fromInclusive,
			K toElement, boolean toInclusive) {
		return new TreapSet<K>(fromElement, toElement, fromInclusive,
				toInclusive, comparator, root, nullNode);
	}

	public NavigableSet<K> headSet(K toElement, boolean inclusive) {
		return subSet(null, false, toElement, inclusive);
	}

	public NavigableSet<K> tailSet(K fromElement, boolean inclusive) {
		return subSet(fromElement, inclusive, null, false);
	}

	public Comparator<? super K> comparator() {
		return comparator;
	}

	public SortedSet<K> subSet(K fromElement, K toElement) {
		return subSet(fromElement, true, toElement, false);
	}

	public SortedSet<K> headSet(K toElement) {
		return subSet(null, false, toElement, false);
	}

	public SortedSet<K> tailSet(K fromElement) {
		return tailSet(fromElement, true);
	}

	public K first() {
		if (isEmpty())
			return null;
		if (from == null)
			return root.first().key;
		if (fromInclusive)
			return ceiling(from);
		return higher(from);
	}

	public K last() {
		if (isEmpty())
			return null;
		if (to == null)
			return root.last().key;
		if (toInclusive)
			return floor(to);
		return lower(to);
	}

	public K get(int index) {
		if (index >= size() || index < 0)
			throw new IndexOutOfBoundsException(Integer.toString(index));
		if (from != null)
			index += headSet(from, !fromInclusive).size();
		return root.get(index);
	}

	protected int compare(K first, K second) {
		if (first == null || second == null)
			return -1;
		if (comparator != null)
			return comparator.compare(first, second);
		// noinspection unchecked
		return ((Comparable<? super K>) first).compareTo(second);
	}

	protected class Node {
		protected final K key;
		protected final long priority;
		protected Node left;
		protected Node right;
		protected int size;

		protected Node(K key, long priority) {
			this.key = key;
			this.priority = priority;
			left = nullNode;
			right = nullNode;
			size = 1;
		}

		@SuppressWarnings({ "unchecked" })
		protected Object[] split(K key) {
			if (compare(key, this.key) < 0) {
				Object[] result = left.split(key);
				left = (Node) result[1];
				result[1] = this;
				updateSize();
				return result;
			}
			Object[] result = right.split(key);
			right = (Node) result[0];
			result[0] = this;
			updateSize();
			return result;
		}

		protected void updateSize() {
			size = left.size + right.size + 1;
		}

		@SuppressWarnings({ "unchecked" })
		protected Node insert(Node node) {
			if (node.priority > priority) {
				Object[] result = split(node.key);
				node.left = (Node) result[0];
				node.right = (Node) result[1];
				node.updateSize();
				return node;
			}
			if (compare(node.key, this.key) < 0) {
				left = left.insert(node);
				updateSize();
				return this;
			}
			right = right.insert(node);
			updateSize();
			return this;
		}

		protected Node merge(Node left, Node right) {
			if (left == nullNode)
				return right;
			if (right == nullNode)
				return left;
			if (left.priority > right.priority) {
				left.right = left.right.merge(left.right, right);
				left.updateSize();
				return left;
			}
			right.left = right.left.merge(left, right.left);
			right.updateSize();
			return right;
		}

		protected Node erase(K key) {
			int value = compare(key, this.key);
			if (value == 0)
				return merge(left, right);
			if (value < 0) {
				left = left.erase(key);
				updateSize();
				return this;
			}
			right = right.erase(key);
			updateSize();
			return this;
		}

		protected Node lower(K key) {
			if (compare(key, this.key) <= 0)
				return left.lower(key);
			Node result = right.lower(key);
			if (result == nullNode)
				return this;
			return result;
		}

		protected Node floor(K key) {
			if (compare(key, this.key) < 0)
				return left.floor(key);
			Node result = right.floor(key);
			if (result == nullNode)
				return this;
			return result;
		}

		protected Node higher(K key) {
			if (compare(key, this.key) >= 0)
				return right.higher(key);
			Node result = left.higher(key);
			if (result == nullNode)
				return this;
			return result;
		}

		protected Node ceil(K key) {
			if (compare(key, this.key) > 0)
				return right.ceil(key);
			Node result = left.ceil(key);
			if (result == nullNode)
				return this;
			return result;
		}

		protected Node first() {
			if (left == nullNode)
				return this;
			return left.first();
		}

		protected Node last() {
			if (right == nullNode)
				return this;
			return right.last();
		}

		protected Node search(K key) {
			int value = compare(key, this.key);
			if (value == 0)
				return this;
			if (value < 0)
				return left.search(key);
			return right.search(key);
		}

		public int indexOf(Node node) {
			if (this == node)
				return left.size;
			if (compare(node.key, this.key) > 0)
				return left.size + 1 + right.indexOf(node);
			return left.indexOf(node);
		}

		public K get(int index) {
			if (index < left.size)
				return left.get(index);
			else if (index == left.size)
				return key;
			else
				return right.get(index - left.size - 1);
		}
	}

	private class NullNode extends Node {
		private Object[] splitResult = new Object[2];

		private NullNode() {
			super(null, Long.MIN_VALUE);
			left = this;
			right = this;
			size = 0;
		}

		@Override
		protected Object[] split(K key) {
			splitResult[0] = splitResult[1] = this;
			return splitResult;
		}

		@Override
		protected Node insert(Node node) {
			return node;
		}

		@Override
		protected Node erase(K key) {
			return this;
		}

		@Override
		protected Node lower(K key) {
			return this;
		}

		@Override
		protected Node floor(K key) {
			return this;
		}

		@Override
		protected Node higher(K key) {
			return this;
		}

		@Override
		protected Node ceil(K key) {
			return this;
		}

		@Override
		protected Node first() {
			throw new NoSuchElementException();
		}

		@Override
		protected Node last() {
			throw new NoSuchElementException();
		}

		@Override
		protected void updateSize() {
		}

		@Override
		protected Node search(K key) {
			return this;
		}

	}
}

abstract class LongIntervalTree extends IntervalTree {
	protected long[] value;
	protected long[] delta;

	protected LongIntervalTree(int size) {
		this(size, true);
	}

	public LongIntervalTree(int size, boolean shouldInit) {
		super(size, shouldInit);
	}

	@Override
	protected void initData(int size, int nodeCount) {
		value = new long[nodeCount];
		delta = new long[nodeCount];
	}

	protected abstract long joinValue(long left, long right);

	protected abstract long joinDelta(long was, long delta);

	protected abstract long accumulate(long value, long delta, int length);

	protected abstract long neutralValue();

	protected abstract long neutralDelta();

	protected long initValue(int index) {
		return neutralValue();
	}

	@Override
	protected void initAfter(int root, int left, int right, int middle) {
		value[root] = joinValue(value[2 * root + 1], value[2 * root + 2]);
		delta[root] = neutralDelta();
	}

	@Override
	protected void initBefore(int root, int left, int right, int middle) {
	}

	@Override
	protected void initLeaf(int root, int index) {
		value[root] = initValue(index);
		delta[root] = neutralDelta();
	}

	@Override
	protected void updatePostProcess(int root, int left, int right, int from,
			int to, long delta, int middle) {
		value[root] = joinValue(value[2 * root + 1], value[2 * root + 2]);
	}

	@Override
	protected void updatePreProcess(int root, int left, int right, int from,
			int to, long delta, int middle) {
		pushDown(root, left, middle, right);
	}

	protected void pushDown(int root, int left, int middle, int right) {
		value[2 * root + 1] = accumulate(value[2 * root + 1], delta[root],
				middle - left + 1);
		value[2 * root + 2] = accumulate(value[2 * root + 2], delta[root],
				right - middle);
		delta[2 * root + 1] = joinDelta(delta[2 * root + 1], delta[root]);
		delta[2 * root + 2] = joinDelta(delta[2 * root + 2], delta[root]);
		delta[root] = neutralDelta();
	}

	@Override
	protected void updateFull(int root, int left, int right, int from, int to,
			long delta) {
		value[root] = accumulate(value[root], delta, right - left + 1);
		this.delta[root] = joinDelta(this.delta[root], delta);
	}

	@Override
	protected long queryPostProcess(int root, int left, int right, int from,
			int to, int middle, long leftResult, long rightResult) {
		return joinValue(leftResult, rightResult);
	}

	@Override
	protected void queryPreProcess(int root, int left, int right, int from,
			int to, int middle) {
		pushDown(root, left, middle, right);
	}

	@Override
	protected long queryFull(int root, int left, int right, int from, int to) {
		return value[root];
	}

	@Override
	protected long emptySegmentResult() {
		return neutralValue();
	}
}

class IntPair implements Comparable<IntPair> {
	public final int first, second;

	public IntPair(int first, int second) {
		this.first = first;
		this.second = second;
	}

	@Override
	public String toString() {
		return "(" + first + "," + second + ")";
	}

	@Override
	public boolean equals(Object o) {
		if (this == o)
			return true;
		if (o == null || getClass() != o.getClass())
			return false;

		IntPair intPair = (IntPair) o;

		return first == intPair.first && second == intPair.second;

	}

	@Override
	public int hashCode() {
		int result = first;
		result = 31 * result + second;
		return result;
	}

	public int compareTo(IntPair o) {
		if (first < o.first)
			return -1;
		if (first > o.first)
			return 1;
		if (second < o.second)
			return -1;
		if (second > o.second)
			return 1;
		return 0;
	}
}

class Matrix {
	public static long mod = Long.MAX_VALUE;
	public final long[][] data;
	public final int rowCount;
	public final int columnCount;

	public Matrix(int rowCount, int columnCount) {
		this.rowCount = rowCount;
		this.columnCount = columnCount;
		this.data = new long[rowCount][columnCount];
	}

	public Matrix(long[][] data) {
		this.rowCount = data.length;
		this.columnCount = data[0].length;
		this.data = data;
	}

	public static Matrix add(Matrix first, Matrix second) {
		Matrix result = new Matrix(first.rowCount, first.columnCount);
		for (int i = 0; i < result.rowCount; i++) {
			for (int j = 0; j < result.columnCount; j++) {
				result.data[i][j] = first.data[i][j] + second.data[i][j];
				if (result.data[i][j] >= mod)
					result.data[i][j] -= mod;
			}
		}
		return result;
	}

	public static Matrix multiply(Matrix first, Matrix second) {
		Matrix result = new Matrix(first.rowCount, second.columnCount);
		for (int i = 0; i < first.rowCount; i++) {
			for (int j = 0; j < second.rowCount; j++) {
				for (int k = 0; k < second.columnCount; k++)
					result.data[i][k] = (result.data[i][k] + first.data[i][j]
							* second.data[j][k])
							% mod;
			}
		}
		return result;
	}

	public static Matrix fastMultiply(Matrix first, Matrix second) {
		Matrix result = new Matrix(first.rowCount, second.columnCount);
		for (int i = 0; i < first.rowCount; i++) {
			for (int j = 0; j < second.rowCount; j++) {
				for (int k = 0; k < second.columnCount; k++)
					result.data[i][k] += first.data[i][j] * second.data[j][k];
			}
		}
		for (int i = 0; i < first.rowCount; i++) {
			for (int j = 0; j < second.columnCount; j++)
				result.data[i][j] %= mod;
		}
		return result;
	}

	public static Matrix identityMatrix(int size) {
		Matrix result = new Matrix(size, size);
		for (int i = 0; i < size; i++)
			result.data[i][i] = 1;
		return result;
	}

	public static long[] convert(long[][] matrix) {
		long[] result = new long[matrix.length * matrix.length];
		for (int i = 0; i < matrix.length; i++) {
			for (int j = 0; j < matrix.length; j++)
				result[i * matrix.length + j] = matrix[i][j];
		}
		return result;
	}

	public static long[] sumPowers(long[] matrix, long exponent, long mod,
			int side) {
		long[] result = new long[matrix.length];
		long[] power = new long[matrix.length];
		long[] temp = new long[matrix.length];
		long[] temp2 = new long[matrix.length];
		sumPowers(matrix, result, power, temp, temp2, exponent + 1, mod, side);
		return result;
	}

	private static void sumPowers(long[] matrix, long[] result, long[] power,
			long[] temp, long[] temp2, long exponent, long mod, int side) {
		if (exponent == 0) {
			for (int i = 0; i < matrix.length; i += side + 1)
				power[i] = 1 % mod;
			return;
		}
		if ((exponent & 1) == 0) {
			sumPowers(matrix, result, temp, power, temp2, exponent >> 1, mod,
					side);
			multiply(temp2, result, temp, mod, side);
			add(result, temp2, mod, side);
			multiply(power, temp, temp, mod, side);
		} else {
			sumPowers(matrix, result, temp, power, temp2, exponent - 1, mod,
					side);
			add(result, temp, mod, side);
			multiply(power, temp, matrix, mod, side);
		}
	}

	public static long[][] convert(long[] matrix, int side) {
		long[][] result = new long[side][side];
		for (int i = 0; i < side; i++) {
			for (int j = 0; j < side; j++)
				result[i][j] = matrix[i * side + j];
		}
		return result;
	}

	public static long[] power(long[] matrix, long exponent, long mod, int side) {
		long[] result = new long[matrix.length];
		long[] temp = new long[result.length];
		power(matrix, result, temp, exponent, mod, side);
		return result;
	}

	private static void power(long[] matrix, long[] result, long[] temp,
			long exponent, long mod, int side) {
		if (exponent == 0) {
			for (int i = 0; i < matrix.length; i += side + 1)
				result[i] = 1 % mod;
			return;
		}
		if ((exponent & 1) == 0) {
			power(matrix, temp, result, exponent >> 1, mod, side);
			multiply(result, temp, temp, mod, side);
		} else {
			power(matrix, temp, result, exponent - 1, mod, side);
			multiply(result, temp, matrix, mod, side);
		}
	}

	public static void multiply(long[] c, long[] a, long[] b, long mod, int side) {
		Arrays.fill(c, 0);
		for (int i = 0; i < side; i++) {
			for (int j = 0; j < side; j++) {
				for (int k = 0; k < side; k++) {
					c[i * side + k] += a[i * side + j] * b[j * side + k];
					if ((j & 3) == 3) {
						c[i * side + k] %= mod;
					}
				}
			}
		}
		for (int i = 0; i < c.length; i++)
			c[i] %= mod;
	}

	public static void add(long[] c, long[] a, long mod, int side) {
		for (int i = 0; i < side; i++) {
			for (int j = 0; j < side; j++) {
				c[i * side + j] += a[i * side + j];
				if (c[i * side + j] >= mod)
					c[i * side + j] -= mod;
			}
		}
	}

	public static long[] fastPower(long[] matrix, long exponent, long mod,
			int side) {
		long[] result = new long[matrix.length];
		long[] temp = new long[result.length];
		fastPower(matrix, result, temp, exponent, mod, side);
		return result;
	}

	private static void fastPower(long[] matrix, long[] result, long[] temp,
			long exponent, long mod, int side) {
		if (exponent == 0) {
			for (int i = 0; i < matrix.length; i += side + 1)
				result[i] = 1;
			return;
		}
		if ((exponent & 1) == 0) {
			fastPower(matrix, temp, result, exponent >> 1, mod, side);
			fastMultiply(result, temp, temp, mod, side);
		} else {
			power(matrix, temp, result, exponent - 1, mod, side);
			fastMultiply(result, temp, matrix, mod, side);
		}
	}

	public static void fastMultiply(long[] c, long[] a, long[] b, long mod,
			int side) {
		Arrays.fill(c, 0);
		for (int i = 0; i < side; i++) {
			for (int j = 0; j < side; j++) {
				for (int k = 0; k < side; k++)
					c[i * side + k] += a[i * side + j] * b[j * side + k];
			}
		}
		for (int i = 0; i < c.length; i++)
			c[i] %= mod;
	}

	public Matrix power(long exponent) {
		if (exponent == 0)
			return identityMatrix(rowCount);
		if (exponent == 1)
			return this;
		Matrix result = power(exponent >> 1);
		result = multiply(result, result);
		if ((exponent & 1) == 1)
			result = multiply(result, this);
		return result;
	}

	public Matrix fastPower(long exponent) {
		if (exponent == 0)
			return identityMatrix(rowCount);
		if (exponent == 1)
			return this;
		Matrix result = power(exponent >> 1);
		result = fastMultiply(result, result);
		if ((exponent & 1) == 1)
			result = fastMultiply(result, this);
		return result;
	}
}

class MiscUtils {
	public static final int[] DX4 = { 1, 0, -1, 0 };
	public static final int[] DY4 = { 0, -1, 0, 1 };
	public static final int[] DX8 = { 1, 1, 1, 0, -1, -1, -1, 0 };
	public static final int[] DY8 = { -1, 0, 1, 1, 1, 0, -1, -1 };
	public static final int[] DX_KNIGHT = { 2, 1, -1, -2, -2, -1, 1, 2 };
	public static final int[] DY_KNIGHT = { 1, 2, 2, 1, -1, -2, -2, -1 };

	private static final String[] ROMAN_TOKENS = { "M", "CM", "D", "CD", "C",
			"XC", "L", "XL", "X", "IX", "V", "IV", "I" };
	private static final int[] ROMAN_VALUES = { 1000, 900, 500, 400, 100, 90,
			50, 40, 10, 9, 5, 4, 1 };

	public static long josephProblem(long n, int k) {
		if (n == 1)
			return 0;
		if (k == 1)
			return n - 1;
		if (k > n)
			return (josephProblem(n - 1, k) + k) % n;
		long count = n / k;
		long result = josephProblem(n - count, k);
		result -= n % k;
		if (result < 0)
			result += n;
		else
			result += result / (k - 1);
		return result;
	}

	public static boolean isValidCell(int row, int column, int rowCount,
			int columnCount) {
		return row >= 0 && row < rowCount && column >= 0
				&& column < columnCount;
	}

	public static long maximalRectangleSum(long[][] array) {
		int n = array.length;
		int m = array[0].length;
		long[][] partialSums = new long[n + 1][m + 1];
		for (int i = 0; i < n; i++) {
			long rowSum = 0;
			for (int j = 0; j < m; j++) {
				rowSum += array[i][j];
				partialSums[i + 1][j + 1] = partialSums[i][j + 1] + rowSum;
			}
		}
		long result = Long.MIN_VALUE;
		for (int i = 0; i < m; i++) {
			for (int j = i; j < m; j++) {
				long minPartialSum = 0;
				for (int k = 1; k <= n; k++) {
					long current = partialSums[k][j + 1] - partialSums[k][i];
					result = Math.max(result, current - minPartialSum);
					minPartialSum = Math.min(minPartialSum, current);
				}
			}
		}
		return result;
	}

	public static int parseIP(String ip) {
		String[] components = ip.split("[.]");
		int result = 0;
		for (int i = 0; i < 4; i++)
			result += (1 << (24 - 8 * i)) * Integer.parseInt(components[i]);
		return result;
	}

	public static String buildIP(int mask) {
		StringBuilder result = new StringBuilder();
		for (int i = 0; i < 4; i++) {
			if (i != 0)
				result.append('.');
			result.append(mask >> (24 - 8 * i) & 255);
		}
		return result.toString();
	}

	public static <T> boolean equals(T first, T second) {
		return first == null && second == null || first != null
				&& first.equals(second);
	}

	public static boolean isVowel(char ch) {
		ch = Character.toUpperCase(ch);
		return ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U'
				|| ch == 'Y';
	}

	public static boolean isStrictVowel(char ch) {
		ch = Character.toUpperCase(ch);
		return ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U';
	}

	public static String convertToRoman(int number) {
		StringBuilder result = new StringBuilder();
		for (int i = 0; i < ROMAN_TOKENS.length; i++) {
			while (number >= ROMAN_VALUES[i]) {
				number -= ROMAN_VALUES[i];
				result.append(ROMAN_TOKENS[i]);
			}
		}
		return result.toString();
	}

	public static int convertFromRoman(String number) {
		int result = 0;
		for (int i = 0; i < ROMAN_TOKENS.length; i++) {
			while (number.startsWith(ROMAN_TOKENS[i])) {
				number = number.substring(ROMAN_TOKENS[i].length());
				result += ROMAN_VALUES[i];
			}
		}
		return result;
	}

	public static int distance(int x1, int y1, int x2, int y2) {
		int dx = x1 - x2;
		int dy = y1 - y2;
		return dx * dx + dy * dy;
	}

	public static <T extends Comparable<T>> T min(T first, T second) {
		if (first.compareTo(second) <= 0)
			return first;
		return second;
	}

	public static <T extends Comparable<T>> T max(T first, T second) {
		if (first.compareTo(second) <= 0)
			return second;
		return first;
	}

	public static void decreaseByOne(int[]... arrays) {
		for (int[] array : arrays) {
			for (int i = 0; i < array.length; i++)
				array[i]--;
		}
	}

	public static int[] getIntArray(String s) {
		String[] tokens = s.split(" ");
		int[] result = new int[tokens.length];
		for (int i = 0; i < result.length; i++)
			result[i] = Integer.parseInt(tokens[i]);
		return result;
	}
}

class Graph {
	public static final int REMOVED_BIT = 0;

	protected int vertexCount;
	protected int edgeCount;

	private int[] firstOutbound;
	private int[] firstInbound;

	private Edge[] edges;
	private int[] nextInbound;
	private int[] nextOutbound;
	private int[] from;
	private int[] to;
	private long[] weight;
	public long[] capacity;
	private int[] reverseEdge;
	private int[] flags;

	public Graph(int vertexCount) {
		this(vertexCount, vertexCount);
	}

	public Graph(int vertexCount, int edgeCapacity) {
		this.vertexCount = vertexCount;
		firstOutbound = new int[vertexCount];
		Arrays.fill(firstOutbound, -1);

		from = new int[edgeCapacity];
		to = new int[edgeCapacity];
		nextOutbound = new int[edgeCapacity];
		flags = new int[edgeCapacity];
	}

	public static Graph createGraph(int vertexCount, int[] from, int[] to) {
		Graph graph = new Graph(vertexCount, from.length);
		for (int i = 0; i < from.length; i++)
			graph.addSimpleEdge(from[i], to[i]);
		return graph;
	}

	public static Graph createWeightedGraph(int vertexCount, int[] from,
			int[] to, long[] weight) {
		Graph graph = new Graph(vertexCount, from.length);
		for (int i = 0; i < from.length; i++)
			graph.addWeightedEdge(from[i], to[i], weight[i]);
		return graph;
	}

	public static Graph createFlowGraph(int vertexCount, int[] from, int[] to,
			long[] capacity) {
		Graph graph = new Graph(vertexCount, from.length * 2);
		for (int i = 0; i < from.length; i++)
			graph.addFlowEdge(from[i], to[i], capacity[i]);
		return graph;
	}

	public static Graph createFlowWeightedGraph(int vertexCount, int[] from,
			int[] to, long[] weight, long[] capacity) {
		Graph graph = new Graph(vertexCount, from.length * 2);
		for (int i = 0; i < from.length; i++)
			graph.addFlowWeightedEdge(from[i], to[i], weight[i], capacity[i]);
		return graph;
	}

	public static Graph createTree(int[] parent) {
		Graph graph = new Graph(parent.length + 1, parent.length);
		for (int i = 0; i < parent.length; i++)
			graph.addSimpleEdge(parent[i], i + 1);
		return graph;
	}

	public int addEdge(int fromID, int toID, long weight, long capacity,
			int reverseEdge) {
		ensureEdgeCapacity(edgeCount + 1);
		if (firstOutbound[fromID] != -1)
			nextOutbound[edgeCount] = firstOutbound[fromID];
		else
			nextOutbound[edgeCount] = -1;
		firstOutbound[fromID] = edgeCount;
		if (firstInbound != null) {
			if (firstInbound[toID] != -1)
				nextInbound[edgeCount] = firstInbound[toID];
			else
				nextInbound[edgeCount] = -1;
			firstInbound[toID] = edgeCount;
		}
		this.from[edgeCount] = fromID;
		this.to[edgeCount] = toID;
		if (capacity != 0) {
			if (this.capacity == null)
				this.capacity = new long[from.length];
			this.capacity[edgeCount] = capacity;
		}
		if (weight != 0) {
			if (this.weight == null)
				this.weight = new long[from.length];
			this.weight[edgeCount] = weight;
		}
		if (reverseEdge != -1) {
			if (this.reverseEdge == null) {
				this.reverseEdge = new int[from.length];
				Arrays.fill(this.reverseEdge, 0, edgeCount, -1);
			}
			this.reverseEdge[edgeCount] = reverseEdge;
		}
		if (edges != null)
			edges[edgeCount] = createEdge(edgeCount);
		return edgeCount++;
	}

	protected final GraphEdge createEdge(int id) {
		return new GraphEdge(id);
	}

	public final int addFlowWeightedEdge(int from, int to, long weight,
			long capacity) {
		if (capacity == 0) {
			return addEdge(from, to, weight, 0, -1);
		} else {
			int lastEdgeCount = edgeCount;
			addEdge(to, from, -weight, 0, lastEdgeCount + entriesPerEdge());
			return addEdge(from, to, weight, capacity, lastEdgeCount);
		}
	}

	protected int entriesPerEdge() {
		return 1;
	}

	public final int addFlowEdge(int from, int to, long capacity) {
		return addFlowWeightedEdge(from, to, 0, capacity);
	}

	public final int addWeightedEdge(int from, int to, long weight) {
		return addFlowWeightedEdge(from, to, weight, 0);
	}

	public final int addSimpleEdge(int from, int to) {
		return addWeightedEdge(from, to, 0);
	}

	public final int vertexCount() {
		return vertexCount;
	}

	public final int edgeCount() {
		return edgeCount;
	}

	protected final int edgeCapacity() {
		return from.length;
	}

	public final Edge edge(int id) {
		initEdges();
		return edges[id];
	}

	public final int firstOutbound(int vertex) {
		int id = firstOutbound[vertex];
		while (id != -1 && isRemoved(id))
			id = nextOutbound[id];
		return id;
	}

	public final int nextOutbound(int id) {
		id = nextOutbound[id];
		while (id != -1 && isRemoved(id))
			id = nextOutbound[id];
		return id;
	}

	public final int firstInbound(int vertex) {
		initInbound();
		int id = firstInbound[vertex];
		while (id != -1 && isRemoved(id))
			id = nextInbound[id];
		return id;
	}

	public final int nextInbound(int id) {
		initInbound();
		id = nextInbound[id];
		while (id != -1 && isRemoved(id))
			id = nextInbound[id];
		return id;
	}

	public final int source(int id) {
		return from[id];
	}

	public final int destination(int id) {
		return to[id];
	}

	public final long weight(int id) {
		if (weight == null)
			return 0;
		return weight[id];
	}

	public final long capacity(int id) {
		if (capacity == null)
			return 0;
		return capacity[id];
	}

	public final long flow(int id) {
		if (reverseEdge == null)
			return 0;
		return capacity[reverseEdge[id]];
	}

	public final void pushFlow(int id, long flow) {
		if (flow == 0)
			return;
		if (flow > 0) {
			if (capacity(id) < flow)
				throw new IllegalArgumentException("Not enough capacity");
		} else {
			if (flow(id) < -flow)
				throw new IllegalArgumentException("Not enough capacity");
		}
		capacity[id] -= flow;
		capacity[reverseEdge[id]] += flow;
	}

	public int transposed(int id) {
		return -1;
	}

	public final int reverse(int id) {
		if (reverseEdge == null)
			return -1;
		return reverseEdge[id];
	}

	public final void addVertices(int count) {
		ensureVertexCapacity(vertexCount + count);
		Arrays.fill(firstOutbound, vertexCount, vertexCount + count, -1);
		if (firstInbound != null)
			Arrays.fill(firstInbound, vertexCount, vertexCount + count, -1);
		vertexCount += count;
	}

	protected final void initEdges() {
		if (edges == null) {
			edges = new Edge[from.length];
			for (int i = 0; i < edgeCount; i++)
				edges[i] = createEdge(i);
		}
	}

	public final void removeVertex(int vertex) {
		int id = firstOutbound[vertex];
		while (id != -1) {
			removeEdge(id);
			id = nextOutbound[id];
		}
		initInbound();
		id = firstInbound[vertex];
		while (id != -1) {
			removeEdge(id);
			id = nextInbound[id];
		}
	}

	private void initInbound() {
		if (firstInbound == null) {
			firstInbound = new int[firstOutbound.length];
			Arrays.fill(firstInbound, 0, vertexCount, -1);
			nextInbound = new int[from.length];
			for (int i = 0; i < edgeCount; i++) {
				nextInbound[i] = firstInbound[to[i]];
				firstInbound[to[i]] = i;
			}
		}
	}

	public final boolean flag(int id, int bit) {
		return (flags[id] >> bit & 1) != 0;
	}

	public final void setFlag(int id, int bit) {
		flags[id] |= 1 << bit;
	}

	public final void removeFlag(int id, int bit) {
		flags[id] &= -1 - (1 << bit);
	}

	public final void removeEdge(int id) {
		setFlag(id, REMOVED_BIT);
	}

	public final void restoreEdge(int id) {
		removeFlag(id, REMOVED_BIT);
	}

	public final boolean isRemoved(int id) {
		return flag(id, REMOVED_BIT);
	}

	public final Iterable<Edge> outbound(final int id) {
		initEdges();
		return new Iterable<Edge>() {
			public Iterator<Edge> iterator() {
				return new EdgeIterator(id, firstOutbound, nextOutbound);
			}
		};
	}

	public final Iterable<Edge> inbound(final int id) {
		initEdges();
		initInbound();
		return new Iterable<Edge>() {
			public Iterator<Edge> iterator() {
				return new EdgeIterator(id, firstInbound, nextInbound);
			}
		};
	}

	protected void ensureEdgeCapacity(int size) {
		if (from.length < size) {
			int newSize = Math.max(size, 2 * from.length);
			if (edges != null)
				edges = resize(edges, newSize);
			from = resize(from, newSize);
			to = resize(to, newSize);
			nextOutbound = resize(nextOutbound, newSize);
			if (nextInbound != null)
				nextInbound = resize(nextInbound, newSize);
			if (weight != null)
				weight = resize(weight, newSize);
			if (capacity != null)
				capacity = resize(capacity, newSize);
			if (reverseEdge != null)
				reverseEdge = resize(reverseEdge, newSize);
			flags = resize(flags, newSize);
		}
	}

	private void ensureVertexCapacity(int size) {
		if (firstOutbound.length < size) {
			int newSize = Math.max(size, 2 * from.length);
			firstOutbound = resize(firstOutbound, newSize);
			if (firstInbound != null)
				firstInbound = resize(firstInbound, newSize);
		}
	}

	protected final int[] resize(int[] array, int size) {
		int[] newArray = new int[size];
		System.arraycopy(array, 0, newArray, 0, array.length);
		return newArray;
	}

	private long[] resize(long[] array, int size) {
		long[] newArray = new long[size];
		System.arraycopy(array, 0, newArray, 0, array.length);
		return newArray;
	}

	private Edge[] resize(Edge[] array, int size) {
		Edge[] newArray = new Edge[size];
		System.arraycopy(array, 0, newArray, 0, array.length);
		return newArray;
	}

	public final boolean isSparse() {
		return vertexCount == 0 || edgeCount * 20 / vertexCount <= vertexCount;
	}

	protected class GraphEdge implements Edge {
		protected int id;

		protected GraphEdge(int id) {
			this.id = id;
		}

		public int getSource() {
			return source(id);
		}

		public int getDestination() {
			return destination(id);
		}

		public long getWeight() {
			return weight(id);
		}

		public long getCapacity() {
			return capacity(id);
		}

		public long getFlow() {
			return flow(id);
		}

		public void pushFlow(long flow) {
			Graph.this.pushFlow(id, flow);
		}

		public boolean getFlag(int bit) {
			return flag(id, bit);
		}

		public void setFlag(int bit) {
			Graph.this.setFlag(id, bit);
		}

		public void removeFlag(int bit) {
			Graph.this.removeFlag(id, bit);
		}

		public int getTransposedID() {
			return transposed(id);
		}

		public Edge getTransposedEdge() {
			int reverseID = getTransposedID();
			if (reverseID == -1)
				return null;
			initEdges();
			return edge(reverseID);
		}

		public int getReverseID() {
			return reverse(id);
		}

		public Edge getReverseEdge() {
			int reverseID = getReverseID();
			if (reverseID == -1)
				return null;
			initEdges();
			return edge(reverseID);
		}

		public int getID() {
			return id;
		}

		public void remove() {
			removeEdge(id);
		}

		public void restore() {
			restoreEdge(id);
		}
	}

	public class EdgeIterator implements Iterator<Edge> {
		private int edgeID;
		private final int[] next;
		private int lastID = -1;

		public EdgeIterator(int id, int[] first, int[] next) {
			this.next = next;
			edgeID = nextEdge(first[id]);
		}

		private int nextEdge(int id) {
			while (id != -1 && isRemoved(id))
				id = next[id];
			return id;
		}

		public boolean hasNext() {
			return edgeID != -1;
		}

		public Edge next() {
			if (edgeID == -1)
				throw new NoSuchElementException();
			lastID = edgeID;
			edgeID = nextEdge(next[lastID]);
			return edges[lastID];
		}

		public void remove() {
			if (lastID == -1)
				throw new IllegalStateException();
			removeEdge(lastID);
			lastID = -1;
		}
	}

}

class MaxFlow {
	private final Graph graph;
	private int source;
	private int destination;
	private int[] queue;
	private int[] distance;
	private int[] nextEdge;

	private MaxFlow(Graph graph, int source, int destination) {
		this.graph = graph;
		this.source = source;
		this.destination = destination;
		int vertexCount = graph.vertexCount();
		queue = new int[vertexCount];
		distance = new int[vertexCount];
		nextEdge = new int[vertexCount];
	}

	public static long dinic(Graph graph, int source, int destination) {
		return new MaxFlow(graph, source, destination).dinic();
	}

	private long dinic() {
		long totalFlow = 0;
		while (true) {
			edgeDistances();
			if (distance[destination] == -1)
				break;
			Arrays.fill(nextEdge, -2);
			totalFlow += dinicImpl(source, Long.MAX_VALUE);
		}
		return totalFlow;
	}

	private void edgeDistances() {
		Arrays.fill(distance, -1);
		distance[source] = 0;
		int size = 1;
		queue[0] = source;
		for (int i = 0; i < size; i++) {
			int current = queue[i];
			int id = graph.firstOutbound(current);
			while (id != -1) {
				if (graph.capacity(id) != 0) {
					int next = graph.destination(id);
					if (distance[next] == -1) {
						distance[next] = distance[current] + 1;
						queue[size++] = next;
					}
				}
				id = graph.nextOutbound(id);
			}
		}
	}

	private long dinicImpl(int source, long flow) {
		if (source == destination)
			return flow;
		if (flow == 0 || distance[source] == distance[destination])
			return 0;
		int id = nextEdge[source];
		if (id == -2)
			nextEdge[source] = id = graph.firstOutbound(source);
		long totalPushed = 0;
		while (id != -1) {
			int nextDestinationID = graph.destination(id);
			if (graph.capacity(id) != 0
					&& distance[nextDestinationID] == distance[source] + 1) {
				long pushed = dinicImpl(nextDestinationID,
						Math.min(flow, graph.capacity(id)));
				if (pushed != 0) {
					graph.pushFlow(id, pushed);
					flow -= pushed;
					totalPushed += pushed;
					if (flow == 0)
						return totalPushed;
				}
			}
			nextEdge[source] = id = graph.nextOutbound(id);
		}
		return totalPushed;
	}
}

interface Edge {
	public int getSource();

	public int getDestination();

	public long getWeight();

	public long getCapacity();

	public long getFlow();

	public void pushFlow(long flow);

	public boolean getFlag(int bit);

	public void setFlag(int bit);

	public void removeFlag(int bit);

	public int getTransposedID();

	public Edge getTransposedEdge();

	public int getReverseID();

	public Edge getReverseEdge();

	public int getID();

	public void remove();

	public void restore();
}

class Point {
	public static final Point ORIGIN = new Point(0, 0);
	public final double x;
	public final double y;

	@Override
	public String toString() {
		return "(" + x + ", " + y + ")";
	}

	public Point(double x, double y) {
		this.x = x;
		this.y = y;
	}

	public Line line(Point other) {
		if (equals(other))
			return null;
		double a = other.y - y;
		double b = x - other.x;
		double c = -a * x - b * y;
		return new Line(a, b, c);
	}

	@Override
	public boolean equals(Object o) {
		if (this == o)
			return true;
		if (o == null || getClass() != o.getClass())
			return false;

		Point point = (Point) o;

		return Math.abs(x - point.x) <= GeometryUtils.epsilon
				&& Math.abs(y - point.y) <= GeometryUtils.epsilon;
	}

	@Override
	public int hashCode() {
		int result;
		long temp;
		temp = x != +0.0d ? Double.doubleToLongBits(x) : 0L;
		result = (int) (temp ^ (temp >>> 32));
		temp = y != +0.0d ? Double.doubleToLongBits(y) : 0L;
		result = 31 * result + (int) (temp ^ (temp >>> 32));
		return result;
	}

	public double distance(Point other) {
		return GeometryUtils.fastHypot(x - other.x, y - other.y);
	}

	public double distance(Line line) {
		return Math.abs(line.a * x + line.b * y + line.c);
	}

	public double value() {
		return GeometryUtils.fastHypot(x, y);
	}

	public double angle() {
		return Math.atan2(y, x);
	}

	public static Point readPoint(InputReader in) {
		double x = in.readDouble();
		double y = in.readDouble();
		return new Point(x, y);
	}

	public Point rotate(double angle) {
		double nx = x * Math.cos(angle) - y * Math.sin(angle);
		double ny = y * Math.cos(angle) + x * Math.sin(angle);
		return new Point(nx, ny);
	}
}

class Line {
	public final double a;
	public final double b;
	public final double c;

	public Line(Point p, double angle) {
		a = Math.sin(angle);
		b = -Math.cos(angle);
		c = -p.x * a - p.y * b;
	}

	public Line(double a, double b, double c) {
		double h = GeometryUtils.fastHypot(a, b);
		this.a = a / h;
		this.b = b / h;
		this.c = c / h;
	}

	public Point intersect(Line other) {
		if (parallel(other))
			return null;
		double determinant = b * other.a - a * other.b;
		double x = (c * other.b - b * other.c) / determinant;
		double y = (a * other.c - c * other.a) / determinant;
		return new Point(x, y);
	}

	public boolean parallel(Line other) {
		return Math.abs(a * other.b - b * other.a) < GeometryUtils.epsilon;
	}

	public boolean contains(Point point) {
		return Math.abs(value(point)) < GeometryUtils.epsilon;
	}

	public Line perpendicular(Point point) {
		return new Line(-b, a, b * point.x - a * point.y);
	}

	public double value(Point point) {
		return a * point.x + b * point.y + c;
	}

	public double distance(Point center) {
		return Math.abs(value(center));
	}

	@Override
	public boolean equals(Object o) {
		if (this == o)
			return true;
		if (o == null || getClass() != o.getClass())
			return false;

		Line line = (Line) o;

		if (!parallel(line))
			return false;
		if (Math.abs(a * line.c - c * line.a) > GeometryUtils.epsilon
				|| Math.abs(b * line.c - c * line.b) > GeometryUtils.epsilon)
			return false;

		return true;
	}
}

class GeometryUtils {
	public static double epsilon = 1e-8;

	public static double fastHypot(double... x) {
		if (x.length == 0)
			return 0;
		else if (x.length == 1)
			return Math.abs(x[0]);
		else {
			double sumSquares = 0;
			for (double value : x)
				sumSquares += value * value;
			return Math.sqrt(sumSquares);
		}
	}

	public static double fastHypot(double x, double y) {
		return Math.sqrt(x * x + y * y);
	}

	public static double fastHypot(double[] x, double[] y) {
		if (x.length == 0)
			return 0;
		else if (x.length == 1)
			return Math.abs(x[0] - y[0]);
		else {
			double sumSquares = 0;
			for (int i = 0; i < x.length; i++) {
				double diff = x[i] - y[i];
				sumSquares += diff * diff;
			}
			return Math.sqrt(sumSquares);
		}
	}

	public static double fastHypot(int[] x, int[] y) {
		if (x.length == 0)
			return 0;
		else if (x.length == 1)
			return Math.abs(x[0] - y[0]);
		else {
			double sumSquares = 0;
			for (int i = 0; i < x.length; i++) {
				double diff = x[i] - y[i];
				sumSquares += diff * diff;
			}
			return Math.sqrt(sumSquares);
		}
	}

	public static double missileTrajectoryLength(double v, double angle,
			double g) {
		return (v * v * Math.sin(2 * angle)) / g;
	}

	public static double sphereVolume(double radius) {
		return 4 * Math.PI * radius * radius * radius / 3;
	}

	public static double triangleSquare(double first, double second,
			double third) {
		double p = (first + second + third) / 2;
		return Math.sqrt(p * (p - first) * (p - second) * (p - third));
	}

	public static double canonicalAngle(double angle) {
		while (angle > Math.PI)
			angle -= 2 * Math.PI;
		while (angle < -Math.PI)
			angle += 2 * Math.PI;
		return angle;
	}

	public static double positiveAngle(double angle) {
		while (angle > 2 * Math.PI - GeometryUtils.epsilon)
			angle -= 2 * Math.PI;
		while (angle < -GeometryUtils.epsilon)
			angle += 2 * Math.PI;
		return angle;
	}
}

import java.util.*;
import java.math.BigInteger;

public class Main{
   public static void main(String[] args) {
      Scanner sc = new Scanner(System.in);

	int h=sc.nextInt();
	String s=sc.next();

	BigInteger two=new BigInteger("2");
	BigInteger n=two.pow(h).subtract(BigInteger.ONE).add(new BigInteger(s));

	String bin=n.toString(2);

	StringBuffer LR = new StringBuffer();
	for(int i=1;i<bin.length();i++){
		if(bin.charAt(i)=='0') LR.append("L");
		else LR.append("R");
	}

	String _LR=LR.toString();

	BigInteger res=BigInteger.ONE;
	for(int i=0;i<_LR.length();i++){
		if(i==0 && _LR.charAt(i)=='R' || i!=0 && _LR.charAt(i-1)==_LR.charAt(i))
		{
			res=res.add(two.pow(h-i));
		}
		else{
			res=res.add(BigInteger.ONE);
		}

	}

	res=res.subtract(BigInteger.ONE);

	System.out.println(res);

    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
import java.util.regex.Pattern;

public class C {
    public static void main(String[] args) throws IOException {
        Scanner in = new Scanner(System.in);
        int h = in.nextInt();
        long n = in.nextLong();
        in.close();
        long result = 0;
        long all = 1l << h;
        long offset = 0;
        long pow = all;
        boolean right = false;
        for (int i = 0; i < h; i++) {
            long halfPow = pow / 2;
            boolean actualRight = n - offset > halfPow;
//            System.err.println(i + " " + pow + " " + offset + " " + result + " " + right + " " + actualRight);
            if (actualRight == right) {
                result += 1;
            } else {
                result += pow;
            }
            if (actualRight)
                offset += halfPow;
            pow /= 2;
            right = !actualRight;
        }
        System.out.println(result);
    }
}

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.StringTokenizer;
import java.util.TreeSet;

public class con287_A {

	static BufferedReader br = new BufferedReader( new InputStreamReader(System.in, StandardCharsets.US_ASCII) );
	static StringTokenizer tok;

	private static String NL() throws Exception {
		String line = br.readLine();
		tok = new StringTokenizer(line);
		return line;
	}

	static String NT() {
		return tok.nextToken();
	}

	public static void main(String[] args) throws Exception {
		NL();
		int h = Integer.parseInt(NT());
		long n = Long.parseLong(NT());
		System.out.println(solve(h, n));
	}

	static long solve(int oh, long n) {
		TreeSet<Long> set = new TreeSet<Long>();
		int h = oh;
		long k = n - 1 + (1L << h);
		while (k > 0) {
			set.add(k);
			k >>= 1;
		}

		long res = 0;
		long cur = 1;
		char next = 'L';
		n = n - 1 + (1L << h);
		while (cur != n) {
			if (next == 'L') {
				cur <<= 1;
			} else {
				cur <<= 1;
				++cur;
			}
			--h;
			if (set.contains(cur) ) {
				res += 1;
			} else {
				res += (1L << (h+1));
				cur += next == 'L' ? 1 : -1;
				next = next == 'L' ? 'R' : 'L';
			}
			next = next == 'L' ? 'R' : 'L';
		}
		return res;
	}

}

import java.util.Scanner;
public class GuessYourWayOut {
    public static void main(String[] args)
    {
        Scanner cin = new Scanner(System.in);
        long h = cin.nextInt();
        long n = cin.nextLong();
        long[] a = getResult(h,n);
        System.out.println(a[0]);
    }

    public static long getParent(long n)
    {
        return (n+1)/2;
    }

    public static long[] getResult(long h , long n)
    {
        long[] a = new long[2];
        a[0] = 0 ;
        a[1] = 0;
        if(h == 1)
        {
            if(n == 1)
            {
                a[0] = 1;
                a[1] = 0;
            }
            else
            {
                a[0] = 2;
                a[1] = 1;
            }
            return a ;
        }

        long p = getParent(n);
        a = getResult(h-1 , p);

        if(p % 2 == n % 2)
        {
            a[1] = a[1] * 2 + 1;
            a[0] = a[0] + a[1];
        }
        else
        {
            a[1] = a[1] * 2;
            a[0] = a[0] + a[1];
        }
        a[0] ++ ;
        return a ;
    }
}

import java.util.*;
public class GuessYourWayOut
{
	public static void main(String[] args)
	{
		Scanner in = new Scanner(System.in);

		int h = in.nextInt();
		long n = in.nextLong() - 1;

		long result = 0;
		long left = 0;
		long right = (1L << h) - 1;
		int move = 1;
		for(int x = 0; x < h; x++)
		{
			move ^= 1;

			long mid = (left + right) / 2;
			if(n <= mid)
			{
				if(move == 1)
				{
					result += (1L << (h - x));
					move = 0;
				}
				else
				{
					result++;
				}

				right = mid;
			}
			else
			{
				if(move == 0)
				{
					result += (1L << (h - x));
					move = 1;
				}
				else
				{
					result++;
				}

				left = mid + 1;
			}
		}

		System.out.println(result);
	}
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

public class ProblemC {
    BufferedReader rd;
    Map<Node, Long> dpMap = new HashMap<>();
    int maxh;
    long[] p2 = new long[60];

    private ProblemC() throws IOException {
        rd = new BufferedReader(new InputStreamReader(System.in));
        compute();
    }

    private void compute() throws IOException {
        long[] a = longarr();
        maxh = (int)a[0];
        long n = a[1];

        p2[0] = 1;
        for(int i=1;i<60;i++) {
            p2[i] = p2[i-1]*2;
        }
        out(solve(new Node(0, 0, n)));
    }

    private class Node {
        int h;
        int nextMove;
        long exit;

        private Node(int h, int nextMove, long exit) {
            this.h = h;
            this.nextMove = nextMove;
            this.exit = exit;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (!(o instanceof Node)) return false;

            Node node = (Node) o;

            if (exit != node.exit) return false;
            if (h != node.h) return false;
            if (nextMove != node.nextMove) return false;

            return true;
        }

        @Override
        public int hashCode() {
            int result = h;
            result = 31 * result + nextMove;
            result = 31 * result + (int) (exit ^ (exit >>> 32));
            return result;
        }
    }

    private long solve(Node node) {
        Long res = dpMap.get(node);
        if(res == null) {
            if(node.exit == 0) {
                res = p2[maxh-node.h+1]-1;
            } else {
                if(node.h == maxh) {
                    if(node.exit == 1) {
                        res = 0L;
                    } else {
                        res = 1L;
                    }
                } else {
                    long half = p2[maxh-node.h-1];
                    if(node.nextMove == 0) {
                        if(node.exit <= half) {
                            res = 1 + solve(new Node(node.h+1, 1-node.nextMove, node.exit));
                        } else {
                            res = 1 + solve(new Node(node.h+1, 1-node.nextMove, 0)) + solve(new Node(node.h+1, node.nextMove, node.exit - half));
                        }
                    } else if(node.nextMove == 1) {
                        if(node.exit <= half) {
                            res = 1 + solve(new Node(node.h+1, 1-node.nextMove, 0)) + solve(new Node(node.h+1, node.nextMove, node.exit));
                        } else {
                            res = 1 + solve(new Node(node.h+1, 1-node.nextMove, node.exit - half));
                        }
                    }
                }
            }
            dpMap.put(node, res);
        }
        return res;
    }

    private long[] longarr() throws IOException {
        return longarr(rd.readLine());
    }

    private long[] longarr(String s) {
        String[] q = split(s);
        int n = q.length;
        long[] a = new long[n];
        for(int i=0;i<n;i++) {
            a[i] = Long.parseLong(q[i]);
        }
        return a;
    }

    private String[] split(String s) {
        int n = s.length();
        int sp = 0;
        for(int i=0;i<n;i++) {
            if(s.charAt(i)==' ') {
                sp++;
            }
        }
        String[] res = new String[sp+1];
        int last = 0;
        int x = 0;
        for(int i=0;i<n;i++) {
            char c = s.charAt(i);
            if(c == ' ') {
                res[x++] = s.substring(last,i);
                last = i+1;
            }
        }
        res[x] = s.substring(last,n);
        return res;
    }

    private static void out(Object x) {
        System.out.println(x);
    }

    public static void main(String[] args) throws IOException {
        new ProblemC();
    }
}

import java.util.Arrays;
import java.util.Scanner;

public class MainC {
	MyScanner sc = new MyScanner();
	Scanner sc2 = new Scanner(System.in);
	final int MOD = 1000000007;
	int[] dx = { 1, 0, 0, -1 };
	int[] dy = { 0, 1, -1, 0 };

	void run() {
		int h = sc.nextInt();
		long n = sc.nextLong();
		long leaf = (long) Math.pow(2, h);
		long cnt = 0;
		boolean flag = true;
		long l = 0;
		long r = leaf;
		for (int i = 0; i < h; i++) {
			long mid = (l + r) / 2;
			if (flag) {
				if (n <= mid) {
					cnt++;
					r = mid;
				} else {
					cnt += Math.pow(2, h - i);
					flag = !flag;
					l = mid;
				}
			} else {
				if (n > mid) {
					cnt++;
					l = mid;
				} else {
					cnt += Math.pow(2, h - i);
					flag = !flag;
					r = mid;
				}
			}
			flag = !flag;
		}
		System.out.println(cnt);
	}

	public static void main(String[] args) {
		new MainC().run();
	}

	void debug(Object... o) {
		System.out.println(Arrays.deepToString(o));
	}

	void debug2(int[][] array) {
		for (int i = 0; i < array.length; i++) {
			for (int j = 0; j < array[i].length; j++) {
				System.out.print(array[i][j]);
			}
			System.out.println();
		}
	}

	boolean inner(int h, int w, int limH, int limW) {
		return 0 <= h && h < limH && 0 <= w && w < limW;
	}

	void swap(int[] x, int a, int b) {
		int tmp = x[a];
		x[a] = x[b];
		x[b] = tmp;
	}

	// find minimum i (a[i] >= border)
	int lower_bound(int a[], int border) {
		int l = -1;
		int r = a.length;

		while (r - l > 1) {
			int mid = (l + r) / 2;
			if (border <= a[mid]) {
				r = mid;
			} else {
				l = mid;
			}
		}
		// r = l + 1
		return r;
	}

	boolean palindrome(String s) {
		for (int i = 0; i < s.length() / 2; i++) {
			if (s.charAt(i) != s.charAt(s.length() - 1 - i)) {
				return false;
			}
		}
		return true;
	}

	class MyScanner {
		int nextInt() {
			try {
				int c = System.in.read();
				while (c != '-' && (c < '0' || '9' < c))
					c = System.in.read();
				if (c == '-')
					return -nextInt();
				int res = 0;
				do {
					res *= 10;
					res += c - '0';
					c = System.in.read();
				} while ('0' <= c && c <= '9');
				return res;
			} catch (Exception e) {
				return -1;
			}
		}

		double nextDouble() {
			return Double.parseDouble(next());
		}

		long nextLong() {
			return Long.parseLong(next());
		}

		String next() {
			try {
				StringBuilder res = new StringBuilder("");
				int c = System.in.read();
				while (Character.isWhitespace(c))
					c = System.in.read();
				do {
					res.append((char) c);
				} while (!Character.isWhitespace(c = System.in.read()));
				return res.toString();
			} catch (Exception e) {
				return null;
			}
		}

		int[] nextIntArray(int n) {
			int[] in = new int[n];
			for (int i = 0; i < n; i++) {
				in[i] = nextInt();
			}
			return in;
		}

		int[][] nextInt2dArray(int n, int m) {
			int[][] in = new int[n][m];
			for (int i = 0; i < n; i++) {
				in[i] = nextIntArray(m);
			}
			return in;
		}

		double[] nextDoubleArray(int n) {
			double[] in = new double[n];
			for (int i = 0; i < n; i++) {
				in[i] = nextDouble();
			}
			return in;
		}

		long[] nextLongArray(int n) {
			long[] in = new long[n];
			for (int i = 0; i < n; i++) {
				in[i] = nextLong();
			}
			return in;
		}

		char[][] nextCharField(int n, int m) {
			char[][] in = new char[n][m];
			for (int i = 0; i < n; i++) {
				String s = sc.next();
				for (int j = 0; j < m; j++) {
					in[i][j] = s.charAt(j);
				}
			}
			return in;
		}
	}
}

import java.io.*;
import java.text.DecimalFormat;
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        FastScanner fs = new FastScanner();
        PrintWriter out = new PrintWriter(new FileWriter("out.out"));

        int height = fs.nextInt();
        long n = fs.nextLong();
        String look = Long.toBinaryString((1l << height)-1 + n);
        int at = 1, level = 0, turn = 0;
        long res = 0;
        while(at < look.length()) {
            char bit = look.charAt(at);
            if(turn == 0) {
                if(bit == '1') {
                    res += (1l << (height - level));
                    turn--;
                }
                else
                    res++;
            } else {
                if(bit == '1')
                    res++;
                else {
                    res += 1l << (height - level);
                    turn--;
                }
            }
            turn = (turn+1)%2;
            level++;
            at++;
        }
        System.out.println(res);
    }

    static boolean[] V = new boolean[1 << 5];
    static void bruteForce() {

    }

    static class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        public FastScanner() {
            try {
                br = new BufferedReader(new InputStreamReader(System.in));
                st = new StringTokenizer("");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        public String next() {
            if (st.hasMoreTokens()) return st.nextToken();
            try {
                st = new StringTokenizer(br.readLine());
            } catch (Exception e) {
                e.printStackTrace();
            }
            return st.nextToken();
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

        public double nextDouble() {
            return Double.parseDouble(next());
        }

        public String nextLine() {
            String line = "";
            try {
                line = br.readLine();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return line;
        }

        public Integer[] nextIntegerArray(int n) {
            Integer[] a = new Integer[n];
            for (int i = 0; i < n; i++) a[i] = nextInt();
            return a;
        }

        public int[] nextIntArray(int n) {
            int[] a = new int[n];
            for (int i = 0; i < n; i++) a[i] = nextInt();
            return a;
        }

        public char[] nextCharArray() {
            return nextLine().toCharArray();
        }
    }
}

import java.io.InputStreamReader;
import java.io.IOException;
import java.util.InputMismatchException;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.Writer;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author Niyaz Nigmatullin
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		FastScanner in = new FastScanner(inputStream);
		FastPrinter out = new FastPrinter(outputStream);
		TaskC solver = new TaskC();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskC {
    public void solve(int testNumber, FastScanner in, FastPrinter out) {
        int h = in.nextInt();
        long n = in.nextLong();
        long leaves = 1L << h;
        n = leaves - n + 1;
        long ans = 0;
        for (int i = 0; i < h; i++) {
            leaves /= 2;
            if (n > leaves) {
                n = 2 * leaves - n + 1;
                ++ans;
            } else {
                ans += 2 * leaves;
            }
        }
        out.println(ans);
    }
}

class FastScanner extends BufferedReader {

    public FastScanner(InputStream is) {
        super(new InputStreamReader(is));
    }

    public int read() {
        try {
            int ret = super.read();
//            if (isEOF && ret < 0) {
//                throw new InputMismatchException();
//            }
//            isEOF = ret == -1;
            return ret;
        } catch (IOException e) {
            throw new InputMismatchException();
        }
    }

    public String next() {
        StringBuilder sb = new StringBuilder();
        int c = read();
        while (isWhiteSpace(c)) {
            c = read();
        }
        if (c < 0) {
            return null;
        }
        while (c >= 0 && !isWhiteSpace(c)) {
            sb.appendCodePoint(c);
            c = read();
        }
        return sb.toString();
    }

    static boolean isWhiteSpace(int c) {
        return c >= 0 && c <= 32;
    }

    public int nextInt() {
        int c = read();
        while (isWhiteSpace(c)) {
            c = read();
        }
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        int ret = 0;
        while (c >= 0 && !isWhiteSpace(c)) {
            if (c < '0' || c > '9') {
                throw new NumberFormatException("digit expected " + (char) c
                        + " found");
            }
            ret = ret * 10 + c - '0';
            c = read();
        }
        return ret * sgn;
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

    public String readLine() {
        try {
            return super.readLine();
        } catch (IOException e) {
            return null;
        }
    }

}

class FastPrinter extends PrintWriter {

    public FastPrinter(OutputStream out) {
        super(out);
    }

    public FastPrinter(Writer out) {
        super(out);
    }

}

/* package whatever; // don't place package name! */

import java.util.*;
import java.lang.*;
import java.io.*;

/* Name of the class has to be "Main" only if the class is public. */
public class Ideone
{
	public static void main (String[] args) throws java.lang.Exception
	{
		// your code goes here
		Scanner sc=new Scanner(System.in);
		long h=sc.nextLong(),n=sc.nextLong();
		long[] pow2=new long[(int)h+1];
		long pow=1;
		for(int i=0;i<=h;i++){pow2[i]=pow;pow*=2;}
		Stack<Integer> snu=new Stack<>();
		Stack<Character> sch=new Stack<>();
		snu.push(1);
		if(n%2!=0)sch.push('L');
		else sch.push('R');
		n=(long)Math.ceil((((double)n)/2));
		while(snu.peek()!=h){
			snu.push(snu.peek()+1);
			if(n%2!=0)sch.push('L');
			else sch.push('R');
			n=(long)Math.ceil((((double)n)/2));
		}
		Character dir='L';
		long ans=0;
		while(snu.size()!=0){
			Integer nu=snu.pop();
			Character ch=sch.pop();
			if(dir!=ch){
				ans+=(pow2[nu-1]+pow2[nu-1]-1);
				dir=ch;
			}
			ans+=1;
			dir=((dir=='R')?'L':'R');
		}
		System.out.println(ans);
	}
}

import java.io.BufferedWriter;
import java.util.InputMismatchException;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import java.math.BigInteger;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.io.IOException;
import java.util.Arrays;
import java.io.InputStream;
import java.util.Collection;
import java.io.OutputStreamWriter;
import java.util.Comparator;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author Nguyen Trung Hieu - vuondenthanhcong11@gmail.com
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		OutputWriter out = new OutputWriter(outputStream);
		TaskC solver = new TaskC();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskC {
    public void solve(int testNumber, InputReader in, OutputWriter out) {
        int height = in.readInt();
        long idx = in.readLong();
        long actualIdx = IntegerUtils.power(2, height) - 1 + idx;
        String path = "";
        while (actualIdx > 1) {
            if (actualIdx % 2 == 1) {
                path = "R" + path;
            } else {
                path = "L" + path;
            }
            actualIdx >>= 1;
        }
        char mustBe = 'L';
        char[] next = new char[200];
        next['L'] = 'R';
        next['R'] = 'L';
        long answer = 0;
        for (char c : path.toCharArray()) {
            if (c != mustBe) {
                answer += IntegerUtils.power(2, height);
            } else {
                answer++;
            }
            mustBe = next[c];
            height--;
        }

        out.printLine(answer);
    }
}

class InputReader {
    private InputStream stream;
    private byte[] buf = new byte[1024];
    private int curChar;
    private int numChars;
    private SpaceCharFilter filter;

    public InputReader(InputStream stream) {
        this.stream = stream;
    }

    public int read() {
        if (numChars == -1)
            throw new InputMismatchException();
        if (curChar >= numChars) {
            curChar = 0;
            try {
                numChars = stream.read(buf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (numChars <= 0)
                return -1;
        }
        return buf[curChar++];
    }

    public int readInt() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        int res = 0;
        do {
            if (c < '0' || c > '9')
                throw new InputMismatchException();
            res *= 10;
            res += c - '0';
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }

    public boolean isSpaceChar(int c) {
        if (filter != null)
            return filter.isSpaceChar(c);
        return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
    }

    public long readLong() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        long res = 0;
        do {
            if (c < '0' || c > '9')
                throw new InputMismatchException();
            res *= 10;
            res += c - '0';
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }

    public interface SpaceCharFilter {
        public boolean isSpaceChar(int ch);
    }

}

class OutputWriter {
    private final PrintWriter writer;

    public OutputWriter(OutputStream outputStream) {
        writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
    }

    public void print(Object...objects) {
        for (int i = 0; i < objects.length; i++) {
            if (i != 0)
                writer.print(' ');
            writer.print(objects[i]);
        }
    }

    public void printLine(Object...objects) {
        print(objects);
        writer.println();
    }

    public void close() {
        writer.close();
    }

}

class IntegerUtils {

    public static long power(long base, long exponent) {
        if (exponent == 0)
            return 1;
        long result = power(base, exponent >> 1);
        result = result * result;
        if ((exponent & 1) != 0)
            result = result * base;
        return result;
    }

}

//package C.java;

import java.io.*;
import java.util.StringTokenizer;

public class C{
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskA solver = new TaskA();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskA {
    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int h = in.nextInt();
        long n = in.nextLong() - 1;
        long res = 0;
        for(int i = h - 1; i >= 0; i--) {
            if ((n >> i & 1L) == 1L) {
                res += 1L << i + 1;
            } else {
                res += 1L;
                n = ~n;
            }
        }

        out.println(res);

    }

}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream));
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

}

import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.util.StringTokenizer;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author Vitalii Kozhukhivskyi
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }
}

class TaskC {
    public void solve(int testNumber, InputReader in, PrintWriter out) {
        long h = in.nextInt();
        long n = in.nextLong();
        long res = 0;
        char curMove = 'L';
        for (long i = 0; i < h; i++) {
            long cur = 1L << (h - i);
            char neededMove = (n > cur / 2) ? 'R' : 'L';
            if (curMove != neededMove) {
                res += cur - 1;
            } else {
                curMove = (curMove == 'L') ? 'R' : 'L';
            }
            if (neededMove == 'R') {
                n -= cur / 2;
            }
        }
        out.println(res + h);
    }
}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.StringTokenizer;

public class C287 {

	public static void main(String[] args) throws IOException {
		skp();
		int h = nextInt();
		long n = nextLong() - 1;
		long counter = 0;
		int curr = 0;
		for (int i = h; i >= 1; i--) {
			if (((n >> (i - 1)) & 1L) == curr) {

				curr = curr ^ 1;
			} else {
				counter = counter + (1L << i)-1;

			}
			counter++;
		}
		System.out.println(counter);
	}

	static boolean skp() throws IOException {
		String line = r.readLine();
		if (line == null)
			return false;
		tkn = new StringTokenizer(line);
		return true;
	}

	static int nextInt() {
		return Integer.parseInt(tkn.nextToken());
	}

	static int readInt() throws NumberFormatException, IOException {
		return Integer.parseInt(r.readLine());
	}

	static long nextLong() {
		return Long.parseLong(tkn.nextToken());
	}

	static long readLong() throws NumberFormatException, IOException {
		return Long.parseLong(r.readLine());
	}

	static double nextDouble() {

		return Double.parseDouble(tkn.nextToken());
	}

	static BufferedReader r = new BufferedReader(new InputStreamReader(
			System.in));
	static StringTokenizer tkn;
}

import java.io.BufferedInputStream;
import java.io.PrintStream;
import java.util.Scanner;

public class C {

	private static PrintStream out = System.out;

	public static void main(String[] args) {
		Scanner in = new Scanner(new BufferedInputStream(System.in));
		int h = in.nextInt();
		long n = in.nextLong() - 1;
		// get n in reversed bitmask form
		int[] bitmask = new int[h];
		int idx = h;
		for (long nn = n; nn > 0; nn /= 2)
			bitmask[--idx] = (int) (nn%2);
		// go through the bitmask
		long ans = 0;
		int parity = 0;
		for (int i = 0; i < h; ++i) {
			if (bitmask[i] != parity)
				ans += 1L << (h - i);
			else
				++ans;
			parity = 1 - bitmask[i];
		}
		out.println(ans);
	}

}

import java.util.Scanner;

public class Solution {
  public static void main(String[] args) {
    Scanner in = new Scanner(System.in);
    int h = in.nextInt();
    long n = in.nextLong() - 1;
    long ct = 0;
    int offset = 0;
    for(int i = 0; i < h; i++) {
      boolean pathRight = (n & (1L << (h - i - 1))) > 0;
      //System.out.println(pathRight);
      if(pathRight == ((i + offset) % 2 == 1)) {
       // System.out.println(i + " matches ");
        ct++;
      } else {
        offset++;
       // System.out.println(i + " forks " + ((1L << (h - i)) - 1));
        ct += (1L << (h - i));
      }
    }
    System.out.println(ct);
  }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class round_507_C {

	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		int h = sc.nextInt();
		long n = sc.nextLong() + (1L << h) - 1;
		long [] nodes = new long[h + 1];
		long curr = n;
		for (int i = h; i >= 0; i--) {
			nodes[i] = curr;
			curr >>= 1;
		}
		long answer = 0;
		long direction = 0;   // 0 for left , 1 for right
		for (int i = 0; i < nodes.length - 1; i++) {
			long nextNode = (nodes[i] << 1) + direction;
			if(nextNode != nodes[i + 1])
				answer += (1L << (h - i)) - 1;
			else
				direction ^=1;
		}
		System.out.println(answer + h);
	}

	static class Scanner {
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s) {
			br = new BufferedReader(new InputStreamReader(s));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public double nextDouble() throws IOException {
			return Double.parseDouble(next());
		}

		public long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public String nextLine() throws IOException {
			return br.readLine();
		}

		public boolean ready() throws IOException {
			return br.ready();
		}
	}
}

import java.util.Arrays;
import java.util.Scanner;

public class GuessYourWayOut {
	public static void main(String[] args) {
		Scanner sc= new Scanner(System.in);
		int h= sc.nextInt();
		long n= sc.nextLong();
		long ind=  (1L<<h)-1+n;
		long result=0L;
		long h1=h;
		long nodes[]= new long [h+1];
		nodes[h]=ind;

		for(int i=h-1; i>=0; i--)
			nodes[i]=nodes[i+1]>>1;

		//System.out.println(Arrays.toString(nodes));

		long node=1L;
		boolean left=true;
		for(int i=1; i<=h; i++){
			long next=0L;
			if(left)
				next= node<<1;
			else
				next= (node<<1)+1;
			if(next!=nodes[i]){
				result+=((1L<<h1)-1);
			}
			else {

				left=!left;
			}
			result++;
			h1--;
			node=nodes[i];

		}
		System.out.println(result);
	}

}

import java.util.Scanner;

public class Main {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		int h=sc.nextInt();
		long n = sc.nextLong();

		System.out.println(go(h, n, true));
		sc.close();
	}

	public static long go(int h,long n,boolean left){

		long ans,temp;

		if(n==0)
			return 0;

		if(h==0)
			return 0;

		/*if(h==1 && n==1)
		{
			if(left)
				return 1;
			else
				return 2;
		}*/

		if(left)
		{
			//System.out.println("left "+n);
			temp = 1L<<(h-1);
			ans = (1L<<h);
			temp = temp-n;

			if(temp>=0)
				return 1L+go(h-1, n , false);
			else
				return ans+go(h-1, -temp , true);
		}
		else
		{
			//System.out.println("right "+n);
			temp = 1L<<(h-1);
			ans = (1L<<h);
			temp = temp-n;

			if(temp>=0)
				return ans+go(h-1, n , false);
			else
				return 1L+go(h-1, -temp , true);
		}
	}
}

import java.util.Scanner;
public class C {
    public static void main(String args[]) {
        Scanner in = new Scanner(System.in);
        int h = in.nextInt();
        long n = in.nextLong();
        long two = 1;
        long nh = 0;
        for (int i=0;i<h;i++) {
            nh+=two;
            two*=2;
        }
        long destiny = nh + n;

        long total = nh + two;
        int count = 0;
        long a[] = new long  [100];
        long ans = 0;

        while (destiny > 0) {
            a[count++] = destiny;
            destiny/=2;
        }
        boolean dir = false;

        for (int i=count-1;i>=1;i--) {

            total/=2;
            dir = !dir;
            ans++;
            //System.out.println(dir+" "+a[i]+" "+a[i-1]);
            if ((!dir && (a[i] * 2 == a[i-1])) || (dir && (a[i] * 2 == a[i-1]-1))) {
                ans+=total;
                dir = !dir;

            }
            //System.out.println(ans);
        }
        System.out.println(ans);
    }
}

import java.io.*;
import java.util.*;

public class Main {
	static long h,n;
	static boolean found = false;
	static long f(long lvl , long l, long r,boolean dir) {
		if(found) return 0;

		if(lvl == 0 && l == n) {
			found = true;
			return 0;
		}

		if(n < l || n > r) {
			return (1L << (lvl + 1)) - 1;
		}

		long ans = 1,mid = (l+r) >> 1;
		if(dir) {
			ans += f(lvl - 1,l,mid,false);
			ans += f(lvl - 1,mid+1,r,true);
		}else {
			ans += f(lvl - 1,mid+1,r,true);
			ans += f(lvl - 1,l,mid,false);
		}

		return ans;
	}

	public static void main(String[] args) throws Exception {
		Scanner sc = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);
		h = sc.nextLong();
		n = sc.nextLong();
		out.println(f(h,1,1L << h, true));
		out.close();
	}

}

class Scanner {
	StringTokenizer st;
	BufferedReader br;

	public Scanner(InputStream system) {
		br = new BufferedReader(new InputStreamReader(system));
	}

	public Scanner(String file) throws Exception {
		br = new BufferedReader(new FileReader(file));
	}

	public String next() throws IOException {
		while (st == null || !st.hasMoreTokens())
			st = new StringTokenizer(br.readLine());
		return st.nextToken();
	}

	public String nextLine() throws IOException {
		return br.readLine();
	}

	public int nextInt() throws IOException {
		return Integer.parseInt(next());
	}

	public double nextDouble() throws IOException {
		return Double.parseDouble(next());
	}

	public Long nextLong() throws IOException {
		return Long.parseLong(next());
	}
}

import java.util.Scanner;
public class GuessYourWayOut {
    public static void main(String[] args)
    {
        Scanner cin = new Scanner(System.in);
        long h = cin.nextInt();
        long n = cin.nextLong();
        long[] a = getResult(h,n);
        System.out.println(a[0]);
    }

    public static long getParent(long n)
    {
        return (n+1)/2;
    }

    public static long[] getResult(long h , long n)
    {
        long[] a = new long[2];
        a[0] = 0 ;
        a[1] = 0;
        if(h == 1)
        {
            if(n == 1)
            {
                a[0] = 1;
                a[1] = 0;
            }
            else
            {
                a[0] = 2;
                a[1] = 1;
            }
            return a ;
        }

        long p = getParent(n);
        a = getResult(h-1 , p);

        if(p % 2 == n % 2)
        {
            a[1] = a[1] * 2 + 1;
            a[0] = a[0] + a[1];
        }
        else
        {
            a[1] = a[1] * 2;
            a[0] = a[0] + a[1];
        }
        a[0] ++ ;
        return a ;
    }
}

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.PrintStream;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;

/*
public class _507C {

}

 */

public class _507C {
	long ans = 0;
	public void solve() throws FileNotFoundException {
		InputStream inputStream = System.in;

		InputHelper inputHelper = new InputHelper(inputStream);

		PrintStream out = System.out;

		//actual solution
		int h = inputHelper.readInteger();
		long n = inputHelper.readLong();

		count(1L, 1, h, n, 1L, (long)Math.pow(2L, h), 0);

		System.out.println(ans);
		//end here
	}

	private void count(long r, int lr, int h, long n, long min, long max, int ch) {

		if(ch == h)
		{
			return;
		}

		ans++;

		//long rl = max - min + 1;

		if(n <= min - 1 + ((max - min + 1) / 2))
		{
			if(lr == 0)
			{
				ans += (long)Math.pow(2L, h - ch) - 1;
			}
			count(2 * r, 0, h, n, min, min - 1 + ((max - min + 1) / 2), ch + 1);
		}
		else
		{
			if(lr == 1)
			{
				ans += (long)Math.pow(2L, h - ch) - 1;
			}
			count(2 * r + 1, 1, h, n, min + ((max - min + 1) / 2), max, ch + 1);
		}
	}

	public static void main(String[] args) throws FileNotFoundException {
		(new _507C()).solve();
	}

	class InputHelper {
		StringTokenizer tokenizer = null;
		private BufferedReader bufferedReader;

		public InputHelper(InputStream inputStream) {
			InputStreamReader inputStreamReader = new InputStreamReader(
					inputStream);
			bufferedReader = new BufferedReader(inputStreamReader, 16384);
		}

		public String read() {
			while (tokenizer == null || !tokenizer.hasMoreTokens()) {
				try {
					String line = bufferedReader.readLine();
					if (line == null) {
						return null;
					}
					tokenizer = new StringTokenizer(line);
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

			return tokenizer.nextToken();
		}

		public Integer readInteger() {
			return Integer.parseInt(read());
		}

		public Long readLong() {
			return Long.parseLong(read());
		}
	}
}

import java.util.*;
import java.util.Map.Entry;

public class C {

	static long[] twopow;
	static long[] twosums;

	public static void main(String[] args) {

		Scanner scan = new Scanner(System.in);

		int h = scan.nextInt();
		long n = scan.nextLong();

		twopow = new long[h];
		twopow[0] = 1;
		for (int i = 1; i<h; i++)
			twopow[i] = 2*twopow[i-1];

		twosums = new long[h];
		twosums[0] = 1;
		for (int i = 1; i<h; i++)
			twosums[i] = twopow[i] + twosums[i-1];

		System.out.println(rec(h,n,0));

		scan.close();
	}

	private static long rec(int h, long n, int dir) {

		if (h == 0) {
			return 0;
		}

		if (dir == 0) {
			if (n <= twopow[h-1]) {
				return 1 + rec(h-1,n,1);
			} else {
				return 1 + twosums[h-1] + rec(h-1,n-twopow[h-1],0);
			}
		} else {
			if (n > twopow[h-1]) {
				return 1 + rec(h-1,n-twopow[h-1],0);
			} else {
				return 1 + twosums[h-1] + rec(h-1,n,1);
			}
		}
	}
}

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Locale;
import java.util.StringTokenizer;

public class C {
	private static BufferedReader in;
	private static StringTokenizer st;
	private static PrintWriter out;

	public static void main(String[] args) throws Exception{
		Locale.setDefault(Locale.US);
		in = new BufferedReader(new InputStreamReader(System.in));
		st = new StringTokenizer("");
		out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
		int h = nextInt();
		long n = nextLong();
		long pow[] = new long[h+1];
		pow[0] = 1;
		for (int i = 1; i <= h; i++) {
			pow[i] = pow[i-1] << 1;
		}
		final int LEFT = 0;
		final int RIGHT = 1;
		int command = LEFT;
		long ans = 0;
		for (int i = 0; i < h; i++) {
			ans++;
			if(pow[h-i-1] >= n){
				if(command == LEFT){
					command = 1 - command;
				}else{
					ans += pow[h-i]-1;
				}
			}else{
				if(command == RIGHT){
					command = 1 - command;
				}else{
					ans += pow[h-i]-1;
				}
				n -= pow[h-i-1];
			}
//			System.out.println(n);
		}
		out.println(ans);
		out.close();
	}

	private static double nextDouble() throws Exception {
		return Double.parseDouble(next());
	}

	private static long nextLong() throws Exception{
		return Long.parseLong(next());
	}

	private static int nextInt() throws Exception{
		return Integer.parseInt(next());
	}
	private static String next() throws Exception{
		while(!st.hasMoreTokens())
			st = new StringTokenizer(in.readLine());
		return st.nextToken();
	}

}

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.util.StringTokenizer;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }
}

class TaskC {
    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int h = in.nextInt();
        long n = in.nextLong();
        long res = 0;
        boolean direction = true;
        for (int i = h; i > 0; i--) {
            long mid = 1L << (i - 1);
            if (direction) {
                if (n > mid) {
                    n -= mid;
                    res += (1L << i);
                } else {
                    res += 1;
                    direction = !direction;
                }
            } else {
                if (n > mid) {
                    n -= mid;
                    res += 1;
                    direction = !direction;
                } else {
                    res += (1L << i);
                }
            }
        }
        out.println(res);
    }
}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public int nextInt(){
        return Integer.parseInt(next());
    }

    public long nextLong(){
        return Long.parseLong(next());
    }

}

import java.util.Scanner;

/**
 * Created by zephyr on 2/20/15.
 */
public class AmrWay {

    public static void main(String args[]) {
        Scanner cin = new Scanner(System.in);
        long h = cin.nextInt(), n = cin.nextLong();
        int level = 1;
        long total = 1;
        int left = 1;
        //System.out.println(n);
        while (level < h){
            long child = (long)Math.pow(2, h - level);
         //   System.out.println(child);
            if (left == 1){
                if (child < n){
                    total += (long)Math.pow(2, h - level + 1);
                    n -= (long) Math.pow(2, h - level);
                    left = 1;
                } else {
                    total += 1;
                    left = 0;
                }
            }else{
                if (child < n){
                    total += 1;
                    n -= (long) Math.pow(2, h - level);
                    left = 1;
                }else{
                    total += (long)Math.pow(2, h - level + 1);
                    left = 0;

                }
            }
            /*System.out.println("DEBUG");
            System.out.println(total);
            System.out.println(n);
            */

            level++;
        }
        if (n > 1 && left == 1) total += 1;
        if (n == 1 && left == 0) total += 1;
        System.out.println(total);
    }

}

import java.util.Scanner;

/*

1 2

2 3

3 6

10 1024

39 457181784666

 */

public class c {

	public static void main(String[] args)
	{
		Scanner in = new Scanner(System.in);

		int h = in.nextInt();
		long exit = in.nextLong();

		in.close();

		System.out.println(getSteps(h, exit, true));

//		long max = 1 << h;
//		for(exit = 1; exit <= max; ++exit)
//		{
//			System.out.println(exit +" - "+getSteps(h, exit, true));
//		}
	}

	static long getSteps(int size, long exit, boolean left)
	{
		if(size == 0)
			return 0;

		long totalNodes = 1l << (size-1);

		if(exit > totalNodes)
		{
			if(left)
				return (totalNodes << 1) + getSteps(size-1, exit - totalNodes, true);
			else
				return 1 + getSteps(size-1, exit - totalNodes, !left);
		}
		else
		{
			if(left)
				return 1 + getSteps(size-1, exit, !left);
			else
				return (totalNodes << 1) + getSteps(size-1, exit, false);
		}

	}
}

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Random;
import java.util.Scanner;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeSet;
import java.util.concurrent.LinkedBlockingDeque;

import javax.swing.border.Border;

public class a {

	public static long mod = (long) Math.pow(10, 9) + 7;
	public static int t;

	private static class node implements Comparable<node> {
		int num;
		int k;
		int dis;

		node(int m, int k, int dix) {
			num = m;
			this.k = k;
			dis = dix;

		}

		@Override
		public int compareTo(node o) {
			if (o.dis < dis)
				return 1;
			else if (o.dis > dis)
				return -1;
			if (o.k > k)
				return 1;
			else if (o.k < k)
				return -1;
			return 0;

		}

	}

	public static class point {
		long x;
		long y;
		long b;

		point(long x, long y, long b) {
			this.x = x;
			this.y = y;
			this.b = b;
		}
	}

	public static int ch(long y) {
		int r = Long.bitCount(y);
		return r;
	}

	public static long gcd(long x, long y) {
		if (y == 0)
			return x;

		return gcd(y, x % y);
	}

	public static boolean ch[] = new boolean[10000005];
	public static ArrayList<Integer> prime = new ArrayList();

	// public static Queue<Integer> pp;

	public static void sieve(int k) {
		ch[0] = ch[1] = true;

		for (int i = 2; i <= k; i++) {
			if (!ch[i]) {
				prime.add(i);
				// pp.add(i);
				for (long j = (long) i * (long) i; j <= k; j += i) {
					ch[(int) j] = true;
				}
			}
		}

	}

	public static long pw(int x, int power, int mod) {
		if (power == 1)
			return x % mod;
		else if (power % 2 == 0)
			return pw((x % mod * x % mod) % mod, power / 2, mod);
		else
			return (pw(x, power - 1, mod) % mod * x % mod) % mod;

	}

	public static String addToString(String a, int index, char b) {
		String ans = "";
		for (int i = 0; i < a.length(); i++) {
			if (i == index) {
				ans += b;
				index = -1;
				i--;
				continue;
			}
			ans += a.charAt(i);
		}
		return ans;
	}

	public static int bit[];

	public static void add(int idx, int cost) {
		while (idx < bit.length) {
			bit[idx] += cost;
			idx += (idx & -idx);
		}

	}

	public static int get(int idx) {
		int res = 0;
		while (idx > 0) {
			res += bit[idx];
			idx -= (idx & -idx);
		}
		return res;
	}

	public static long ch(int h, int h1, long p) {
		long k = p;
		int h2 = h1;
		while (h2 < h) {
			k = k * 2 + 1;
			h2++;
		}

		return k - (1L << h) + 1L;
	}

	public static long ch2(int h, int h1, long p) {
		long k = p;
		int h2 = h1;
		while (h2 < h) {
			k = k * 2;
			h2++;
		}

		return k - (1L << h) + 1L;
	}

	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		// BufferedReader in = new BufferedReader(new FileReader(
		// "corporate_gifting.txt"));
		StringBuilder qq = new StringBuilder();
		PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
		// PrintWriter out = new PrintWriter(new FileWriter("out.txt"));
		String y[] = in.readLine().split(" ");
		int h = Integer.parseInt(y[0]);
		long n = Long.parseLong(y[1]);
		long p = 1;
		int h1 = 0;
		int e = 0;
		long ans = 0;
		while (h1 < h) {
			if (e == 0) {
				h1++;
				p *= 2;
				long get = ch(h, h1, p);
				if (get < n) {
					ans += (1L << (h - h1 + 1));
					//System.out.println(ans);
					p++;
					e = 0;
				} else {
					e = 1;
					ans++;
				}
			} else {
				h1++;
				p = p * 2 + 1;
				long get = ch2(h, h1, p);
				if (get > n) {
					ans += (1L << (h - h1 + 1));
					p--;
					e = 1;
				} else {
					ans++;
					e = 0;
				}
			}
		}
		System.out.println(ans);

		out.close();

	}
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class GuessYourWayOut {
	public static void main(String[] args) throws IOException {
		BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(bf.readLine());
		int h = Integer.parseInt(st.nextToken());
		long n = Long.parseLong(st.nextToken());
		long dist = n + (1L << h) - 1;
		long[] path = new long[h + 1];
		path[h] = dist;
		for (int i = h - 1; i >= 0; i--)
			path[i] = path[i + 1] / 2;
		long ans = h;
		int level = 0;
		int dir = 0;
		for (int i = 0; i < path.length - 1; i++) {
			long nxt = (path[i] * 2) + dir;
			level++;
			if (nxt != path[i + 1]) {
				ans += (1L << (h - level + 1)) - 1;
			} else {

				dir = dir ^ 1;
			}
		}
		System.out.println(ans);
	}
}

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class A {
	static StringBuilder out = new StringBuilder();
	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	static StringTokenizer st;
	static long n,h;

	static StringBuilder ans = new StringBuilder();
	public static void main(String[]args) throws Throwable{
		st = new StringTokenizer(br.readLine());
		h = Long.parseLong(st.nextToken());
		n = Long.parseLong(st.nextToken());
		System.out.println(state(h,-1,n));
	}

	public static long state(long l,long d,long sol){
		if(d==-1)
		{
			long rightmid = (long)Math.pow(2, l)/2;

			if(sol>rightmid) return 1+(long)((Math.pow(2, l+1)-1)/2)+state(l-1,1,sol-rightmid);

			else return 1+state(l-1,0,sol);
		}
		if(l==0) return 0;

		long rightmid = (long)Math.pow(2, l)/2;

		if(rightmid>=sol&&d==1) return 1+state(l-1,0,sol);

		if(rightmid<sol&&d==1) return 1+(long)((Math.pow(2, l+1)-1)/2)+state(l-1,1,sol-rightmid);

		if(rightmid>=sol&&d==0) return 1+(long) ((Math.pow(2, l+1)-1)/2)+state(l-1,0,sol);

		if(rightmid<sol&&d==0) return 1+state(l-1,1,sol-rightmid);

		return 1+state(l-1,1,sol-rightmid);

	}

}

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
import java.util.StringTokenizer;
import java.util.*;
import java.io.*;
public class codeforces
{
   static class Student{
       long x,y;
        Student(long x,long y){
            this.x=x;
            this.y=y;
        }
    }
    static int prime[];
    static void sieveOfEratosthenes(int n)
    {
        // Create a boolean array "prime[0..n]" and initialize
        // all entries it as true. A value in prime[i] will
        // finally be false if i is Not a prime, else true.
        int pos=0;
        prime= new int[n+1];
        for(int p = 2; p*p <=n; p++)
        {
            // If prime[p] is not changed, then it is a prime
            if(prime[p] == 0)
            {
                // Update all multiples of p
                prime[p]=p;
                for(int i = p*p; i <= n; i += p)
                    prime[i] = p;
            }
        }
    }
static    class Sortbyroll implements Comparator<Student>
{
    // Used for sorting in ascending order of
    // roll number
    public int compare(Student c, Student b)
    {
        if(c.x<=b.x)
            return -1;
        return 1;
    }
}
static class FastReader
    {
        BufferedReader br;
        StringTokenizer st;

        public FastReader()
        {
            br = new BufferedReader(new
                     InputStreamReader(System.in));
        }

        String next()
        {
            while (st == null || !st.hasMoreElements())
            {
                try
                {
                    st = new StringTokenizer(br.readLine());
                }
                catch (IOException  e)
                {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt()
        {
            return Integer.parseInt(next());
        }

        long nextLong()
        {
            return Long.parseLong(next());
        }

        double nextDouble()
        {
            return Double.parseDouble(next());
        }

        String nextLine()
        {
            String str = "";
            try
            {
                str = br.readLine();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
            return str;
        }
    }

    static class Edge{
        int a,b;
        Edge(int a,int b){
            this.a=a;
            this.b=b;
        }
    }
    static class Trie{
        Trie z,o;
        int c;
        Trie(){
            z=null;
            o=null;
            c=0;
        }
    }
    static long ans;
    static int parent[];
    static int rank[];
    static int b[][];
    static int seg[];
   // static int ans;
    static Trie root;
    static void solve()throws IOException{
        FastReader sc=new FastReader();
        long h,n;
        h=sc.nextLong();
        n=sc.nextLong();
        ans=0;
        tr(1,1,(long)Math.pow(2,h),n,0,h);
        System.out.println(ans);
    }
    static void tr(int d,long s,long e,long n,long h,long o){
        if(s==e){
            return;
        }
        long mid=(s+e-(long)1)/(long)2;
        if(n>mid){
            if(d==1){
                ans+=(long)Math.pow(2,o-h);
                tr(1,mid+1,e,n,h+1,o);
            }
            else{
                ans+=1;
                tr(1,mid+1,e,n,h+1,o);
            }
        }
        else{
            if(d==1){
                ans+=1;
                tr(0,s,mid,n,h+1,o);
            }
            else{
                ans+=(long)Math.pow(2,o-h);
                tr(0,s,mid,n,h+1,o);
            }
        }
    }
    static void update(int l,int r,int s,int e,int in,int val,int le){
        if(s>e||s>r||e<l)
            return;
        if(s==e){
            seg[in]=val;
            return;
        }
        update(l,r,s,(s+e)/2,2*in+1,val,le-1);
        update(l,r,(s+e)/2+1,e,2*in+2,val,le-1);
        if(le%2!=0)
            seg[in]=seg[2*in+1]|seg[2*in+2];
        else
            seg[in]=seg[2*in+1]^seg[2*in+2];
    }
    public static void main(String[] args){
        //long sum=0;
        try {
                codeforces.solve();
                } catch (Exception e) {
                    e.printStackTrace();
                }
    }
 /*static long power(long x, long y, long p)
{
    long res = 1;      // Initialize result

    x = x % p;  // Update x if it is more than or
                // equal to p

    /*while (y > 0)
    {
        // If y is odd, multiply x with result
        if ((y & (long)1)%2!=0)
            res = (res*x) % p;

        // y must be even now
        y = y>>1; // y = y/2
        x = (x*x) % p;
    } */
    //return res%p;
   static int find(int x)
    {
        // Finds the representative of the set
        // that x is an element of
        while(parent[x]!=x)
        {
            // if x is not the parent of itself
            // Then x is not the representative of
            // his set,
            x=parent[x];

            // so we recursively call Find on its parent
            // and move i's node directly under the
            // representative of this set
        }

        return x;
    }
    static void union(int x, int y)
    {
        // Find representatives of two sets
        int xRoot = find(x), yRoot = find(y);

        // Elements are in the same set, no need
        // to unite anything.
        if (xRoot == yRoot)
            return;

         // If x's rank is less than y's rank
        if (rank[xRoot] < rank[yRoot])

            // Then move x under y  so that depth
            // of tree remains less
            parent[xRoot] = yRoot;

        // Else if y's rank is less than x's rank
        else if (rank[yRoot] < rank[xRoot])

            // Then move y under x so that depth of
            // tree remains less
            parent[yRoot] = xRoot;

        else // if ranks are the same
        {
            // Then move y under x (doesn't matter
            // which one goes where)
            parent[yRoot] = xRoot;

            // And increment the the result tree's
            // rank by 1
            rank[xRoot] = rank[xRoot] + 1;
        }
    }
    static long gcd(long a, long b)
    {
        if (a == 0)
            return b;
        return gcd(b % a, a);
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;

public class Main {

    void solve() throws IOException {
        int h = nextInt();
        long n = nextLong();
        long[] st = new long[h + 2];
        for (int i = 0; i <= h + 1; i++) {
            st[i] = (1L << i) - 1;
        }

        long ans = 0;
        int lvl = 1;
        long a = n + st[h];
        for (;;) {
            ans++;
            long b = a / 2;
            long c = b / 2;
            boolean left1 = b * 2 == a;
            boolean left2 = c * 2 == b;
            if(b == 1) {
                if (!left1) ans += st[lvl];
                break;
            }
            if(left1 == left2) ans += st[lvl];
            lvl++;
            a = b;
        }
        System.out.println(ans);
    }

    public void run() {
        try {
            br = new BufferedReader(new InputStreamReader(System.in));
            out = new PrintWriter(System.out);
            solve();
            out.close();
            br.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(239);
        }
    }

    BufferedReader br;
    StringTokenizer st;
    PrintWriter out;

    int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

    long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }

    String nextToken() throws IOException {
        while (st == null || !st.hasMoreTokens()) {
            String line = br.readLine();
            if (line == null) {
                return null;
            }
            st = new StringTokenizer(line);
        }
        return st.nextToken();
    }

    public static void main(String[] args) {
        new Main().run();
    }
}

import java.awt.Point;
import java.io.*;
import java.util.*;
import java.math.BigInteger;

public class Tennis {
    static class Solver {
        public void solve(MyReader in, PrintWriter out) {
            long h = in.nextLong();
            long n = in.nextLong();

            long l = 1, r = pow(2,h);
            boolean LR = true; // true = L, false = R
            long res= 0;
            while (l<r){
                long mid = (l+r)/2;

                if(mid < n){
                    long ch = 2*(mid-l+1)-2;
                    res+=LR?ch+2:1;
                    l = mid+1;
                    LR = true;
                }
                else{
                    long ch = 2*(r - mid)-2;
                    res+=LR?1:ch+2;
                    r = mid;
                    LR = false;
                }

                h--;
            }

            out.println(res);
        }

        long pow(long x, long n){
            if(n == 0)return 1;
            long p = pow(x,n/2);
            if(n%2 == 0)return p*p;
            return x*p*p;
        }

    }

    public static void main(String[] args) {
        MyReader mr = new MyReader();
        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
        new Solver().solve(mr, out);
        out.close();
    }

    //    static int[][] dir = {{0,1}, {1,0},{-1,0}, {0,-1}};
//    static int[][] dir = {{0,1}, {1,0},{-1,0}, {0,-1}, {-1,-1},{-1,1}, {1,1}, {1,-1}};
    static class MyReader {
        BufferedReader br;
        StringTokenizer st;

        MyReader() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String nextLine() {
            String res = "";
            try {
                res = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return res;
        }

        int[] nextIntArray(int n) {
            int[] arr = new int[n];
            for (int i = 0; i < n; i++) {
                arr[i] = nextInt();
            }

            return arr;
        }

        Integer[] nextIntegerArray(int n) {
            Integer[] arr = new Integer[n];
            for (int i = 0; i < n; i++) {
                arr[i] = nextInt();
            }

            return arr;
        }

        Long[] nextLongArray(int n) {
            Long[] arr = new Long[n];
            for (int i = 0; i < n; i++) {
                arr[i] = nextLong();
            }

            return arr;
        }

        String[] nextStringArray(int n) {
            String[] arr = new String[n];
            for (int i = 0; i < n; i++) {
                arr[i] = next();
            }
            return arr;
        }
    }

    static void swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

}

import java.util.Scanner;

public class Round287_C_ {
	static Scanner x = new Scanner(System.in);

	static long calculate(long level) {
		return (long) (Math.pow(2, level) - 1);
	}

	public static void main(String[] args) {
		long level = x.nextLong(), n = x.nextLong(), slon = 0, mid = (long) Math
				.pow(2, level) / 2, q = mid;

		boolean turn = false;
		while (level != 0) {
			q /= 2;
			if (n <= mid) {
				if (turn) {
					slon += calculate(level);
				}
				mid -= q;
				turn = true;
			} else if (n > mid) {
				if (!turn) {
					slon += calculate(level);
				}
				mid += q;
				turn = false;
			}
			slon++;
			level--;
		}
		System.out.println(slon);
	}
}

import java.io.*;
import java.util.*;
public class CF_507C {
    public static void main(String[] args) throws IOException {
        new CF_507C().solve();
    }

    long f(long ind, long h, boolean startsLeft){
        if (h==1) return 1;
        boolean targetInLeft=ind<(1L<<(h-2));
        long newInd=ind-(targetInLeft? 0 : (1L<<(h-2)) );
        long alsoVisit=(targetInLeft ^ startsLeft) ? (1L<<(h-1))-1 : 0;
        long res=1+ alsoVisit+f(newInd, h-1, !targetInLeft);
//        System.out.println(ind+" "+h+" "+startsLeft+" "+targetInLeft+" : "+res);
        return res;
    }

    void solve() throws IOException{

        InputStream in = System.in;
        PrintStream out = System.out;

//        in = new FileInputStream("in.txt");
//        out = new PrintStream("out.txt");

        Scanner sc=new Scanner(in);
        long h=sc.nextLong()+1, n=sc.nextLong()-1;
        out.println(f(n, h, true)-1);

    }
}

import java.util.Scanner;

public class CF287C {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        long k = in.nextLong() - 1;
        long size = 1;
        long[] r = new long[] { 1, 1 };
        for (int i = 0; i < n; i++) {
            long[] newR = { 0, 0 };
            if ((k & 1L << i) == 0) {
                newR[0] = 1 + r[1];
                newR[1] = 1 + size + r[1];
            } else {
                newR[0] = 1 + size + r[0];
                newR[1] = 1 + r[0];
            }
            size = size * 2 + 1;
            r = newR;
        }
        System.out.println(r[0] - 1);
    }
}

import java.util.*;
public class KnightTemplar {
public static void main(String [] args){
	Scanner in=new Scanner(System.in);
	int h=in.nextInt();
	long n=in.nextLong()+(long)Math.pow(2,h)-1;
	Stack<Long>st=new Stack<Long>();
	long temp=n;
	while(temp>1){
	st.push(temp);
	temp/=2;
	}
	long ans=1;
	long cnt=0;
	boolean flag=true;
	long prev=2;
	int level=0;
	//System.out.print(st);
	while(!st.isEmpty()){
	long node=st.pop();
	cnt++;level++;
	if(node==prev){
		ans+=1;
		if(cnt%2==0)prev=2*node;
		else prev=2*node+1;
	}
		else {
		ans+=(long)Math.pow(2,h-level +1)-1;
		st.push(node);level--;
		prev=node;
	}
	//System.out.println(prev + " "+node+" "+ans+" "+cnt+ " "+level);
}
System.out.print(ans-1);
}
}

import java.io.BufferedInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import java.util.Map.Entry;

public class Main {
	public static final int C = 1000000007;
	static int MAP[][];
	static int W[][];
	//static int N;
	//static int M;

	public static void main(String[] args) {
		StringBuilder sb = new StringBuilder();
		BufferedInputStream bs = new BufferedInputStream(System.in);
		Scanner sc = new Scanner(bs);

		int h = sc.nextInt();

		long n = sc.nextLong();

		long re = (long)Math.pow(2, h);

		long ans = re * 2 - 1;

		boolean L = true;

		long now = re/2;
		for (int i=1; i <= h; i++) {
			long ha = re / (long)Math.pow(2, i);
			//System.out.println(ha + ":" + L +":" + now );
			if ((now - ha < n && n <= now && L) || (now < n && n <= now + ha && !L)) {
				ans -= ha * 2 - 1;

				now +=  L?-ha/2:ha/2;
				L = !L;
			}else {
				ans += ha * 2 - 1;
				L = !L;

				i--;

			}
			//if (ha == 1) {
				//break;
			//}
		}

		System.out.println(ans-1);
	}

}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Codeforces_507C_GuessYourWayOut {
	static class Scanner
	{
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s){	br = new BufferedReader(new InputStreamReader(s));}

		public String next() throws IOException
		{
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException {return Integer.parseInt(next());}

		public long nextLong() throws IOException {return Long.parseLong(next());}

		public String nextLine() throws IOException {return br.readLine();}

		public double nextDouble() throws IOException
		{
			String x = next();
			StringBuilder sb = new StringBuilder("0");
			double res = 0, f = 1;
			boolean dec = false, neg = false;
			int start = 0;
			if(x.charAt(0) == '-')
			{
				neg = true;
				start++;
			}
			for(int i = start; i < x.length(); i++)
				if(x.charAt(i) == '.')
				{
					res = Long.parseLong(sb.toString());
					sb = new StringBuilder("0");
					dec = true;
				}
				else
				{
					sb.append(x.charAt(i));
					if(dec)
						f *= 10;
				}
			res += Long.parseLong(sb.toString()) / f;
			return res * (neg?-1:1);
		}

		public boolean ready() throws IOException {return br.ready();}

	}

	public static long solve(int h,long n, boolean Command){ //command = true means left;

		if(h==0)
			return 0;
//		System.out.println(Math.pow(2, h-1));
		if(n<=Math.pow(2, h-1)){
//			System.out.println("Left >> ans + "+((long)( (Command)? 1:Math.pow(2, h))));
//			System.out.println();
			return ((long)( (Command)? 1:Math.pow(2, h))) +solve(h-1,n,false);
		}
		else{
//			System.out.println("Right >> ans + "+(((long)( (!Command)? 1:Math.pow(2, h)))));
//			System.out.println(((long)( (!Command)? 1:Math.pow(2, h-1))));
			return ((long)( (!Command)? 1:Math.pow(2, h))) +solve(h-1,(long)(n-Math.pow(2, h-1)),true);
//			return 1+solve(h-1,n,!Command);
		}

//		return 0;
	}

	public static void main(String[] args) throws IOException {
		Scanner sc= new Scanner(System.in);

		int h= sc.nextInt();
		long n= sc.nextLong();

//		System.out.println(Math.pow(2, 50));
		System.out.println(solve(h,n,true));

	}
}

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.util.StringTokenizer;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }
}

class TaskC {
    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int h = in.nextInt();
        long n = in.nextLong();
        long left = 0;
        long right = 1L << h;
        boolean turnLeft = true;
        long ans = 0;
        for (int i = h; i > 0; --i) {
            long mid = (left + right) >> 1;
            if (n > mid) {
                left = mid;
                if (!turnLeft) {
                    turnLeft = true;
                    ans++;

                } else {
                    ans += (1L << i);
                }
            } else {
                right = mid;
                if (turnLeft) {
                    turnLeft = false;
                    ans++;
                } else {
                    ans += (1L << i);
                }
            }
        }
        out.println(ans);
    }
}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

}

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

public class C {

  static long dfs(long total, long target, int dir) {
    long value = 0;
    int targetDir;

    while (! (total == 1 && target == 1)) {
      if (target <= total / 2) {
        targetDir = 0;
      } else {
        targetDir = 1;
      }
      if (targetDir != dir) {
        value += total;
      } else {
        value += 1;
      }

      if (targetDir == 1) {
        target = target - total / 2;
      }
      total = total / 2;
      dir = targetDir ^ 1;
    }
    return value;

//    if (total == 1 && target == 1) {
//      return 0;
//    }
//
//    if (target <= total / 2) {
//      targetDir = 0;
//    } else {
//      targetDir = 1;
//    }
//
//    long val = 0;
//    if (targetDir != dir) {
//      val += total;
//    } else {
//      val = 1;
//    }
//    if (targetDir == 1) {
//      return val + dfs(total / 2, target - total / 2, targetDir ^ 1);
//    } else {
//      return val + dfs(total / 2, target, targetDir ^ 1);
//    }
  }

  public static void main(String[] args) {
    MyScanner sc = new MyScanner();
    out = new PrintWriter(new BufferedOutputStream(System.out));

    int h = sc.nextInt();
    long total = 1L << h;
    long target = sc.nextLong();
    out.println(dfs(total, target, 0));

    out.close();
  }

  public static PrintWriter out;

  static class MyScanner {

    BufferedReader br;
    StringTokenizer st;

    public MyScanner() {
      br = new BufferedReader(new InputStreamReader(System.in));
    }

    String next() {
      while (st == null || !st.hasMoreElements()) {
        try {
          st = new StringTokenizer(br.readLine());
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
      return st.nextToken();
    }

    int nextInt() {
      return Integer.parseInt(next());
    }

    long nextLong() {
      return Long.parseLong(next());
    }

    double nextDouble() {
      return Double.parseDouble(next());
    }

    String nextLine() {
      String str = "";
      try {
        str = br.readLine();
      } catch (IOException e) {
        e.printStackTrace();
      }
      return str;
    }

  }

}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        CGuessYourWayOut solver = new CGuessYourWayOut();
        solver.solve(1, in, out);
        out.close();
    }

    static class CGuessYourWayOut {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            long h = in.nextLong();
            long n = in.nextLong();
            out.println(dfs((long) 1 << h, n, 0));
        }

        long dfs(long nodesInSubtree, long height, int leftRight) {
            if (nodesInSubtree <= 1 || height == 0)
                return 0;
            if (leftRight == 0) {
                if (nodesInSubtree / 2 >= height)
                    return dfs(nodesInSubtree / 2, height, 1) + 1;
                else
                    return dfs(nodesInSubtree / 2, height - nodesInSubtree / 2, 0) + nodesInSubtree;
            } else {
                if (nodesInSubtree / 2 >= height)
                    return dfs(nodesInSubtree / 2, height, 1) + nodesInSubtree;
                else
                    return dfs(nodesInSubtree / 2, height - nodesInSubtree / 2, 0) + 1;
            }
        }

    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }

        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

    }
}

import java.util.Scanner;

public class Main_Round287Div2_C {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);

		int h = sc.nextInt();
		long n = sc.nextLong() - 1;

		long mask = 0x01L << (h - 1);
		long mask2 = (0x01L << h) - 1;
		long sum = 0;
		boolean prev = true;;
		for (int i = 0; i < h; i++) {
			if ((n & mask) != 0 && prev) {
				sum += mask2;
//			} else if ((n & mask) == 0 && prev) {
//				sum += 1;
//			} else if ((n & mask) != 0 && !prev) {
//				sum += 1;
			} else if ((n & mask) == 0 && !prev) {
				sum += mask2;
			}

			sum++;

			prev = (n & mask) != 0;
			mask >>= 1;
			mask2 >>= 1;
		}

		System.out.println(sum);

		sc.close();
	}
}

//package C.java;

import java.io.*;
import java.util.StringTokenizer;

public class C{
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskA solver = new TaskA();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskA {
    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int h = in.nextInt();
        long n = in.nextLong() - 1;
        long res = 0;
        for(int i = h - 1; i >= 0; i--) {
            if ((n >> i & 1L) == 1L) {
                res += 1L << i + 1;
            } else {
                res += 1L;
                n = ~n;
            }
        }

        out.println(res);

    }

}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream));
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

}

import java.io.*;
import java.math.BigInteger;

import java.util.*;

public class Main {
    static long n, h;

    public static boolean inThisDes(boolean left) {
        return left ? n <= Math.pow(2, h - 1) : n > Math.pow(2, h - 1);
    }

    public static void main(String[] args) throws IOException {
        InputReader in = new InputReader(System.in);
        FastPrinter out = new FastPrinter(System.out);
        boolean left = true;
        h = in.nextLong();
        n = in.nextLong();
        long count = 0;
        while (h != 0) {
            if (inThisDes(left)) {
                left = !left;
                count++;
            } else
                count += Math.pow(2, h);
            h--;
            if (left)
                n -= Math.pow(2, h);
        }
        out.println(count);
        out.close();
    }
}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public String nextLine() {
        try {
            return reader.readLine();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

    public double nextDouble() {
        return Double.parseDouble(next());
    }

    public BigInteger nextBigInt() {
        return new BigInteger(next());
    }
}

class FastPrinter extends PrintWriter {

    public FastPrinter(OutputStream out) {
        super(out);
    }

    public FastPrinter(Writer out) {
        super(out);
    }

}

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

import java.util.Scanner;

/**
 *
 * @author fz
 */
public class CF_287C {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        long h = sc.nextLong();
        long k = sc.nextLong();
        System.out.println(recur(h, k, true));

    }
    public static long recur(long h, long k, boolean left) {
        if(h == 1) {
            if(k == 1 && left)
                return 1L;
            else if(k == 2 && !left)
                return 1L;
            else
                return 2L;
        }
        long val = pow2(h - 1);
        if(k > val) {
            if(left)
                return 2 * val + recur(h - 1, k - val, left);
            else
                return 1 + recur(h - 1, k - val, !left);
        }
        else {
            if(left)
                return 1 + recur(h - 1, k, !left);
            else
                return 2 * val + recur(h - 1, k, left);

        }

    }
    public static long pow2(long h) {
        long res = 1;
        for(long i = 0; i < h; i++)
            res = res * 2;
        return res;
    }
}

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class GuessYourWayOut {
	static long n;
	static int height;
	static final int L = 0;
	static final int R = 1;

	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);

		height = sc.nextInt();
		n = sc.nextLong();

		System.out.println(rec(height, L));
	}

	public static long rec(int h, int inst) {
		if (h == 0) return 0;

		long half = ((long)1 << h);
		half /= 2;
		if (n <= half) { // exit on left
			if (inst == L)
				return rec(h-1, R) + 1;
			else {
				long nodes =  ((((long)1 << (h+1)) - 1) / 2);

				return rec(h-1, R) + nodes + 1;
			}
		}
		else { // exit on right
			if (inst == L) {
				long nodes = ((((long)1 << (h+1)) - 1) / 2);
				n -= half;
				return rec(h-1, L) + nodes + 1;
			}
			else {
				n -= half;
				return rec(h-1, L) + 1;
			}
		}
	}

	static class Scanner {
		BufferedReader br;
		StringTokenizer st;

		public Scanner(FileReader f) {
			br = new BufferedReader(f);
		}

		public Scanner(InputStream in) {
			br = new BufferedReader(new InputStreamReader(in));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public String nextLine() throws IOException {
			return br.readLine();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public double nextDouble() throws IOException {
			return Double.parseDouble(next());
		}

		public boolean Ready() throws IOException {
			return br.ready();
		}

		public void waitForInput(long time) {
			long ct = System.currentTimeMillis();
			while(System.currentTimeMillis() - ct < time) {};
		}

	}
}

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int h=sc.nextInt();
        double n=sc.nextDouble();
        System.out.printf("%.0f",1+caso1(h, n));
        System.out.println("");
    }
    public static double caso1(int h, double n){
        if(h==1){
            return n%2==0?1:0;
        }
        double canNodosVis=(Math.pow(2, h+1)/2);
        double canHojas=Math.pow(2, h);
        if(n>canHojas/2){
            n=n-canHojas/2;
            return canNodosVis+caso1(h-1,n);
        }
        return 1+caso2(h-1,n);
    }
    public static double caso2(int h,double n){
        if(h==1){
            return n%2;
        }
        double canNodosVis=(Math.pow(2, h+1)/2);
        double canHojas=Math.pow(2, h);
        if(n<=canHojas/2){
            return canNodosVis+caso2(h-1,n);

        }
        n=n-canHojas/2;
        return 1+caso1(h-1,n);
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class GuessYourWayOut {

	static final int L = 0, R = 1;
	static long[] nodes;

	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

		StringTokenizer s = new StringTokenizer(in.readLine());

		int h = Integer.parseInt(s.nextToken());
		long n = Long.parseLong(s.nextToken());

		nodes = new long[51];
		nodes[0] = 1;
		for (int i = 1; i < 51; i++) {
			nodes[i] = nodes[i - 1] + (long) Math.pow(2, i);
		}

		System.out.println(count(h, n, L));

	}

	public static long count(int h, long exit, int direction){
		if(h == 0)
			return 0;

		int exitDirection = (exit <= ((long) Math.pow(2, h) / 2))? L : R;

		long res = 1;

		if(exitDirection != direction) {
			res += nodes[h - 1];
		}

		long newExit = exit;
		if(exitDirection == R)
			newExit = exit - ((long) Math.pow(2, h) / 2);

		exitDirection++;
		exitDirection %= 2;

		return res + count(h - 1, newExit, exitDirection);
	}
}

import java.io.*;
import java.util.*;
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(in, out);
        out.close();
    }
}

class TaskC {

    public void solve(InputReader in, OutputWriter out) {
        long h = in.nextLong();
        long n = in.nextLong();
        long numberOfLeafs = (long) Math.pow(2, h);
        long count = 0;
        char last = 'R';
        while(numberOfLeafs > 1) {
            if(last == 'R') {
                 if(n > numberOfLeafs / 2 ) {
                    count += get(numberOfLeafs / 2);
                } else{
                    count += 1;
                    numberOfLeafs /= 2;
                }
                last = 'L';
            } else {
                if(n <= numberOfLeafs / 2) {
                    count += get(numberOfLeafs / 2);
                } else {
                    count+= 1;
                    numberOfLeafs /= 2;
                    n -= (numberOfLeafs);
                }
                last = 'R';
            }
        }
        out.printLine(count);
    }

    private long get(long numberOfLeafs) {
        long value = numberOfLeafs;
        while(numberOfLeafs > 0) {
            numberOfLeafs /= 2;
            value += numberOfLeafs;
        }
        return value;
    }

}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;
    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }
    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }
    public boolean hasNext() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                String line = reader.readLine();
                if ( line == null ) {
                    return false;
                }
                tokenizer = new StringTokenizer(line);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return true;
    }
    public int nextInt() {
        return Integer.parseInt(next());
    }
    public long nextLong() {
        return Long.parseLong(next());
    }
    public double nextDouble() { return Double.parseDouble(next());}
}
class OutputWriter {
    private final PrintWriter writer;
    public OutputWriter(OutputStream outputStream) {
        writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
    }
    public OutputWriter(Writer writer) {
        this.writer = new PrintWriter(writer);
    }
    public void print(Object... objects) {
        for (int i = 0; i < objects.length; i++) {
            if ( i != 0 ) {
                writer.print(' ');
            }
            writer.print(objects[i]);
        }
    }
    public void printLine(Object... objects) {
        print(objects);
        writer.println();
    }
    public void close() {
        writer.close();
    }
}

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.io.ObjectInputStream.GetField;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TimeZone;
import java.util.TreeMap;
import java.text.*;

public class Main {
	static int h;

	public static void main(String[] args) {
		FastReader in = new FastReader();
		PrintWriter out = new PrintWriter(System.out);
		h = in.nextInt();
		long n = in.nextLong();
		long res = solve(1, 'L', (long) Math.pow(2, h), n);
		out.println(res);
		out.close();
	}

	public static long solve(int level, char dir, long leafs, long pos) {
		if (level == h + 1)
			return 0;
		char d;
		if (pos > leafs / 2l)
			d = 'R';
		else
			d = 'L';
		long path1 = -1, path2 = -1;
		if (dir == d)
			path1 = 1 + solve(level + 1, dir == 'L' ? 'R' : 'L', leafs / 2l, (d == 'R') ? pos - leafs / 2l : pos);
		else {
			long r = (long) Math.pow(2, h + 1 - level);
			path2 = r + solve(level + 1, dir, leafs / 2l, (d == 'R') ? pos - leafs / 2l : pos);
		}
		return path1 == -1 ? path2 : path1;

	}
}

class FastReader {
	BufferedReader br;
	StringTokenizer st;

	public FastReader() {
		br = new BufferedReader(new InputStreamReader(System.in));

	}

	public FastReader(File f) throws FileNotFoundException {
		br = new BufferedReader(new FileReader(f));
	}

	String next() {
		while (st == null || !st.hasMoreElements()) {
			try {
				st = new StringTokenizer(br.readLine());

			} catch (IOException e) {
				e.printStackTrace();
			}

		}

		return st.nextToken();

	}

	int nextInt() {

		return Integer.parseInt(next());
	}

	double nextDouble() {

		return Double.parseDouble(next());
	}

	long nextLong() {

		return Long.parseLong(next());
	}

	String nextLine() {
		String str = "";
		try {
			str = br.readLine();

		} catch (IOException e) {

			e.printStackTrace();
		}
		return str;

	}
}

import java.io.*;
import java.math.BigInteger;

import java.util.*;

public class Main {
    static long n, h;

    public static boolean inThisDes(boolean left) {
        return left ? n <= Math.pow(2, h - 1) : n > Math.pow(2, h - 1);
    }

    public static void main(String[] args) throws IOException {
        InputReader in = new InputReader(System.in);
        FastPrinter out = new FastPrinter(System.out);
        boolean left = true;
        h = in.nextLong();
        n = in.nextLong();
        long count = 0;
        while (h != 0) {
            if (inThisDes(left)) {
                if (!left)
                    n -= Math.pow(2, h - 1);
                left = !left;
                count++;
                h--;
            } else {
                if (left)
                    n -= Math.pow(2, h - 1);
                count += Math.pow(2, h);
                h--;
            }
        }
        out.println(count);
        out.close();
    }
}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public String nextLine() {
        try {
            return reader.readLine();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

    public double nextDouble() {
        return Double.parseDouble(next());
    }

    public BigInteger nextBigInt() {
        return new BigInteger(next());
    }
}

class FastPrinter extends PrintWriter {

    public FastPrinter(OutputStream out) {
        super(out);
    }

    public FastPrinter(Writer out) {
        super(out);
    }

}

import java.io.*;
import java.util.*;
import java.math.*;

public class Main {

    FastScanner in;
    PrintWriter out;

    static class FastScanner {

        BufferedReader br;
        StringTokenizer st;

        FastScanner(InputStream in) {
            br = new BufferedReader(new InputStreamReader(in));
            st = null;
        }

        String next() throws IOException {
            while (st == null || !st.hasMoreTokens())
                st = new StringTokenizer(br.readLine());
            return st.nextToken();
        }

        String nextLine() throws IOException {
            if (st == null || !st.hasMoreTokens())
                return br.readLine();
            StringBuilder result = new StringBuilder(st.nextToken());
            while (st.hasMoreTokens()) {
                result.append(" ");
                result.append(st.nextToken());
            }
            return result.toString();
        }

        int nextInt() throws IOException {
            return Integer.parseInt(next());
        }

        long nextLong() throws IOException {
            return Long.parseLong(next());
        }

        double nextDouble() throws IOException {
            return Double.parseDouble(next());
        }

    }

    void run() throws IOException {
        in = new FastScanner(System.in);
        out = new PrintWriter(System.out, false);
        solve();
        out.close();
    }

    public static void main(String[] args) throws IOException{
        new Main().run();
    }

    public void printArr(int[] arr){
        for(int i = 0; i < arr.length; i++){
            out.print(arr[i] + " ");
        }
        out.println();
    }

    public long gcd(long a, long b){
        if(a == 0) return b;
        return gcd(b % a, a);
    }

    public boolean isPrime(long num){

        if(num == 0 || num == 1){
            return false;
        }

        for(int i = 2; i * i <= num; i++){
            if(num % i == 0){
                return false;
            }
        }

        return true;
    }

    public void solve() throws IOException{

        long res = 0L;
        long h = in.nextLong();
        long n = in.nextLong() + (1L << h) - 1; // adjustment make sense
        HashMap<Long, Long> tgtPath = new HashMap<>();

        //out.println(n);

        long height = 0L;
        long cur = n;
        while(cur != 0){
            tgtPath.put(cur, height);
            cur /= 2;
            height++;
        }

        long prevHeight = h;
        long dir = 0L;
        long node = 1L;
        long counter = 0L;

        while(node != n){

            //out.println("curNode" + node + " dir " + dir + " prevHeight " + prevHeight + " res " + res);

            // search from top to bottom and reset to the end
            List<Long> path = new ArrayList<>();

            while(node <= ((1L << h) - 1)){ // not a leaf node

                path.add(node);
                node = 2 * node + dir;
                dir = 1 - dir;

            }

            path.add(node);
            //out.println("ending node: " + node + " normalized: " + (node - (1 << h) + 1) + "upper bonud " + (((1 << h) - 1)));

            for(int i = path.size() - 1; i >= 0; i--){

                long anc = path.get(i);
                  if(anc == n){
                    res += prevHeight;
                    node = n;
                    //out.println("FOUND AND BROKE");
                    break;
                }

                if(tgtPath.containsKey(anc)){
                    //out.println("same ancestor" + anc);
                    long lcaHeight = tgtPath.get(anc);
                    //out.println("LCA: " + anc + " LCA height :" + lcaHeight);
                    res = res + (1L << lcaHeight) - 1 + prevHeight - lcaHeight;
                    prevHeight = lcaHeight;
                    boolean isTgtOnLeft = node > n;
                    node = isTgtOnLeft ? (anc * 2) : (anc * 2 + 1);// redefine node
                    if(node == n){ res++; }
                    dir = isTgtOnLeft ? 1L : 0L;// redfine dir
                    break;
                }
            }

        }

        out.println(res);

        return;
    }

}

//package CF;
import java.io.*;
import java.util.*;
public class C {

	public static void main(String[] args) throws IOException   {
		Scanner bf = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);
		int h = bf.nextInt();
		long n = bf.nextLong();
		long [] nodes = new long[h+1];
		nodes[h] = (1L<<h)-1+n;
		for (int i = h-1; i >= 0; i--) {
			nodes[i] = nodes[i+1]/2;
		}
		int dir = 0;
		long node = 1L;
		long res = 0L;
		for (int i = 1; i < nodes.length; i++) {
			long next = 2*node + dir;
			if(next == nodes[i])
				dir ^= 1;
			else{
				res += (1L << (h-i+1))-1;
			}
			node = nodes[i];
			res++;
		}
		out.println(res);
		out.flush();
		out.close();
	}
	/** static class newType implements Comparable{
	int a;
	int b;
	public newType(int a,int b){
	    this.a = a;
	    this.b = b;

	}
	public int compareTo(newType t){
	    if(a != t.a)
		return a - t.a;
	    return b - t.b;

	}
    }**/
	static class Scanner
	{
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s){	br = new BufferedReader(new InputStreamReader(s));}

		public String next() throws IOException
		{
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException {return Integer.parseInt(next());}

		public long nextLong() throws IOException {return Long.parseLong(next());}

		public String nextLine() throws IOException {return br.readLine();}

		public double nextDouble() throws IOException
		{
			String x = next();
			StringBuilder sb = new StringBuilder("0");
			double res = 0, f = 1;
			boolean dec = false, neg = false;
			int start = 0;
			if(x.charAt(0) == '-')
			{
				neg = true;
				start++;
			}
			for(int i = start; i < x.length(); i++)
				if(x.charAt(i) == '.')
				{
					res = Long.parseLong(sb.toString());
					sb = new StringBuilder("0");
					dec = true;
				}
				else
				{
					sb.append(x.charAt(i));
					if(dec)
						f *= 10;
				}
			res += Long.parseLong(sb.toString()) / f;
			return res * (neg?-1:1);
		}

		public boolean ready() throws IOException {return br.ready();}
	}

}

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class C {

    static StringTokenizer st;
    static BufferedReader br;
    static PrintWriter pw;
    public static void main(String[] args) throws IOException {
        br = new BufferedReader(new InputStreamReader(System.in));
        pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        int h = nextInt();
        long n = nextLong();
        long ans = 0;
        long[]pow = new long[h+1];
        pow[0] = 1;
        for (int i = 1; i <= h; i++) {
            pow[i] = pow[i-1] * 2;
        }
        long[]sum = new long[h+1];
        sum[0] = 1;
        for (int i = 1; i <= h; i++) {
            sum[i] = sum[i-1] + pow[i];
        }
        boolean left = true;
        while (h > 0) {
            long half = pow[h] / 2;
            if (left) {
                if (n > half) {
                    ans += sum[h-1]+1;
                    n -= half;
                }
                else {
                    ans++;
                    left = false;
                }
            }
            else {
                if (n > half) {
                    ans++;
                    n -= half;
                    left = true;
                }
                else {
                    ans += sum[h-1]+1;
                }
            }
            h--;
        }
        System.out.println(ans);
        pw.close();
    }
    private static int nextInt() throws IOException {
        return Integer.parseInt(next());
    }
    private static long nextLong() throws IOException {
        return Long.parseLong(next());
    }
    private static double nextDouble() throws IOException {
        return Double.parseDouble(next());
    }
    private static String next() throws IOException {
        while (st==null || !st.hasMoreTokens())
            st = new StringTokenizer(br.readLine());
        return st.nextToken();
    }
}

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.StringTokenizer;

    public class Main{
        public static void main(String[] args) {
            InputStream inputStream = System.in;
            InputReader in = new InputReader(inputStream);
            TaskC solver = new TaskC();
            solver.solve(1, in);
        }
    }
class TaskC{
    static int kl;
    public void solve(int numb, InputReader in){
        long lvl = Long.parseLong(in.next());
        long kl = 0;
        long index = Long.parseLong(in.next());
        obx(lvl,index,0,1);
    }
    public void obx(long lvl, long ind, long kl, long current){
        if (lvl == 0){
            System.out.print(kl);
            return;
        }
        long all = 0;
        for(long i  = 0; i < lvl+1;i++) all += (long) Math.pow(2.0, i);
        all -= 1;
        if (ind > Math.pow(2.0, lvl)/2){
            if (current == 1){
                kl += all/2 + 1;
            }
            else{
                kl += 1;
                current *= -1;
            }
            obx(lvl-1,ind-(long)Math.pow(2.0, lvl)/2,kl,current);
        }
        else {
            if (current == -1) {
                kl += all / 2 + 1;
            } else {
                kl += 1;
                current *= -1;
            }
            obx(lvl - 1, ind,kl, current);
        }
    }
}
class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

}

import java.util.Scanner;
public class GuessYourWayOut {
    public static void main(String[] args)
    {
        Scanner cin = new Scanner(System.in);
        long h = cin.nextInt();
        long n = cin.nextLong();
        long[] a = getResult(h,n);
        System.out.println(a[0]);
    }

    public static long getParent(long n)
    {
        return (n+1)/2;
    }

    public static long[] getResult(long h , long n)
    {
        long[] a = new long[2];
        a[0] = 0 ;
        a[1] = 0;
        if(h == 1)
        {
            if(n == 1)
            {
                a[0] = 1;
                a[1] = 0;
            }
            else
            {
                a[0] = 2;
                a[1] = 1;
            }
            return a ;
        }

        long p = getParent(n);
        a = getResult(h-1 , p);

        if(p % 2 == n % 2)
        {
            a[1] = a[1] * 2 + 1;
            a[0] = a[0] + a[1];
        }
        else
        {
            a[1] = a[1] * 2;
            a[0] = a[0] + a[1];
        }
        a[0] ++ ;
        return a ;
    }
}

import java.util.Scanner;

public class CF287C {

	static long n;
	static long count;

	private static long twoPow(long p) {
		return ((long) 1) << (p);
	}

	private static void solve(long h, boolean isLeft) {
		if (h==0) return;
		if ((isLeft && twoPow(h - 1) < n) || (!isLeft && twoPow(h - 1) >= n)) {
			count += twoPow(h) - 1;
			isLeft = !isLeft;
		}
		count++;
		if (n > twoPow(h - 1))
			n -= twoPow(h - 1);
		//System.out.println(count);
		solve(h - 1, !isLeft);

	}

	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		long h = scan.nextInt();
		count = 0;
		n = scan.nextLong();
		solve(h, true);
		System.out.println(count);

	}
}

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;

public class C {
  public static void main(String[] args) throws Exception {
    BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    PrintWriter out = new PrintWriter(System.out);
    String[] part = in.readLine().split(" ");
    long h = Long.parseLong(part[0]);
    long n = Long.parseLong(part[1]);
    out.println(count(h, n, true));
    out.close();
    in.close();
  }

  static long count(long h, long n, boolean left) {
    if (h == 1) {
      if (n == 1 && left || n == 2 && !left)
        return 1;
      else
        return 2;
    }
    long leaf = (long) Math.pow(2, h);
    if (n <= leaf / 2) {
      long t = count(h - 1, n, false);
      if (!left)
        t += (long) (Math.pow(2, h + 1) - 2) / 2;
      return t + 1;
    } else {
      n -= leaf / 2;
      long t = count(h - 1, n, true);
      if (left)
        t += (long) (Math.pow(2, h + 1) - 2) / 2;
      return t + 1;
    }
  }
}

import java.util.Scanner;

public class Guess {

	public static void main(String args[]) {
		Scanner s = new Scanner(System.in);
		int h = s.nextInt();
		long n = s.nextLong();

		long start = 1, end = (long) Math.pow(2, h);

		long left = end / 2, right = left + 1;
		long curr = h;

		char move = 'L';
		long moves = 1;
		long total = (long) Math.pow(2, h + 1) - 2;

		while (curr != 0) {
		//	System.out.println("cc " + curr + " moves " + moves);
			if (n <= left) {
				if (move == 'L') {
					moves++;
					move = 'R';
					end = left;
					left = start + (end - start) / 2;
					right = left + 1;
					total = total / 2;
					curr--;
					// left = left / 2;
				} else {
					// cover all right nodes;
					moves += total / 2;
					move = 'L';
				}
			} else {
				if (move == 'R') {
					moves++;
					move = 'L';
					start = right;
					left = start + (end - start) / 2;
					right = left + 1;
					total = total / 2;
					curr--;
				} else {
					move = 'R';
					moves += total / 2;
				}
			}
		}

		System.out.println(moves - 1);
		s.close();
	}
}

//package _287;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class C {

	static long cnt = 0;
	static char cur = 'L';

	public static long[] readNums( String str ){
		String[] aux = str.split(" ");
		long[] nums = new long[ aux.length ];
		for( int i = 0; i < aux.length; i++ )
			nums[i] = Long.parseLong( aux[i] );
		return nums;
	}

	public static void solve( long h, long n ){
		if( h == 0 ) return;
		long aux = (long) Math.pow( 2, h );
		char side = ( n <= aux / 2l) ? 'L' : 'R';
		long newN = ( side == 'L' ) ? n : n - (aux / 2l);
		if( side == cur ){
			cnt++;
			if( cur == 'L' ) cur = 'R';
			else cur = 'L';
		}
		else{
			cnt += aux;
		}
		solve( h - 1, newN );
	}

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader( new InputStreamReader( System.in ) );
		long[] nums = readNums( br.readLine() );
		solve( nums[0], nums[1] );
		System.out.println( cnt );
	}

}

import java.util.Scanner;

public class Solution {

    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        int h = cin.nextInt();
        long leaf = cin.nextLong() - 1;
        System.out.println(countNodes(h, leaf));
        cin.close();
    }

    private static long countNodes(long h, long leaf) {
        long low = 0, high = (1L << h) - 1;
        long count = 0;
        boolean goLeft = true;
        while (low < high) {
            long mid = low + (high - low) / 2;
            if (goLeft != (low <= leaf && leaf <= mid)) {
                count += (1L << h) - 1;
                goLeft = !goLeft;
            }
            if (low <= leaf && leaf <= mid) {
                high = mid;
            } else {
                low = mid + 1;
            }
            goLeft = !goLeft;
            count++;
            --h;
        }
        return count;
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class GuessYourWayOut {
	public static void main(String[] args) throws IOException {
		BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(bf.readLine());
		int h = Integer.parseInt(st.nextToken());
		long n = Long.parseLong(st.nextToken());
		long dist = n + (1L << h) - 1;
		long[] path = new long[h + 1];
		path[h] = dist;
		for (int i = h - 1; i >= 0; i--)
			path[i] = path[i + 1] / 2;
		long ans = h;
		int level = 0;
		int dir = 0;
		for (int i = 0; i < path.length - 1; i++) {
			long nxt = (path[i] * 2) + dir;
			level++;
			if (nxt != path[i + 1]) {
				ans += (1L << (h - level + 1)) - 1;
			} else {

				dir = dir ^ 1;
			}
		}
		System.out.println(ans);
	}
}

import java.util.*;
import java.io.*;

public class Main {

	BufferedReader in;
	StringTokenizer str = null;
	PrintWriter out;

	private String next() throws Exception{
		while (str == null || !str.hasMoreElements())
			str = new StringTokenizer(in.readLine());
		return str.nextToken();
	}

	private int nextInt() throws Exception{
		return Integer.parseInt(next());
	}

	private long nextLong() throws Exception{
		return Long.parseLong(next());
	}

	private double nextDouble() throws Exception{
		return Double.parseDouble(next());
	}

	public void run() throws Exception{
		in =  new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);
		int h = nextInt();
		long n = nextLong();
		long r = go(h, 'L', 1, 1L<<h, n);
		out.println(r);
		out.close();
	}

	private long go(int h, char dir, long left, long right, long n) {
		// System.out.println(h + " "  + dir + " " + left + " " + right + " " + n);
		if (h == 0) return 0;
		if (dir == 'L') {
			if (left <= n && n <= (left + right) / 2 ) {
				return go(h - 1, 'R', left, (left + right) / 2, n) + 1;
			}else {
				return (1L << h) + go(h - 1, 'L', (left + right) / 2 + 1, right, n);
			}
		}else {
			if ((left + right) / 2 + 1 <= n && n <= right) {
				return go(h - 1,'L', (left + right) / 2 + 1, right, n) + 1;
			}else {
				return (1L << h) + go(h - 1, 'R', left, (left + right) / 2, n);
			}
		}
	}

	public static void main(String[] args) throws Exception{
		new Main().run();
	}
}

import java.io.*;
import java.util.*;

/**
 *
 * @author PRAVEER SATYAM
 */
public class CODETWO {
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer stz = new StringTokenizer(br.readLine());
        long h = Long.parseLong(stz.nextToken());
        long n = Long.parseLong(stz.nextToken());n--;
        int st = (int)Math.pow(2,h)-1;
        long t =1;
        int end = st+(int)Math.pow(2, h)-1;
        int po = (int)(int)Math.pow(2, h)/2;
        //System.out.pritnln(mid+" "+st+" "+po);
        int mid = (st-1)+po;
        long s=0, k=0;
        //System.out.println(mid+" "+st+" "+po+" "+end);
        while(h-->0){
            if(((n>>h)&1)!=k)s+=1L<<(h+1);
            else
            {s++; k^=1;}
        }
        System.out.println(s);
    }
}

import java.io.*;
import java.util.*;
public class CF_507C {
    public static void main(String[] args) throws IOException {
        new CF_507C().solve();
    }

    long f(long ind, long h, boolean startsLeft){
        if (h==1) return 1;
        boolean targetInLeft=ind<(1L<<(h-2));
        long newInd=ind-(targetInLeft? 0 : (1L<<(h-2)) );
        long alsoVisit=(targetInLeft ^ startsLeft) ? (1L<<(h-1))-1 : 0;
        long res=1+ alsoVisit+f(newInd, h-1, !targetInLeft);
//        System.out.println(ind+" "+h+" "+startsLeft+" "+targetInLeft+" : "+res);
        return res;
    }

    void solve() throws IOException{

        InputStream in = System.in;
        PrintStream out = System.out;

//        in = new FileInputStream("in.txt");
//        out = new PrintStream("out.txt");

        Scanner sc=new Scanner(in);
        long h=sc.nextLong()+1, n=sc.nextLong()-1;
        out.println(f(n, h, true)-1);

    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class C507C {
	private StringTokenizer st;
	private BufferedReader bf;
	private int m;
	private int goal;
	private int cnt;
	private int skip;
	private boolean[] a;

	public C507C() {
		try {
			bf = new BufferedReader(new InputStreamReader(System.in));
			st = new StringTokenizer(bf.readLine());

			int h = nextInt();
			int n = nextInt();

			m = 0;
			for (int i=0;i<=h;i++) {
				m += (int)Math.pow(2, i);
			}
			int k = 0;
			goal = 0;
			for (int i=0;i<h;i++) {
				k += (int)Math.pow(2, i);
			}
			goal = k + n;
//			a = new boolean[m+1];

			search(1, false);

			System.out.println(cnt);

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private boolean search(int ci, boolean f) {
		int nexti;

		if (ci == goal)
			return true;

		cnt++;
//		a[ci] = true;

		if ((ci * 2) > m)
			return false;

		for (int i=0;i<2;i++) {
			if (f) {
				//right
				nexti = ci * 2 + 1;
			} else {
				//left
				nexti = ci * 2;
			}

			if ((ci * 2) > m)
				return false;

//			if (a[nexti]) {
//				skip++;
//				if (skip==2) {
//					skip = 0;
//					return false;
//				}
//			} else {
				f = !f;
				if (search(nexti, f))
					return true;
//			}
		}
		return false;
	}

	private int nextInt() throws IOException {
		return Integer.parseInt(next());
	}

	private String next() throws IOException {
		if (st == null || !st.hasMoreTokens())
			st = new StringTokenizer(bf.readLine());
		return st.nextToken();
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		C507C c = new C507C();
	}

}

import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.util.StringTokenizer;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author Alexey Potapov
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }
}

class TaskC {

    public int n, h;

    public long[] step = new long [51];

    public long goExit(int level, int command) {

        if (level == h) {
            return 0;
        }

        long cnt = step[h - level - 1];

        if (command == 0) {

            long up = 1;

            command = 1;
            if (cnt < n) {
                up += step[h - level] - 1;
                n -= cnt;
                command = 0;
            }

            return up + goExit(level + 1, command);

        } else {

            long up = 1;

            command = 0;
            if (cnt >= n) {
                up += step[h - level] - 1;
                command = 1;
            }

            return up + goExit(level + 1, command ^ 1);

        }

    }

    public void init() {
        step[0] = 1;
        for (int i = 1; i < h + 1; i++) {
            step[i] = step[i - 1] * 2;
        }
    }

    public void solve(int testNumber, InputReader in, PrintWriter out) {

        this.h = in.nextInt();
        this.n = in.nextInt();

        init();

        out.print(goExit(0, 0));

    }
}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

}

import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author Tifuera
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskC solver = new TaskC();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskC {

    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int h = in.nextInt();
        long n = in.nextLong();

        long result = 0;

        int lvl = 0;
        boolean goLeft = true;
        while (lvl < h) {
            long half = 1L << (h - lvl - 1);
            if (n > half) {
                if (goLeft) {
                    long tmp = (1L << (h - lvl)) - 1;
                    result += tmp + 1L;
                    n -= half;
                } else {
                    result++;
                    goLeft = true;
                }

            } else {
                if (goLeft) {
                    result++;
                    goLeft = false;
                } else {
                    long tmp = (1L << (h - lvl)) - 1;
                    result += tmp + 1L;
                    goLeft = true;
                }
            }
            lvl++;
        }

        out.println(result);
    }

}

class InputReader {
    private BufferedReader reader;
    private String[] currentArray;
    private int curPointer;

    public InputReader(InputStream inputStream) {
        reader = new BufferedReader(new InputStreamReader(inputStream));
    }

    public int nextInt() {
        if ((currentArray == null) || (curPointer >= currentArray.length)) {
            try {
                currentArray = reader.readLine().split(" ");
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            curPointer = 0;
        }
        return Integer.parseInt(currentArray[curPointer++]);
    }

    public long nextLong() {
        if ((currentArray == null) || (curPointer >= currentArray.length)) {
            try {
                currentArray = reader.readLine().split(" ");
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            curPointer = 0;
        }
        return Long.parseLong(currentArray[curPointer++]);
    }
}

import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskC solver = new TaskC();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskC {
    public void solve(int testNumber, InputReader in, PrintWriter out) {
        long h = in.nextInt();
        long n = in.nextLong();
        long max = (1L << (h));
        long ans = ways(1L, max, h, n, true);
        out.println(ans);
    }

    private long ways(long min, long max, long h, long n, boolean left) {
        if (min == max) {
            return 0L;
        }
        long mid = (min + max) / 2L;
        if (left) {
            if (n <= mid) {
                return 1L + ways(min, mid, h - 1, n, !left);
            } else {
                long rest = h > 0 ? ((1 << h) - 1L) : 0L;
                return 1L + rest + ways(1L + mid, max, h - 1, n, left);
            }
        } else {
            if (n<=mid){
                long rest = h > 0 ? ((1 << h) - 1L) : 0L;
                return 1L + rest + ways(min, mid, h - 1, n, left);
            } else {
                return 1L + ways(mid+1L, max, h-1, n, !left);
            }
        }

    }
}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }
}

import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;

public class Solution{

	public static void main(String[] args){
		Scanner scan = new Scanner(System.in);
		long h = scan.nextLong();
		long exit = scan.nextLong() - 1;
		long count = 0;
		boolean leftFirst = true;
		int base = 1;
		while(h > 0){
			count ++;
			if(leftFirst && exit < (base << (h - 1))){
				leftFirst = false;
			} else if(leftFirst && exit >= (base << (h - 1))){
				leftFirst = true;
				count += ((base << h) - 1);
			} else if(exit < (base << (h - 1))){
				leftFirst = false;
				count += ((base << h) - 1);
			} else{
				leftFirst = true;
			}
			exit = exit % (base << (h - 1));
			h --;
		}
		System.out.println(count);
		scan.close();
	}
}

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.BufferedWriter;
import java.util.InputMismatchException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.NoSuchElementException;
import java.io.Writer;
import java.math.BigInteger;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author Stanislav Pak
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }
}

class TaskC {
    public void solve(int testNumber, InputReader in, OutputWriter out) {
        long h = in.readInt();
        long n = in.readInt();
        long l = 1;
        long r = 1L << h;
        long ans = 0;
        boolean left = true;
        while (l < r) {
            long m = (l + r) >> 1;
            if (n <= m) {
                if (left) {
                    ++ans;
                } else {
                    ans += r - l + 1;
                }
                r = m;
                left = false;
            } else {
                if (left) {
                    ans += r - l + 1;
                } else {
                    ++ans;
                }
                l = m + 1;
                left = true;
            }
        }
        out.printLine(ans);
    }
}

class InputReader {

    private InputStream stream;
    private byte[] buf = new byte[1024];
    private int curChar;
    private int numChars;
    private SpaceCharFilter filter;

    public InputReader(InputStream stream) {
        this.stream = stream;
    }

    public int read() {
        if (numChars == -1)
            throw new InputMismatchException();
        if (curChar >= numChars) {
            curChar = 0;
            try {
                numChars = stream.read(buf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (numChars <= 0)
                return -1;
        }
        return buf[curChar++];
    }

    public int readInt() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        int res = 0;
        do {
            if (c < '0' || c > '9')
                throw new InputMismatchException();
            res *= 10;
            res += c - '0';
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }

    public boolean isSpaceChar(int c) {
        if (filter != null)
            return filter.isSpaceChar(c);
        return isWhitespace(c);
    }

    public static boolean isWhitespace(int c) {
        return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
    }

    public interface SpaceCharFilter {
        public boolean isSpaceChar(int ch);
    }
}

class OutputWriter {
    private final PrintWriter writer;

    public OutputWriter(OutputStream outputStream) {
        writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
    }

    public void close() {
        writer.close();
    }

    public void printLine(long i) {
        writer.println(i);
    }

}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.StringTokenizer;

public class C287 {

	public static void main(String[] args) throws IOException {
		skp();
		int h = nextInt();
		long n = nextLong() - 1;
		long counter = 0;
		int curr = 0;
		for (int i = h; i >= 1; i--) {
			// System.out.println(((n>>(i-1))&1L)+" "+curr+" "+i+" "+Long.toBinaryString(n)+" "+(1<<i));
			if (((n >> (i - 1)) & 1L) == curr) {
				counter++;
				curr = curr ^ 1;
			} else {
				counter = counter + (1 << i);

			}

		}
		System.out.println(counter);
	}

	static boolean skp() throws IOException {
		String line = r.readLine();
		if (line == null)
			return false;
		tkn = new StringTokenizer(line);
		return true;
	}

	static int nextInt() {
		return Integer.parseInt(tkn.nextToken());
	}

	static int readInt() throws NumberFormatException, IOException {
		return Integer.parseInt(r.readLine());
	}

	static long nextLong() {
		return Long.parseLong(tkn.nextToken());
	}

	static long readLong() throws NumberFormatException, IOException {
		return Long.parseLong(r.readLine());
	}

	static double nextDouble() {

		return Double.parseDouble(tkn.nextToken());
	}

	static BufferedReader r = new BufferedReader(new InputStreamReader(
			System.in));
	static StringTokenizer tkn;
}

import java.util.*;
import java.lang.*;
import java.io.*;

public class Trees
{
	public static void main (String[] args) throws java.lang.Exception
	{
		long t,h,n;
		Scanner sc = new Scanner(System.in);
		//t=sc.nextInt();
		//while(t!=0)
		//{
			//t--;
			h=sc.nextLong();
			n=sc.nextLong();
			long leaf = 1<<(h);
			long up,low,ans=0;
			boolean dir = true; // true = left, false = right
			up = leaf;
			low = 1;
			while(up>low && h>0)
			{
				long mid = (up+low)/2;
				long uc=up,lc=low;
				if(dir)
					uc=mid;
				else
					lc=mid+1;
				if(n<=uc && n>=lc)
				{
					up=uc;
					low=lc;
					dir=!dir;
					ans++;
				}
				else
				{
					long nodes = (1<<(h));
					ans+=nodes;
					if(dir)
						low=mid+1;
					else
						up=mid;

				}
				h--;
			}
			System.out.println(ans);
		//}
	}
}

import java.io.*;
import java.util.*;

public class SolutionB {
	public void solve(){
		long h = nextLong(), id = nextLong();
		out.println(f(h, id, true));
	}
	public long f(long h, long id, boolean left){
		if(h == 1){
			if(left && id == 1 || !left && id == 2) return 1;
			return 2;
		}
		long res = 1;
		if(id > 1<<(h-1)){
			if(left) res+= sum(h);
			id-= 1<<(h-1);
			return res + f(h-1, id, true);
		}
		if(!left) res+= sum(h);
		return res + f(h-1, id, false);
	}
	public long sum(long h){
		long res = 0, level = 1;
		while(h > 0){
			h--;
			res += level;
			level<<=1;
		}
		return res;
	}
	class Song implements Comparable<Song>{
		int id, days;
		public Song(int id, int days){
			this.id = id;
			this.days = days;
		}
		public int compareTo(Song other){
			return Integer.compare(days, other.days);
		}
	}
	public void run(){
		solve();
		out.close();
	}
	public static void main(String args[]){
		new SolutionB().run();
	}
	BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
	PrintWriter out = new PrintWriter(System.out);
	String line;
	StringTokenizer st;
	public String nextLine(){
		try {
			line = bf.readLine();
			st = new StringTokenizer(line);
		} catch (IOException e) {
			return null;
		}
		return line;
	}
	public String nextString(){
		while (st == null || !st.hasMoreElements()) {
            try {
                line = bf.readLine();
                st = new StringTokenizer(line);
            } catch (IOException e) {
                return null;
            }
        }
        return st.nextToken();
	}
	public int nextInt(){
		return Integer.parseInt(nextString());
	}
	public long nextLong(){
		return Long.parseLong(nextString());
	}
	public double nextDouble(){
		return Double.parseDouble(nextString());
	}
}

import java.util.Scanner;

public class Main {

	public static void main(String[] args)
	{
		Scanner s=new Scanner(System.in);

		long h=s.nextLong();
		long n=s.nextLong();

		String path=Long.toBinaryString(n-1);

		char[] arr=new char[(int)h];

		int ptr=(int)(h-1);

		for(int j=path.length()-1;j>=0;j--)
		{
			arr[ptr]=path.charAt(j);
			ptr--;
		}

		char curr='0';

		long count=0;

		for(int i=0;i<h;i++)
		{
			if(arr[i]!=curr)
			{
				count=count+(long)((Math.pow(2,h-i+1)-2)/2)+1;
				curr='0';
			}
			else
			{
				if(curr=='0')
					curr='1';
				else
					curr='0';

				count++;
			}
		}

		System.out.println(count);

	}

}

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Main {

    public static void main(String[] args) {
        try {
            BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
            String[] split = in.readLine().split(" ");
            long h = Integer.parseInt(split[0]);
            long num = Integer.parseInt(split[1]);

            if (h == 0) {
                System.out.println(0);
            }

            System.out.println(count(h, num, true));

        } catch (Exception e) {
            e.printStackTrace();
            // nothing
        }
    }

    // how much to visit in tree with level stated
    private static long count(long level, long number, boolean leftChoice) {
        // base case
        if (level == 1) {
            if (leftChoice) {
                if (number == 1) {
                    return 1;
                } else if (number == 2) {
                    return 2;
                } else {
                    throw new IllegalStateException();
                }
            } else {
                if (number == 1) {
                    return 2;
                } else if (number == 2) {
                    return 1;
                } else {
                    throw new IllegalStateException();
                }
            }
        }

        //recursion
        long leafCount = power(2, level);
        long halfLeafCount = leafCount / 2;
        boolean leftSubTree = number <= halfLeafCount;
        if (leftChoice && leftSubTree) {
            return 1 + count(level - 1, number, !leftChoice);
        } else if (leftChoice) {
            return leafCount + count(level - 1, number - halfLeafCount, leftChoice);
        } else if (leftSubTree) {
            return leafCount + count(level - 1, number, leftChoice);
        } else {
            return 1 + count(level - 1, number - halfLeafCount, !leftChoice);
        }
    }

    public static long power(long a, long b) {
        if (b == 0) {
            return 1;
        } else if (b == 1) {
            return a;
        } else if (b % 2 == 0) {
            long c = power(a, (b / 2));
            return c * c;
        } else {
            long c = power(a, (b - 1) / 2);
            return a * c * c;
        }
    }
}

import java.io.*;
import java.util.*;

public class Main {

	static BufferedReader br = new BufferedReader(new InputStreamReader(
			System.in));
	static PrintWriter out = new PrintWriter(new BufferedOutputStream(
			System.out));
	static StringTokenizer st = new StringTokenizer("");

	public static String next() {
		try	{
		while (!st.hasMoreTokens()) {
			String s = br.readLine();
			if (s == null)
				return null;
			st = new StringTokenizer(s);
		}
		return st.nextToken();
		}	catch(Exception e)	{
			return	null;
		}
	}
	public static void main(String[] asda) throws Exception {

        int h = Integer.parseInt( next() );
        int to = Integer.parseInt( next() );

        long leafs = 1L << h;
        long nonLeaf = leafs - 1;

        size = new long [h + 1];
        size[h] = 1;
        for (int k = h - 1; k >= 0; k--)
        	size[k] = (size[k + 1] << 1) + 1;

        levels = h;
        end = nonLeaf + to;

        moves = 0;
        go(0, end, 0);

        out.println(moves);

        //
        out.flush();
        System.exit(0);
    }

	static boolean go(int level, long end, int cmd)	{
		if	( end == 1 )	{
			return	true;
		}

		if	( level == levels )	{
			// leaf
			moves++;
			return	false;
		}

        if	( size[level] < end )	{
        	moves += size[level];
        	return	false;
        }
		moves++;

		long leaf = size[level] + 1;
		leaf >>= 1;
        leaf >>= 1;

		if	( cmd == 0 )	{
			// left
			if	( go(level + 1, end - leaf, cmd ^ 1) )
				return	true;

			if	( go(level + 1, end - (size[level + 1] + 1), cmd) )
				return	true;

		}	else	{
			// right
			if	( go(level + 1, end - (size[level + 1] + 1), cmd) )
				return	true;

			if	( go(level + 1, end - leaf, cmd ^ 1) )
				return	true;
		}

		return	false;
	}
	static long [] size;
	static long moves, end;
	static int levels;
}

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Random;
import java.util.Scanner;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeSet;
import java.util.concurrent.LinkedBlockingDeque;

import javax.swing.border.Border;

public class a {

	public static long mod = (long) Math.pow(10, 9) + 7;
	public static int t;

	private static class node implements Comparable<node> {
		int num;
		int k;
		int dis;

		node(int m, int k, int dix) {
			num = m;
			this.k = k;
			dis = dix;

		}

		@Override
		public int compareTo(node o) {
			if (o.dis < dis)
				return 1;
			else if (o.dis > dis)
				return -1;
			if (o.k > k)
				return 1;
			else if (o.k < k)
				return -1;
			return 0;

		}

	}

	public static class point {
		long x;
		long y;
		long b;

		point(long x, long y, long b) {
			this.x = x;
			this.y = y;
			this.b = b;
		}
	}

	public static int ch(long y) {
		int r = Long.bitCount(y);
		return r;
	}

	public static long gcd(long x, long y) {
		if (y == 0)
			return x;

		return gcd(y, x % y);
	}

	public static boolean ch[] = new boolean[10000005];
	public static ArrayList<Integer> prime = new ArrayList();

	// public static Queue<Integer> pp;

	public static void sieve(int k) {
		ch[0] = ch[1] = true;

		for (int i = 2; i <= k; i++) {
			if (!ch[i]) {
				prime.add(i);
				// pp.add(i);
				for (long j = (long) i * (long) i; j <= k; j += i) {
					ch[(int) j] = true;
				}
			}
		}

	}

	public static long pw(int x, int power, int mod) {
		if (power == 1)
			return x % mod;
		else if (power % 2 == 0)
			return pw((x % mod * x % mod) % mod, power / 2, mod);
		else
			return (pw(x, power - 1, mod) % mod * x % mod) % mod;

	}

	public static String addToString(String a, int index, char b) {
		String ans = "";
		for (int i = 0; i < a.length(); i++) {
			if (i == index) {
				ans += b;
				index = -1;
				i--;
				continue;
			}
			ans += a.charAt(i);
		}
		return ans;
	}

	public static int bit[];

	public static void add(int idx, int cost) {
		while (idx < bit.length) {
			bit[idx] += cost;
			idx += (idx & -idx);
		}

	}

	public static int get(int idx) {
		int res = 0;
		while (idx > 0) {
			res += bit[idx];
			idx -= (idx & -idx);
		}
		return res;
	}

	public static long ch(int h, int h1, long p) {
		long k = p;
		int h2 = h1;
		while (h2 < h) {
			k = k * 2 + 1;
			h2++;
		}

		return k - (1L << h) + 1L;
	}

	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		// BufferedReader in = new BufferedReader(new FileReader(
		// "corporate_gifting.txt"));
		StringBuilder qq = new StringBuilder();
		PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
		// PrintWriter out = new PrintWriter(new FileWriter("out.txt"));
		String y[] = in.readLine().split(" ");
		int h = Integer.parseInt(y[0]);
		long n = Long.parseLong(y[1]);
		long p = 1;
		int h1 = 0;
		int e = 0;
		long ans = 0;
		while (h1 < h) {
			if (e == 0) {
				h1++;
				p *= 2;
				long get = ch(h, h1, p);
				if (get < n) {
					ans += (1L << (h - h1 + 1));
					p++;
					e = 0;
				} else {
					e = 1;
					ans++;
				}
			} else {
				h1++;
				p = p * 2 + 1;
				ans++;
				e = 0;
			}
		}
		System.out.println(ans);

		out.close();

	}
}

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.util.StringTokenizer;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }
}

class TaskC {
    public void solve(int testNumber, InputReader in, PrintWriter out) {
        long h = in.nextLong();
        long n = in.nextLong();
        long res = cal(h,n,1);
        out.println(res);
    }

    private long cal(long h, long n, int dir) {
        if(h == 0) return 0;
        long hi = 1L << h;
        long mid = hi >> 1;
        if(dir % 2 == 1){
            // have to turn left
            if(n <= mid){
                return cal(h-1,n,dir+1) + 1;
            } else {
                return cal(h-1,n-mid,dir) + (1L << h);
            }
        } else {
            // turn right
            if(n > mid){
                // right
                return cal(h-1,n,dir+1) + 1;
            } else {
                // left
                return cal(h-1,n-mid,dir) + (1L << h);
            }
        }
    }
}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

}

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.math.BigInteger;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.util.StringTokenizer;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author Vitalii Kozhukhivskyi
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }
}

class TaskC {
    public void solve(int testNumber, InputReader in, PrintWriter out) {
        long h = in.nextInt();
        long n = in.nextLong();
        BigInteger res = BigInteger.valueOf(h);
        Character curMove = 'L';
        for (long i = 0; i < h; i++) {
            long cur = 1L << (h - i);
            Character neededMove = (n > cur / 2) ? 'R' : 'L';
            if (!curMove.equals(neededMove)) {
                res = res.add(BigInteger.valueOf(cur - 1));
                if (neededMove.equals('R')) {
                    n -= cur / 2;
                }
            } else {
                curMove = (curMove.equals('L')) ? 'R' : 'L';
            }
        }
        out.println(res);
    }
}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

}

import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.InputStreamReader;
import java.io.IOException;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Alejandro Lopez
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskC {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            long h = in.nextInt();
            long n = in.nextInt();

            if (h == 1 && n == 1) {
                out.println(0);
                return;
            }

            long ans = 0;
            int cur = 0;
            for (long i = h; i > 0; --i) {
                int leaves = (1 << (i - 1));
                int subtreeSize = 1 << i;
                if (n > leaves) { // right subtree
                    if (cur == 0) { // going left
                        ans += subtreeSize;
                        n -= leaves;
                    } else { // going right
                        ans += 1;
                        cur = 0;
                    }
                } else { // left subtree
                    if (cur == 1) { // going right
                        ans += subtreeSize;
                    } else { // going left
                        ans += 1;
                        cur = 1;
                    }
                }
            }

            out.println(ans);
        }

    }

    static class InputReader {
        BufferedReader in;
        StringTokenizer tokenizer = null;

        public InputReader(InputStream inputStream) {
            in = new BufferedReader(new InputStreamReader(inputStream));
        }

        public String next() {
            try {
                while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                    tokenizer = new StringTokenizer(in.readLine());
                }
                return tokenizer.nextToken();
            } catch (IOException e) {
                return null;
            }
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }
}

import java.io.BufferedInputStream;
import java.io.PrintStream;
import java.util.Scanner;

public class C {

	private static PrintStream out = System.out;

	public static void main(String[] args) {
		Scanner in = new Scanner(new BufferedInputStream(System.in));
		int h = in.nextInt();
		long n = in.nextLong() - 1;
		// get n in reversed bitmask form
		int[] bitmask = new int[h];
		int idx = h;
		for (long nn = n; nn > 0; nn /= 2)
			bitmask[--idx] = (int) (nn%2);
		// go through the bitmask
		long ans = 0;
		int parity = 0;
		for (int i = 0; i < h; ++i) {
			if (bitmask[i] != parity)
				ans += 1 << (h - i);
			else
				++ans;
			parity = 1 - bitmask[i];
		}
		out.println(ans);
	}

}

import java.io.*;
import java.util.*;
import java.math.*;

public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		OutputWriter out = new OutputWriter(outputStream);
		Task solver = new Task();
		solver.solve(1, in, out);
		out.close();
	}
}

class Task {

	public void solve(int testNumber, InputReader in, OutputWriter out) {
		int h=in.readInt(), x=0;
		long n=in.readLong(), ret=0;
		for (; h>0; h--) {
			ret++;
			if ((n>1L<<(h-1) && x==0) || (x==1 && n<=1L<<(h-1))) {
				x=1-x;
				ret+=(1L<<h)-1;
			}
			n-=1L<<(h-1);
		}
		out.printLine(ret);
	}
}

class InputReader {
	private boolean finished = false;

	private InputStream stream;
	private byte[] buf = new byte[1024];
	private int curChar;
	private int numChars;
	private SpaceCharFilter filter;

	public InputReader(InputStream stream) {
		this.stream = stream;
	}

	public int read() {
		if (numChars == -1)
			throw new InputMismatchException();
		if (curChar >= numChars) {
			curChar = 0;
			try {
				numChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (numChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}

	public int peek() {
		if (numChars == -1)
			return -1;
		if (curChar >= numChars) {
			curChar = 0;
			try {
				numChars = stream.read(buf);
			} catch (IOException e) {
				return -1;
			}
			if (numChars <= 0)
				return -1;
		}
		return buf[curChar];
	}

	public int readInt() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public long readLong() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		long res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public String readString() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		StringBuilder res = new StringBuilder();
		do {
			if (Character.isValidCodePoint(c))
				res.appendCodePoint(c);
			c = read();
		} while (!isSpaceChar(c));
		return res.toString();
	}

	public boolean isSpaceChar(int c) {
		if (filter != null)
			return filter.isSpaceChar(c);
		return isWhitespace(c);
	}

	public static boolean isWhitespace(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}

	private String readLine0() {
		StringBuilder buf = new StringBuilder();
		int c = read();
		while (c != '\n' && c != -1) {
			if (c != '\r')
				buf.appendCodePoint(c);
			c = read();
		}
		return buf.toString();
	}

	public String readLine() {
		String s = readLine0();
		while (s.trim().length() == 0)
			s = readLine0();
		return s;
	}

	public String readLine(boolean ignoreEmptyLines) {
		if (ignoreEmptyLines)
			return readLine();
		else
			return readLine0();
	}

	public BigInteger readBigInteger() {
		try {
			return new BigInteger(readString());
		} catch (NumberFormatException e) {
			throw new InputMismatchException();
		}
	}

	public char readCharacter() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		return (char) c;
	}

	public double readDouble() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		double res = 0;
		while (!isSpaceChar(c) && c != '.') {
			if (c == 'e' || c == 'E')
				return res * Math.pow(10, readInt());
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		}
		if (c == '.') {
			c = read();
			double m = 1;
			while (!isSpaceChar(c)) {
				if (c == 'e' || c == 'E')
					return res * Math.pow(10, readInt());
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				m /= 10;
				res += (c - '0') * m;
				c = read();
			}
		}
		return res * sgn;
	}

	public boolean isExhausted() {
		int value;
		while (isSpaceChar(value = peek()) && value != -1)
			read();
		return value == -1;
	}

	public String next() {
		return readString();
	}

	public SpaceCharFilter getFilter() {
		return filter;
	}

	public void setFilter(SpaceCharFilter filter) {
		this.filter = filter;
	}

	public interface SpaceCharFilter {
		public boolean isSpaceChar(int ch);
	}
}

class OutputWriter {
	private final PrintWriter writer;

	public OutputWriter(OutputStream outputStream) {
		writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
				outputStream)));
	}

	public OutputWriter(Writer writer) {
		this.writer = new PrintWriter(writer);
	}

	public void print(char[] array) {
		writer.print(array);
	}

	public void print(Object... objects) {
		for (int i = 0; i < objects.length; i++) {
			if (i != 0)
				writer.print(' ');
			writer.print(objects[i]);
		}
	}

	public void print(int[] array) {
		for (int i = 0; i < array.length; i++) {
			if (i != 0)
				writer.print(' ');
			writer.print(array[i]);
		}
	}

	public void print(long[] array) {
		for (int i = 0; i < array.length; i++) {
			if (i != 0)
				writer.print(' ');
			writer.print(array[i]);
		}
	}

	public void printLine(int[] array) {
		print(array);
		writer.println();
	}

	public void printLine(long[] array) {
		print(array);
		writer.println();
	}

	public void printLine() {
		writer.println();
	}

	public void printLine(Object... objects) {
		print(objects);
		writer.println();
	}

	public void print(char i) {
		writer.print(i);
	}

	public void printLine(char i) {
		writer.println(i);
	}

	public void printLine(char[] array) {
		writer.println(array);
	}

	public void printFormat(String format, Object... objects) {
		writer.printf(format, objects);
	}

	public void close() {
		writer.close();
	}

	public void flush() {
		writer.flush();
	}

	public void print(long i) {
		writer.print(i);
	}

	public void printLine(long i) {
		writer.println(i);
	}

	public void print(int i) {
		writer.print(i);
	}

	public void printLine(int i) {
		writer.println(i);
	}
}

class IOUtils {

	public static int[] readIntArray(InputReader in, int size) {
		int[] array = new int[size];
		for (int i = 0; i < size; i++)
			array[i] = in.readInt();
		return array;
	}

	public static long[] readLongArray(InputReader in, int size) {
		long[] array = new long[size];
		for (int i = 0; i < size; i++)
			array[i] = in.readLong();
		return array;
	}

	public static double[] readDoubleArray(InputReader in, int size) {
		double[] array = new double[size];
		for (int i = 0; i < size; i++)
			array[i] = in.readDouble();
		return array;
	}

	public static String[] readStringArray(InputReader in, int size) {
		String[] array = new String[size];
		for (int i = 0; i < size; i++)
			array[i] = in.readString();
		return array;
	}

	public static char[] readCharArray(InputReader in, int size) {
		char[] array = new char[size];
		for (int i = 0; i < size; i++)
			array[i] = in.readCharacter();
		return array;
	}

	public static void readIntArrays(InputReader in, int[]... arrays) {
		for (int i = 0; i < arrays[0].length; i++) {
			for (int j = 0; j < arrays.length; j++)
				arrays[j][i] = in.readInt();
		}
	}

	public static void readLongArrays(InputReader in, long[]... arrays) {
		for (int i = 0; i < arrays[0].length; i++) {
			for (int j = 0; j < arrays.length; j++)
				arrays[j][i] = in.readLong();
		}
	}

	public static void readDoubleArrays(InputReader in, double[]... arrays) {
		for (int i = 0; i < arrays[0].length; i++) {
			for (int j = 0; j < arrays.length; j++)
				arrays[j][i] = in.readDouble();
		}
	}

	public static char[][] readTable(InputReader in, int rowCount,
			int columnCount) {
		char[][] table = new char[rowCount][];
		for (int i = 0; i < rowCount; i++)
			table[i] = readCharArray(in, columnCount);
		return table;
	}

	public static int[][] readIntTable(InputReader in, int rowCount,
			int columnCount) {
		int[][] table = new int[rowCount][];
		for (int i = 0; i < rowCount; i++)
			table[i] = readIntArray(in, columnCount);
		return table;
	}

	public static double[][] readDoubleTable(InputReader in, int rowCount,
			int columnCount) {
		double[][] table = new double[rowCount][];
		for (int i = 0; i < rowCount; i++)
			table[i] = readDoubleArray(in, columnCount);
		return table;
	}

	public static long[][] readLongTable(InputReader in, int rowCount,
			int columnCount) {
		long[][] table = new long[rowCount][];
		for (int i = 0; i < rowCount; i++)
			table[i] = readLongArray(in, columnCount);
		return table;
	}

	public static String[][] readStringTable(InputReader in, int rowCount,
			int columnCount) {
		String[][] table = new String[rowCount][];
		for (int i = 0; i < rowCount; i++)
			table[i] = readStringArray(in, columnCount);
		return table;
	}

	public static String readText(InputReader in) {
		StringBuilder result = new StringBuilder();
		while (true) {
			int character = in.read();
			if (character == '\r')
				continue;
			if (character == -1)
				break;
			result.append((char) character);
		}
		return result.toString();
	}

	public static void readStringArrays(InputReader in, String[]... arrays) {
		for (int i = 0; i < arrays[0].length; i++) {
			for (int j = 0; j < arrays.length; j++)
				arrays[j][i] = in.readString();
		}
	}

	public static void printTable(OutputWriter out, char[][] table) {
		for (char[] row : table)
			out.printLine(new String(row));
	}
}

class SumIntervalTree extends LongIntervalTree {
	public SumIntervalTree(int size) {
		super(size);
	}

	@Override
	protected long joinValue(long left, long right) {
		return left + right;
	}

	@Override
	protected long joinDelta(long was, long delta) {
		return was + delta;
	}

	@Override
	protected long accumulate(long value, long delta, int length) {
		return value + delta * length;
	}

	@Override
	protected long neutralValue() {
		return 0;
	}

	@Override
	protected long neutralDelta() {
		return 0;
	}
}

abstract class IntervalTree {
	protected int size;

	protected IntervalTree(int size) {
		this(size, true);
	}

	public IntervalTree(int size, boolean shouldInit) {
		this.size = size;
		int nodeCount = Math.max(1, Integer.highestOneBit(size) << 2);
		initData(size, nodeCount);
		if (shouldInit)
			init();
	}

	protected abstract void initData(int size, int nodeCount);

	protected abstract void initAfter(int root, int left, int right, int middle);

	protected abstract void initBefore(int root, int left, int right, int middle);

	protected abstract void initLeaf(int root, int index);

	protected abstract void updatePostProcess(int root, int left, int right,
			int from, int to, long delta, int middle);

	protected abstract void updatePreProcess(int root, int left, int right,
			int from, int to, long delta, int middle);

	protected abstract void updateFull(int root, int left, int right, int from,
			int to, long delta);

	protected abstract long queryPostProcess(int root, int left, int right,
			int from, int to, int middle, long leftResult, long rightResult);

	protected abstract void queryPreProcess(int root, int left, int right,
			int from, int to, int middle);

	protected abstract long queryFull(int root, int left, int right, int from,
			int to);

	protected abstract long emptySegmentResult();

	public void init() {
		if (size == 0)
			return;
		init(0, 0, size - 1);
	}

	private void init(int root, int left, int right) {
		if (left == right) {
			initLeaf(root, left);
		} else {
			int middle = (left + right) >> 1;
			initBefore(root, left, right, middle);
			init(2 * root + 1, left, middle);
			init(2 * root + 2, middle + 1, right);
			initAfter(root, left, right, middle);
		}
	}

	public void update(int from, int to, long delta) {
		update(0, 0, size - 1, from, to, delta);
	}

	protected void update(int root, int left, int right, int from, int to,
			long delta) {
		if (left > to || right < from)
			return;
		if (left >= from && right <= to) {
			updateFull(root, left, right, from, to, delta);
			return;
		}
		int middle = (left + right) >> 1;
		updatePreProcess(root, left, right, from, to, delta, middle);
		update(2 * root + 1, left, middle, from, to, delta);
		update(2 * root + 2, middle + 1, right, from, to, delta);
		updatePostProcess(root, left, right, from, to, delta, middle);
	}

	public long query(int from, int to) {
		return query(0, 0, size - 1, from, to);
	}

	protected long query(int root, int left, int right, int from, int to) {
		if (left > to || right < from)
			return emptySegmentResult();
		if (left >= from && right <= to)
			return queryFull(root, left, right, from, to);
		int middle = (left + right) >> 1;
		queryPreProcess(root, left, right, from, to, middle);
		long leftResult = query(2 * root + 1, left, middle, from, to);
		long rightResult = query(2 * root + 2, middle + 1, right, from, to);
		return queryPostProcess(root, left, right, from, to, middle,
				leftResult, rightResult);
	}
}

class TreapSet<K> implements NavigableSet<K> {
	protected static final Random rnd = new Random(239);

	protected final Node nullNode;
	protected final Comparator<? super K> comparator;
	protected Node root;
	private final K from;
	private final K to;
	private final boolean fromInclusive;
	private final boolean toInclusive;

	public TreapSet() {
		this((Comparator<? super K>) null);
	}

	public TreapSet(Comparator<? super K> comparator) {
		this(null, null, false, false, comparator, null, null);
	}

	public TreapSet(Iterable<? extends K> collection) {
		this(collection, null);
	}

	public TreapSet(Iterable<? extends K> collection,
			Comparator<? super K> comparator) {
		this(comparator);
		addAll(collection);
	}

	protected TreapSet(K from, K to, boolean fromInclusive,
			boolean toInclusive, Comparator<? super K> comparator, Node root,
			Node nullNode) {
		this.comparator = comparator;
		this.from = from;
		this.to = to;
		this.fromInclusive = fromInclusive;
		this.toInclusive = toInclusive;
		if (nullNode == null)
			nullNode = new NullNode();
		if (root == null)
			root = nullNode;
		this.root = root;
		this.nullNode = nullNode;
	}

	public boolean addAll(Iterable<? extends K> collection) {
		boolean result = false;
		for (K element : collection)
			result |= add(element);
		return result;
	}

	public K lower(K k) {
		Node target = root.lower(k);
		if (target == nullNode)
			return null;
		if (belongs(target.key))
			return target.key;
		return null;
	}

	private boolean belongs(K key) {
		int valueFrom = compare(from, key);
		int valueTo = compare(key, to);
		return (valueFrom < 0 || valueFrom == 0 && fromInclusive)
				&& (valueTo < 0 || valueTo == 0 && toInclusive);
	}

	public K floor(K k) {
		Node target = root.floor(k);
		if (target == nullNode)
			return null;
		if (belongs(target.key))
			return target.key;
		return null;
	}

	public K ceiling(K k) {
		Node target = root.ceil(k);
		if (target == nullNode)
			return null;
		if (belongs(target.key))
			return target.key;
		return null;
	}

	public K higher(K k) {
		Node target = root.higher(k);
		if (target == nullNode)
			return null;
		if (belongs(target.key))
			return target.key;
		return null;
	}

	public K pollFirst() {
		K first = first();
		if (first == null)
			throw new NoSuchElementException();
		root.erase(first);
		return first;
	}

	public K pollLast() {
		K last = last();
		if (last == null)
			throw new NoSuchElementException();
		root.erase(last);
		return last;
	}

	public int size() {
		if (from == null && to == null)
			return root.size;
		if (from == null) {
			Node to = toInclusive ? root.floor(this.to) : root.lower(this.to);
			if (to == nullNode)
				return 0;
			return root.indexOf(to) + 1;
		}
		if (to == null) {
			Node from = fromInclusive ? root.ceil(this.from) : root
					.higher(this.from);
			if (from == nullNode)
				return 0;
			return root.size - root.indexOf(from);
		}
		Node from = fromInclusive ? root.ceil(this.from) : root
				.higher(this.from);
		if (from == nullNode || !belongs(from.key))
			return 0;
		Node to = toInclusive ? root.floor(this.to) : root.lower(this.to);
		return root.indexOf(to) - root.indexOf(from) + 1;
	}

	public boolean isEmpty() {
		return size() == 0;
	}

	@SuppressWarnings({ "unchecked" })
	public boolean contains(Object o) {
		return belongs((K) o) && root.search((K) o) != nullNode;
	}

	public Iterator<K> iterator() {
		return new Iterator<K>() {
			private K current = first();

			public boolean hasNext() {
				return current != null;
			}

			public K next() {
				K result = current;
				current = higher(current);
				return result;
			}

			public void remove() {
				TreapSet.this.remove(current);
			}
		};
	}

	public Object[] toArray() {
		Object[] array = new Object[size()];
		int index = 0;
		for (K key : this)
			array[index++] = key;
		return array;
	}

	@SuppressWarnings({ "unchecked" })
	public <T> T[] toArray(T[] a) {
		if (a.length < size())
			throw new IllegalArgumentException();
		int index = 0;
		for (K key : this)
			a[index++] = (T) key;
		return a;
	}

	public boolean add(K k) {
		if (k == null)
			throw new NullPointerException();
		if (contains(k))
			return false;
		root = root.insert(createNode(k));
		return true;
	}

	protected Node createNode(K k) {
		return new Node(k, rnd.nextLong());
	}

	public boolean remove(Object o) {
		if (!contains(o))
			return false;
		// noinspection unchecked
		root = root.erase((K) o);
		return true;
	}

	public boolean containsAll(Collection<?> c) {
		for (Object o : c) {
			if (!contains(o))
				return false;
		}
		return true;
	}

	public boolean addAll(Collection<? extends K> c) {
		return addAll((Iterable<? extends K>) c);
	}

	public boolean retainAll(Collection<?> c) {
		List<K> toRemove = new ArrayList<K>();
		for (K key : this) {
			if (!c.contains(key))
				toRemove.add(key);
		}
		return removeAll(toRemove);
	}

	public boolean removeAll(Collection<?> c) {
		boolean result = false;
		for (Object o : c)
			result |= remove(o);
		return result;
	}

	public void clear() {
		retainAll(Collections.<Object> emptySet());
	}

	public NavigableSet<K> descendingSet() {
		throw new UnsupportedOperationException();
	}

	public Iterator<K> descendingIterator() {
		return new Iterator<K>() {
			private K current = last();

			public boolean hasNext() {
				return current != null;
			}

			public K next() {
				K result = current;
				current = lower(current);
				return result;
			}

			public void remove() {
				TreapSet.this.remove(current);
			}
		};
	}

	public NavigableSet<K> subSet(K fromElement, boolean fromInclusive,
			K toElement, boolean toInclusive) {
		return new TreapSet<K>(fromElement, toElement, fromInclusive,
				toInclusive, comparator, root, nullNode);
	}

	public NavigableSet<K> headSet(K toElement, boolean inclusive) {
		return subSet(null, false, toElement, inclusive);
	}

	public NavigableSet<K> tailSet(K fromElement, boolean inclusive) {
		return subSet(fromElement, inclusive, null, false);
	}

	public Comparator<? super K> comparator() {
		return comparator;
	}

	public SortedSet<K> subSet(K fromElement, K toElement) {
		return subSet(fromElement, true, toElement, false);
	}

	public SortedSet<K> headSet(K toElement) {
		return subSet(null, false, toElement, false);
	}

	public SortedSet<K> tailSet(K fromElement) {
		return tailSet(fromElement, true);
	}

	public K first() {
		if (isEmpty())
			return null;
		if (from == null)
			return root.first().key;
		if (fromInclusive)
			return ceiling(from);
		return higher(from);
	}

	public K last() {
		if (isEmpty())
			return null;
		if (to == null)
			return root.last().key;
		if (toInclusive)
			return floor(to);
		return lower(to);
	}

	public K get(int index) {
		if (index >= size() || index < 0)
			throw new IndexOutOfBoundsException(Integer.toString(index));
		if (from != null)
			index += headSet(from, !fromInclusive).size();
		return root.get(index);
	}

	protected int compare(K first, K second) {
		if (first == null || second == null)
			return -1;
		if (comparator != null)
			return comparator.compare(first, second);
		// noinspection unchecked
		return ((Comparable<? super K>) first).compareTo(second);
	}

	protected class Node {
		protected final K key;
		protected final long priority;
		protected Node left;
		protected Node right;
		protected int size;

		protected Node(K key, long priority) {
			this.key = key;
			this.priority = priority;
			left = nullNode;
			right = nullNode;
			size = 1;
		}

		@SuppressWarnings({ "unchecked" })
		protected Object[] split(K key) {
			if (compare(key, this.key) < 0) {
				Object[] result = left.split(key);
				left = (Node) result[1];
				result[1] = this;
				updateSize();
				return result;
			}
			Object[] result = right.split(key);
			right = (Node) result[0];
			result[0] = this;
			updateSize();
			return result;
		}

		protected void updateSize() {
			size = left.size + right.size + 1;
		}

		@SuppressWarnings({ "unchecked" })
		protected Node insert(Node node) {
			if (node.priority > priority) {
				Object[] result = split(node.key);
				node.left = (Node) result[0];
				node.right = (Node) result[1];
				node.updateSize();
				return node;
			}
			if (compare(node.key, this.key) < 0) {
				left = left.insert(node);
				updateSize();
				return this;
			}
			right = right.insert(node);
			updateSize();
			return this;
		}

		protected Node merge(Node left, Node right) {
			if (left == nullNode)
				return right;
			if (right == nullNode)
				return left;
			if (left.priority > right.priority) {
				left.right = left.right.merge(left.right, right);
				left.updateSize();
				return left;
			}
			right.left = right.left.merge(left, right.left);
			right.updateSize();
			return right;
		}

		protected Node erase(K key) {
			int value = compare(key, this.key);
			if (value == 0)
				return merge(left, right);
			if (value < 0) {
				left = left.erase(key);
				updateSize();
				return this;
			}
			right = right.erase(key);
			updateSize();
			return this;
		}

		protected Node lower(K key) {
			if (compare(key, this.key) <= 0)
				return left.lower(key);
			Node result = right.lower(key);
			if (result == nullNode)
				return this;
			return result;
		}

		protected Node floor(K key) {
			if (compare(key, this.key) < 0)
				return left.floor(key);
			Node result = right.floor(key);
			if (result == nullNode)
				return this;
			return result;
		}

		protected Node higher(K key) {
			if (compare(key, this.key) >= 0)
				return right.higher(key);
			Node result = left.higher(key);
			if (result == nullNode)
				return this;
			return result;
		}

		protected Node ceil(K key) {
			if (compare(key, this.key) > 0)
				return right.ceil(key);
			Node result = left.ceil(key);
			if (result == nullNode)
				return this;
			return result;
		}

		protected Node first() {
			if (left == nullNode)
				return this;
			return left.first();
		}

		protected Node last() {
			if (right == nullNode)
				return this;
			return right.last();
		}

		protected Node search(K key) {
			int value = compare(key, this.key);
			if (value == 0)
				return this;
			if (value < 0)
				return left.search(key);
			return right.search(key);
		}

		public int indexOf(Node node) {
			if (this == node)
				return left.size;
			if (compare(node.key, this.key) > 0)
				return left.size + 1 + right.indexOf(node);
			return left.indexOf(node);
		}

		public K get(int index) {
			if (index < left.size)
				return left.get(index);
			else if (index == left.size)
				return key;
			else
				return right.get(index - left.size - 1);
		}
	}

	private class NullNode extends Node {
		private Object[] splitResult = new Object[2];

		private NullNode() {
			super(null, Long.MIN_VALUE);
			left = this;
			right = this;
			size = 0;
		}

		@Override
		protected Object[] split(K key) {
			splitResult[0] = splitResult[1] = this;
			return splitResult;
		}

		@Override
		protected Node insert(Node node) {
			return node;
		}

		@Override
		protected Node erase(K key) {
			return this;
		}

		@Override
		protected Node lower(K key) {
			return this;
		}

		@Override
		protected Node floor(K key) {
			return this;
		}

		@Override
		protected Node higher(K key) {
			return this;
		}

		@Override
		protected Node ceil(K key) {
			return this;
		}

		@Override
		protected Node first() {
			throw new NoSuchElementException();
		}

		@Override
		protected Node last() {
			throw new NoSuchElementException();
		}

		@Override
		protected void updateSize() {
		}

		@Override
		protected Node search(K key) {
			return this;
		}

	}
}

abstract class LongIntervalTree extends IntervalTree {
	protected long[] value;
	protected long[] delta;

	protected LongIntervalTree(int size) {
		this(size, true);
	}

	public LongIntervalTree(int size, boolean shouldInit) {
		super(size, shouldInit);
	}

	@Override
	protected void initData(int size, int nodeCount) {
		value = new long[nodeCount];
		delta = new long[nodeCount];
	}

	protected abstract long joinValue(long left, long right);

	protected abstract long joinDelta(long was, long delta);

	protected abstract long accumulate(long value, long delta, int length);

	protected abstract long neutralValue();

	protected abstract long neutralDelta();

	protected long initValue(int index) {
		return neutralValue();
	}

	@Override
	protected void initAfter(int root, int left, int right, int middle) {
		value[root] = joinValue(value[2 * root + 1], value[2 * root + 2]);
		delta[root] = neutralDelta();
	}

	@Override
	protected void initBefore(int root, int left, int right, int middle) {
	}

	@Override
	protected void initLeaf(int root, int index) {
		value[root] = initValue(index);
		delta[root] = neutralDelta();
	}

	@Override
	protected void updatePostProcess(int root, int left, int right, int from,
			int to, long delta, int middle) {
		value[root] = joinValue(value[2 * root + 1], value[2 * root + 2]);
	}

	@Override
	protected void updatePreProcess(int root, int left, int right, int from,
			int to, long delta, int middle) {
		pushDown(root, left, middle, right);
	}

	protected void pushDown(int root, int left, int middle, int right) {
		value[2 * root + 1] = accumulate(value[2 * root + 1], delta[root],
				middle - left + 1);
		value[2 * root + 2] = accumulate(value[2 * root + 2], delta[root],
				right - middle);
		delta[2 * root + 1] = joinDelta(delta[2 * root + 1], delta[root]);
		delta[2 * root + 2] = joinDelta(delta[2 * root + 2], delta[root]);
		delta[root] = neutralDelta();
	}

	@Override
	protected void updateFull(int root, int left, int right, int from, int to,
			long delta) {
		value[root] = accumulate(value[root], delta, right - left + 1);
		this.delta[root] = joinDelta(this.delta[root], delta);
	}

	@Override
	protected long queryPostProcess(int root, int left, int right, int from,
			int to, int middle, long leftResult, long rightResult) {
		return joinValue(leftResult, rightResult);
	}

	@Override
	protected void queryPreProcess(int root, int left, int right, int from,
			int to, int middle) {
		pushDown(root, left, middle, right);
	}

	@Override
	protected long queryFull(int root, int left, int right, int from, int to) {
		return value[root];
	}

	@Override
	protected long emptySegmentResult() {
		return neutralValue();
	}
}

class IntPair implements Comparable<IntPair> {
	public final int first, second;

	public IntPair(int first, int second) {
		this.first = first;
		this.second = second;
	}

	@Override
	public String toString() {
		return "(" + first + "," + second + ")";
	}

	@Override
	public boolean equals(Object o) {
		if (this == o)
			return true;
		if (o == null || getClass() != o.getClass())
			return false;

		IntPair intPair = (IntPair) o;

		return first == intPair.first && second == intPair.second;

	}

	@Override
	public int hashCode() {
		int result = first;
		result = 31 * result + second;
		return result;
	}

	public int compareTo(IntPair o) {
		if (first < o.first)
			return -1;
		if (first > o.first)
			return 1;
		if (second < o.second)
			return -1;
		if (second > o.second)
			return 1;
		return 0;
	}
}

class Matrix {
	public static long mod = Long.MAX_VALUE;
	public final long[][] data;
	public final int rowCount;
	public final int columnCount;

	public Matrix(int rowCount, int columnCount) {
		this.rowCount = rowCount;
		this.columnCount = columnCount;
		this.data = new long[rowCount][columnCount];
	}

	public Matrix(long[][] data) {
		this.rowCount = data.length;
		this.columnCount = data[0].length;
		this.data = data;
	}

	public static Matrix add(Matrix first, Matrix second) {
		Matrix result = new Matrix(first.rowCount, first.columnCount);
		for (int i = 0; i < result.rowCount; i++) {
			for (int j = 0; j < result.columnCount; j++) {
				result.data[i][j] = first.data[i][j] + second.data[i][j];
				if (result.data[i][j] >= mod)
					result.data[i][j] -= mod;
			}
		}
		return result;
	}

	public static Matrix multiply(Matrix first, Matrix second) {
		Matrix result = new Matrix(first.rowCount, second.columnCount);
		for (int i = 0; i < first.rowCount; i++) {
			for (int j = 0; j < second.rowCount; j++) {
				for (int k = 0; k < second.columnCount; k++)
					result.data[i][k] = (result.data[i][k] + first.data[i][j]
							* second.data[j][k])
							% mod;
			}
		}
		return result;
	}

	public static Matrix fastMultiply(Matrix first, Matrix second) {
		Matrix result = new Matrix(first.rowCount, second.columnCount);
		for (int i = 0; i < first.rowCount; i++) {
			for (int j = 0; j < second.rowCount; j++) {
				for (int k = 0; k < second.columnCount; k++)
					result.data[i][k] += first.data[i][j] * second.data[j][k];
			}
		}
		for (int i = 0; i < first.rowCount; i++) {
			for (int j = 0; j < second.columnCount; j++)
				result.data[i][j] %= mod;
		}
		return result;
	}

	public static Matrix identityMatrix(int size) {
		Matrix result = new Matrix(size, size);
		for (int i = 0; i < size; i++)
			result.data[i][i] = 1;
		return result;
	}

	public static long[] convert(long[][] matrix) {
		long[] result = new long[matrix.length * matrix.length];
		for (int i = 0; i < matrix.length; i++) {
			for (int j = 0; j < matrix.length; j++)
				result[i * matrix.length + j] = matrix[i][j];
		}
		return result;
	}

	public static long[] sumPowers(long[] matrix, long exponent, long mod,
			int side) {
		long[] result = new long[matrix.length];
		long[] power = new long[matrix.length];
		long[] temp = new long[matrix.length];
		long[] temp2 = new long[matrix.length];
		sumPowers(matrix, result, power, temp, temp2, exponent + 1, mod, side);
		return result;
	}

	private static void sumPowers(long[] matrix, long[] result, long[] power,
			long[] temp, long[] temp2, long exponent, long mod, int side) {
		if (exponent == 0) {
			for (int i = 0; i < matrix.length; i += side + 1)
				power[i] = 1 % mod;
			return;
		}
		if ((exponent & 1) == 0) {
			sumPowers(matrix, result, temp, power, temp2, exponent >> 1, mod,
					side);
			multiply(temp2, result, temp, mod, side);
			add(result, temp2, mod, side);
			multiply(power, temp, temp, mod, side);
		} else {
			sumPowers(matrix, result, temp, power, temp2, exponent - 1, mod,
					side);
			add(result, temp, mod, side);
			multiply(power, temp, matrix, mod, side);
		}
	}

	public static long[][] convert(long[] matrix, int side) {
		long[][] result = new long[side][side];
		for (int i = 0; i < side; i++) {
			for (int j = 0; j < side; j++)
				result[i][j] = matrix[i * side + j];
		}
		return result;
	}

	public static long[] power(long[] matrix, long exponent, long mod, int side) {
		long[] result = new long[matrix.length];
		long[] temp = new long[result.length];
		power(matrix, result, temp, exponent, mod, side);
		return result;
	}

	private static void power(long[] matrix, long[] result, long[] temp,
			long exponent, long mod, int side) {
		if (exponent == 0) {
			for (int i = 0; i < matrix.length; i += side + 1)
				result[i] = 1 % mod;
			return;
		}
		if ((exponent & 1) == 0) {
			power(matrix, temp, result, exponent >> 1, mod, side);
			multiply(result, temp, temp, mod, side);
		} else {
			power(matrix, temp, result, exponent - 1, mod, side);
			multiply(result, temp, matrix, mod, side);
		}
	}

	public static void multiply(long[] c, long[] a, long[] b, long mod, int side) {
		Arrays.fill(c, 0);
		for (int i = 0; i < side; i++) {
			for (int j = 0; j < side; j++) {
				for (int k = 0; k < side; k++) {
					c[i * side + k] += a[i * side + j] * b[j * side + k];
					if ((j & 3) == 3) {
						c[i * side + k] %= mod;
					}
				}
			}
		}
		for (int i = 0; i < c.length; i++)
			c[i] %= mod;
	}

	public static void add(long[] c, long[] a, long mod, int side) {
		for (int i = 0; i < side; i++) {
			for (int j = 0; j < side; j++) {
				c[i * side + j] += a[i * side + j];
				if (c[i * side + j] >= mod)
					c[i * side + j] -= mod;
			}
		}
	}

	public static long[] fastPower(long[] matrix, long exponent, long mod,
			int side) {
		long[] result = new long[matrix.length];
		long[] temp = new long[result.length];
		fastPower(matrix, result, temp, exponent, mod, side);
		return result;
	}

	private static void fastPower(long[] matrix, long[] result, long[] temp,
			long exponent, long mod, int side) {
		if (exponent == 0) {
			for (int i = 0; i < matrix.length; i += side + 1)
				result[i] = 1;
			return;
		}
		if ((exponent & 1) == 0) {
			fastPower(matrix, temp, result, exponent >> 1, mod, side);
			fastMultiply(result, temp, temp, mod, side);
		} else {
			power(matrix, temp, result, exponent - 1, mod, side);
			fastMultiply(result, temp, matrix, mod, side);
		}
	}

	public static void fastMultiply(long[] c, long[] a, long[] b, long mod,
			int side) {
		Arrays.fill(c, 0);
		for (int i = 0; i < side; i++) {
			for (int j = 0; j < side; j++) {
				for (int k = 0; k < side; k++)
					c[i * side + k] += a[i * side + j] * b[j * side + k];
			}
		}
		for (int i = 0; i < c.length; i++)
			c[i] %= mod;
	}

	public Matrix power(long exponent) {
		if (exponent == 0)
			return identityMatrix(rowCount);
		if (exponent == 1)
			return this;
		Matrix result = power(exponent >> 1);
		result = multiply(result, result);
		if ((exponent & 1) == 1)
			result = multiply(result, this);
		return result;
	}

	public Matrix fastPower(long exponent) {
		if (exponent == 0)
			return identityMatrix(rowCount);
		if (exponent == 1)
			return this;
		Matrix result = power(exponent >> 1);
		result = fastMultiply(result, result);
		if ((exponent & 1) == 1)
			result = fastMultiply(result, this);
		return result;
	}
}

class MiscUtils {
	public static final int[] DX4 = { 1, 0, -1, 0 };
	public static final int[] DY4 = { 0, -1, 0, 1 };
	public static final int[] DX8 = { 1, 1, 1, 0, -1, -1, -1, 0 };
	public static final int[] DY8 = { -1, 0, 1, 1, 1, 0, -1, -1 };
	public static final int[] DX_KNIGHT = { 2, 1, -1, -2, -2, -1, 1, 2 };
	public static final int[] DY_KNIGHT = { 1, 2, 2, 1, -1, -2, -2, -1 };

	private static final String[] ROMAN_TOKENS = { "M", "CM", "D", "CD", "C",
			"XC", "L", "XL", "X", "IX", "V", "IV", "I" };
	private static final int[] ROMAN_VALUES = { 1000, 900, 500, 400, 100, 90,
			50, 40, 10, 9, 5, 4, 1 };

	public static long josephProblem(long n, int k) {
		if (n == 1)
			return 0;
		if (k == 1)
			return n - 1;
		if (k > n)
			return (josephProblem(n - 1, k) + k) % n;
		long count = n / k;
		long result = josephProblem(n - count, k);
		result -= n % k;
		if (result < 0)
			result += n;
		else
			result += result / (k - 1);
		return result;
	}

	public static boolean isValidCell(int row, int column, int rowCount,
			int columnCount) {
		return row >= 0 && row < rowCount && column >= 0
				&& column < columnCount;
	}

	public static long maximalRectangleSum(long[][] array) {
		int n = array.length;
		int m = array[0].length;
		long[][] partialSums = new long[n + 1][m + 1];
		for (int i = 0; i < n; i++) {
			long rowSum = 0;
			for (int j = 0; j < m; j++) {
				rowSum += array[i][j];
				partialSums[i + 1][j + 1] = partialSums[i][j + 1] + rowSum;
			}
		}
		long result = Long.MIN_VALUE;
		for (int i = 0; i < m; i++) {
			for (int j = i; j < m; j++) {
				long minPartialSum = 0;
				for (int k = 1; k <= n; k++) {
					long current = partialSums[k][j + 1] - partialSums[k][i];
					result = Math.max(result, current - minPartialSum);
					minPartialSum = Math.min(minPartialSum, current);
				}
			}
		}
		return result;
	}

	public static int parseIP(String ip) {
		String[] components = ip.split("[.]");
		int result = 0;
		for (int i = 0; i < 4; i++)
			result += (1 << (24 - 8 * i)) * Integer.parseInt(components[i]);
		return result;
	}

	public static String buildIP(int mask) {
		StringBuilder result = new StringBuilder();
		for (int i = 0; i < 4; i++) {
			if (i != 0)
				result.append('.');
			result.append(mask >> (24 - 8 * i) & 255);
		}
		return result.toString();
	}

	public static <T> boolean equals(T first, T second) {
		return first == null && second == null || first != null
				&& first.equals(second);
	}

	public static boolean isVowel(char ch) {
		ch = Character.toUpperCase(ch);
		return ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U'
				|| ch == 'Y';
	}

	public static boolean isStrictVowel(char ch) {
		ch = Character.toUpperCase(ch);
		return ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U';
	}

	public static String convertToRoman(int number) {
		StringBuilder result = new StringBuilder();
		for (int i = 0; i < ROMAN_TOKENS.length; i++) {
			while (number >= ROMAN_VALUES[i]) {
				number -= ROMAN_VALUES[i];
				result.append(ROMAN_TOKENS[i]);
			}
		}
		return result.toString();
	}

	public static int convertFromRoman(String number) {
		int result = 0;
		for (int i = 0; i < ROMAN_TOKENS.length; i++) {
			while (number.startsWith(ROMAN_TOKENS[i])) {
				number = number.substring(ROMAN_TOKENS[i].length());
				result += ROMAN_VALUES[i];
			}
		}
		return result;
	}

	public static int distance(int x1, int y1, int x2, int y2) {
		int dx = x1 - x2;
		int dy = y1 - y2;
		return dx * dx + dy * dy;
	}

	public static <T extends Comparable<T>> T min(T first, T second) {
		if (first.compareTo(second) <= 0)
			return first;
		return second;
	}

	public static <T extends Comparable<T>> T max(T first, T second) {
		if (first.compareTo(second) <= 0)
			return second;
		return first;
	}

	public static void decreaseByOne(int[]... arrays) {
		for (int[] array : arrays) {
			for (int i = 0; i < array.length; i++)
				array[i]--;
		}
	}

	public static int[] getIntArray(String s) {
		String[] tokens = s.split(" ");
		int[] result = new int[tokens.length];
		for (int i = 0; i < result.length; i++)
			result[i] = Integer.parseInt(tokens[i]);
		return result;
	}
}

class Graph {
	public static final int REMOVED_BIT = 0;

	protected int vertexCount;
	protected int edgeCount;

	private int[] firstOutbound;
	private int[] firstInbound;

	private Edge[] edges;
	private int[] nextInbound;
	private int[] nextOutbound;
	private int[] from;
	private int[] to;
	private long[] weight;
	public long[] capacity;
	private int[] reverseEdge;
	private int[] flags;

	public Graph(int vertexCount) {
		this(vertexCount, vertexCount);
	}

	public Graph(int vertexCount, int edgeCapacity) {
		this.vertexCount = vertexCount;
		firstOutbound = new int[vertexCount];
		Arrays.fill(firstOutbound, -1);

		from = new int[edgeCapacity];
		to = new int[edgeCapacity];
		nextOutbound = new int[edgeCapacity];
		flags = new int[edgeCapacity];
	}

	public static Graph createGraph(int vertexCount, int[] from, int[] to) {
		Graph graph = new Graph(vertexCount, from.length);
		for (int i = 0; i < from.length; i++)
			graph.addSimpleEdge(from[i], to[i]);
		return graph;
	}

	public static Graph createWeightedGraph(int vertexCount, int[] from,
			int[] to, long[] weight) {
		Graph graph = new Graph(vertexCount, from.length);
		for (int i = 0; i < from.length; i++)
			graph.addWeightedEdge(from[i], to[i], weight[i]);
		return graph;
	}

	public static Graph createFlowGraph(int vertexCount, int[] from, int[] to,
			long[] capacity) {
		Graph graph = new Graph(vertexCount, from.length * 2);
		for (int i = 0; i < from.length; i++)
			graph.addFlowEdge(from[i], to[i], capacity[i]);
		return graph;
	}

	public static Graph createFlowWeightedGraph(int vertexCount, int[] from,
			int[] to, long[] weight, long[] capacity) {
		Graph graph = new Graph(vertexCount, from.length * 2);
		for (int i = 0; i < from.length; i++)
			graph.addFlowWeightedEdge(from[i], to[i], weight[i], capacity[i]);
		return graph;
	}

	public static Graph createTree(int[] parent) {
		Graph graph = new Graph(parent.length + 1, parent.length);
		for (int i = 0; i < parent.length; i++)
			graph.addSimpleEdge(parent[i], i + 1);
		return graph;
	}

	public int addEdge(int fromID, int toID, long weight, long capacity,
			int reverseEdge) {
		ensureEdgeCapacity(edgeCount + 1);
		if (firstOutbound[fromID] != -1)
			nextOutbound[edgeCount] = firstOutbound[fromID];
		else
			nextOutbound[edgeCount] = -1;
		firstOutbound[fromID] = edgeCount;
		if (firstInbound != null) {
			if (firstInbound[toID] != -1)
				nextInbound[edgeCount] = firstInbound[toID];
			else
				nextInbound[edgeCount] = -1;
			firstInbound[toID] = edgeCount;
		}
		this.from[edgeCount] = fromID;
		this.to[edgeCount] = toID;
		if (capacity != 0) {
			if (this.capacity == null)
				this.capacity = new long[from.length];
			this.capacity[edgeCount] = capacity;
		}
		if (weight != 0) {
			if (this.weight == null)
				this.weight = new long[from.length];
			this.weight[edgeCount] = weight;
		}
		if (reverseEdge != -1) {
			if (this.reverseEdge == null) {
				this.reverseEdge = new int[from.length];
				Arrays.fill(this.reverseEdge, 0, edgeCount, -1);
			}
			this.reverseEdge[edgeCount] = reverseEdge;
		}
		if (edges != null)
			edges[edgeCount] = createEdge(edgeCount);
		return edgeCount++;
	}

	protected final GraphEdge createEdge(int id) {
		return new GraphEdge(id);
	}

	public final int addFlowWeightedEdge(int from, int to, long weight,
			long capacity) {
		if (capacity == 0) {
			return addEdge(from, to, weight, 0, -1);
		} else {
			int lastEdgeCount = edgeCount;
			addEdge(to, from, -weight, 0, lastEdgeCount + entriesPerEdge());
			return addEdge(from, to, weight, capacity, lastEdgeCount);
		}
	}

	protected int entriesPerEdge() {
		return 1;
	}

	public final int addFlowEdge(int from, int to, long capacity) {
		return addFlowWeightedEdge(from, to, 0, capacity);
	}

	public final int addWeightedEdge(int from, int to, long weight) {
		return addFlowWeightedEdge(from, to, weight, 0);
	}

	public final int addSimpleEdge(int from, int to) {
		return addWeightedEdge(from, to, 0);
	}

	public final int vertexCount() {
		return vertexCount;
	}

	public final int edgeCount() {
		return edgeCount;
	}

	protected final int edgeCapacity() {
		return from.length;
	}

	public final Edge edge(int id) {
		initEdges();
		return edges[id];
	}

	public final int firstOutbound(int vertex) {
		int id = firstOutbound[vertex];
		while (id != -1 && isRemoved(id))
			id = nextOutbound[id];
		return id;
	}

	public final int nextOutbound(int id) {
		id = nextOutbound[id];
		while (id != -1 && isRemoved(id))
			id = nextOutbound[id];
		return id;
	}

	public final int firstInbound(int vertex) {
		initInbound();
		int id = firstInbound[vertex];
		while (id != -1 && isRemoved(id))
			id = nextInbound[id];
		return id;
	}

	public final int nextInbound(int id) {
		initInbound();
		id = nextInbound[id];
		while (id != -1 && isRemoved(id))
			id = nextInbound[id];
		return id;
	}

	public final int source(int id) {
		return from[id];
	}

	public final int destination(int id) {
		return to[id];
	}

	public final long weight(int id) {
		if (weight == null)
			return 0;
		return weight[id];
	}

	public final long capacity(int id) {
		if (capacity == null)
			return 0;
		return capacity[id];
	}

	public final long flow(int id) {
		if (reverseEdge == null)
			return 0;
		return capacity[reverseEdge[id]];
	}

	public final void pushFlow(int id, long flow) {
		if (flow == 0)
			return;
		if (flow > 0) {
			if (capacity(id) < flow)
				throw new IllegalArgumentException("Not enough capacity");
		} else {
			if (flow(id) < -flow)
				throw new IllegalArgumentException("Not enough capacity");
		}
		capacity[id] -= flow;
		capacity[reverseEdge[id]] += flow;
	}

	public int transposed(int id) {
		return -1;
	}

	public final int reverse(int id) {
		if (reverseEdge == null)
			return -1;
		return reverseEdge[id];
	}

	public final void addVertices(int count) {
		ensureVertexCapacity(vertexCount + count);
		Arrays.fill(firstOutbound, vertexCount, vertexCount + count, -1);
		if (firstInbound != null)
			Arrays.fill(firstInbound, vertexCount, vertexCount + count, -1);
		vertexCount += count;
	}

	protected final void initEdges() {
		if (edges == null) {
			edges = new Edge[from.length];
			for (int i = 0; i < edgeCount; i++)
				edges[i] = createEdge(i);
		}
	}

	public final void removeVertex(int vertex) {
		int id = firstOutbound[vertex];
		while (id != -1) {
			removeEdge(id);
			id = nextOutbound[id];
		}
		initInbound();
		id = firstInbound[vertex];
		while (id != -1) {
			removeEdge(id);
			id = nextInbound[id];
		}
	}

	private void initInbound() {
		if (firstInbound == null) {
			firstInbound = new int[firstOutbound.length];
			Arrays.fill(firstInbound, 0, vertexCount, -1);
			nextInbound = new int[from.length];
			for (int i = 0; i < edgeCount; i++) {
				nextInbound[i] = firstInbound[to[i]];
				firstInbound[to[i]] = i;
			}
		}
	}

	public final boolean flag(int id, int bit) {
		return (flags[id] >> bit & 1) != 0;
	}

	public final void setFlag(int id, int bit) {
		flags[id] |= 1 << bit;
	}

	public final void removeFlag(int id, int bit) {
		flags[id] &= -1 - (1 << bit);
	}

	public final void removeEdge(int id) {
		setFlag(id, REMOVED_BIT);
	}

	public final void restoreEdge(int id) {
		removeFlag(id, REMOVED_BIT);
	}

	public final boolean isRemoved(int id) {
		return flag(id, REMOVED_BIT);
	}

	public final Iterable<Edge> outbound(final int id) {
		initEdges();
		return new Iterable<Edge>() {
			public Iterator<Edge> iterator() {
				return new EdgeIterator(id, firstOutbound, nextOutbound);
			}
		};
	}

	public final Iterable<Edge> inbound(final int id) {
		initEdges();
		initInbound();
		return new Iterable<Edge>() {
			public Iterator<Edge> iterator() {
				return new EdgeIterator(id, firstInbound, nextInbound);
			}
		};
	}

	protected void ensureEdgeCapacity(int size) {
		if (from.length < size) {
			int newSize = Math.max(size, 2 * from.length);
			if (edges != null)
				edges = resize(edges, newSize);
			from = resize(from, newSize);
			to = resize(to, newSize);
			nextOutbound = resize(nextOutbound, newSize);
			if (nextInbound != null)
				nextInbound = resize(nextInbound, newSize);
			if (weight != null)
				weight = resize(weight, newSize);
			if (capacity != null)
				capacity = resize(capacity, newSize);
			if (reverseEdge != null)
				reverseEdge = resize(reverseEdge, newSize);
			flags = resize(flags, newSize);
		}
	}

	private void ensureVertexCapacity(int size) {
		if (firstOutbound.length < size) {
			int newSize = Math.max(size, 2 * from.length);
			firstOutbound = resize(firstOutbound, newSize);
			if (firstInbound != null)
				firstInbound = resize(firstInbound, newSize);
		}
	}

	protected final int[] resize(int[] array, int size) {
		int[] newArray = new int[size];
		System.arraycopy(array, 0, newArray, 0, array.length);
		return newArray;
	}

	private long[] resize(long[] array, int size) {
		long[] newArray = new long[size];
		System.arraycopy(array, 0, newArray, 0, array.length);
		return newArray;
	}

	private Edge[] resize(Edge[] array, int size) {
		Edge[] newArray = new Edge[size];
		System.arraycopy(array, 0, newArray, 0, array.length);
		return newArray;
	}

	public final boolean isSparse() {
		return vertexCount == 0 || edgeCount * 20 / vertexCount <= vertexCount;
	}

	protected class GraphEdge implements Edge {
		protected int id;

		protected GraphEdge(int id) {
			this.id = id;
		}

		public int getSource() {
			return source(id);
		}

		public int getDestination() {
			return destination(id);
		}

		public long getWeight() {
			return weight(id);
		}

		public long getCapacity() {
			return capacity(id);
		}

		public long getFlow() {
			return flow(id);
		}

		public void pushFlow(long flow) {
			Graph.this.pushFlow(id, flow);
		}

		public boolean getFlag(int bit) {
			return flag(id, bit);
		}

		public void setFlag(int bit) {
			Graph.this.setFlag(id, bit);
		}

		public void removeFlag(int bit) {
			Graph.this.removeFlag(id, bit);
		}

		public int getTransposedID() {
			return transposed(id);
		}

		public Edge getTransposedEdge() {
			int reverseID = getTransposedID();
			if (reverseID == -1)
				return null;
			initEdges();
			return edge(reverseID);
		}

		public int getReverseID() {
			return reverse(id);
		}

		public Edge getReverseEdge() {
			int reverseID = getReverseID();
			if (reverseID == -1)
				return null;
			initEdges();
			return edge(reverseID);
		}

		public int getID() {
			return id;
		}

		public void remove() {
			removeEdge(id);
		}

		public void restore() {
			restoreEdge(id);
		}
	}

	public class EdgeIterator implements Iterator<Edge> {
		private int edgeID;
		private final int[] next;
		private int lastID = -1;

		public EdgeIterator(int id, int[] first, int[] next) {
			this.next = next;
			edgeID = nextEdge(first[id]);
		}

		private int nextEdge(int id) {
			while (id != -1 && isRemoved(id))
				id = next[id];
			return id;
		}

		public boolean hasNext() {
			return edgeID != -1;
		}

		public Edge next() {
			if (edgeID == -1)
				throw new NoSuchElementException();
			lastID = edgeID;
			edgeID = nextEdge(next[lastID]);
			return edges[lastID];
		}

		public void remove() {
			if (lastID == -1)
				throw new IllegalStateException();
			removeEdge(lastID);
			lastID = -1;
		}
	}

}

class MaxFlow {
	private final Graph graph;
	private int source;
	private int destination;
	private int[] queue;
	private int[] distance;
	private int[] nextEdge;

	private MaxFlow(Graph graph, int source, int destination) {
		this.graph = graph;
		this.source = source;
		this.destination = destination;
		int vertexCount = graph.vertexCount();
		queue = new int[vertexCount];
		distance = new int[vertexCount];
		nextEdge = new int[vertexCount];
	}

	public static long dinic(Graph graph, int source, int destination) {
		return new MaxFlow(graph, source, destination).dinic();
	}

	private long dinic() {
		long totalFlow = 0;
		while (true) {
			edgeDistances();
			if (distance[destination] == -1)
				break;
			Arrays.fill(nextEdge, -2);
			totalFlow += dinicImpl(source, Long.MAX_VALUE);
		}
		return totalFlow;
	}

	private void edgeDistances() {
		Arrays.fill(distance, -1);
		distance[source] = 0;
		int size = 1;
		queue[0] = source;
		for (int i = 0; i < size; i++) {
			int current = queue[i];
			int id = graph.firstOutbound(current);
			while (id != -1) {
				if (graph.capacity(id) != 0) {
					int next = graph.destination(id);
					if (distance[next] == -1) {
						distance[next] = distance[current] + 1;
						queue[size++] = next;
					}
				}
				id = graph.nextOutbound(id);
			}
		}
	}

	private long dinicImpl(int source, long flow) {
		if (source == destination)
			return flow;
		if (flow == 0 || distance[source] == distance[destination])
			return 0;
		int id = nextEdge[source];
		if (id == -2)
			nextEdge[source] = id = graph.firstOutbound(source);
		long totalPushed = 0;
		while (id != -1) {
			int nextDestinationID = graph.destination(id);
			if (graph.capacity(id) != 0
					&& distance[nextDestinationID] == distance[source] + 1) {
				long pushed = dinicImpl(nextDestinationID,
						Math.min(flow, graph.capacity(id)));
				if (pushed != 0) {
					graph.pushFlow(id, pushed);
					flow -= pushed;
					totalPushed += pushed;
					if (flow == 0)
						return totalPushed;
				}
			}
			nextEdge[source] = id = graph.nextOutbound(id);
		}
		return totalPushed;
	}
}

interface Edge {
	public int getSource();

	public int getDestination();

	public long getWeight();

	public long getCapacity();

	public long getFlow();

	public void pushFlow(long flow);

	public boolean getFlag(int bit);

	public void setFlag(int bit);

	public void removeFlag(int bit);

	public int getTransposedID();

	public Edge getTransposedEdge();

	public int getReverseID();

	public Edge getReverseEdge();

	public int getID();

	public void remove();

	public void restore();
}

class Point {
	public static final Point ORIGIN = new Point(0, 0);
	public final double x;
	public final double y;

	@Override
	public String toString() {
		return "(" + x + ", " + y + ")";
	}

	public Point(double x, double y) {
		this.x = x;
		this.y = y;
	}

	public Line line(Point other) {
		if (equals(other))
			return null;
		double a = other.y - y;
		double b = x - other.x;
		double c = -a * x - b * y;
		return new Line(a, b, c);
	}

	@Override
	public boolean equals(Object o) {
		if (this == o)
			return true;
		if (o == null || getClass() != o.getClass())
			return false;

		Point point = (Point) o;

		return Math.abs(x - point.x) <= GeometryUtils.epsilon
				&& Math.abs(y - point.y) <= GeometryUtils.epsilon;
	}

	@Override
	public int hashCode() {
		int result;
		long temp;
		temp = x != +0.0d ? Double.doubleToLongBits(x) : 0L;
		result = (int) (temp ^ (temp >>> 32));
		temp = y != +0.0d ? Double.doubleToLongBits(y) : 0L;
		result = 31 * result + (int) (temp ^ (temp >>> 32));
		return result;
	}

	public double distance(Point other) {
		return GeometryUtils.fastHypot(x - other.x, y - other.y);
	}

	public double distance(Line line) {
		return Math.abs(line.a * x + line.b * y + line.c);
	}

	public double value() {
		return GeometryUtils.fastHypot(x, y);
	}

	public double angle() {
		return Math.atan2(y, x);
	}

	public static Point readPoint(InputReader in) {
		double x = in.readDouble();
		double y = in.readDouble();
		return new Point(x, y);
	}

	public Point rotate(double angle) {
		double nx = x * Math.cos(angle) - y * Math.sin(angle);
		double ny = y * Math.cos(angle) + x * Math.sin(angle);
		return new Point(nx, ny);
	}
}

class Line {
	public final double a;
	public final double b;
	public final double c;

	public Line(Point p, double angle) {
		a = Math.sin(angle);
		b = -Math.cos(angle);
		c = -p.x * a - p.y * b;
	}

	public Line(double a, double b, double c) {
		double h = GeometryUtils.fastHypot(a, b);
		this.a = a / h;
		this.b = b / h;
		this.c = c / h;
	}

	public Point intersect(Line other) {
		if (parallel(other))
			return null;
		double determinant = b * other.a - a * other.b;
		double x = (c * other.b - b * other.c) / determinant;
		double y = (a * other.c - c * other.a) / determinant;
		return new Point(x, y);
	}

	public boolean parallel(Line other) {
		return Math.abs(a * other.b - b * other.a) < GeometryUtils.epsilon;
	}

	public boolean contains(Point point) {
		return Math.abs(value(point)) < GeometryUtils.epsilon;
	}

	public Line perpendicular(Point point) {
		return new Line(-b, a, b * point.x - a * point.y);
	}

	public double value(Point point) {
		return a * point.x + b * point.y + c;
	}

	public double distance(Point center) {
		return Math.abs(value(center));
	}

	@Override
	public boolean equals(Object o) {
		if (this == o)
			return true;
		if (o == null || getClass() != o.getClass())
			return false;

		Line line = (Line) o;

		if (!parallel(line))
			return false;
		if (Math.abs(a * line.c - c * line.a) > GeometryUtils.epsilon
				|| Math.abs(b * line.c - c * line.b) > GeometryUtils.epsilon)
			return false;

		return true;
	}
}

class GeometryUtils {
	public static double epsilon = 1e-8;

	public static double fastHypot(double... x) {
		if (x.length == 0)
			return 0;
		else if (x.length == 1)
			return Math.abs(x[0]);
		else {
			double sumSquares = 0;
			for (double value : x)
				sumSquares += value * value;
			return Math.sqrt(sumSquares);
		}
	}

	public static double fastHypot(double x, double y) {
		return Math.sqrt(x * x + y * y);
	}

	public static double fastHypot(double[] x, double[] y) {
		if (x.length == 0)
			return 0;
		else if (x.length == 1)
			return Math.abs(x[0] - y[0]);
		else {
			double sumSquares = 0;
			for (int i = 0; i < x.length; i++) {
				double diff = x[i] - y[i];
				sumSquares += diff * diff;
			}
			return Math.sqrt(sumSquares);
		}
	}

	public static double fastHypot(int[] x, int[] y) {
		if (x.length == 0)
			return 0;
		else if (x.length == 1)
			return Math.abs(x[0] - y[0]);
		else {
			double sumSquares = 0;
			for (int i = 0; i < x.length; i++) {
				double diff = x[i] - y[i];
				sumSquares += diff * diff;
			}
			return Math.sqrt(sumSquares);
		}
	}

	public static double missileTrajectoryLength(double v, double angle,
			double g) {
		return (v * v * Math.sin(2 * angle)) / g;
	}

	public static double sphereVolume(double radius) {
		return 4 * Math.PI * radius * radius * radius / 3;
	}

	public static double triangleSquare(double first, double second,
			double third) {
		double p = (first + second + third) / 2;
		return Math.sqrt(p * (p - first) * (p - second) * (p - third));
	}

	public static double canonicalAngle(double angle) {
		while (angle > Math.PI)
			angle -= 2 * Math.PI;
		while (angle < -Math.PI)
			angle += 2 * Math.PI;
		return angle;
	}

	public static double positiveAngle(double angle) {
		while (angle > 2 * Math.PI - GeometryUtils.epsilon)
			angle -= 2 * Math.PI;
		while (angle < -GeometryUtils.epsilon)
			angle += 2 * Math.PI;
		return angle;
	}
}

import java.util.Scanner;

public class YourWayOut {

    int total = 0;

    public int solve(int h, int exit) {
        int totalLeafs = (int) Math.pow(2, h);
        int result = totalLeafs;
        if (exit <= totalLeafs / 2) {
            result = 1 + solve2(h - 1, exit, 'L');
        } else {

            result += solve2(h - 1, exit - (totalLeafs / 2), 'R');
        }
        return result;
    }

    public int solve2(int h, int exit, char stat) {
        int totalLeafs = (int) Math.pow(2, h);
        int result = totalLeafs;
        if (exit == 0) return 0;
        if (h ==0) return 0;
//        if (h ==1) return 1;
        if (stat == 'L') {
            if (exit > totalLeafs / 2) {
                result = 1 + solve2(h - 1, exit, 'R');
            } else {
                result += solve2(h - 1, exit, 'L');
            }
        } else {

            if (exit <= totalLeafs / 2) {
                result = 1 + solve2(h - 1, exit, 'L');
            } else {
                exit -= (totalLeafs / 2);
                result += solve2(h - 1, exit, 'R');
            }
        }
        return result;

    }

    public static void main(String args[]) {
        YourWayOut r = new YourWayOut();
        Scanner in = new Scanner(System.in);
        int h = in.nextInt();
        int exit = in.nextInt();
        System.out.println(r.solve(h, exit));
//        System.out.println(r.solve(3, 6));
//        System.out.println(r.solve(1, 2));
//        System.out.println(r.solve(2, 3));
//        System.out.println(r.total);
    }
}

import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.InputStreamReader;
import java.io.IOException;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Alejandro Lopez
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskC {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            long h = in.nextLong();
            long n = in.nextLong();

            if (h == 1 && n == 1) {
                out.println(0);
                return;
            }

            long ans = 0;
            int cur = 0;
            long leaves = 1 << (h - 1);
            long subtreeSize = 1 << h;
            for (long i = h; i > 0; --i) {
                ans += 1;
                if (n > leaves) { // in right subtree
                    if (cur == 0) { // going left
                        ans += subtreeSize - 1;
                    } else { // going right
                        cur = 0;
                    }
                    n -= leaves;
                } else { // in left subtree
                    if (cur == 1) { // going right
                        ans += subtreeSize - 1;
                    } else { // going left
                        cur = 1;
                    }
                }
                leaves >>= 1;
                subtreeSize >>= 1;
            }

            out.println(ans);
        }

    }

    static class InputReader {
        BufferedReader in;
        StringTokenizer tokenizer = null;

        public InputReader(InputStream inputStream) {
            in = new BufferedReader(new InputStreamReader(inputStream));
        }

        public String next() {
            try {
                while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                    tokenizer = new StringTokenizer(in.readLine());
                }
                return tokenizer.nextToken();
            } catch (IOException e) {
                return null;
            }
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

    }
}

import java.io.*;
import java.util.*;

public class Main {

	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	static PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));
	static StringTokenizer st = new StringTokenizer("");

	public static String next() {
		try	{
		while (!st.hasMoreTokens()) {
			String s = br.readLine();
			if (s == null)
				return null;
			st = new StringTokenizer(s);
		}
		return st.nextToken();
		}	catch(Exception e)	{
			return	null;
		}
	}
	public static void main(String[] asda) throws Exception {

        int h = Integer.parseInt( next() );
        long to = Long.parseLong( next() );

        long leafs = 1L << h;
        long nonLeaf = leafs - 1;

        size = new long [h + 1];
        size[h] = 1;
        for (int k = h - 1; k >= 0; k--)
        	size[k] = (size[k + 1] << 1) + 1;

        levels = h;
        long end = nonLeaf + to;

        moves = 0;
        go(0, end, 0);

        out.println(moves);

        //
        out.flush();
        System.exit(0);
    }

	static boolean go(int level, long end, int cmd)	{
		if	( end == 1 )	{
			return	true;
		}

		if	( level == levels )	{
			// leaf
			moves++;
			return	false;
		}

        if	( size[level] < end || end < 1 )	{
        	moves += size[level];
        	return	false;
        }
		moves++;

		long leaf = size[level] + 1;
		leaf >>= 2;
        boolean isInLeft = (size[level] >> 1) + (size[level] >> 2) >= end;

		if	( cmd == 0 )	{
			// left
			if	( go(level + 1, end - leaf, cmd ^ 1) )
				return	true;

			if	( go(level + 1, end - (size[level + 1] + 1), cmd) )
				return	true;

		}	else	{
			// right
			if	( isInLeft )
				moves += size[level + 1];
			else if	( go(level + 1, end - (size[level + 1] + 1), cmd ^ 1) )
					return	true;

			if	( go(level + 1, end - leaf, cmd) )
				return	true;
		}

		return	false;
	}
	static long [] size;
	static long moves;
	static int levels;
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;
import java.util.Scanner;
import java.util.Stack;
import java.util.StringTokenizer;

import javax.xml.bind.ValidationEvent;

public class R287 {
	public static void main(String[] args) {
		//amrAndMusic(System.in);
		//amrAndPins(System.in);
//		for (int i = 0; i < 16; i++) {
//			guessYourWayOut(4, i+1);
//		}
		//guessYourWayOut(4, 4);
		guessYourWayOut(System.in);
	}

	public static void guessYourWayOut(InputStream in) {
		MyScanner scan = new MyScanner(in);
		int height = scan.nextInt();
		long n = scan.nextLong();
		guessYourWayOut(height, n);
	}

	public static void guessYourWayOut(int height, long n) {
		long b = n -1;
		int i = 0;
		long visited = 0;
		for (int h = height-1; h >= 0; h--) {
			boolean bit = (((1 << h) & b) != 0) ? true: false;
			boolean left = (i % 2 == 0) ? false : true;
			if (bit == left) {
				visited++;
			} else {
				visited += 1L << (h+1);
				i++;
			}
			i++;
			//System.out.println(h + " " + visited + " " + (bit ? 1 : 0));
		}
		System.out.println(visited);
	}

	public static void amrAndPins(InputStream in) {
		MyScanner scan = new MyScanner(in);
		long r = scan.nextInt();
		long x = scan.nextInt();
		long y = scan.nextInt();
		long x1 = scan.nextInt();
		long y1 = scan.nextInt();
		double d = Math.sqrt((x-x1)*(x-x1) + (y-y1)*(y-y1));
		int m  = (int) (Math.ceil(d / (2 * r)));
		System.out.println(m);
	}

	public static void amrAndMusic(InputStream in) {
		MyScanner scan = new MyScanner(in);
		int n = scan.nextInt();
		int k = scan.nextInt();
		int[][] inst = new int[n][2];
		for (int i = 0; i < inst.length; i++) {
			inst[i][0] = scan.nextInt();
			inst[i][1] = i+1;
		}
		Arrays.sort(inst, new Comparator<int[]>(){
			@Override
			public int compare(int[] o1, int[] o2) {
				return Integer.compare(o1[0], o2[0]);
			}
		});
		int max = 0;
		for (int i = 0; i < inst.length && k >= 0; i++) {
			k -= inst[i][0];
			if (k >= 0) {
				max++;
			}
		}
		StringBuilder sb = new StringBuilder();
		sb.append(max + "\n");
		for (int i = 0; i < max; i++) {
			sb.append(inst[i][1] + " ");
		}
		System.out.println(sb);
	}

	public static class MyScanner {
		BufferedReader br;
		StringTokenizer st;

		public MyScanner(InputStream in) {
			this.br = new BufferedReader(new InputStreamReader(in));
		}

		public void close() {
			try {
				this.br.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		String next() {
			while (st == null || !st.hasMoreElements()) {
				try {
					String s = br.readLine();
					if (s != null) {
						st = new StringTokenizer(s);
					} else {
						return null;
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			return st.nextToken();
		}

		long[] nextLongArray(int n) {
			long[] a = new long[n];
			for (int i = 0; i < a.length; i++) {
				a[i] = this.nextLong();
			}
			return a;
		}

		int[] nextIntArray(int n) {
			int[] a = new int[n];
			for (int i = 0; i < a.length; i++) {
				a[i] = this.nextInt();
			}
			return a;
		}

		int nextInt() {
			return Integer.parseInt(next());
		}

		long nextLong() {
			return Long.parseLong(next());
		}

		double nextDouble() {
			return Double.parseDouble(next());
		}

		String nextLine(){
			String str = "";
			try {
				str = br.readLine();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return str;
		}
	}
}

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringTokenizer;

public class C {

	public static void main(String[] args) throws Exception {
		Scanner sc = new Scanner(System.in);
		int h=sc.nextInt();
		int n=sc.nextInt();
		long ans=0;
		boolean left=true;
		for(int i=0;i<h;i++)
		{
			int h2=h-i;
			long x=1L<<(h2-1);
			if(n>x && left)
			{
				ans+=2*x-1;

				n-=x;
			}
			else if(n<=x && !left)
			{
				ans+=2*x-1;

				n-=x;
			}
			else
				left=!left;

			ans++;

		}
		System.out.println(ans);

	}

	static class Scanner
	{
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s) {
			br = new BufferedReader(new InputStreamReader(s));
		}

		public Scanner(String s) throws FileNotFoundException {
			br = new BufferedReader(new FileReader(s));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public String nextLine() throws IOException {
			return br.readLine();
		}

		public boolean ready() throws IOException {
			return br.ready();
		}
	}
}

import java.util.*;
import java.io.*;

public class Main {

	BufferedReader in;
	StringTokenizer str = null;
	PrintWriter out;

	private String next() throws Exception{
		while (str == null || !str.hasMoreElements())
			str = new StringTokenizer(in.readLine());
		return str.nextToken();
	}

	private int nextInt() throws Exception{
		return Integer.parseInt(next());
	}

	private long nextLong() throws Exception{
		return Long.parseLong(next());
	}

	private double nextDouble() throws Exception{
		return Double.parseDouble(next());
	}

	public void run() throws Exception{
		in =  new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);
		int h = nextInt();
		long n = nextLong();
		long r = go(h, 'L', 1, 1L<<h, n);
		out.println(r);
		out.close();
	}

	private long go(int h, char dir, long left, long right, long n) {
		// System.out.println(h + " "  + dir + " " + left + " " + right + " " + n);
		if (h == 0) return 0;
		if (dir == 'L') {
			if (left <= n && n <= (left + right) / 2 ) {
				return go(h - 1, 'R', left, (left + right) / 2, n) + 1;
			}else {
				return (1L << h) + go(h - 1, 'L', (left + right) / 2 + 1, right, n);
			}
		}else {
			if (right / 2 + 1 <= n && n <= right) {
				return go(h - 1,'L', (left + right) / 2 + 1, right, n) + 1;
			}else {
				return (1L << h) + go(h, 'L', left, (left + right) / 2, n);
			}
		}
	}

	public static void main(String[] args) throws Exception{
		new Main().run();
	}
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.StringTokenizer;

public class C287 {

	public static void main(String[] args) throws IOException {
		skp();
		int h = nextInt();
		long n = nextLong() - 1;
		long counter = 0;
		int curr = 0;
		for (int i = h; i >= 1; i--) {
			// System.out.println(((n>>(i-1))&1L)+" "+curr+" "+i+" "+Long.toBinaryString(n)+" "+(1<<i));
			if (((n >> (i - 1)) & 1L) == curr) {
				counter++;
				curr = curr ^ 1;
			} else {
				counter = counter + (1 << i);

			}

		}
		System.out.println(counter);
	}

	static boolean skp() throws IOException {
		String line = r.readLine();
		if (line == null)
			return false;
		tkn = new StringTokenizer(line);
		return true;
	}

	static int nextInt() {
		return Integer.parseInt(tkn.nextToken());
	}

	static int readInt() throws NumberFormatException, IOException {
		return Integer.parseInt(r.readLine());
	}

	static long nextLong() {
		return Long.parseLong(tkn.nextToken());
	}

	static long readLong() throws NumberFormatException, IOException {
		return Long.parseLong(r.readLine());
	}

	static double nextDouble() {

		return Double.parseDouble(tkn.nextToken());
	}

	static BufferedReader r = new BufferedReader(new InputStreamReader(
			System.in));
	static StringTokenizer tkn;
}

import java.io.*;
import java.util.*;
import java.util.Map.Entry;

public class Main {
	static long solve(long l,long r,long e,int dir) {//dir=0 ->left
		if(l==r) {
			return 0;
		}
		long mid=(l+r)>>1;
		if(e<=mid) {
			if(dir==0) {
				return 1+solve(l,mid,e,1);
			}
			else {
				long nodes=((r-l+1)*2-1)/2;
				return nodes+1+solve(l,mid,e,1);
			}
		}
		else {
			if(dir==0) {
				long nodes=((r-l+1)*2-1)/2;
				return nodes+1+solve(mid+1,r,e,0);
			}
			else {
				return 1+solve(mid+1,r,e,0);
			}
		}
	}
	public static void main(String[] args) throws IOException {
		MScanner sc=new MScanner(System.in);
		PrintWriter pw=new PrintWriter(System.out);
		int n=sc.nextInt();long e=sc.nextLong();
		pw.println(solve(1,1<<n,e,0));
		pw.flush();
	}
    static class MScanner {
		StringTokenizer st;
		BufferedReader br;

		public MScanner(InputStream system) {
			br = new BufferedReader(new InputStreamReader(system));
		}

		public MScanner(String file) throws Exception {
			br = new BufferedReader(new FileReader(file));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public String nextLine() throws IOException {
			return br.readLine();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public double nextDouble() throws IOException {
			return Double.parseDouble(next());
		}

		public char nextChar() throws IOException {
			return next().charAt(0);
		}

		public Long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public boolean ready() throws IOException {
			return br.ready();
		}

		public void waitForInput() throws InterruptedException {
			Thread.sleep(3000);
		}
	}
}

import java.util.Scanner;

public class GuessYourWayOut {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int h = sc.nextInt();
		long n = sc.nextLong();
		long leafs;
		long ans = 0;
		boolean left = true;
		while (h > 0) {
			leafs = 1L << h;
			if (n > leafs / 2) {
				// on the right
				if (left) {
					ans += numOfNodes(h - 1) + 1;
					left = true;
				} else {
					ans++;
					left = true;
				}
				if (n % 2 == 0) {
					n = n / 2;
					if (n % 2 == 1)
						n--;
				} else {
					n = n / 2;
					if (n % 2 == 0)
						n--;
				}

			} else {
				if (left) {
					ans++;
					left = false;
				} else {
					ans += numOfNodes(h - 1) + 1;
					left = false;
				}
			}
			h--;
		}
		System.out.println(ans);
	}

	private static long numOfNodes(int i) {
		long ans = 1L << (i + 1);
		return ans - 1;
	}
}

import java.awt.Point;
import java.io.*;
import java.util.*;
import java.math.BigInteger;

public class Tennis {
    static class Solver {
        public void solve(MyReader in, PrintWriter out) {
            long h = in.nextLong();
            long n = in.nextLong();

            long l = 1, r = pow(2,h);
            boolean LR = true; // true = L, false = R
            long res= 0;
            while (l<=r){
                long mid = (l+r)/2;

                if(mid == n){
                    if(l == r)out.println(res);
                    else {
                        if(LR){
                            res+=h;

                        }
                        else{
                            long ch = 2*(r-mid) -1;
                            res+=(h+ch);
                        }

                        if(l!=mid)res++;

                        out.println(res);

                    }
                    return;
                }
                else if(mid < n){
                    long ch = 2*(mid-l+1)-2;
                    res+=LR?ch+2:1;
                    l = mid+1;
                    LR = true;
                }
                else{
                    long ch = 2*(r - mid)-2;
                    res+=LR?1:ch+2;
                    r = mid;
                    LR = false;
                }

                h--;
            }
        }

        long pow(long x, long n){
            if(n == 0)return 1;
            long p = pow(x,n/2);
            if(n%2 == 0)return p*p;
            return x*p*p;
        }

    }

    public static void main(String[] args) {
        MyReader mr = new MyReader();
        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
        new Solver().solve(mr, out);
        out.close();
    }

    //    static int[][] dir = {{0,1}, {1,0},{-1,0}, {0,-1}};
//    static int[][] dir = {{0,1}, {1,0},{-1,0}, {0,-1}, {-1,-1},{-1,1}, {1,1}, {1,-1}};
    static class MyReader {
        BufferedReader br;
        StringTokenizer st;

        MyReader() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String nextLine() {
            String res = "";
            try {
                res = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return res;
        }

        int[] nextIntArray(int n) {
            int[] arr = new int[n];
            for (int i = 0; i < n; i++) {
                arr[i] = nextInt();
            }

            return arr;
        }

        Integer[] nextIntegerArray(int n) {
            Integer[] arr = new Integer[n];
            for (int i = 0; i < n; i++) {
                arr[i] = nextInt();
            }

            return arr;
        }

        Long[] nextLongArray(int n) {
            Long[] arr = new Long[n];
            for (int i = 0; i < n; i++) {
                arr[i] = nextLong();
            }

            return arr;
        }

        String[] nextStringArray(int n) {
            String[] arr = new String[n];
            for (int i = 0; i < n; i++) {
                arr[i] = next();
            }
            return arr;
        }
    }

    static void swap(int[] arr, int i, int j) {
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

}

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.io.ObjectInputStream.GetField;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TimeZone;
import java.util.TreeMap;
import java.text.*;

public class Main {
	static int h;

	public static void main(String[] args) {
		FastReader in = new FastReader();
		PrintWriter out = new PrintWriter(System.out);
		h = in.nextInt();
		long n = in.nextLong();
		long res = solve(1, 'L', (long) Math.pow(2, h), n);
		out.println(res);
		out.close();
	}

	public static long solve(int level, char dir, long leafs, long pos) {
		if (level == h + 1)
			return 0;
		char d;
		if (pos > leafs / 2l)
			d = 'R';
		else
			d = 'L';
		long path1 = -1, path2 = -1;
		if (dir == d)
			path1 = 1 + solve(level + 1, dir == 'L' ? 'R' : 'L', leafs / 2l, pos);
		else
			path2 = ((long) (Math.pow(2, h + 1 - level)) + solve(level + 1, dir, leafs / 2l, pos-leafs/2l ));
		return path1 == -1 ? path2 : path1;

	}
}

class FastReader {
	BufferedReader br;
	StringTokenizer st;

	public FastReader() {
		br = new BufferedReader(new InputStreamReader(System.in));

	}

	public FastReader(File f) throws FileNotFoundException {
		br = new BufferedReader(new FileReader(f));
	}

	String next() {
		while (st == null || !st.hasMoreElements()) {
			try {
				st = new StringTokenizer(br.readLine());

			} catch (IOException e) {
				e.printStackTrace();
			}

		}

		return st.nextToken();

	}

	int nextInt() {

		return Integer.parseInt(next());
	}

	double nextDouble() {

		return Double.parseDouble(next());
	}

	long nextLong() {

		return Long.parseLong(next());
	}

	String nextLine() {
		String str = "";
		try {
			str = br.readLine();

		} catch (IOException e) {

			e.printStackTrace();
		}
		return str;

	}
}

import java.util.Arrays;
import java.util.Scanner;

public class GuessYourWayOut {
	public static void main(String[] args) {
		Scanner sc= new Scanner(System.in);
		int h= sc.nextInt();
		long n= sc.nextLong();
		long ind=  (1L<<h)-1+n;
		long result=0L;
		long h1=h;
		long nodes[]= new long [h+1];
		nodes[h]=ind;

		for(int i=h-1; i>=0; i--)
			nodes[i]=nodes[i+1]>>1;

		//System.out.println(Arrays.toString(nodes));

		long node=1L;
		boolean left=true;
		for(int i=1; i<=h; i++){
			long next=0L;
			if(left)
				next= node<<1;
			else
				next= (node<<1)+1;
			if(next!=nodes[i]){
				result+=((1<<h1)-1);
			}
			else {

				left=!left;
			}
			result++;
			h1--;
			node=nodes[i];

		}
		System.out.println(result);
	}

}

import java.io.BufferedWriter;
import java.util.InputMismatchException;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import java.math.BigInteger;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.io.IOException;
import java.util.Arrays;
import java.io.InputStream;
import java.util.Collection;
import java.io.OutputStreamWriter;
import java.util.Comparator;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author Nguyen Trung Hieu - vuondenthanhcong11@gmail.com
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		OutputWriter out = new OutputWriter(outputStream);
		TaskC solver = new TaskC();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskC {
    public void solve(int testNumber, InputReader in, OutputWriter out) {
        int height = in.readInt();
        int idx = in.readInt();
        long actualIdx = IntegerUtils.power(2, height) - 1 + idx;
        String path = "";
        while (actualIdx > 1) {
            if (actualIdx % 2 == 1) {
                path = "R" + path;
            } else {
                path = "L" + path;
            }
            actualIdx >>= 1;
        }
        char mustBe = 'L';
        char[] next = new char[200];
        next['L'] = 'R';
        next['R'] = 'L';
        long answer = 0;
        for (char c : path.toCharArray()) {
            if (c != mustBe) {
                answer += IntegerUtils.power(2, height);
            } else {
                answer++;
            }
            mustBe = next[c];
            height--;
        }

        out.printLine(answer);
    }
}

class InputReader {
    private InputStream stream;
    private byte[] buf = new byte[1024];
    private int curChar;
    private int numChars;
    private SpaceCharFilter filter;

    public InputReader(InputStream stream) {
        this.stream = stream;
    }

    public int read() {
        if (numChars == -1)
            throw new InputMismatchException();
        if (curChar >= numChars) {
            curChar = 0;
            try {
                numChars = stream.read(buf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (numChars <= 0)
                return -1;
        }
        return buf[curChar++];
    }

    public int readInt() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        int res = 0;
        do {
            if (c < '0' || c > '9')
                throw new InputMismatchException();
            res *= 10;
            res += c - '0';
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }

    public boolean isSpaceChar(int c) {
        if (filter != null)
            return filter.isSpaceChar(c);
        return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
    }

    public interface SpaceCharFilter {
        public boolean isSpaceChar(int ch);
    }

}

class OutputWriter {
    private final PrintWriter writer;

    public OutputWriter(OutputStream outputStream) {
        writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
    }

    public void print(Object...objects) {
        for (int i = 0; i < objects.length; i++) {
            if (i != 0)
                writer.print(' ');
            writer.print(objects[i]);
        }
    }

    public void printLine(Object...objects) {
        print(objects);
        writer.println();
    }

    public void close() {
        writer.close();
    }

}

class IntegerUtils {

    public static long power(long base, long exponent) {
        if (exponent == 0)
            return 1;
        long result = power(base, exponent >> 1);
        result = result * result;
        if ((exponent & 1) != 0)
            result = result * base;
        return result;
    }

}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;

public class Main {

    public void solve(){

        int h = in.nextInt();
        n = in.nextInt();
        solve(true, 0, h);

    }

    long ans = -1;
    int n;
    long visited = 0;
    public void solve(boolean order, long val, int h){
        if(h == 0){
            if(val + 1 == n){
                ans = visited;
                out.println(ans);
                out.flush();
                out.close();
                System.exit(0);
            }
            else{
                visited++;
            }
        }
        else{
            visited ++;
            if(order){
                solve(!order, (val<<1), h-1);
                solve(order, (val<<1) ^ 1L, h-1);

            }
            else{
                solve(order, (val<<1) ^ 1L, h-1);
                solve(!order, (val<<1), h-1);

            }
        }

    }

    public static void main(String[] args){
        Main m = new Main();
        m.solve();
        m.out.flush();
        m.out.close();
    }

    InputStream inputStream;
    OutputStream outputStream;
    InputReader in;
    PrintWriter out;

    public Main(){
        inputStream = System.in;
        outputStream = System.out;
        in = new InputReader(inputStream);
        out = new PrintWriter(outputStream);
    }

}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        return tokenizer.nextToken();
    }
    public String nextLine(){
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        String s = "";
        while(tokenizer.hasMoreTokens()){
            s += tokenizer.nextToken();
            if(tokenizer.hasMoreTokens()){
                s+=" ";
            }
        }

        return s;

    }

    public int nextInt() {
        return Integer.parseInt(next());
    }
    public double nextDouble(){
        return Double.parseDouble(next());
    }

    public long nextLong(){
        return Long.parseLong(next());
    }

    public float nextFloat(){
        return Float.parseFloat(next());
    }

}

import javax.swing.text.MutableAttributeSet;
import java.io.*;
import java.util.*;

  public class Main {

      public static void main(String[] args) throws IOException {
          Scanner input = new Scanner(System.in);
          int h = input.nextInt();
          long n = input.nextLong();
          long ans = 0;
          boolean left = true;
          while (h != 0) {
              if (n > ((1 << h)/2) && left) {
                  ans += (1 << h);
                  n -= ((1<<h)/2);
                  h--;
              } else if (n <= ((1 << h)/2) && !left) {
                  ans += (1 << h);
                  h--;
              } else {
                  ans++;
                  if(!left)
                      n -= ((1<<h)/2);
                  h--;
                  left ^= true;
               }
           }

          System.out.println(ans);
      }
  }

import java.util.*;
import java.io.*;

public class Main implements Runnable {

	public void solve() throws IOException {

	}

	//-----------------------------------------------------------
	public static void main(String[] args) {
		new Main().run();
	}

        public void debug(Object... arr){
            System.out.println(Arrays.deepToString(arr));
        }

        public void print1Int(int[] a){
                for(int i = 0; i < a.length; i++)
                        System.out.print(a[i] + " ");
                System.out.println();
        }

        public void print2Int(int[][] a){
                for(int i = 0; i < a.length; i++){
                        for(int j = 0; j < a[0].length; j++){
                                System.out.print(a[i][j] + " ");
                        }
                        System.out.println();
                }
        }

	public void run() {
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
                        out = new PrintWriter(System.out);
			tok = null;
			solve();
			in.close();
                        out.close();
		} catch (IOException e) {
			System.exit(0);
		}
	}

	public String nextToken() throws IOException {
		while (tok == null || !tok.hasMoreTokens()) {
			tok = new StringTokenizer(in.readLine());
		}
		return tok.nextToken();
	}

	public int nextInt() throws IOException {
		return Integer.parseInt(nextToken());
	}

	public long nextLong() throws IOException {
		return Long.parseLong(nextToken());
	}

	public double nextDouble() throws IOException {
		return Double.parseDouble(nextToken());
	}
        PrintWriter out;
	BufferedReader in;
	StringTokenizer tok;
}

import java.util.Scanner;

public class GuessYourWayOut {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int h = sc.nextInt();
		long n = sc.nextLong();
		long leafs;
		long ans = 0;
		boolean left = true;
		while (h > 0) {
			leafs = 1L << h;
			if (n > leafs / 2) {
				// on the right
				if (left) {
					ans += numOfNodes(h - 1) + 1;
					left = true;
				} else {
					ans++;
					left = true;
				}
				if (n % 2 == 0) {
					n = n / 2;
					if (n % 2 == 1)
						n--;
				} else {
					n = n / 2;
					if (n % 2 == 0)
						n--;
				}

			} else {
				if (left) {
					ans++;
					left = false;
				} else {
					ans += numOfNodes(h - 1) + 1;
					left = true;
				}
			}
			h--;
		}
		System.out.println(ans);
	}

	private static long numOfNodes(int i) {
		long ans = 1L << (i + 1);
		return ans - 1;
	}
}

import java.io.*;
import java.util.*;

public class problem507C {
	public static void main (String[]args)throws IOException{
		BufferedReader x=new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st=new StringTokenizer(x.readLine());
		int h=Integer.parseInt(st.nextToken());
		int n=Integer.parseInt(st.nextToken());
		String s=Integer.toBinaryString(n-1);
		for (int i=0; i<h-s.length(); i++){
			s="0"+s;
		}
		int ans=0;
		if (s.charAt(0)=='0')ans++;else{ans+=Math.pow(2,h);}
		for (int i=1; i<s.length(); i++){
			if (((s.charAt(i)-'0')+(s.charAt(i-1)-'0'))%2==0){
				ans+=Math.pow(2,h-i);
			}else{
				ans++;
			}
		}
		System.out.println(ans);
	}
}

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringTokenizer;

public class B {

	public static void main(String[] args) throws Exception {
		Scanner sc = new Scanner(System.in);
		int h=sc.nextInt();
		long n=sc.nextLong();
		long ans=0;
		boolean left=true;
		for(int i=0;i<h;i++)
		{
			int h2=h-i;
			long x=1L<<(h2-1);
			if(n>x && left)
			{
				ans+=2*x-1;

				n-=x;
			}
			else if(n<=x && !left)
			{
				ans+=2*x-1;

				n-=x;
			}
			else
				left=!left;

			ans++;

		}
		System.out.println(ans);

	}

	static class Scanner
	{
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s) {
			br = new BufferedReader(new InputStreamReader(s));
		}

		public Scanner(String s) throws FileNotFoundException {
			br = new BufferedReader(new FileReader(s));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public String nextLine() throws IOException {
			return br.readLine();
		}

		public boolean ready() throws IOException {
			return br.ready();
		}
	}
}

import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.util.StringTokenizer;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author Vitalii Kozhukhivskyi
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }
}

class TaskC {
    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int h = in.nextInt();
        long n = in.nextLong();
        long res = 0;
        char curMove = 'L';
        for (int i = 0; i < h; i++) {
            long cur = 1L << (h - i);
            char neededMove = (n > cur / 2) ? 'R' : 'L';
            if (curMove != neededMove) {
                res += cur - 1;
                if (neededMove == 'R') {
                    n -= cur / 2;
                }
            } else {
                curMove = (curMove == 'L') ? 'R' : 'L';
            }
        }
        out.println(res + h);
    }
}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

}

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.InputMismatchException;

public class TaskC {

	public FasterScanner mFScanner;
	public PrintWriter mOut;
	private static final boolean LEFT = true;
	private static final boolean RIGHT = false;
	private static boolean sFound;

	public TaskC() {
		mFScanner = new FasterScanner();
		mOut = new PrintWriter(System.out);
	}

	public void solve() {
		int h;
		long visNodes;
		long n;

		h = mFScanner.nextInt();
		n = mFScanner.nextInt();

		sFound = false;

		visNodes = dfs(n, LEFT, h, 1, (1L << h));

		mOut.println(visNodes);

	}

	public long dfs(long child, boolean dir, int height, long begin, long end) {

		long sum = 1;
		long temp;

		if (height == 0 && begin == child) {
			sFound = true;
			return 0;
		}

		if (height == 0)
			return 1;

		if (child >= begin && child <= end) {
			temp = end - begin + 1;
			temp /= 2;

			if (dir == LEFT) {
				sum += dfs(child, RIGHT, height - 1, begin, begin + temp - 1);
			} else {
				sum += dfs(child, LEFT, height - 1, end - temp + 1, end);
			}

			dir = !dir;

			if (!sFound) {
				if (dir == LEFT) {
					sum += dfs(child, RIGHT, height - 1, begin, begin + temp
							- 1);
				} else {
					sum += dfs(child, LEFT, height - 1, end - temp + 1, end);
				}
			}

		} else {
			sum += (1L << (height + 1)) - 2;
		}

		return sum;

	}

	public void flush() {
		mOut.flush();
	}

	public void close() {
		mOut.close();
	}

	public static void main(String[] args) {
		TaskC mSol = new TaskC();
		mSol.solve();
		mSol.flush();
		mSol.close();
	}

	class FasterScanner {
		private InputStream mIs;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;

		public FasterScanner() {
			this(System.in);
		}

		public FasterScanner(InputStream is) {
			mIs = is;
		}

		public int read() {
			if (numChars == -1)
				throw new InputMismatchException();
			if (curChar >= numChars) {
				curChar = 0;
				try {
					numChars = mIs.read(buf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (numChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public String nextLine() {
			int c = read();
			while (isSpaceChar(c))
				c = read();
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = read();
			} while (!isEndOfLine(c));
			return res.toString();
		}

		public String nextString() {
			int c = read();
			while (isSpaceChar(c))
				c = read();
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = read();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public long nextLong() {
			int c = read();
			while (isSpaceChar(c))
				c = read();
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = read();
			}
			long res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public int nextInt() {
			int c = read();
			while (isSpaceChar(c))
				c = read();
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = read();
			}
			int res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public double nextDouble() {
			Double next;
			next = Double.parseDouble(nextString());
			return next;
		}

		public boolean isSpaceChar(int c) {
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		public boolean isEndOfLine(int c) {
			return c == '\n' || c == '\r' || c == -1;
		}

		public char[] nextCharArray(int N) {
			int i;
			char[] array;
			String str;

			array = new char[N];

			i = 0;

			str = nextLine();

			for (i = 0; i < N && i < str.length(); i++) {
				array[i] = str.charAt(i);
			}

			return array;
		}

		public char[][] nextChar2DArray(int M, int N) {
			int i;
			char[][] array;

			array = new char[M][N];

			i = 0;

			for (i = 0; i < M; i++) {
				array[i] = nextCharArray(N);
			}

			return array;
		}

		public int[] nextIntArray(int N) {
			int i;
			int[] array;

			array = new int[N];

			i = 0;

			for (i = 0; i < N; i++) {
				array[i] = nextInt();
			}

			return array;
		}

		public int[][] nextInt2DArray(int M, int N) {
			int i;
			int[][] array;

			array = new int[M][N];

			i = 0;

			for (i = 0; i < M; i++) {
				array[i] = nextIntArray(N);
			}

			return array;
		}

		public long[] nextLongArray(int N) {
			int i;
			long[] array;

			array = new long[N];

			i = 0;

			for (i = 0; i < N; i++) {
				array[i] = nextLong();
			}

			return array;
		}

		public long[][] nextLong2DArray(int M, int N) {
			int i;
			long[][] array;

			array = new long[M][N];

			i = 0;

			for (i = 0; i < M; i++) {
				array[i] = nextLongArray(N);
			}

			return array;
		}

		public double[] nextDoubleArray(int N) {
			int i;
			double[] array;

			array = new double[N];

			for (i = 0; i < N; i++) {
				array[i] = nextDouble();
			}

			return array;
		}

		public double[][] nextDouble2DArray(int M, int N) {
			int i;
			double[][] array;

			array = new double[M][N];

			for (i = 0; i < M; i++) {
				array[i] = nextDoubleArray(N);
			}

			return array;
		}

	}
}

import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.InputStreamReader;
import java.io.IOException;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Alejandro Lopez
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskC {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            long h = in.nextLong();
            long n = in.nextLong();

            if (h == 1 && n == 1) {
                out.println(0);
                return;
            }

            long ans = 0;
            int cur = 0;
            long leaves = 1l << (h - 1);
            long subtreeSize = 1l << h;
            for (long i = h; i > 0; --i) {
                ans += 1;
                if (n > leaves) {
                    if (cur == 0) {
                        ans += subtreeSize - 1;
                    } else {
                        cur = 0;
                    }
                    n -= leaves;
                } else {
                    if (cur == 1) {
                        ans += subtreeSize - 1;
                    } else {
                        cur = 1;
                    }
                }
                leaves >>= 1;
                subtreeSize >>= 1;
            }

            out.println(ans);
        }

    }

    static class InputReader {
        BufferedReader in;
        StringTokenizer tokenizer = null;

        public InputReader(InputStream inputStream) {
            in = new BufferedReader(new InputStreamReader(inputStream));
        }

        public String next() {
            try {
                while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                    tokenizer = new StringTokenizer(in.readLine());
                }
                return tokenizer.nextToken();
            } catch (IOException e) {
                return null;
            }
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

    }
}

import java.io.*;
import java.util.*;

public class problem507C {
	public static void main (String[]args)throws IOException{
		BufferedReader x=new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st=new StringTokenizer(x.readLine());
		int h=Integer.parseInt(st.nextToken());
		int n=Integer.parseInt(st.nextToken());
		String s=Integer.toBinaryString(n-1);
		int ans=0;
		if (s.charAt(0)=='0')ans++;else{ans+=Math.pow(2,h);}
		for (int i=1; i<s.length(); i++){
			if (((s.charAt(i)-'0')+(s.charAt(i-1)-'0'))%2==0){
				ans+=Math.pow(2,h-i);
			}else{
				ans++;
			}
		}
		System.out.println(ans);
	}
}

import java.io.*;
import java.util.*;

public class Main {

	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	static PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));
	static StringTokenizer st = new StringTokenizer("");

	public static String next() {
		try	{
		while (!st.hasMoreTokens()) {
			String s = br.readLine();
			if (s == null)
				return null;
			st = new StringTokenizer(s);
		}
		return st.nextToken();
		}	catch(Exception e)	{
			return	null;
		}
	}
	public static void main(String[] asda) throws Exception {

        int h = Integer.parseInt( next() );
        long to = Long.parseLong( next() );

        long leafs = 1L << h;
        long nonLeaf = leafs - 1;

        size = new long [h + 1];
        size[h] = 1;
        for (int k = h - 1; k >= 0; k--)
        	size[k] = (size[k + 1] << 1) + 1;

        levels = h;
        long end = nonLeaf + to;

        moves = 0;
        go(0, end, 0);

        out.println(moves);

        //
        out.flush();
        System.exit(0);
    }

	static boolean go(int level, long end, int cmd)	{
		if	( end == 1 )	{
			return	true;
		}

		if	( level == levels )	{
			// leaf
			moves++;
			return	false;
		}

        if	( size[level] < end )	{
        	moves += size[level];
        	return	false;
        }
		moves++;

		long leaf = size[level] + 1;
		leaf >>= 1;
        leaf >>= 1;

		if	( cmd == 0 )	{
			// left
			if	( go(level + 1, end - leaf, cmd ^ 1) )
				return	true;

			if	( go(level + 1, end - (size[level + 1] + 1), cmd) )
				return	true;

		}	else	{
			// right
			if	( go(level + 1, end - (size[level + 1] + 1), cmd) )
				return	true;

			if	( go(level + 1, end - leaf, cmd ^ 1) )
				return	true;
		}

		return	false;
	}
	static long [] size;
	static long moves;
	static int levels;
}

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.InputMismatchException;

public class TaskC {

	public FasterScanner mFScanner;
	public PrintWriter mOut;
	private static final boolean LEFT = true;
	private static final boolean RIGHT = false;
	private static boolean sFound;

	public TaskC() {
		mFScanner = new FasterScanner();
		mOut = new PrintWriter(System.out);
	}

	public void solve() {
		int h;
		long visNodes;
		long n;

		h = mFScanner.nextInt();
		n = mFScanner.nextInt();

		sFound = false;

		visNodes = dfs(n, LEFT, h, 1, (1 << h));

		mOut.println(visNodes);

	}

	public long dfs(long child, boolean dir, int height, long begin, long end) {

		long sum = 1;
		long temp;

		if (height == 0 && begin == child) {
			sFound = true;
			return 0;
		}

		if (height == 0)
			return 1;

		if (child >= begin && child <= end) {
			temp = end - begin + 1;
			temp /= 2;

			if (dir == LEFT) {
				sum += dfs(child, RIGHT, height - 1, begin, begin + temp - 1);
			} else {
				sum += dfs(child, LEFT, height - 1, end - temp + 1, end);
			}

			dir = !dir;

			if (!sFound) {
				if (dir == LEFT) {
					sum += dfs(child, RIGHT, height - 1, begin, begin + temp
							- 1);
				} else {
					sum += dfs(child, LEFT, height - 1, end - temp + 1, end);
				}
			}

		} else {
			sum += (1L << (height + 1)) - 2;
		}

		return sum;

	}

	public void flush() {
		mOut.flush();
	}

	public void close() {
		mOut.close();
	}

	public static void main(String[] args) {
		TaskC mSol = new TaskC();
		mSol.solve();
		mSol.flush();
		mSol.close();
	}

	class FasterScanner {
		private InputStream mIs;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;

		public FasterScanner() {
			this(System.in);
		}

		public FasterScanner(InputStream is) {
			mIs = is;
		}

		public int read() {
			if (numChars == -1)
				throw new InputMismatchException();
			if (curChar >= numChars) {
				curChar = 0;
				try {
					numChars = mIs.read(buf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (numChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public String nextLine() {
			int c = read();
			while (isSpaceChar(c))
				c = read();
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = read();
			} while (!isEndOfLine(c));
			return res.toString();
		}

		public String nextString() {
			int c = read();
			while (isSpaceChar(c))
				c = read();
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = read();
			} while (!isSpaceChar(c));
			return res.toString();
		}

		public long nextLong() {
			int c = read();
			while (isSpaceChar(c))
				c = read();
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = read();
			}
			long res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public int nextInt() {
			int c = read();
			while (isSpaceChar(c))
				c = read();
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = read();
			}
			int res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			} while (!isSpaceChar(c));
			return res * sgn;
		}

		public double nextDouble() {
			Double next;
			next = Double.parseDouble(nextString());
			return next;
		}

		public boolean isSpaceChar(int c) {
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		public boolean isEndOfLine(int c) {
			return c == '\n' || c == '\r' || c == -1;
		}

		public char[] nextCharArray(int N) {
			int i;
			char[] array;
			String str;

			array = new char[N];

			i = 0;

			str = nextLine();

			for (i = 0; i < N && i < str.length(); i++) {
				array[i] = str.charAt(i);
			}

			return array;
		}

		public char[][] nextChar2DArray(int M, int N) {
			int i;
			char[][] array;

			array = new char[M][N];

			i = 0;

			for (i = 0; i < M; i++) {
				array[i] = nextCharArray(N);
			}

			return array;
		}

		public int[] nextIntArray(int N) {
			int i;
			int[] array;

			array = new int[N];

			i = 0;

			for (i = 0; i < N; i++) {
				array[i] = nextInt();
			}

			return array;
		}

		public int[][] nextInt2DArray(int M, int N) {
			int i;
			int[][] array;

			array = new int[M][N];

			i = 0;

			for (i = 0; i < M; i++) {
				array[i] = nextIntArray(N);
			}

			return array;
		}

		public long[] nextLongArray(int N) {
			int i;
			long[] array;

			array = new long[N];

			i = 0;

			for (i = 0; i < N; i++) {
				array[i] = nextLong();
			}

			return array;
		}

		public long[][] nextLong2DArray(int M, int N) {
			int i;
			long[][] array;

			array = new long[M][N];

			i = 0;

			for (i = 0; i < M; i++) {
				array[i] = nextLongArray(N);
			}

			return array;
		}

		public double[] nextDoubleArray(int N) {
			int i;
			double[] array;

			array = new double[N];

			for (i = 0; i < N; i++) {
				array[i] = nextDouble();
			}

			return array;
		}

		public double[][] nextDouble2DArray(int M, int N) {
			int i;
			double[][] array;

			array = new double[M][N];

			for (i = 0; i < M; i++) {
				array[i] = nextDoubleArray(N);
			}

			return array;
		}

	}
}

import java.io.InputStreamReader;
import java.io.IOException;
import java.util.InputMismatchException;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.Writer;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author Niyaz Nigmatullin
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		FastScanner in = new FastScanner(inputStream);
		FastPrinter out = new FastPrinter(outputStream);
		TaskC solver = new TaskC();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskC {
    public void solve(int testNumber, FastScanner in, FastPrinter out) {
        int h = in.nextInt();
        long n = in.nextLong();
        n = (1 << h) - n + 1;
        long leaves = 1 << h;
        long ans = 0;
        for (int i = 0; i < h; i++) {
            leaves /= 2;
            if (n > leaves) {
                n = 2 * leaves - n + 1;
                ++ans;
            } else {
                ans += 2 * leaves;
            }
        }
        out.println(ans);
    }
}

class FastScanner extends BufferedReader {

    public FastScanner(InputStream is) {
        super(new InputStreamReader(is));
    }

    public int read() {
        try {
            int ret = super.read();
//            if (isEOF && ret < 0) {
//                throw new InputMismatchException();
//            }
//            isEOF = ret == -1;
            return ret;
        } catch (IOException e) {
            throw new InputMismatchException();
        }
    }

    public String next() {
        StringBuilder sb = new StringBuilder();
        int c = read();
        while (isWhiteSpace(c)) {
            c = read();
        }
        if (c < 0) {
            return null;
        }
        while (c >= 0 && !isWhiteSpace(c)) {
            sb.appendCodePoint(c);
            c = read();
        }
        return sb.toString();
    }

    static boolean isWhiteSpace(int c) {
        return c >= 0 && c <= 32;
    }

    public int nextInt() {
        int c = read();
        while (isWhiteSpace(c)) {
            c = read();
        }
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        int ret = 0;
        while (c >= 0 && !isWhiteSpace(c)) {
            if (c < '0' || c > '9') {
                throw new NumberFormatException("digit expected " + (char) c
                        + " found");
            }
            ret = ret * 10 + c - '0';
            c = read();
        }
        return ret * sgn;
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

    public String readLine() {
        try {
            return super.readLine();
        } catch (IOException e) {
            return null;
        }
    }

}

class FastPrinter extends PrintWriter {

    public FastPrinter(OutputStream out) {
        super(out);
    }

    public FastPrinter(Writer out) {
        super(out);
    }

}

import java.util.InputMismatchException;
import java.util.Scanner;

public class node1 {

	public static long generer(int h,Long n)
	{
		long result=0;
		long interval=(long) Math.pow(2,h-1);
		int i=1;
		int direction=0;

		while(i<=h)
		{
			if(n<=interval && direction==0)
			{
				result=result+1;
				i++;
				interval=(long) (interval-Math.pow(2,h-i));
				direction=1;
			}
			else if(n<=interval && direction==1)
			{
				for(int j=0;j<=h-i;j++)
				{
					result=(long) (result+Math.pow(2,j));
				}
				result++;
				i++;
				interval=(long) (interval-Math.pow(2,h-i));
				direction=1;
			}
			else if(n>interval && direction==1)
			{
				result=result+1;
				i++;
				interval=(long) (interval+Math.pow(2,h-i));
				direction=0;
			}
			else if(n>interval && direction==0)
			{
				for(int j=0;j<=h-i;j++)
				{
					result=(long) (result+Math.pow(2,j));
				}
				result++;
				i++;
				interval=(long) (interval+Math.pow(2,h-i));
				direction=0;
			}

			}

		return result;

	}

	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);
		try{

		int h=sc.nextInt();
		long n=sc.nextLong();

		if(h>=1 && h<=50 && 1<=n && n<=(long)Math.pow(2,h))
			System.out.println(generer(39,n));
		}
		catch(InputMismatchException e)
		{

		}

	}

}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class GuessYourWayOut {

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String str[] = br.readLine().trim().split(" ");
		long n = Long.parseLong(str[0]);
		long k = Long.parseLong(str[1]);
		long t = 1<<n;
		boolean p = false;
		long s = 0;
		while(t!=1) {
			if((k<=t/2 && !p) || (k>t/2 && p)) {
				if(p)
					k = k-t/2;
				s++;
				p=!p;
			}
			else {
				if(!p)
					k = k-t/2;
				s = s+t;
			}
			t = t>>1;
		}
		System.out.println(s);
	}

}

import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskC solver = new TaskC();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskC {
    public void solve(int testNumber, InputReader in, PrintWriter out) {
        long h = in.nextInt();
        long n = in.nextLong();
        long max = (1L << (h));
        long ans = ways(1, max, h, n);
        out.println(ans);
    }

    private long ways(long min, long max, long h, long n) {
        if (min == max) {
            return 1;
        }
        long mid = (min + max) / 2L;
        if (n <= mid) {
            return ways(min, mid, h - 1, n);
        } else {
            long rest = h > 1 ? ((1 << h) - 1L) : 0L;
            return 1L + rest + ways(1L+mid, max, h - 1, n);
        }
    }
}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }
}

import java.util.Arrays;
import java.util.Scanner;

public class GuessYourWayOut {
	public static void main(String[] args) {
		Scanner sc= new Scanner(System.in);
		int h= sc.nextInt();
		long n= sc.nextLong();
		long ind=  (1L<<h)-1+n;
		long result=0L;
		long h1=h;
		long nodes[]= new long [h+1];
		nodes[h]=ind;

		for(int i=h-1; i>=0; i--)
			nodes[i]=nodes[i+1]>>1;

		//System.out.println(Arrays.toString(nodes));

		long node=1L;
		boolean left=true;
		for(int i=1; i<=h; i++){
			long next=0L;
			if(left)
				next= node<<1;
			else
				next= (node<<1)+1;
			if(next!=nodes[i]){
				result+=((1<<h1)-1);
			}
			else {

				left=!left;
			}
			result++;
			h1--;
			node=nodes[i];

		}
		System.out.println(result);
	}

}

import java.io.*;
import java.util.*;

import static java.lang.Math.*;

public class Main extends PrintWriter {
    BufferedReader in;
    StringTokenizer stok;
    final Random rand = new Random(31);
    final int inf = (int) 1e9;
    final long linf = (long) 1e18;

    final static String IO = "_std";

    void solve() throws IOException {
        int h = nextInt();
        long n = nextLong() - 1;
        int cur = 0;
        long ans = 0;
        for (int i = 0; i < h; i++) {
            long t = n / (1 << (h - i - 1));
            if (t != cur) {
                ans += (1 << (h - i)) - 1;
            } else {
                cur = 1 - cur;
            }
            if (t == 1) {
                n -= 1 << (h - i - 1);
            }
            ans++;
        }
        println(ans);
    }

    Main() {
        super(System.out);
        in = new BufferedReader(new InputStreamReader(System.in));
    }

    Main(String fileIn, String fileOut) throws IOException {
        super(fileOut);
        in = new BufferedReader(new FileReader(fileIn));
    }

    public static void main(String[] args) throws IOException {
        Main main;
        if ("_std".equals(IO)) {
            main = new Main();
        } else if ("_iotxt".equals(IO)) {
            main = new Main("input.txt", "output.txt");
        } else {
            main = new Main(IO + ".in", IO + ".out");
        }
        main.solve();
        main.close();
    }

    String next() throws IOException {
        while (stok == null || !stok.hasMoreTokens()) {
            String s = in.readLine();
            if (s == null) {
                return null;
            }
            stok = new StringTokenizer(s);
        }
        return stok.nextToken();
    }

    int nextInt() throws IOException {
        return Integer.parseInt(next());
    }

    long nextLong() throws IOException {
        return Long.parseLong(next());
    }

    double nextDouble() throws IOException {
        return Double.parseDouble(next());
    }

    int[] nextIntArray(int len) throws IOException {
        int[] a = new int[len];
        for (int i = 0; i < len; i++) {
            a[i] = nextInt();
        }
        return a;
    }

    int[] nextIntArraySorted(int len) throws IOException {
        int[] a = nextIntArray(len);
        shuffle(a);
        Arrays.sort(a);
        return a;
    }

    void shuffle(int[] a) {
        for (int i = 1; i < a.length; i++) {
            int x = rand.nextInt(i + 1);
            int _ = a[i];
            a[i] = a[x];
            a[x] = _;
        }
    }

    void shuffleAndSort(int[] a) {
        shuffle(a);
        Arrays.sort(a);
    }

    boolean nextPermutation(int[] p) {
        for (int a = p.length - 2; a >= 0; --a) {
            if (p[a] < p[a + 1])
                for (int b = p.length - 1; ; --b)
                    if (p[b] > p[a]) {
                        int t = p[a];
                        p[a] = p[b];
                        p[b] = t;
                        for (++a, b = p.length - 1; a < b; ++a, --b) {
                            t = p[a];
                            p[a] = p[b];
                            p[b] = t;
                        }
                        return true;
                    }
        }
        return false;
    }

    <T> List<T>[] createAdjacencyList(int n) {
        List<T>[] res = new List[n];
        for (int i = 0; i < n; i++) {
            res[i] = new ArrayList<>();
        }
        return res;
    }
}

import java.util.Scanner;

public class GuessYourWayOut {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int h = sc.nextInt();
		long n = sc.nextLong();
		long leafs;
		long ans = 0;
		boolean left = true;
		while (h > 0) {
			leafs = 1L << h;
			if (n > leafs / 2) {
				// on the right
				if (left) {
					ans += numOfNodes(h - 1) + 1;
					left = true;
				} else {
					ans++;
					left = true;
				}
				if (n % 2 == 0) {
					n = n / 2;
					if (n % 2 == 1)
						n--;
				} else {
					n = n / 2;
					if (n % 2 == 0)
						n--;
				}

			} else {
				if (left) {
					ans++;
					left = false;
				} else {
					ans += numOfNodes(h - 1) + 1;
					left = true;
				}
			}
			h--;
		}
		System.out.println(ans);
	}

	private static long numOfNodes(int i) {
		long ans = 1L << (i + 1);
		return ans - 1;
	}
}

import java.util.*;
public class C2 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int h = scanner.nextInt();
        long n = scanner.nextLong() - (long)Math.pow(2, 32);

        long k = 0;
        char[] have = new char[h];
        char[] need = new char[h];
        for (int i = 0; i < h; i++) {
            have[i] = i%2 == 0 ? 'L' : 'R';
            if (n <= k + Math.pow(2, h - 1 - i) - (long)Math.pow(2, 32)) {
                need[i] = 'L';
            }
            else {
                need[i] = 'R';
                k += Math.pow(2, h - 1 - i);
            }
        }

        int res = h;
        for (int i = 0; i < h; i++) {
            if (have[i] != need[i]) {
                res += Math.pow(2, h-i)-1;
                for (int j = i+1; j < h; j++) {
                    have[j] = (j-i-1)%2 == 0 ? have[i] : need[i];
                }
            }
        }

        System.out.println(res);
    }
}

import java.util.Scanner;

public class Main {

	public static void main(String[] args)
	{
		Scanner s=new Scanner(System.in);

		long h=s.nextLong();
		long n=s.nextLong();

		String path=Long.toBinaryString(n-1);

		char[] arr=new char[(int)h];

		int ptr=(int)(h-1);

		for(int j=path.length()-1;j>=0;j--)
		{
			arr[ptr]=path.charAt(j);
			ptr--;
		}

		char curr='0';

		long count=0;

		for(int i=0;i<h;i++)
		{
			if(arr[i]!=curr)
			{
				count=count+(long)((Math.pow(2,h-i+1)-2)/2)+1;
				curr='0';
			}
			else
			{
				if(curr=='0')
					curr='1';
				else
					curr='0';

				count++;
			}
		}

		System.out.println(count);

	}

}

import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;

public class Solution{

	public static void main(String[] args){
		Scanner scan = new Scanner(System.in);
		long h = scan.nextLong();
		long exit = scan.nextLong() - 1;
		long count = 0;
		boolean leftFirst = true;
		int base = 1;
		while(h > 0){
			count ++;
			if(leftFirst && exit < (base << (h - 1))){
				leftFirst = false;
			} else if(leftFirst && exit >= (base << (h - 1))){
				leftFirst = true;
				count += ((base << h) - 1);
			} else if(exit < (base << (h - 1))){
				leftFirst = false;
				count += ((base << h) - 1);
			} else{
				leftFirst = true;
			}
			exit = exit % (base << (h - 1));
			h --;
		}
		System.out.println(count);
		scan.close();
	}
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.*;

public class GuessYourWayOut {

    public static void main(String[] args) {
        InputReader in = new InputReader(System.in);

        long h = in.nextLong();
        long n = in.nextLong();

        long ans = 0;
        boolean left = true;
        while (h > 0) {
            ++ans;
            if ((left && n > (1 << (h - 1))) || (!left && n <= (1 << (h - 1)))) {
                ans += (1 << h) - 1;
                n -= (1 << (h - 1));
            } else {
                left = !left;
            }
            --h;
        }

        System.out.println(ans);
    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream));
            tokenizer = new StringTokenizer("");
        }

        public String next() {
            try {
                while (!tokenizer.hasMoreTokens())
                    tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

            return tokenizer.nextToken();
        }

        public String nextLine() {
            String line = null;
            try {
                tokenizer = new StringTokenizer("");
                line =  reader.readLine();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            return line;
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public double nextDouble() {
            return Double.parseDouble(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

        boolean hasNext() {
            while (!tokenizer.hasMoreTokens()) {
                String line = nextLine();
                if (line == null) return false;
                tokenizer = new StringTokenizer(line);
            }
            return true;
        }
    }
}

import java.io.*;
import java.util.*;

public class Main {

	static BufferedReader br = new BufferedReader(new InputStreamReader(
			System.in));
	static PrintWriter out = new PrintWriter(new BufferedOutputStream(
			System.out));
	static StringTokenizer st = new StringTokenizer("");

	public static String next() {
		try	{
		while (!st.hasMoreTokens()) {
			String s = br.readLine();
			if (s == null)
				return null;
			st = new StringTokenizer(s);
		}
		return st.nextToken();
		}	catch(Exception e)	{
			return	null;
		}
	}
	public static void main(String[] asda) throws Exception {

        int h = Integer.parseInt( next() );
        int to = Integer.parseInt( next() );

        long leafs = 1L << h;
        long nonLeaf = leafs - 1;

        size = new long [h + 1];
        size[h] = 1;
        for (int k = h - 1; k >= 0; k--)
        	size[k] = (size[k + 1] << 1) + 1;

        levels = h;
        end = nonLeaf + to;

        moves = 0;
        go(0, end, 0);

        out.println(moves);

        //
        out.flush();
        System.exit(0);
    }

	static boolean go(int level, long end, int cmd)	{
		if	( end == 1 )	{
			return	true;
		}

		if	( level == levels )	{
			// leaf
			moves++;
			return	false;
		}

        if	( size[level] < end )	{
        	moves += size[level];
        	return	false;
        }
		moves++;

		long leaf = size[level] + 1;
		leaf >>= 1;
        leaf >>= 1;

		if	( cmd == 0 )	{
			// left
			if	( go(level + 1, end - leaf, cmd ^ 1) )
				return	true;

			if	( go(level + 1, end - (size[level + 1] + 1), cmd) )
				return	true;

		}	else	{
			// right
			if	( go(level + 1, end - (size[level + 1] + 1), cmd) )
				return	true;

			if	( go(level + 1, end - leaf, cmd ^ 1) )
				return	true;
		}

		return	false;
	}
	static long [] size;
	static long moves, end;
	static int levels;
}

import java.util.Scanner;

public class YourWayOut {

    public long solve(int h, long exit) {
        long totalLeafs = (long) Math.pow(2, h);
        long result = totalLeafs;
        if (exit <= totalLeafs / 2) {
            result = 1 + solve2(h - 1, exit, 'L');
        } else {

            result += solve2(h - 1, exit - (totalLeafs / 2), 'R');
        }
        return result;
    }

    public long solve2(int h, long exit, char stat) {
        long totalLeafs = (long) Math.pow(2, h);
        long result = totalLeafs;
        if (exit == 0) return 1;
//        if (h ==1) return 1;
        if (h ==0) return 0;
//        if (h ==1) return 1;
//        System.out.println(h+","+exit+","+stat);
        if (stat == 'L') {
            if (exit >= totalLeafs / 2) {
                exit -= (totalLeafs / 2);
                result = 1 + solve2(h - 1, exit, 'R');
            } else {
//
                result += solve2(h - 1, exit, 'L');
            }
        } else {

            if (exit <= totalLeafs / 2) {

                result = 1 + solve2(h - 1, exit, 'L');
            } else {
                exit -= (totalLeafs / 2);

                result += solve2(h - 1, exit, 'R');
            }
        }
        return result;

    }

    public static void main(String args[]) {
        YourWayOut r = new YourWayOut();
        Scanner in = new Scanner(System.in);
        int h = in.nextInt();
        long exit = in.nextLong();
        System.out.println(r.solve(h, exit));
//        System.out.println(r.solve(3, 6));
//        System.out.println(r.solve(1, 2));
//        System.out.println(r.solve(2, 3));
//        System.out.println(r.solve(10, 1024));
//        System.out.println(r.solve(10, 577));
//        System.out.println(r.total);
    }
}

/* package whatever; // don't place package name! */

import java.util.*;
import java.lang.*;
import java.io.*;

/* Name of the class has to be "Main" only if the class is public. */
public class Ideone
{
	public static void main (String[] args) throws java.lang.Exception
	{
		// your code goes here
		Scanner sc=new Scanner(System.in);
		long h=sc.nextLong(),n=sc.nextLong();
		long[] pow2=new long[(int)h+1];
		int pow=1;
		for(int i=0;i<=h;i++){pow2[i]=pow;pow*=2;}
		Stack<Integer> snu=new Stack<>();
		Stack<Character> sch=new Stack<>();
		snu.push(1);
		if(n%2!=0)sch.push('L');
		else sch.push('R');
		n=(int)Math.ceil((((double)n)/2));
		while(snu.peek()!=h){
			snu.push(snu.peek()+1);
			if(n%2!=0)sch.push('L');
			else sch.push('R');
			n=(int)Math.ceil((((double)n)/2));
		}
		Character dir='L';
		long ans=0;
		while(snu.size()!=0){
			Integer nu=snu.pop();
			Character ch=sch.pop();
			if(dir!=ch){
				ans+=(pow2[nu-1]+pow2[nu-1]-1);
				dir=ch;
			}
			ans+=1;
			dir=((dir=='R')?'L':'R');
		}
		System.out.println(ans);
	}
}

import java.util.*;
import java.io.*;

public class GuessYourWayOut {

	// https://codeforces.com/contest/507/problem/C

	public static void main(String[] args) throws IOException, FileNotFoundException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		//BufferedReader in = new BufferedReader(new FileReader("GuessYourWayOut"));

		StringTokenizer st = new StringTokenizer(in.readLine());
		long h = Long.parseLong(st.nextToken());
		long n = Long.parseLong(st.nextToken());
		long total = (long) Math.pow(2, h);
		long steps =0;
		boolean right=false;
		while (total >= 2) {
			steps++;
			if (!right) {
				if (n > total/2) {
					// we are not in right tree
					steps += total-1;
					right = !right;
					n = n-total/2;
				}
			}
			else {
				if (n <= total/2) {
					steps += total-1;
					right = !right;
				}
			}
			total /=2;
			right = !right;
		}
		System.out.println(steps);
	}
}

/*while (total > 0) {
steps++;
if (!s) {
	if (n <= total/2) {
		// first tree
		n = total-n+1;
	}
	else {
		steps += total-1;
		n = total-n+1;
		//total *=2;
		s=!s;
	}
}
else {
	if (n > total/2) {
		n = total-n+1;
	}
	else {
		steps += total-1;
		n = total-n+1;
		//total *=2;
		s=!s;
	}
}
total /=2;
s = !s;
}*/

//	bug in pretest
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;

public class Solution{

	public long solve(long pos, int h, boolean leftFirst){
		if(h == 0)
			return 0;
		boolean newLeftFirst = (pos >= (1 << (h - 1)));
		long result = 1;
		if(leftFirst != (pos < (1 << (h - 1))))
			result += ((1 << h) - 1);
		pos = pos % (1 << (h - 1));
		result += solve(pos, h - 1, newLeftFirst);
		return result;
	}
	public static void main(String[] args){
		Scanner scan = new Scanner(System.in);
		int h = scan.nextInt();
		long exit = scan.nextLong() - 1;
		long count = new Solution().solve(exit, h, true);
		/*
		while(h > 0){
			count ++;
			if(leftFirst && exit < (1 << (h - 1))){
				leftFirst = false;
			} else if(leftFirst && exit >= (1 << (h - 1))){
				leftFirst = true;
				count += ((1 << h) - 1);
			} else if(exit < (1 << (h - 1))){
				leftFirst = false;
				count += ((1 << h) - 1);
			} else{
				leftFirst = true;
			}
			exit = exit % (1 << (h - 1));
			h --;
		}
		*/

		System.out.println(count);
		scan.close();
	}
}

import java.io.*;
import java.util.*;

public class SolutionB {
	public void solve(){
		long h = nextLong(), id = nextLong();
		out.println(f(h, id, true));
	}
	public long f(long h, long id, boolean left){
		if(h == 1){
			if(left && id == 1 || !left && id == 2) return 1;
			return 2;
		}
		long res = 1;
		if(id > 1<<(h-1)){
			res+= sum(h);
			id-= 1<<(h-1);
			return res + f(h-1, id, true);
		}
		return res + f(h-1, id, false);
	}
	public long sum(long h){
		long res = 0, level = 1;
		while(h > 0){
			h--;
			res += level;
			level<<=1;
		}
		return res;
	}
	class Song implements Comparable<Song>{
		int id, days;
		public Song(int id, int days){
			this.id = id;
			this.days = days;
		}
		public int compareTo(Song other){
			return Integer.compare(days, other.days);
		}
	}
	public void run(){
		solve();
		out.close();
	}
	public static void main(String args[]){
		new SolutionB().run();
	}
	BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
	PrintWriter out = new PrintWriter(System.out);
	String line;
	StringTokenizer st;
	public String nextLine(){
		try {
			line = bf.readLine();
			st = new StringTokenizer(line);
		} catch (IOException e) {
			return null;
		}
		return line;
	}
	public String nextString(){
		while (st == null || !st.hasMoreElements()) {
            try {
                line = bf.readLine();
                st = new StringTokenizer(line);
            } catch (IOException e) {
                return null;
            }
        }
        return st.nextToken();
	}
	public int nextInt(){
		return Integer.parseInt(nextString());
	}
	public long nextLong(){
		return Long.parseLong(nextString());
	}
	public double nextDouble(){
		return Double.parseDouble(nextString());
	}
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;

public class Main {

    void solve() throws IOException {
        int h = nextInt();
        long n = nextLong();
        if(n == 1) {
            System.out.println(1);
            return;
        }
        long[] st = new long[h + 2];
        for (int i = 0; i <= h + 1; i++) {
            st[i] = (1L << i) - 1;
        }

        long ans = 0;
        int lvl = 1;
        long a = n + st[h];
        for (;;) {
            ans++;
            long b = a / 2;
            long c = b / 2;
            boolean left1 = b * 2 == a;
            boolean left2 = c * 2 == b;
            if(b == 1) {
                if (!left1) ans += st[lvl];
                break;
            }
            if(left1 == left2) ans += st[lvl];
            lvl++;
            a = b;
        }
        System.out.println(ans);
    }

    public void run() {
        try {
            br = new BufferedReader(new InputStreamReader(System.in));
            out = new PrintWriter(System.out);
            solve();
            out.close();
            br.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(239);
        }
    }

    BufferedReader br;
    StringTokenizer st;
    PrintWriter out;

    int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

    long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }

    String nextToken() throws IOException {
        while (st == null || !st.hasMoreTokens()) {
            String line = br.readLine();
            if (line == null) {
                return null;
            }
            st = new StringTokenizer(line);
        }
        return st.nextToken();
    }

    public static void main(String[] args) {
        new Main().run();
    }
}

import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.InputStreamReader;
import java.io.IOException;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author Alejandro Lopez
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskC {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            long h = in.nextInt();
            long n = in.nextInt();

            long ans = 0;
            int cur = 0;
            for (long i = h; i > 0; --i) {
                // out.printf("h = %d\n", i);
                if (n > (1 << (i - 1))) { // right subtree
                    if (cur == 0) { // going left
                        ans += 1 << i;
                        n -= (1 << (i - 1));
                    } else {
                        ans += 1;
                        cur = 0;
                    }
                    // out.printf("  [R] ans = %d, n = %d\n", ans, n);
                } else { // left subtree
                    if (cur == 0) { // going left
                        ans += 1;
                        cur = 1;
                    } else {
                        ans += 1 << i;
                        n -= (1 << (i - 1));
                    }
                    // out.printf("  [l] ans = %d, n = %d\n", ans, n);
                }
            }

            out.println(ans);
        }

    }

    static class InputReader {
        BufferedReader in;
        StringTokenizer tokenizer = null;

        public InputReader(InputStream inputStream) {
            in = new BufferedReader(new InputStreamReader(inputStream));
        }

        public String next() {
            try {
                while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                    tokenizer = new StringTokenizer(in.readLine());
                }
                return tokenizer.nextToken();
            } catch (IOException e) {
                return null;
            }
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

    }
}

import java.util.*;
import java.lang.*;
import java.io.*;

public class Trees
{
	public static void main (String[] args) throws java.lang.Exception
	{
		long t,h,n;
		Scanner sc = new Scanner(System.in);
		//t=sc.nextInt();
		//while(t!=0)
		//{
			//t--;
			h=sc.nextLong();
			n=sc.nextLong();
			long leaf = 1<<(h);
			long up,low,ans=0;
			boolean dir = true; // true = left, false = right
			up = leaf;
			low = 1;
			while(up>low && h>0)
			{
				long mid = (up+low)/2;
				long uc=up,lc=low;
				if(dir)
					uc=mid;
				else
					lc=mid+1;
				if(n<=uc && n>=lc)
				{
					up=uc;
					low=lc;
					dir=!dir;
					ans++;
				}
				else
				{
					long nodes = (1<<(h));
					ans+=nodes;
					if(dir)
						low=mid+1;
					else
						up=mid;

				}
				h--;
			}
			System.out.println(ans);
		//}
	}
}

import java.io.InputStreamReader;
import java.io.IOException;
import java.util.InputMismatchException;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.Writer;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author Niyaz Nigmatullin
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		FastScanner in = new FastScanner(inputStream);
		FastPrinter out = new FastPrinter(outputStream);
		TaskC solver = new TaskC();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskC {
    public void solve(int testNumber, FastScanner in, FastPrinter out) {
        int h = in.nextInt();
        long n = in.nextLong();
        n = (1 << h) - n + 1;
        long leaves = 1L << h;
        long ans = 0;
        for (int i = 0; i < h; i++) {
            leaves /= 2;
            if (n > leaves) {
                n = 2 * leaves - n + 1;
                ++ans;
            } else {
                ans += 2 * leaves;
            }
        }
        out.println(ans);
    }
}

class FastScanner extends BufferedReader {

    public FastScanner(InputStream is) {
        super(new InputStreamReader(is));
    }

    public int read() {
        try {
            int ret = super.read();
//            if (isEOF && ret < 0) {
//                throw new InputMismatchException();
//            }
//            isEOF = ret == -1;
            return ret;
        } catch (IOException e) {
            throw new InputMismatchException();
        }
    }

    public String next() {
        StringBuilder sb = new StringBuilder();
        int c = read();
        while (isWhiteSpace(c)) {
            c = read();
        }
        if (c < 0) {
            return null;
        }
        while (c >= 0 && !isWhiteSpace(c)) {
            sb.appendCodePoint(c);
            c = read();
        }
        return sb.toString();
    }

    static boolean isWhiteSpace(int c) {
        return c >= 0 && c <= 32;
    }

    public int nextInt() {
        int c = read();
        while (isWhiteSpace(c)) {
            c = read();
        }
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        int ret = 0;
        while (c >= 0 && !isWhiteSpace(c)) {
            if (c < '0' || c > '9') {
                throw new NumberFormatException("digit expected " + (char) c
                        + " found");
            }
            ret = ret * 10 + c - '0';
            c = read();
        }
        return ret * sgn;
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

    public String readLine() {
        try {
            return super.readLine();
        } catch (IOException e) {
            return null;
        }
    }

}

class FastPrinter extends PrintWriter {

    public FastPrinter(OutputStream out) {
        super(out);
    }

    public FastPrinter(Writer out) {
        super(out);
    }

}

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.*;
import java.math.BigInteger;
import java.util.*;
import java.util.Map.Entry;

public class Main
{
    public static void main(String args[]) throws IOException
    {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;
        StringBuilder ans=new StringBuilder("");
        st=new StringTokenizer(br.readLine());
        int h=Integer.parseInt(st.nextToken());
        long n=Long.parseLong(st.nextToken());
        boolean f=true;
        long res=0;
        long w=(long)1<<(h-1);
        while(h>0)
        {
            if(n>w == f)
            {
                res+=(2*w);
                n-=w;
            }
            else
            {
                f=!f;
                res++;
            }
            h--;
            w/=2;
        }
        System.out.print(res);
    }
}

import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskC solver = new TaskC();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskC {
    public void solve(int testNumber, InputReader in, PrintWriter out) {
        long h = in.nextInt();
        long n = in.nextLong();
        long max = (1L << (h));
        long ans = ways(1, max, h, n);
        out.println(ans);
    }

    private long ways(long min, long max, long h, long n) {
        if (min == max) {
            return 1;
        }
        long mid = (min + max) / 2L;
        if (n <= mid) {
            return ways(min, mid, h - 1, n);
        } else {
            long rest = h > 1 ? ((1 << h) - 1L) : 0L;
            return 1L + rest + ways(1L+mid, max, h - 1, n);
        }
    }
}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.*;

public class GuessYourWayOut {

    static long go(long h, long n, boolean left) {
        if (h == 0) {
            return 0;
        }

        long numChildren = (1 << h) - 1;
        long numLeaves = (1 << (h - 1));

        if (left && n > numLeaves) {
            return 1 + numChildren + go(h - 1, n - numLeaves, true);
        }
        if (left && n <= numLeaves) {
            return 1 + go(h - 1, n, false);
        }
        if (!left && n > numLeaves) {
            return 1 + go(h - 1, n - numLeaves, true);
        }
        if (!left && n <= numLeaves) {
            return 1 + numChildren + go(h - 1, n, true);
        }

        return 0;
    }

    public static void main(String[] args) {
        InputReader in = new InputReader(System.in);

        long h = in.nextLong();
        long n = in.nextLong();

        long ans = go(h, n, true);

        System.out.println(ans);
    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream));
            tokenizer = new StringTokenizer("");
        }

        public String next() {
            try {
                while (!tokenizer.hasMoreTokens())
                    tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

            return tokenizer.nextToken();
        }

        public String nextLine() {
            String line = null;
            try {
                tokenizer = new StringTokenizer("");
                line =  reader.readLine();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            return line;
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public double nextDouble() {
            return Double.parseDouble(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

        boolean hasNext() {
            while (!tokenizer.hasMoreTokens()) {
                String line = nextLine();
                if (line == null) return false;
                tokenizer = new StringTokenizer(line);
            }
            return true;
        }
    }
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class round_507_C {

	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		int h = sc.nextInt();
		long n = sc.nextLong();
		long lo = 1;
		long hi = (1 << h);
		long tempH = h;
		long answer = 0;
		while(lo <= hi)
		{
			long mid = lo + (hi - lo) / 2;
			if(mid == n){
				answer += tempH;
				break;
			}
			else if(n > mid)
			{
				answer += (1 << h)  - 1;
				h--;
				lo = mid + 1;

			}
			else
			{
				hi = mid - 1;
			}

		}
		System.out.println(answer);
	}

	static class Scanner {
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s) {
			br = new BufferedReader(new InputStreamReader(s));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public double nextDouble() throws IOException {
			return Double.parseDouble(next());
		}

		public long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public String nextLine() throws IOException {
			return br.readLine();
		}

		public boolean ready() throws IOException {
			return br.ready();
		}
	}
}

import javax.swing.text.MutableAttributeSet;
import java.io.*;
import java.util.*;

 public  class Main {

      public static void main(String[] args) throws IOException {
          Scanner input = new Scanner(System.in);
          int h = input.nextInt();
          long n = input.nextLong();
          long ans = 0;
          boolean left = true;
          while (h != 0) {
              if (n > ((1 << h)/2) && left) {
                  ans += (1 << h);
                  n -= (1<<h)/2;
                  h--;
              } else if (n < ((1 << h)/2) && !left) {
                  ans += (1 << h);
                  h--;
              } else {
                  ans++;
                  if(!left)
                      n -= (1<<h)/2;
                  h--;
                  left ^= left;
               }
           }

          System.out.println(ans);
      }
  }

import java.io.*;
import java.util.*;

public class problem507C {
	public static void main (String[]args)throws IOException{
		BufferedReader x=new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st=new StringTokenizer(x.readLine());
		int h=Integer.parseInt(st.nextToken());
		int n=Integer.parseInt(st.nextToken());
		String s=Integer.toBinaryString(n-1);
		int ans=0;
		if (s.charAt(0)=='0')ans++;else{ans+=Math.pow(2,h);}
		for (int i=1; i<s.length(); i++){
			if (((s.charAt(i)-'0')+(s.charAt(i-1)-'0'))%2==0){
				ans+=Math.pow(2,h-i);
			}else{
				ans++;
			}
		}
		System.out.println(ans);
	}
}

import java.io.*;
import java.util.StringTokenizer;

public class Main{
        public static void main(String[] args) throws Exception {

            Scanner sc = new Scanner(System.in);
            PrintWriter out = new PrintWriter(System.out);
            StringBuilder sb = new StringBuilder();
            int h  = sc.nextInt() , n = sc.nextInt();
            long cnt = 0;
            for(int i = h ; i >=0 ; --i)
            {
                long allHere = (long)Math.pow(2,i);
                cnt+=(n);
                n/=2;
            }
            System.out.println(cnt - 1);
      }
        static class Scanner {
            StringTokenizer st;
            BufferedReader br;

            public Scanner(InputStream s) {
                br = new BufferedReader(new InputStreamReader(s));
            }

            public Scanner(FileReader r) {
                br = new BufferedReader(r);
            }

            public String next() throws IOException {
                while (st == null || !st.hasMoreTokens())
                    st = new StringTokenizer(br.readLine());
                return st.nextToken();
            }

            public int nextInt() throws IOException {
                return Integer.parseInt(next());
            }

            public long nextLong() throws IOException {
                return Long.parseLong(next());
            }

            public String nextLine() throws IOException {
                return br.readLine();
            }

            public double nextDouble() throws IOException {
                String x = next();
                StringBuilder sb = new StringBuilder("0");
                double res = 0, f = 1;
                boolean dec = false, neg = false;
                int start = 0;
                if (x.charAt(0) == '-') {
                    neg = true;
                    start++;
                }
                for (int i = start; i < x.length(); i++)
                    if (x.charAt(i) == '.') {
                        res = Long.parseLong(sb.toString());
                        sb = new StringBuilder("0");
                        dec = true;
                    } else {
                        sb.append(x.charAt(i));
                        if (dec)
                            f *= 10;
                    }
                res += Long.parseLong(sb.toString()) / f;
                return res * (neg ? -1 : 1);
            }

            public boolean ready() throws IOException {
                return br.ready();
            }

        }

    }

import java.util.Scanner;

public class node {

	public static int generer(int h,int n)
	{
		int result=0;
		int interval=(int) Math.pow(2,h-1);
		int i=1;

		while(i<=h)
		{
			if(n<=interval)
			{
				result=result+1;
				i++;
				interval=(int) (interval-Math.pow(2,h-i));
				if(n>interval && i<=h)
				{
					result=result+1;
					i++;
					interval=(int) (interval+Math.pow(2,h-i));
				}
				else if(n<=interval && i<=h)
				{
					for(int j=0;j<=h-i;j++)
					{
						result=(int) (result+Math.pow(2,j));
					}
					result++;
					i++;
					interval=(int) (interval-Math.pow(2,h-i));
				}
			}

				else
				{
					for(int j=0;j<=h-i;j++)
					{
						result=(int) (result+Math.pow(2,j));
					}
					result++;
					i++;
					interval=(int) (interval+Math.pow(2,h-i));

				}

			}

		return result;
	}

	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);
		int h=sc.nextInt();
		int n=sc.nextInt();

		if(1<=n && n<=(int)Math.pow(2,h))
		System.out.println(generer(h,n));

	}

}

import java.util.*;
import java.io.*;
import java.math.*;

public class binary {
    public static void main(String[] args) throws IOException
    {
        Scanner cin = new Scanner(System.in);
        int h;
        h = cin.nextInt();
        BigDecimal num2 = cin.nextBigDecimal();
        num2 = num2.subtract(BigDecimal.ONE);
        BigDecimal po = new BigDecimal(1);
        BigDecimal ans = new BigDecimal(0);
        final BigDecimal two = new BigDecimal(2);
        int count = 1;
        int [] stack = new int[55];
        int top = 0;
        while (num2.compareTo(BigDecimal.ZERO) > 0)
        {
            stack[top] = num2.remainder(two).intValue();
            top++;
            num2 = num2.divide(two,1);
            po = po.multiply(two);
        }
        top--;
        while (top >= 0)
        {
            if (stack[top]%2 == count%2)
            {
                ans = ans.add(po);
            }
            else
            {
                count++;
                ans = ans.add(BigDecimal.ONE);
            }
            po = po.divide(two,1);
            top--;
        }
        System.out.println(ans);
    }
}

import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;

public class Solution{

	public static void main(String[] args){
		Scanner scan = new Scanner(System.in);
		long h = scan.nextLong();
		long exit = scan.nextLong() - 1;
		long count = 0;
		boolean leftFirst = true;
		int base = 1;
		while(h > 0){
			count ++;
			if(leftFirst && exit < (base << (h - 1))){
				leftFirst = false;
			} else if(leftFirst && exit >= (base << (h - 1))){
				leftFirst = true;
				count += ((base << h) - 1);
			} else if(exit < (base << (h - 1))){
				leftFirst = false;
				count += ((base << h) - 1);
			} else{
				leftFirst = true;
			}
			exit = exit % (base << (h - 1));
			h --;
		}
		System.out.println(count);
		scan.close();
	}
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.*;

public class GuessYourWayOut {

    static long go(long h, long n, boolean left) {
        if (h == 0) {
            return 0;
        }

        long numChildren = (1L << h) - 1;
        long numLeaves = (1L << (h - 1));

        if (left && n > numLeaves) {
            return 1 + numChildren + go(h - 1, n - numLeaves, true);
        }
        if (left && n <= numLeaves) {
            return 1 + go(h - 1, n, false);
        }
        if (!left && n > numLeaves) {
            return 1 + go(h - 1, n - numLeaves, true);
        }
        if (!left && n <= numLeaves) {
            return 1 + numChildren + go(h - 1, n, true);
        }

        return 0;
    }

    public static void main(String[] args) {
        InputReader in = new InputReader(System.in);

        long h = in.nextLong();
        long n = in.nextLong();

        long ans = go(h, n, true);

        System.out.println(ans);
    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream));
            tokenizer = new StringTokenizer("");
        }

        public String next() {
            try {
                while (!tokenizer.hasMoreTokens())
                    tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }

            return tokenizer.nextToken();
        }

        public String nextLine() {
            String line = null;
            try {
                tokenizer = new StringTokenizer("");
                line =  reader.readLine();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            return line;
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public double nextDouble() {
            return Double.parseDouble(next());
        }

        public long nextLong() {
            return Long.parseLong(next());
        }

        boolean hasNext() {
            while (!tokenizer.hasMoreTokens()) {
                String line = nextLine();
                if (line == null) return false;
                tokenizer = new StringTokenizer(line);
            }
            return true;
        }
    }
}

import javax.swing.text.MutableAttributeSet;
import java.io.*;
import java.util.*;

  public class Main {

      public static void main(String[] args) throws IOException {
          Scanner input = new Scanner(System.in);
          int h = input.nextInt();
          long n = input.nextLong();
          long ans = 0;
          boolean left = true;
          while (h != 0) {
              if (n > ((1 << h)/2) && left) {
                  ans += (1 << h);
                  n -= ((1<<h)/2);
                  h--;
              } else if (n <= ((1 << h)/2) && !left) {
                  ans += (1 << h);
                  h--;
              } else {
                  ans++;
                  if(!left)
                      n -= ((1<<h)/2);
                  h--;
                  left ^= true;
               }
           }

          System.out.println(ans);
      }
  }

import java.util.Scanner;

public class Solution {

    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        int h = cin.nextInt();
        long leaf = cin.nextLong() - 1;
        System.out.println(countNodes(h, leaf));
        cin.close();
    }

    private static long countNodes(long h, long leaf) {
        long low = 0, high = (1 << h) - 1;
        long count = 0;
        boolean goLeft = true;
        while (low < high) {
            long mid = low + (high - low) / 2;
            if (goLeft != (low <= leaf && leaf <= mid)) {
                count += (1 << h) - 1;
                goLeft = !goLeft;
            }
            if (low <= leaf && leaf <= mid) {
                high = mid;
            } else {
                low = mid + 1;
            }
            goLeft = !goLeft;
            count++;
            --h;
        }
        return count;
    }
}

import java.io.*;
import java.util.*;

public class test
{
    public static void main(String[] args) throws IOException
    {
        InputStreamReader inp = new InputStreamReader(System.in);
        BufferedReader br = new BufferedReader(inp);

        String s[] = br.readLine().split(" ");

        int h = Integer.parseInt(s[0]);
        long n = Long.parseLong(s[1]);

        double leaf_nodes = Math.pow(2,h);
        double total_nodes = 0;
        for(int i=0;i<=h;i++)
        {
            total_nodes+=Math.pow(2,i);
        }

        int flag=1;   //1=left, 0=right
        long visited=1;
        int level=0;
        int dest = (int)leaf_nodes/2;
        int to_add = (int)total_nodes/2;
        int prev=0;
        while(level<h)
        {

            if((n>dest && flag==1)  || (n<=dest && flag==0 ))
            {
                visited+=to_add;
                flag=1-flag;

                continue;
            }else
            {
                level++;
                visited+=1;
                if(n>dest)
                {
                    n = n-dest;

                }

                flag=1-flag;
                dest = dest/2;
                to_add = to_add/2;

            }

        }

        System.out.println(visited-1);

    }
}

/* package whatever; // don't place package name! */

import java.util.*;
import java.lang.*;
import java.io.*;

/* Name of the class has to be "Main" only if the class is public. */
public class Ideone
{
	public static void main (String[] args) throws java.lang.Exception
	{
		// your code goes here
		Scanner sc=new Scanner(System.in);
		long h=sc.nextLong(),n=sc.nextLong();
		long[] pow2=new long[(int)h+1];
		int pow=1;
		for(int i=0;i<=h;i++){pow2[i]=pow;pow*=2;}
		Stack<Integer> snu=new Stack<>();
		Stack<Character> sch=new Stack<>();
		snu.push(1);
		if(n%2!=0)sch.push('L');
		else sch.push('R');
		n=(int)Math.ceil((((double)n)/2));
		while(snu.peek()!=h){
			snu.push(snu.peek()+1);
			if(n%2!=0)sch.push('L');
			else sch.push('R');
			n=(int)Math.ceil((((double)n)/2));
		}
		Character dir='L';
		long ans=0;
		while(snu.size()!=0){
			Integer nu=snu.pop();
			Character ch=sch.pop();
			if(dir!=ch){
				ans+=(pow2[nu-1]+pow2[nu-1]-1);
				dir=ch;
			}
			ans+=1;
			dir=((dir=='R')?'L':'R');
		}
		System.out.println(ans);
	}
}

import java.util.Scanner;

public class GuessYourWayOut {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		long h = sc.nextLong();
		long n = sc.nextLong();
		long leafs;
		long ans = 0;
		boolean left = true;
		while (h > 0) {
			leafs = (1L << h);
			if (n > leafs / 2) {
				// on the right
				if (left) {
					ans += numOfNodes(h - 1) + 1;
					left = true;
				} else {
					ans++;
					left = true;
				}
				if (n % 2 == 0) {
					n = n / 2;
					if (n % 2 == 1)
						n--;
				} else {
					n = n / 2;
					if (n % 2 == 0)
						n--;
				}

			} else {
				if (left) {
					ans++;
					left = false;
				} else {
					ans += numOfNodes(h - 1) + 1;
					left = false;
				}
			}
			h--;
		}
		System.out.println(ans);
	}

	private static long numOfNodes(long i) {
		long ans = (1L << (i + 1));
		return ans - 1;
	}
}