import java.util.Arrays;
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];

		Arrays.fill(arr,'0');

		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;

				if(arr[i]=='0')
				{
					curr='1';
				}
				else
				{
					curr='0';
				}

			}
			else
			{
				if(curr=='0')
					curr='1';
				else
					curr='0';

				count++;
			}
		}

		System.out.println(count);

	}

}

//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.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.*;
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.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.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.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.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.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.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.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.*;
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.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.*;
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.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.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);
    }

}

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);
    }

}

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.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.*;
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;
    }

}

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.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.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();
	}
}

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.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 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.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.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.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.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;
    }

}

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.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 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());
	}
}

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.*;
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.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.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.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.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.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 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);
    }
}

//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.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;
    }
  }
}

//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.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.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();
	}
}

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;
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 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;

/*

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.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.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.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 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.*;
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 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.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();
	}

}

/* 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);
	}
}

//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.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.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.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.*;
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.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.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.*;

/**
 *
 * @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.*;
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.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.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.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.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;
    }

}

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();
    }
}

/*
 * 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.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.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);
	}

}

//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.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.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;
	}
}