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

public class MadokaAndTheBestUniversity {
	private static final int N_MAX = 100_000;

	private static final int MOD = 1_000_000_007;

	private static final IntList[] FACTORS = new IntList[N_MAX + 1];
	static {
		for (int i = 1; i <= N_MAX; ++i) {
			FACTORS[i] = new IntList();
		}
		for (int i = 1; i <= N_MAX; ++i) {
			for (int j = i; j <= N_MAX; j += i) {
				FACTORS[j].add(i);
			}
		}
	}

	public static void solve(FastIO io) {
		final int N = io.nextInt();

		long total = 0;
		for (int c = 1; c + 2 <= N; ++c) {
			int rem = N - c;
			System.out.format("c = %d, rem = %d\n", c, rem);
			IntList facs = FACTORS[rem];
			int[] countFacs = new int[facs.size()];
			for (int i = facs.size() - 1; i >= 0; --i) {
				int fi = facs.get(i);
				countFacs[i] = rem / fi - 1;
				for (int j = i + 1; j < facs.size(); ++j) {
					int fj = facs.get(j);
					if (fj % fi != 0) {
						continue;
					}
					countFacs[i] -= countFacs[j];
				}
				total += 1L * c * facs.get(i) * countFacs[i] / gcd(fi, c);
				total %= MOD;
			}
		}
		io.println(total);
	}

	/**
	 * Computes the GCD (greatest common denominator) between two numbers.
	 */
	public static int gcd(int a, int b) {
		if (a < b)
			return gcd(b, a);

		int r = a % b;
		if (r == 0)
			return b;

		return gcd(b, r);
	}

	private static class IntList extends ArrayList<Integer> {
		private static final long serialVersionUID = 8986468115134862220L;
	}

	public static class FastIO {
		private InputStream reader;
		private PrintWriter writer;

		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;

		public FastIO(InputStream r, OutputStream w) {
			reader = r;
			writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(w)));
		}

		public int read() {
			if (numChars == -1)
				throw new InputMismatchException();
			if (curChar >= numChars) {
				curChar = 0;
				try {
					numChars = reader.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;
		}

		// TODO: read this byte-by-byte like the other read functions.
		public double nextDouble() {
			return Double.parseDouble(nextString());
		}

		public int[] nextIntArray(int n) {
			return nextIntArray(n, 0);
		}

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

		public long[] nextLongArray(int n) {
			return nextLongArray(n, 0);
		}

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

		private boolean isSpaceChar(int c) {
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c) {
			return c == '\n' || c == '\r' || c == -1;
		}

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

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

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

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

		public void printlnArray(int[] arr) {
			printArray(arr);
			writer.println();
		}

		public void printlnArray(long[] arr) {
			printArray(arr);
			writer.println();
		}

		public void printf(String format, Object... args) {
			print(String.format(format, args));
		}

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

	public static void main(String[] args) {
		FastIO io = new FastIO(System.in, System.out);
		solve(io);
		io.flush();
	}
}


/* package codechef; // 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 Codechef
{
    static class Reader {
        final private int BUFFER_SIZE = 1 << 16;
        private DataInputStream din;
        private byte[] buffer;
        private int bufferPointer, bytesRead;

        public Reader()
        {
            din = new DataInputStream(System.in);
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }

        public Reader(String file_name) throws IOException
        {
            din = new DataInputStream(
                new FileInputStream(file_name));
            buffer = new byte[BUFFER_SIZE];
            bufferPointer = bytesRead = 0;
        }

        public String readLine() throws IOException
        {
            byte[] buf = new byte[64]; // line length
            int cnt = 0, c;
            while ((c = read()) != -1) {
                if (c == '\n') {
                    if (cnt != 0) {
                        break;
                    }
                    else {
                        continue;
                    }
                }
                buf[cnt++] = (byte)c;
            }
            return new String(buf, 0, cnt);
        }

        public int nextInt() throws IOException
        {
            int ret = 0;
            byte c = read();
            while (c <= ' ') {
                c = read();
            }
            boolean neg = (c == '-');
            if (neg)
                c = read();
            do {
                ret = ret * 10 + c - '0';
            } while ((c = read()) >= '0' && c <= '9');

            if (neg)
                return -ret;
            return ret;
        }

        public long nextLong() throws IOException
        {
            long ret = 0;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();
            do {
                ret = ret * 10 + c - '0';
            } while ((c = read()) >= '0' && c <= '9');
            if (neg)
                return -ret;
            return ret;
        }

        public double nextDouble() throws IOException
        {
            double ret = 0, div = 1;
            byte c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();

            do {
                ret = ret * 10 + c - '0';
            } while ((c = read()) >= '0' && c <= '9');

            if (c == '.') {
                while ((c = read()) >= '0' && c <= '9') {
                    ret += (c - '0') / (div *= 10);
                }
            }

            if (neg)
                return -ret;
            return ret;
        }

        private void fillBuffer() throws IOException
        {
            bytesRead = din.read(buffer, bufferPointer = 0,
                                 BUFFER_SIZE);
            if (bytesRead == -1)
                buffer[0] = -1;
        }

        private byte read() throws IOException
        {
            if (bufferPointer == bytesRead)
                fillBuffer();
            return buffer[bufferPointer++];
        }

        public void close() throws IOException
        {
            if (din == null)
                return;
            din.close();
        }
    }

    public static long gcd(long a, long b)
    {
        if (a == 0)
            return b;

        return gcd(b % a, a);
    }

    public static void main(String []args) throws IOException
    {

           Reader sc = new Reader();
           int n = sc.nextInt();

        long phi[] = new long[n + 1];
    for (int i = 1; i <= n; i++)
    phi[i] = i; // indicates not evaluated yet
                // and initializes for product
                // formula.

    // Compute other Phi values
    for (int p = 2; p <= n; p++) {

    // If phi[p] is not computed already,
    // then number p is prime
    if (phi[p] == p) {

        // Phi of a prime number p is
        // always equal to p-1.
        phi[p] = p - 1;

        // Update phi values of all
        // multiples of p
        for (int i = 2 * p; i <= n; i += p) {

        // Add contribution of p to its
        // multiple i by multiplying with
        // (1 - 1/p)
        phi[i] = (phi[i] / p) * (p - 1);
        }
    }
    }

    long ans = 0;
    long mod = 1000000007;
           for(int c = 1 ; c <= n-2 ; c++)
           {
               int sum = n-c;
               for(int j = 1 ; j <= (int)Math.sqrt(sum) ; j++)
               {
                   if(sum%j == 0)
                   {
                       int xx = sum/j;
                       long lc = (long)c*(long)j/(gcd(c,j));

                       ans += lc*phi[xx]%mod;
                       ans %= mod;
                   }
               }
           }
           System.out.println(ans);
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.StringTokenizer;
public class Main {
    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();
        }

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

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

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

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

   static MyScanner s=new MyScanner();

   public static int process(int a,int k) {
	   long ans=1;
	   for(int i=0;i<a;i++)ans*=10;
	   return (int)ans%k;
   }
   static int[]arr;
   static int mod=(int)1e9+7;
   {
	   arr=new int[100010];
	   arr[0]=1;
	   for(int i=1;i<=100000;i++) {
		   arr[i]=((arr[i-1]%mod)*2)%mod;
	   }
   }
   public static long C(int n,int i) {
	  if(i>n/2)i=n-i;
	  long a=1,b=1;
	  for(int j=1;j<=i;j++) {
		  a*=(n-j+1);a%=mod;
		  b*=j;b%=mod;
		  if(a%b==0) {
			  a/=b;b=1;
		  }
	  }
	  return (a/b)%mod;
   }
public static void main(String[] args) {
int K=1;
int N=10,M=10;
while(K>0) {
    int n=s.nextInt(),k=s.nextInt();
    if(k>=n)System.out.println(arr[n]);
    long ans=0;
    for(int i=0;i<=k;i++) {
    	ans=ans%mod+C(n,i)%mod;ans%=mod;
    }
    System.out.println(ans);
	K--;
}
}
}


//常用的快捷键

//1.代码自动补全的快捷键  alt+/
//main, syso
//取消多行注释 ctrl shift \   使用多行注释 ctrl shift /
//自动导包    ctrl shift +o
//生成gettter,setter方法  ctrl shift +s
//Alt+CTRL+↓ 复制当前行到下一行(复制增加)
//Alt+CTRL+↑ 复制当前行到上一行(复制增加)     Ctrl+D: 删除当前行

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.StringTokenizer;
public class  Main {
    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();
        }

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

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

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

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

   static MyScanner s=new MyScanner();

   public static int process(int a,int k) {
	   long ans=1;
	   for(int i=0;i<a;i++)ans*=10;
	   return (int)ans%k;
   }
   static int[]arr=new int[100010];
   static int mod=(int)1e9+7;
  static  {
	   arr[0]=1;
	   for(int i=1;i<=100000;i++) {
		   arr[i]=((arr[i-1]%mod)*2)%mod;
	   }
   }
  static class Info{
      int x;int y;
      public Info(){}
      public Info(int x,int y){
          this.x=x;this.y=y;
      }
  }
  public static Info exgcd(int a,int b){
      if(b==0){
          return new Info(1,0);
      }
      Info info=exgcd(b,a%b);
      return new Info(info.y,info.x-a/b*info.y);
  }
   public static long C(int n,int i) {
	  if(i>n/2)i=n-i;
	  long a=1,b=1;
	  for(int j=1;j<=i;j++) {
		  a*=(n-j+1);a%=mod;
		  b*=j;b%=mod;
		  if(a%b==0) {
			  a/=b;b=1;
		  }
	  }
	  Info info=exgcd((int)b,mod);
	  return (a%mod*(info.x%mod))%mod;
   }
public static void main(String[] args) {
int K=1;
int N=10,M=10;
while(K>0) {
    int n=s.nextInt(),k=s.nextInt();
    if(k>=n){
        System.out.println(arr[n]);
        break;
        }
    long ans=0;
    for(int i=0;i<=k;i++) {
    	ans=ans%mod+C(n,i)%mod;ans%=mod;
    }
    System.out.println(ans);
	K--;
}
}
}
//99999 3123


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

public class MadokaAndTheCorruptionScheme {
	private static final int MOD = 1000000007;

	private static final long INV2 = modInverse(2, MOD);

	public static void solve(FastIO io) {
		final int N = io.nextInt();
		final int K = io.nextInt();

		int p = Math.min(N, K);
		io.println(add(add(modPow(2, N, MOD), MOD - add(modPow(2, p, MOD), MOD - 1)), 1));
//		if (K >= N) {
//			long ans = 1;
//			for (int i = 0; i < N; ++i) {
//				ans <<= 1;
//				ans %= MOD;
//			}
//			io.println(ans);
//			return;
//		}
//
//		long ans = 0;
//		for (int i = 0; i <= K; ++i) {
//			ans = (ans << 1) | 1;
//			ans %= MOD;
//		}
//		io.println(ans % MOD);
//
//		int rCount = Math.min(N, K);
//		int lCount = N - rCount;
//		long a0 = 0;
//		long d = 1;
//		for (int i = 0; i < lCount; ++i) {
//			d = (d << 1) % MOD;
//		}
//		for (int i = 0; i < rCount; ++i) {
//			a0 = (a0 + d) % MOD;
//			d = (d << 1) % MOD;
//		}
//		io.println((a0 + 1) % MOD);
	}

	private static long add(long a, long b) {
		long ans = a + b;
		if (ans >= MOD) {
			ans -= MOD;
		}
		return ans;
	}

	/**
	 * Computes the value of (b ^ e) % m.
	 */
	public static long modPow(long b, long e, long m) {
		long p = b % m;
		long ans = 1;
		while (e > 0) {
			if ((e & 1) == 1) {
				ans = ans * p % m;
			}
			p = p * p % m;
			e >>= 1;
		}
		return ans;
	}

	/**
	 * Computes the modular inverse, such that: ak % m = 1, for some k.
	 * See this page for details:  http://rosettacode.org/wiki/Modular_inverse
	 */
	public static long modInverse(long a, long b) {
		return BigInteger.valueOf(a).modInverse(BigInteger.valueOf(b)).longValue();
	}

	public static class FastIO {
		private InputStream reader;
		private PrintWriter writer;

		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;

		public FastIO(InputStream r, OutputStream w) {
			reader = r;
			writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(w)));
		}

		public int read() {
			if (numChars == -1)
				throw new InputMismatchException();
			if (curChar >= numChars) {
				curChar = 0;
				try {
					numChars = reader.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;
		}

		// TODO: read this byte-by-byte like the other read functions.
		public double nextDouble() {
			return Double.parseDouble(nextString());
		}

		public int[] nextIntArray(int n) {
			return nextIntArray(n, 0);
		}

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

		public long[] nextLongArray(int n) {
			return nextLongArray(n, 0);
		}

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

		private boolean isSpaceChar(int c) {
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}

		private boolean isEndOfLine(int c) {
			return c == '\n' || c == '\r' || c == -1;
		}

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

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

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

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

		public void printlnArray(int[] arr) {
			printArray(arr);
			writer.println();
		}

		public void printlnArray(long[] arr) {
			printArray(arr);
			writer.println();
		}

		public void printf(String format, Object... args) {
			print(String.format(format, args));
		}

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

	public static void main(String[] args) {
		FastIO io = new FastIO(System.in, System.out);
		solve(io);
		io.flush();
	}
}


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

public class Main {
    static FastReader sc=new FastReader();
	static PrintWriter out=new PrintWriter(System.out);
	static int dx[]={0,0,-1,1},dy[]={-1,1,0,0};
	static final double pi=3.1415926536;
	static long mod=1000000007;
	// static long mod=998244353;
	static int MAX=Integer.MAX_VALUE;
	static int MIN=Integer.MIN_VALUE;
	static long MAXL=Long.MAX_VALUE;
	static long MINL=Long.MIN_VALUE;
	static ArrayList<Integer> graph[];
	static long fact[];
	static long seg[];
	static int dp[];
	// static long dp[][];
	public static void main (String[] args) throws java.lang.Exception
	{
		// code goes here
		// int t=I();
		// outer:while(t-->0)
		// {
			int n=I(),k=I();
			long nodes=pwr(2,k)-1;
			long levels=n-k;
			out.println(nodes*pwr(2,levels)+1);
		// }
		out.close();
	}
	public static class pair
    {
    	int a;
    	int b;
    	public pair(int aa,int bb)
    	{
    	    a=aa;
    	    b=bb;
    	}
    }
	public static class myComp implements Comparator<pair>
	{
		//sort in ascending order.
		public int compare(pair p1,pair p2)
		{
			if(p1.a==p2.a)
    	    return 0;
    	    else if(p1.a<p2.a)
    	    return -1;
    	    else
    	    return 1;
		}
		// sort in descending order.
		// public int compare(pair p1,pair p2)
    	// {
    	//     if(p1.b==p2.b)
    	//     return 0;
    	//     else if(p1.b<p2.b)
    	//     return 1;
    	//     else
    	//     return -1;
    	// }
	}
	public static void setGraph(int n,int m)throws IOException
	{
		graph=new ArrayList[n+1];
		for(int i=0;i<=n;i++){
			graph[i]=new ArrayList<>();
		}
		for(int i=0;i<m;i++){
			int u=I(),v=I();
			graph[u].add(v);
			graph[v].add(u);
		}
	}

	//LOWER_BOUND and UPPER_BOUND functions

	//It returns answer according to zero based indexing.
	public static int lower_bound(pair[] arr,int X,int start, int end)   //start=0,end=n-1
	{
		if(start>end)return -1;
		// if(arr.get(end)<X)return end;
		if(arr[end].a<X)return end;
		// if(arr.get(start)>X)return -1;
		if(arr[start].a>X)return -1;
		int left=start,right=end;
		while(left<right){
			int mid=(left+right)/2;

			if(arr[mid].a==X){
			// if(arr.get(mid)==X){                                    //Returns last index of lower bound value.
				if(mid<end && arr[mid+1].a==X){
				// if(mid<end && arr.get(mid+1)==X){
					left=mid+1;
				}else{
					return mid;
				}
			}

			// if(arr.get(mid)==X){                                   //Returns first index of lower bound value.
			// if(arr[mid]==X){
			// 	// if(mid>start && arr.get(mid-1)==X){
			// 	if(mid>start && arr[mid-1]==X){
			// 		right=mid-1;
			// 	}else{
			// 		return mid;
			// 	}
			// }

			else if(arr[mid].a>X){
			// else if(arr.get(mid)>X){
				if(mid>start && arr[mid-1].a<X){
				// if(mid>start && arr.get(mid-1)<X){
					return mid-1;
				}else{
					right=mid-1;
				}
			}else{
				if(mid<end && arr[mid+1].a>X){
				// if(mid<end && arr.get(mid+1)>X){
					return mid;
				}else{
					left=mid+1;
				}
			}
		}
		return left;
	}
	//It returns answer according to zero based indexing.
	public static int upper_bound(long arr[],long X,int start,int end)			//start=0,end=n-1
	{
		if(arr[0]>=X)return start;
		if(arr[arr.length-1]<X)return -1;
		int left=start,right=end;
		while(left<right){
			int mid=(left+right)/2;
			if(arr[mid]==X){                                   //returns first index of upper bound value.
				if(mid>start && arr[mid-1]==X){
					right=mid-1;
				}else{
					return mid;
				}
			}
			// if(arr[mid]==X){									//returns last index of upper bound value.
			// 	if(mid<end && arr[mid+1]==X){
			// 		left=mid+1;
			// 	}else{
			// 		return mid;
			// 	}
			// }
			else if(arr[mid]>X){
				if(mid>start && arr[mid-1]<X){
					return mid;
				}else{
					right=mid-1;
				}
			}else{
				if(mid<end && arr[mid+1]>X){
					return mid+1;
				}else{
					left=mid+1;
				}
			}
		}
		return left;
	}

	//END

	//Segment Tree Code
	public static void buildTree(long a[],int si,int ss,int se)
	{
		if(ss==se){
			seg[si]=a[ss];
			return;
		}
		int mid=(ss+se)/2;
		buildTree(a,2*si+1,ss,mid);
		buildTree(a,2*si+2,mid+1,se);
		seg[si]=max(seg[2*si+1],seg[2*si+2]);
	}
	// public static void update(int si,int ss,int se,int pos,int val)
	// {
	// 	if(ss==se){
	// 		// seg[si]=val;
	// 		return;
	// 	}
	// 	int mid=(ss+se)/2;
	// 	if(pos<=mid){
	// 		update(2*si+1,ss,mid,pos,val);
	// 	}else{
	// 		update(2*si+2,mid+1,se,pos,val);
	// 	}
	// 	// seg[si]=min(seg[2*si+1],seg[2*si+2]);
	// 	if(seg[2*si+1].a < seg[2*si+2].a){
	// 		seg[si].a=seg[2*si+1].a;
	// 		seg[si].b=seg[2*si+1].b;
	// 	}else{
	// 		seg[si].a=seg[2*si+2].a;
	// 		seg[si].b=seg[2*si+2].b;
	// 	}
	// }
	public static long query(int si,int ss,int se,int qs,int qe)
	{
		if(qs>se || qe<ss)return 0;
		if(ss>=qs && se<=qe)return seg[si];
		int mid=(ss+se)/2;
		long p1=query(2*si+1,ss,mid,qs,qe);
		long p2=query(2*si+2,mid+1,se,qs,qe);
		return max(p1,p2);

	}

	public static void merge(ArrayList<Integer> f,ArrayList<Integer> a,ArrayList<Integer> b)
	{
		int i=0,j=0;
		while(i<a.size() && j<b.size()){
			if(a.get(i)<=b.get(j)){
				f.add(a.get(i));
				i++;
			}else{
				f.add(b.get(j));
				j++;
			}
		}
		while(i<a.size()){
			f.add(a.get(i));
			i++;
		}
		while(j<b.size()){
			f.add(b.get(j));
			j++;
		}
	}

	//Segment Tree Code end

	//Prefix Function of KMP Algorithm
	public static int[] KMP(char c[],int n)
	{
		int pi[]=new int[n];
		for(int i=1;i<n;i++){
			int j=pi[i-1];
			while(j>0 && c[i]!=c[j]){
				j=pi[j-1];
			}
			if(c[i]==c[j])j++;
			pi[i]=j;
		}
		return pi;
	}
	public static long kadane(long a[],int n)  //largest sum subarray
	{
		long max_sum=Long.MIN_VALUE,max_end=0;
		for(int i=0;i<n;i++){
			max_end+=a[i];
			if(max_sum<max_end){max_sum=max_end;}
			if(max_end<0){max_end=0;}
		}
		return max_sum;
	}

	public static ArrayList<Long> primeFact(long x)
	{
		ArrayList<Long> arr=new ArrayList<>();
		if(x%2==0){
			arr.add(2L);
			while(x%2==0){
				x/=2;
			}
		}
		for(long i=3;i*i<=x;i+=2){
			if(x%i==0){
				arr.add(i);
				while(x%i==0){
					x/=i;
				}
			}
		}
		if(x>0){
			arr.add(x);
		}
		return arr;
	}
	public static long nPr(int n,int r)
	{
		long ans=divide(fact(n),fact(n-r),mod);
		return ans;
	}
	public static long nCr(int n,int r)
	{
		long ans=divide(fact[n],mul(fact[n-r],fact[r]),mod);
		return ans;
	}

	public static boolean isSorted(int a[])
	{
		int n=a.length;
		for(int i=0;i<n-1;i++){
			if(a[i]>a[i+1])return false;
		}
		return true;
	}
	public static boolean isSorted(long a[])
	{
		int n=a.length;
		for(int i=0;i<n-1;i++){
			if(a[i]>a[i+1])return false;
		}
		return true;
	}
	public static long toggleBits(long x)//one's complement || Toggle bits
	{
		int n=(int)(Math.floor(Math.log(x)/Math.log(2)))+1;

		return ((1<<n)-1)^x;
	}
	public static int computeXOR(int n) //compute XOR of all numbers between 1 to n.
    {
        if (n % 4 == 0)
            return n;
        if (n % 4 == 1)
            return 1;
        if (n % 4 == 2)
            return n + 1;
        return 0;
    }
	public static int np2(int x)
	{
		x--;
		x |= x >> 1;
		x |= x >> 2;
		x |= x >> 4;
		x |= x >> 8;
		x |= x >> 16;
		x++;
		return x;
	}
	public static int hp2(int x)
	{
		x |= x >> 1;
		x |= x >> 2;
		x |= x >> 4;
		x |= x >> 8;
		x |= x >> 16;
		return x ^ (x >> 1);
	}
	public static long hp2(long x)
	{
		x |= x >> 1;
		x |= x >> 2;
		x |= x >> 4;
		x |= x >> 8;
		x |= x >> 16;
		return x ^ (x >> 1);
	}
	public static ArrayList<Integer> primeSieve(int n)
	{
	    ArrayList<Integer> arr=new ArrayList<>();
	    boolean prime[] = new boolean[n + 1];
        for (int i = 0; i <= n; i++)
        prime[i] = true;
        for (int p = 2; p * p <= n; p++)
        {
            if (prime[p] == true)
            {
                for (int i = p * p; i <= n; i += p)
                prime[i] = false;
            }
        }
        for (int i = 2; i <= n; i++)
        {
            if (prime[i] == true)
            arr.add(i);
        }
        return arr;
	}

	// Fenwick / BinaryIndexed  Tree  USE IT - FenwickTree ft1=new FenwickTree(n);
	public static class FenwickTree
	{
		int farr[];
		int n;
		public FenwickTree(int c)
		{
			n=c+1;
			farr=new int[n];
		}
		// public void update_range(int l,int r,long p)
		// {
		// 	update(l,p);
		// 	update(r+1,(-1)*p);
		// }
		public void update(int x,int p)
		{
			for(;x<n;x+=x&(-x))
			{
				farr[x]+=p;
			}
		}
		public int get(int x)
		{
			int ans=0;
			for(;x>0;x-=x&(-x))
			{
				ans=ans+farr[x];
			}
			return ans;
		}
	}
	//Disjoint Set Union

	//NOTE: call find function for all the index in the par array at last,
	//in order to set parent of every index properly.
	public static class DSU
	{
	    int par[],rank[];
	    public DSU(int c)
	    {
	        par=new int[c+1];
	        rank=new int[c+1];
	        for(int i=0;i<=c;i++)
	        {
	            par[i]=i;
	            rank[i]=0;
	        }
	    }
	    public int find(int a)
	    {
	        if(a==par[a])
	        return a;
	        return par[a]=find(par[a]);
	    }
	    public void union(int a,int b)
	    {
	        int a_rep=find(a),b_rep=find(b);
	        if(a_rep==b_rep)
	        return;
	        if(rank[a_rep]<rank[b_rep])
	        par[a_rep]=b_rep;
	        else if(rank[a_rep]>rank[b_rep])
	        par[b_rep]=a_rep;
	        else
	        {
	            par[b_rep]=a_rep;
	            rank[a_rep]++;
	        }
	    }
	}
	public static boolean isVowel(char c)
	{
		if(c=='a' || c=='e' || c=='i' || c=='u' || c=='o')return true;
		return false;
	}
	public static boolean isInteger(double N)
	{
		int X = (int)N;
		double temp2 = N - X;
		if (temp2 > 0)
		{
			return false;
		}
		return true;
	}
	public static boolean isPalindrome(String s)
	{
		int n=s.length();
		for(int i=0;i<=n/2;i++){
			if(s.charAt(i)!=s.charAt(n-i-1)){
				return false;
			}
		}
		return true;
	}
	public static int gcd(int a,int b)
	{
	    if(b==0)
	    return a;
	    else
	    return gcd(b,a%b);
	}
	public static long gcd(long a,long b)
	{
	    if(b==0)
	    return a;
	    else
	    return gcd(b,a%b);
	}
	public static long fact(long n)
	{
		long fact=1;
		for(long i=2;i<=n;i++){
			fact=((fact%mod)*(i%mod))%mod;
		}
		return fact;
	}
	public static long fact(int n)
	{
		long fact=1;
		for(int i=2;i<=n;i++){
			fact=((fact%mod)*(i%mod))%mod;
		}
		return fact;
	}
	public static boolean isPrime(int n)
	{
	    if (n <= 1)
	        return false;
	    if (n <= 3)
	        return true;
	    if (n % 2 == 0 || n % 3 == 0)
	        return false;
	    double sq=Math.sqrt(n);

	    for (int i = 5; i <= sq; i = i + 6)
	        if (n % i == 0 || n % (i + 2) == 0)
	            return false;
	    return true;
	}
    public static boolean isPrime(long n)
	{
	    if (n <= 1)
	        return false;
	    if (n <= 3)
	        return true;
	    if (n % 2 == 0 || n % 3 == 0)
	        return false;
	    double sq=Math.sqrt(n);

	    for (int i = 5; i <= sq; i = i + 6)
	        if (n % i == 0 || n % (i + 2) == 0)
	            return false;
	    return true;
	}
	public static void printArray(long a[])
	{
		for(int i=0;i<a.length;i++){
			out.print(a[i]+" ");
		}
		out.println();
	}
	public static void printArray(int a[])
	{
		for(int i=0;i<a.length;i++){
			out.print(a[i]+" ");
		}
		out.println();
	}
	public static void printArray(char a[])
	{
		for(int i=0;i<a.length;i++){
			out.print(a[i]);
		}
		out.println();
	}
	public static void printArray(String a[])
	{
		for(int i=0;i<a.length;i++){
			out.print(a[i]+" ");
		}
		out.println();
	}
	public static void printArray(boolean a[])
	{
		for(int i=0;i<a.length;i++){
			out.print(a[i]+" ");
		}
		out.println();
	}
	public static void printArray(pair a[])
	{
		for(pair p:a){
			out.println(p.a+"->"+p.b);
		}
	}
	public static void printArray(int a[][])
	{
		for(int i=0;i<a.length;i++){
			for(int j=0;j<a[i].length;j++){
				out.print(a[i][j]+" ");
			}out.println();
		}
	}
	public static void printArray(String a[][])
	{
		for(int i=0;i<a.length;i++){
			for(int j=0;j<a[i].length;j++){
				out.print(a[i][j]+" ");
			}out.println();
		}
	}
	public static void printArray(boolean a[][])
	{
		for(int i=0;i<a.length;i++){
			for(int j=0;j<a[i].length;j++){
				out.print(a[i][j]+" ");
			}out.println();
		}
	}
	public static void printArray(long a[][])
	{
		for(int i=0;i<a.length;i++){
			for(int j=0;j<a[i].length;j++){
				out.print(a[i][j]+" ");
			}out.println();
		}
	}
	public static void printArray(char a[][])
	{
		for(int i=0;i<a.length;i++){
			for(int j=0;j<a[i].length;j++){
				out.print(a[i][j]+" ");
			}out.println();
		}
	}
	public static void printArray(ArrayList<?> arr)
	{
		for(int i=0;i<arr.size();i++){
			out.print(arr.get(i)+" ");
		}
		out.println();
	}
	public static void printMapI(HashMap<?,?> hm){
		for(Map.Entry<?,?> e:hm.entrySet()){
			out.println(e.getKey()+"->"+e.getValue());
		}out.println();
	}
	public static void printMap(HashMap<Long,ArrayList<Integer>> hm){
		for(Map.Entry<Long,ArrayList<Integer>> e:hm.entrySet()){
			out.print(e.getKey()+"->");
			ArrayList<Integer> arr=e.getValue();
			for(int i=0;i<arr.size();i++){
				out.print(arr.get(i)+" ");
			}out.println();
		}
	}
	public static void printGraph(ArrayList<Integer> graph[])
	{
		int n=graph.length;
		for(int i=0;i<n;i++){
			out.print(i+"->");
			for(int j:graph[i]){
				out.print(j+" ");
			}out.println();
		}
	}

	//Modular Arithmetic

	public static long add(long a,long b)
	{
		a+=b;
		if(a>=mod)a-=mod;
		return a;
	}
	public static long sub(long a,long b)
	{
		a-=b;
		if(a<0)a+=mod;
		return a;
	}
	public static long mul(long a,long b)
	{
		return ((a%mod)*(b%mod))%mod;
	}
	public static long divide(long a,long b,long m)
	{
		a=mul(a,modInverse(b,m));
		return a;
	}
	public static long modInverse(long a,long m)
	{
		int x=0,y=0;
		own p=new own(x,y);
		long g=gcdExt(a,m,p);
		if(g!=1){
			out.println("inverse does not exists");
			return -1;
		}else{
			long res=((p.a%m)+m)%m;
			return res;
		}
	}
	public static long gcdExt(long a,long b,own p)
	{
		if(b==0){
			p.a=1;
			p.b=0;
			return a;
		}
		int x1=0,y1=0;
		own p1=new own(x1,y1);
		long gcd=gcdExt(b,a%b,p1);
		p.b=p1.a - (a/b) * p1.b;
		p.a=p1.b;
		return gcd;
	}
	public static long pwr(long m,long n)
	{
		long res=1;
		if(m==0)
		return 0;
		while(n>0)
		{
			if((n&1)!=0)
			{
				res=(res*m);
			}
			n=n>>1;
			m=(m*m);
		}
		return res;
	}
	public static long modpwr(long m,long n)
	{
		long res=1;
		m=m%mod;
		if(m==0)
		return 0;
		while(n>0)
		{
			if((n&1)!=0)
			{
				res=(res*m)%mod;
			}
			n=n>>1;
			m=(m*m)%mod;
		}
		return res;
	}
	public static class own
    {
    	long a;
    	long b;
    	public own(long val,long index)
    	{
    	    a=val;
    	    b=index;
    	}
    }

	//Modular Airthmetic

	public static void sort(int[] A)
	{
        int n = A.length;
        Random rnd = new Random();
        for(int i=0; i<n; ++i)
		{
            int tmp = A[i];
            int randomPos = i + rnd.nextInt(n-i);
            A[i] = A[randomPos];
            A[randomPos] = tmp;
        }
        Arrays.sort(A);
    }
	public static void sort(char[] A)
	{
        int n = A.length;
        Random rnd = new Random();
        for(int i=0; i<n; ++i)
		{
            char tmp = A[i];
            int randomPos = i + rnd.nextInt(n-i);
            A[i] = A[randomPos];
            A[randomPos] = tmp;
        }
        Arrays.sort(A);
    }
    public static void sort(long[] A)
	{
	    int n = A.length;
        Random rnd = new Random();
        for(int i=0; i<n; ++i)
		{
            long tmp = A[i];
            int randomPos = i + rnd.nextInt(n-i);
            A[i] = A[randomPos];
            A[randomPos] = tmp;
        }
	    Arrays.sort(A);
	}

	//max,min,sum and sqrt
	public static int max(int a,int b){return Math.max(a,b);}
	public static int min(int a,int b){return Math.min(a,b);}
	public static int max(int a,int b,int c){return Math.max(a,Math.max(b,c));}
	public static int min(int a,int b,int c){return Math.min(a,Math.min(b,c));}
	public static long max(long a,long b){return Math.max(a,b);}
	public static long min(long a,long b){return Math.min(a,b);}
	public static long max(long a,long b,long c){return Math.max(a,Math.max(b,c));}
	public static long min(long a,long b,long c){return Math.min(a,Math.min(b,c));}
	public static int maxinA(int a[]){int n=a.length;int mx=a[0];for(int i=1;i<n;i++){mx=max(mx,a[i]);}return mx;}
	public static long maxinA(long a[]){int n=a.length;long mx=a[0];for(int i=1;i<n;i++){mx=max(mx,a[i]);}return mx;}
	public static int mininA(int a[]){int n=a.length;int mn=a[0];for(int i=1;i<n;i++){mn=min(mn,a[i]);}return mn;}
	public static long mininA(long a[]){int n=a.length;long mn=a[0];for(int i=1;i<n;i++){mn=min(mn,a[i]);}return mn;}
	public static long suminA(int a[]){int n=a.length;long sum=0;for(int i=0;i<n;i++){sum+=a[i];}return sum;}
	public static long suminA(long a[]){int n=a.length;long sum=0;for(int i=0;i<n;i++){sum+=a[i];}return sum;}
	public static int sqrt(int a){int p=(int)Math.sqrt(a);if(p*p>a)p--;return p;}
	public static long sqrt(long a){long p=(long)Math.sqrt(a);if(p*p>a)p--;return p;}
	//end

	public static int[] I(int n)throws IOException{int a[]=new int[n];for(int i=0;i<n;i++){a[i]=I();}return a;}
	public static long[] IL(int n)throws IOException{long a[]=new long[n];for(int i=0;i<n;i++){a[i]=L();}return a;}
	public static long[] prefix(int a[]){int n=a.length;long pre[]=new long[n];pre[0]=a[0];for(int i=1;i<n;i++){pre[i]=pre[i-1]+a[i];}return pre;}
	public static long[] prefix(long a[]){int n=a.length;long pre[]=new long[n];pre[0]=a[0];for(int i=1;i<n;i++){pre[i]=pre[i-1]+a[i];}return pre;}

	public static int I()throws IOException{return sc.I();}
    public static long L()throws IOException{return sc.L();}
    public static String S()throws IOException{return sc.S();}
    public static double D()throws IOException{return sc.D();}
}
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 I(){ return Integer.parseInt(next());}
    long L(){ return Long.parseLong(next());}
    double D(){return Double.parseDouble(next());}
    String S(){
        String str = "";
        try {
            str = br.readLine();
        }
        catch (IOException e){
            e.printStackTrace();
        }
        return str;
    }
}


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

public class Main {

    public static PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));

    static long[] modArr = new long[100001];
    static final int mod = 1000000007;

    public static void main(String[] args){
        MyScanner scanner = new MyScanner();
        processMod();

        int n = scanner.nextInt();
        int k = scanner.nextInt();
        if(k >= n){
            out.println(modArr[n]);
        }
        else{
            int diff = n - k - 1;
            long res = (modArr[n - diff] - 1 + mod) % mod;
            out.println(res);
        }
        out.close();
    }

    static void processMod(){
        modArr[0] = 1L;
        modArr[1] = 2L;
        for(int i = 2; i <= 100000; i++){
            modArr[i] = (2 * modArr[i-1]) % mod;
        }
    }

    static boolean solve(int n, int[] A, int[] B){
        for(int i = 0; i < n; i++){
            if(A[i] > B[i]){
                return false;
            }
            if (A[i] < B[i]) {
                int nextIdx = (i+1)% n;
                if(B[i] - B[nextIdx] > 1){
                    return false;
                }
            }
        }
        return true;

    }

    static int gcd(int n1, int n2) {
        if (n2 == 0) {
            return n1;
        }
        return gcd(n2, n1 % n2);
    }

    public 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.*;
import java.util.*;

public class Main {

    public static PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));

    static final int mod = 1000000007;

    static long[][] C;
    private static void getCrTableLong(int n){
        C = new long[n+1][n+1];
        for(int i = 0; i <= n; i++){
            for (int j = 0; j <= i; j++){
                if(j == 0){
                    C[i][j] = 1L;
                }
                else {
                    C[i][j] = (C[i-1][j] + C[i-1][j-1]) % mod;
                }
            }
        }
    }

    public static void main(String[] args){
        MyScanner scanner = new MyScanner();
        int n = scanner.nextInt();
        int k = scanner.nextInt();
        getCrTableLong(n);
        k = Math.min(k, n);
        long res = 0;
        for(int i = 0; i <= k; i++){
            res += C[n][i];
            res %= mod;
        }
        out.println(res);
        out.close();
    }

    static boolean solve(int n, int[] A, int[] B){
        for(int i = 0; i < n; i++){
            if(A[i] > B[i]){
                return false;
            }
            if (A[i] < B[i]) {
                int nextIdx = (i+1)% n;
                if(B[i] - B[nextIdx] > 1){
                    return false;
                }
            }
        }
        return true;

    }

    static int gcd(int n1, int n2) {
        if (n2 == 0) {
            return n1;
        }
        return gcd(n2, n1 % n2);
    }

    public 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.*;
import java.util.*;

public class Main {
    static Main2 admin = new Main2();

    public static void main(String[] args) {
        admin.start();
    }
}

class Main2 {
    //---------------------------------INPUT READER-----------------------------------------//
    public BufferedReader br;
    StringTokenizer st = new StringTokenizer("");
    String next() {
        while (!st.hasMoreTokens()) {
            try { st = new StringTokenizer(br.readLine());} catch (IOException e) { e.printStackTrace(); }
        }
        return st.nextToken();
    }

    int ni() { return Integer.parseInt(next()); }
    long nl() { return Long.parseLong(next()); }
    double nd() { return Double.parseDouble(next()); }
    String ns() { return next(); }

    int[] na(long n) {int[]ret=new int[(int)n]; for(int i=0;i<n;i++) ret[i]=ni(); return ret;}
    long[] nal(long n) {long[]ret=new long[(int)n]; for(int i=0;i<n;i++) ret[i]=nl(); return ret;}
    Integer[] nA(long n) {Integer[]ret=new Integer[(int)n]; for(int i=0;i<n;i++) ret[i]=ni(); return ret;}
    Long[] nAl(long n) {Long[]ret=new Long[(int)n]; for(int i=0;i<n;i++) ret[i]=nl(); return ret;}

    //--------------------------------------PRINTER------------------------------------------//
    PrintWriter w;
    void p(int i) {w.println(i);} void p(long l) {w.println(l);}
    void p(double d) {w.println(d);} void p(String s) { w.println(s);}
    void pr(int i) {w.print(i);} void pr(long l) {w.print(l);}
    void pr(double d) {w.print(d);} void pr(String s) { w.print(s);}
    void pl() {w.println();}

    //--------------------------------------VARIABLES-----------------------------------------//
    long lma = Long.MAX_VALUE, lmi = Long.MIN_VALUE;
    int ima = Integer.MAX_VALUE, imi = Integer.MIN_VALUE;
    long mod = 1000000007;

    {
        w = new PrintWriter(System.out);
        br = new BufferedReader(new InputStreamReader(System.in));
        try {if(new File(System.getProperty("user.dir")).getName().equals("Main_CP")) {
            w = new PrintWriter(new OutputStreamWriter(new FileOutputStream("output.txt")));
            br = new BufferedReader(new InputStreamReader(new FileInputStream("input.txt")));}
        } catch (Exception ignore) { }
    }

    //----------------------START---------------------//
    void start() {
        //int t = ni(); while(t-- > 0)
            solve();

        w.close();
    }

    void solve() {
        long n = ni(), k = ni();

        if(k >= n) {
            p(mp(2, n));
            return;
        }

        long rem = (n - k + mod) % mod;

        p((mp(2, n) - rem + mod) % mod);
    }

    long mp (long b, long x) {
        if (x == 0) return 1;
        if (x == 1) return b;
        if (x % 2 == 0) return mp (b * b % mod, x / 2) % mod;

        return b * mp (b * b % mod, x / 2) % mod;
    }
}


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

public class Solution {

    public static void main(String[] args) {
        FastReader sc = new FastReader();
        int n = sc.nextInt();
        int k = sc.nextInt();

        if(k >= n){
            int m = 1;
            for(int i =0; i < n;i ++){
                m *= 2;
                m %= (1000000000 + 7);
            }
            System.out.println(m);
            return;
        }

        int ans = 1;
        for(int i = n-1; i >= n-k; i --){
            int m = 1;
            for(int j =0; j < i;j ++){
                m *= 2;
                m %= (1000000000 + 7);
            }
            ans += m;
            ans %= (1000000000 + 7);
        }
        System.out.println(ans);
    }

    private static int max(int a, int b){
        return Math.max(a, b);
    }

    private static int min(int a, int b){
        return Math.min(a, b);
    }

    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 {
                if(st.hasMoreTokens()){
                    str = st.nextToken("\n");
                }
                else{
                    str = br.readLine();
                }
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

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


import java.util.*;
import java.io.*;
public class Test {
	 	static long mod = 1000000007;
		static PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));
		public static void main(String[] args) throws IOException  {
			FastReader sc = new FastReader();
			int t = 1;
			while( t-- > 0) {
				long n = sc.nextLong();
				long k = sc.nextLong();
				long ans = 1;
				for( int i = 0 ; i < n; i++) {
					ans*=2;
					ans%=mod;
				}
				if( k >= n) {
					out.println(ans);
				}
				else {
					ans--;
					ans-=(((n)*(n-k-1))%mod);
					out.println(ans);
				}
			}
			out.flush();
		}
		/*
		 * look at test cases
		 * do significant case work
		 */
		public static boolean ifpowof2(long n ) {
			return ((n&(n-1)) == 0);
		}

		static boolean isprime(long x ) {
			if( x== 2) {
				return true;
			}
			if( x%2 == 0) {
				return false;
			}
			for( long i = 3 ;i*i <= x ;i+=2) {
				if( x%i == 0) {
					return false;
				}
			}
			return true;
		}

		static boolean[] sieveOfEratosthenes(long n) {
			boolean prime[] = new boolean[(int)n + 1];
			for (int i = 0; i <= n; i++) {
				prime[i] = true;
			}
			for (long p = 2; p * p <= n; p++) {
				if (prime[(int)p] == true) {
					for (long i = p * p; i <= n; i += p)
						prime[(int)i] = false;
				}
			}
			return prime;
		}

		public static int[] nextLargerElement(int[] arr, int n)	{
			Stack<Integer> stack = new Stack<>();
			int rtrn[] = new int[n];
			rtrn[n-1] = -1;
	        stack.push( n-1);
	        for( int i = n-2 ;i >= 0 ; i--){
	            int temp = arr[i];
	            int lol = -1;
	            while( !stack.isEmpty() && arr[stack.peek()] <= temp){
	            	if(arr[stack.peek()] == temp ) {
	            		lol = stack.peek();
	            	}
	                stack.pop();
	            }
	            if( stack.isEmpty()){
	            	if( lol != -1) {
	            		rtrn[i] = lol;
	            	}
	            	else {
	            		rtrn[i] = -1;
	            	}
	            }
	            else{
	            	rtrn[i] = stack.peek();
	            }
	            stack.push( i);
	        }
	        return rtrn;
		}

		static void mysort(int[] arr) {
			for(int i=0;i<arr.length;i++) {
	            int rand = (int) (Math.random() * arr.length);
	            int loc = arr[rand];
	            arr[rand] = arr[i];
	            arr[i] = loc;
	        }
	        Arrays.sort(arr);
	    }

		static void mySort(long[] arr) {
	        for(int i=0;i<arr.length;i++) {
	            int rand = (int) (Math.random() * arr.length);
	            long loc = arr[rand];
	            arr[rand] = arr[i];
	            arr[i] = loc;
	        }
	        Arrays.sort(arr);
	    }

		static long gcd(long a, long b)
		{
			if (a == 0)
				return b;
			return gcd(b % a, a);
		}

		 static long lcm(long a, long b)
		 {
			 return (a / gcd(a, b)) * b;
		 }

		 static long rightmostsetbit(long n) {
			 return n&-n;
		 }

		 static long leftmostsetbit(long n)
		    {
		        long k = (long)(Math.log(n) / Math.log(2));
		        return k;
		    }

		 static HashMap<Long,Long> primefactor( long n){
			 HashMap<Long ,Long> hm = new HashMap<>();
			 long temp = 0;
			 while( n%2 == 0) {
				 temp++;
				 n/=2;
			 }
			 if( temp!= 0) {
				 hm.put( 2L, temp);
			 }
			 long c = (long)Math.sqrt(n);
			 for( long i = 3 ; i <= c ; i+=2) {
				 temp = 0;
				 while( n% i == 0) {
					 temp++;
					 n/=i;
				 }
				 if( temp!= 0) {
					 hm.put( i, temp);
				 }
	 		 }
	 		 if( n!= 1) {
	 			 hm.put( n , 1L);
	 		 }
	 		 return hm;
		 }

		 static ArrayList<Long> allfactors(long abs) {
			 HashMap<Long,Integer> hm = new HashMap<>();
			 ArrayList<Long> rtrn = new ArrayList<>();
			 for( long i = 2 ;i*i <= abs; i++) {
				 if( abs% i == 0) {
					 hm.put( i , 0);
					 hm.put(abs/i, 0);
				 }
			 }
			 for( long x : hm.keySet()) {
				 rtrn.add(x);
			 }

			 if( abs != 0) {
				 rtrn.add(abs);
			 }

			 return rtrn;
		 }

		 public static int[][] prefixsum( int n , int m , int arr[][] ){
			 int prefixsum[][] = new int[n+1][m+1];
			 for( int i = 1 ;i <= n ;i++) {
				 for( int j = 1 ; j<= m ; j++) {
					 int toadd = 0;
					 if( arr[i-1][j-1] == 1) {
						 toadd = 1;
					 }
					 prefixsum[i][j] = toadd + prefixsum[i][j-1] + prefixsum[i-1][j] - prefixsum[i-1][j-1];
				 }
			 }
			 return prefixsum;
		 }

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


// Imports
import java.io.*;
import java.util.*;

public class D {
    // i don't know if htis works and at this point i'm afraid to touch it
    public static long degree(long a, long k, long p) {
        long res = 1;
        long cur = a;

        while(k > 0) {
          if (k % 2 == 1) {
            res = (res * cur) % p;
          }
          k /= 2;
          cur = (cur * cur) % p;
        }
        return res;
    }

    public static void main(String[] args) throws IOException {
        // Test once done
        BufferedReader f = new BufferedReader(new InputStreamReader(System.in));

        StringTokenizer st = new StringTokenizer(f.readLine());
        int N = Integer.parseInt(st.nextToken());
        int K = Integer.parseInt(st.nextToken());

        K = Math.min(K, N);

        // C(n,k+1) = C(n,k) * (n-k) / (k+1)
        long solution = 0;
        int mod = (int)(1E9 + 7);
        long[] numerators = new long[N + 1];
        long[] denominators = new long[N + 1];
        numerators[0] = 1;
        denominators[0] = 1;

        for(int i = 0; i < N; i++) {
            numerators[i + 1] = numerators[i] * (N - i);
            numerators[i + 1] %= mod;

            denominators[i + 1] = denominators[i] * (i + 1);
            denominators[i + 1] %= mod;
        }

        for(int i = 0; i < K; i++) {
            solution += (numerators[i] * degree(denominators[i], mod - 2, mod)) % mod;
            solution %= mod;
        }

        System.out.println(solution);
    }
}


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

public class D {

	static long MOD = (long) (1e9 + 7);
	static long factorial[] = new long[100001];

	public static void main(String args[]) throws Exception {

		factorial[0] = 1;
		for (int i = 1; i <= 10000; i++) {

		    factorial[i] = factorial[i - 1] * i % MOD;

		}

		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
		StringTokenizer st = new StringTokenizer(br.readLine());

		int n = Integer.parseInt(st.nextToken());
		int k = Integer.parseInt(st.nextToken());

		long val = 0;

		for(int i = 0; i <= Math.min(n, k); i++) {

			val = (val + binomial_coefficient(n, i)) % MOD;

		}

		pw.println(val);
		pw.close();

	}

	static long binomial_coefficient(int n, int k) {

	    return factorial[n] * binpow(factorial[k] * factorial[n - k] % MOD, MOD - 2, MOD) % MOD;

	}

	static long binpow(long a, long b, long m) {
	    a %= m;
	    long res = 1;
	    while (b > 0) {
	        if ((b & 1) == 1)
	            res = res * a % m;
	        a = a * a % m;
	        b >>= 1;
	    }
	    return res;
	}

}


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

public class Main {
    static ContestScanner sc = new ContestScanner(System.in);
    static PrintWriter pw = new PrintWriter(System.out);
    static StringBuilder sb = new StringBuilder();
    static long mod = (long) 1e9 + 7;

    public static void main(String[] args) throws Exception {
        //int T = sc.nextInt();
        //for(int i = 0; i < T; i++)solve();

        solve();
        pw.flush();
    }

    public static void solve() {
        int n = sc.nextInt();
        int k = sc.nextInt();
        if(n <= k){
            pw.println(rep2(2,Math.min(n,k),mod));
        }else{
            long total = rep2(2,n,mod);
            long down = rep2(2,n-k-1,mod);
            pw.println((total-down+mod)%mod);
        }
    }

    private static long rep2(long b, long n, long mod){
        if(n == 0) return 1;
        long bn = rep2(b,n/2,mod);
        if(n % 2 == 0){
            return (bn*bn)%mod;
        }else{
            return (bn*bn)%mod*b%mod;
        }
    }

    static class GeekInteger {
        public static void save_sort(int[] array) {
            shuffle(array);
            Arrays.sort(array);
        }

        public static int[] shuffle(int[] array) {
            int n = array.length;
            Random random = new Random();
            for (int i = 0, j; i < n; i++) {
                j = i + random.nextInt(n - i);
                int randomElement = array[j];
                array[j] = array[i];
                array[i] = randomElement;
            }
            return array;
        }

        public static void save_sort(long[] array) {
            shuffle(array);
            Arrays.sort(array);
        }

        public static long[] shuffle(long[] array) {
            int n = array.length;
            Random random = new Random();
            for (int i = 0, j; i < n; i++) {
                j = i + random.nextInt(n - i);
                long randomElement = array[j];
                array[j] = array[i];
                array[i] = randomElement;
            }
            return array;
        }

    }
}

/**
 * refercence : https://github.com/NASU41/AtCoderLibraryForJava/blob/master/ContestIO/ContestScanner.java
 */
class ContestScanner {
    private final java.io.InputStream in;
    private final byte[] buffer = new byte[1024];
    private int ptr = 0;
    private int buflen = 0;

    private static final long LONG_MAX_TENTHS = 922337203685477580L;
    private static final int LONG_MAX_LAST_DIGIT = 7;
    private static final int LONG_MIN_LAST_DIGIT = 8;

    public ContestScanner(java.io.InputStream in){
        this.in = in;
    }
    public ContestScanner(java.io.File file) throws java.io.FileNotFoundException {
        this(new java.io.BufferedInputStream(new java.io.FileInputStream(file)));
    }
    public ContestScanner(){
        this(System.in);
    }

    private boolean hasNextByte() {
        if (ptr < buflen) {
            return true;
        }else{
            ptr = 0;
            try {
                buflen = in.read(buffer);
            } catch (java.io.IOException e) {
                e.printStackTrace();
            }
            if (buflen <= 0) {
                return false;
            }
        }
        return true;
    }
    private int readByte() {
        if (hasNextByte()) return buffer[ptr++]; else return -1;
    }
    private static boolean isPrintableChar(int c) {
        return 33 <= c && c <= 126;
    }
    public boolean hasNext() {
        while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++;
        return hasNextByte();
    }
    public String next() {
        if (!hasNext()) throw new java.util.NoSuchElementException();
        StringBuilder sb = new StringBuilder();
        int b = readByte();
        while(isPrintableChar(b)) {
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    public long nextLong() {
        if (!hasNext()) throw new java.util.NoSuchElementException();
        long n = 0;
        boolean minus = false;
        int b = readByte();
        if (b == '-') {
            minus = true;
            b = readByte();
        }
        if (b < '0' || '9' < b) {
            throw new NumberFormatException();
        }
        while (true) {
            if ('0' <= b && b <= '9') {
                int digit = b - '0';
                if (n >= LONG_MAX_TENTHS) {
                    if (n == LONG_MAX_TENTHS) {
                        if (minus) {
                            if (digit <= LONG_MIN_LAST_DIGIT) {
                                n = -n * 10 - digit;
                                b = readByte();
                                if (!isPrintableChar(b)) {
                                    return n;
                                } else if (b < '0' || '9' < b) {
                                    throw new NumberFormatException(
                                        String.format("%d%s... is not number", n, Character.toString(b))
                                    );
                                }
                            }
                        } else {
                            if (digit <= LONG_MAX_LAST_DIGIT) {
                                n = n * 10 + digit;
                                b = readByte();
                                if (!isPrintableChar(b)) {
                                    return n;
                                } else if (b < '0' || '9' < b) {
                                    throw new NumberFormatException(
                                        String.format("%d%s... is not number", n, Character.toString(b))
                                    );
                                }
                            }
                        }
                    }
                    throw new ArithmeticException(
                        String.format("%s%d%d... overflows long.", minus ? "-" : "", n, digit)
                    );
                }
                n = n * 10 + digit;
            }else if(b == -1 || !isPrintableChar(b)){
                return minus ? -n : n;
            }else{
                throw new NumberFormatException();
            }
            b = readByte();
        }
    }
    public int nextInt() {
        long nl = nextLong();
        if (nl < Integer.MIN_VALUE || nl > Integer.MAX_VALUE) throw new NumberFormatException();
        return (int) nl;
    }
    public double nextDouble() {
        return Double.parseDouble(next());
    }

    public long[] nextLongArray(int length){
        long[] array = new long[length];
        for(int i=0; i<length; i++) array[i] = this.nextLong();
        return array;
    }
    public long[] nextLongArray(int length, java.util.function.LongUnaryOperator map){
        long[] array = new long[length];
        for(int i=0; i<length; i++) array[i] = map.applyAsLong(this.nextLong());
        return array;
    }
    public int[] nextIntArray(int length){
        int[] array = new int[length];
        for(int i=0; i<length; i++) array[i] = this.nextInt();
        return array;
    }
    public int[] nextIntArray(int length, java.util.function.IntUnaryOperator map){
        int[] array = new int[length];
        for(int i=0; i<length; i++) array[i] = map.applyAsInt(this.nextInt());
        return array;
    }
    public double[] nextDoubleArray(int length){
        double[] array = new double[length];
        for(int i=0; i<length; i++) array[i] = this.nextDouble();
        return array;
    }
    public double[] nextDoubleArray(int length, java.util.function.DoubleUnaryOperator map){
        double[] array = new double[length];
        for(int i=0; i<length; i++) array[i] = map.applyAsDouble(this.nextDouble());
        return array;
    }

    public long[][] nextLongMatrix(int height, int width){
        long[][] mat = new long[height][width];
        for(int h=0; h<height; h++) for(int w=0; w<width; w++){
            mat[h][w] = this.nextLong();
        }
        return mat;
    }
    public int[][] nextIntMatrix(int height, int width){
        int[][] mat = new int[height][width];
        for(int h=0; h<height; h++) for(int w=0; w<width; w++){
            mat[h][w] = this.nextInt();
        }
        return mat;
    }
    public double[][] nextDoubleMatrix(int height, int width){
        double[][] mat = new double[height][width];
        for(int h=0; h<height; h++) for(int w=0; w<width; w++){
            mat[h][w] = this.nextDouble();
        }
        return mat;
    }

    public char[][] nextCharMatrix(int height, int width){
        char[][] mat = new char[height][width];
        for(int h=0; h<height; h++){
            String s = this.next();
            for(int w=0; w<width; w++){
                mat[h][w] = s.charAt(w);
            }
        }
        return mat;
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;

public class CF1528E {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    StreamTokenizer st = new StreamTokenizer(br);

    final int N = (int) (1e6 + 10);
    final int M = 998244353;

    long[] dp = new long[N], dp1 = new long[N], dp2 = new long[N];

    private long readLong() throws IOException {
        st.nextToken();
        return (long) st.nval;
    }

    private int readInt() throws IOException {
        st.nextToken();
        return (int) st.nval;
    }

    private String readString() throws Exception {
        st.nextToken();
        return st.sval;
    }

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

    long inv(long a) {
        return inv(a, M);
    }

    public long inv(long a, long mod) {
        long b = mod;
        long p = 1, q = 0;
        while (b > 0) {
            long c = a / b;
            long d;
            d = a;
            a = b;
            b = d % b;
            d = p;
            p = q;
            q = d - c * q;
        }
        return p < 0 ? p + mod : p;
    }

    long g(int n) {
        if (n < 0)
            return 0;
        long t = dp[n];
        long res = (t * (t + 1)) % M;
        res = (res * (t + 5)) % M;
        res = (res * inv(3)) % M;
        return (res + M) % M;
    }

    private void run() throws Exception {
        int n = readInt();
        dp[0] = dp1[0] = dp2[0] = 1;

        for (int i = 1; i <= n; i++) {
            dp[i] = ((dp[i - 1] + 1) * (dp[i - 1] + 2) / 2) % M;
            dp1[i] = dp[i] - dp[i - 1];
            dp2[i] = dp1[i] - dp1[i - 1];
        }
        long res = (g(n - 1) - g(n - 2)) % M;
        for (int i = 0; i < n; i++)
            res = (res + dp2[i] * dp1[n - 1 - i]) % M;

        System.out.println(res);
    }
}


/*
  Goal: Become better in CP!
  Key: Consistency and Discipline
  Desire: SDE @ Google USA
  Motto: Do what i Love <=> Love what i do
  If you don't use your brain 100%, it deteriorates gradually
*/

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

public class Solution {

  static StringBuffer str=new StringBuffer();
  static BufferedReader bf;
  static PrintWriter pw;
  static int n, x;
  static long mod=998244353l;
  static long dp[][];
  static long comb[][];

  static long mod_mul(long a, long b) {
    a = a % mod;
    b = b % mod;
    return (((a * b) % mod) + mod) % mod;
  }

  static long mod_add(long a, long b) {
    a = a % mod;
    b = b % mod;
    return (((a + b) % mod) + mod) % mod;
  }

  static long pow(long a, long b) {
    long res = 1;
    while (b > 0) {
        if (b % 2 == 1) res = (res * a)%mod;
        a = (a * a)%mod;
        b = b >> 1l;
    }
    return res;
  }

  // O(n*x*n) solution
  static long count(int i, int j){
    if(i==1) return 0;
    if(i==0) return 1;
    if(j>=x) return 0;
    if(dp[i][j]!=-1) return dp[i][j];

    int cost = Math.min(x, j+i-1);
    // Transition from dp[i][j] to dp[k][cost]
    long ans=0;
    for(int k=0;k<=i;k++){
      ans=mod_add(ans, mod_mul(comb[i][i-k], mod_mul(pow(cost-j, i-k), count(k, cost))));
    }
    return dp[i][j]=ans;
  }

  // DP + Combinatorics
  static void solve(int te) throws Exception{
    comb = new long[501][501];
    comb[0][0] = 1;
    for (int i = 1; i <= 500; i++) {
      comb[i][0] = 1;
      for (int j = 1; j <= i; j++) {
        comb[i][j] = (comb[i-1][j] + comb[i-1][j-1]) % mod;
      }
    }

    // dp[i][j] = # of ways to choose health = required answer
    // i -> i heros still alive => i=n is required
    // j -> already received j damage => j<=x is required

    // sum of dp[0][j] for each j in [0, x] is the answer
    dp=new long[n+1][x+1];
    for(int i=0;i<=n;i++){
      for(int j=0;j<=x;j++){
        dp[i][j]=-1;
      }
    }
    str.append(count(n, 0)).append("\n");
  }

  public static void main(String[] args) throws java.lang.Exception {
    boolean lenv=true;
    int te=1;
    if(lenv){
      bf = new BufferedReader(
                          new FileReader("input.txt"));
      pw=new PrintWriter(new
            BufferedWriter(new FileWriter("output.txt")));
    }else{
      bf = new BufferedReader(new InputStreamReader(System.in));
      pw = new PrintWriter(new OutputStreamWriter(System.out));
    }

    // int q1 = Integer.parseInt(bf.readLine().trim());
    // for(te=1;te<=q1;te++) {
      String s[]=bf.readLine().trim().split("\\s+");
      n=Integer.parseInt(s[0]);
      x=Integer.parseInt(s[1]);
      solve(te);
    // }
    pw.print(str);
    pw.flush();
    // System.out.println(str);
  }
}


// Problem: E. Arena
// Contest: Codeforces - Educational Codeforces Round 116 (Rated for Div. 2)
// URL: https://codeforces.com/contest/1606/problem/E
// Memory Limit: 256 MB
// Time Limit: 3000 ms
//
// Powered by CP Editor (https://cpeditor.org)

// Problem: D. Frog Traveler
// Contest: Codeforces - Codeforces Round #751 (Div. 2)
// URL: https://codeforces.com/contest/1602/problem/D
// Memory Limit: 512 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)

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

import static java.lang.Math.max;
import static java.lang.Math.min;
import static java.lang.Math.abs;

/**
 * zxz
 * problem link:
 **/
public class Main {

    //put some data here

    /**
     * do some clean action before next testcase
     */
    private void clear() {

    }

	void cal(int n, int x){
		long t = pow_mod(x,n,mod);
		ans = (ans + t) % mod;
	}
	long [][] c;
	long ans = 0;
	long mod = 998244353L;
	long [][] dp;
	long dfs(int n, int x){
		if(dp[n][x] >= 0){
			return dp[n][x];
		}
		// System.out.println(n + "-" + x);
		long res = pow_mod(min(n-1, x),n, mod);
		// System.out.println("all die" + res);
		if(x >= n){
			for(int i = 2; i <= n; i++){
// System.out.println(i + "  " + pow_mod(n-1,x - i,mod) * Cnm(n,i));
				res += pow_mod(n-1,n - i,mod)* c[n][i] * dfs(i, x - n + 1) % mod;
				res %= mod;

			}
		}
		dp[n][x] = res;
		// System.out.println(n + " " + x + " " + res);
		return res;
	}

    private void solve() throws Exception {
        rf();
        int n = ri();
        int x = ri();
		dp = new long[n + 1][x + 1];
		for(int i = 0; i <= n; i++){
			Arrays.fill(dp[i], -1);
		}

		c = new long[n + 1][n + 1];
		c[0][0]= 1;
		for(int i = 1; i <= n; i++){
			c[i][0] = 1;
			// System.out.print(c[i][0] + " ");
			for(int j = 1; j <= i; j++){
				c[i][j] = (c[i - 1][j] + c[i-1][j-1]) % mod ;
				// System.out.print(c[i][j] + " ");
			}
			// System.out.println();
		}

		// dfs(n,x);
		addAns(dfs(n,x));
    }

    private void run() throws Exception {

        int T = 1;

        while (T-- > 0) {
            solve();
            if (T != 0) {
                clear();
            }
        }
        printAns();
    }

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

    StringBuilder sb = new StringBuilder();
    BufferedReader infile = new BufferedReader(new InputStreamReader(System.in));
    StringTokenizer strT;

	private void addAns(int a){
		sb.append(a + "\n");
	}

	private void addAns(long a){
		sb.append(a + "\n");
	}

	private void addAns(String s){
		sb.append(s + "\n");
	}

    private void rf() throws IOException {
        strT = new StringTokenizer(infile.readLine());
    }

    private int ri() {
        return Integer.parseInt(strT.nextToken());
    }

    private long rl() {
        return Long.parseLong(strT.nextToken());
    }

	private char [] rs2c(){
		return strT.nextToken().toCharArray();
	}

	private String rs(){
		return strT.nextToken();
	}

    private void printAns() {
        System.out.println(sb);
    }

    private int[] readArr(int N) throws Exception {
        int[] arr = new int[N];
        rf();
        for (int i = 0; i < N; i++) {
            arr[i] = Integer.parseInt(strT.nextToken());
        }
        return arr;
    }

    private void print(int[] arr) {
        //for debugging only
        for (int x : arr) {
            System.out.print(x + " ");
        }
        System.out.println();
    }

    private void print(long[] arr) {
        //for debugging only
        for (long x : arr) {
            System.out.print(x + " ");
        }
        System.out.println();
    }

    private long[] readArr2(int N) throws Exception {
        long[] arr = new long[N];
        strT = new StringTokenizer(infile.readLine());
        for (int i = 0; i < N; i++) {
            arr[i] = Long.parseLong(strT.nextToken());
        }
        return arr;
    }

    private boolean isPrime(long n) {
        if (n < 2) {
            return false;
        }
        if (n == 2 || n == 3) {
            return true;
        }
        if (n % 2 == 0 || n % 3 == 0) {
            return false;
        }
        long sqrtN = (long) Math.sqrt(n) + 1;
        for (long i = 6L; i <= sqrtN; i += 6) {
            if (n % (i - 1) == 0 || n % (i + 1) == 0) {
                return false;
            }
        }
        return true;
    }

    private long gcd(long a, long b) {
        if (a > b) {
            a = (a + b) - (b = a);
        }
        if (a == 0L) {
            return b;
        }
        return gcd(b % a, a);
    }

    private int gcd(int a, int b) {
        if (a > b) {
            a = (a + b) - (b = a);
        }
        if (a == 0) {
            return b;
        }
        return gcd(b % a, a);
    }

    private double pow(double x, long N) {
        double ans = 1.0;
        // 贡献的初始值为 x
        double x_contribute = x;
        // 在对 N 进行二进制拆分的同时计算答案
        while (N > 0) {
            if (N % 2 == 1) {
                // 如果 N 二进制表示的最低位为 1，那么需要计入贡献
                ans *= x_contribute;
            }
            // 将贡献不断地平方
            x_contribute *= x_contribute;
            // 舍弃 N 二进制表示的最低位，这样我们每次只要判断最低位即可
            N /= 2;
        }
        return ans;
    }

    long pow_mod(long x, long i, long mod){
	    if(i == 0){
	        return 1;
	    }
	    long temp = pow_mod(x, i >> 1, mod);
	    temp = temp * temp % mod;
	    if((i & 1 )!= 0){
	        temp = temp * x % mod;
	    }
	    return temp;
	}

}


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

public class Div21606E {

	public static long MOD = 998244353;
	public static long[] factorial = new long[501];
	public static long[] inverse_fac = new long[501];

	public static void main(String[] args) throws IOException {

		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());

		int n = Integer.parseInt(st.nextToken());
		int x = Integer.parseInt(st.nextToken());

		factorial[0] = 1;
		for (long i = 1; i <= 500; i++)
		    factorial[(int) i] = (factorial[(int) (i - 1)] * i) % MOD;

		inverse_fac[1] = binpow(1, MOD-2, MOD);
		for(int i = 2; i <= 500; ++i)
			inverse_fac[i] = binpow(factorial[i], MOD-2, MOD);

		long[][] dp = new long[n][x];

		Arrays.fill(dp[0], 0);

		for(int i = 1; i < n; i++) {

			for(int j = 0; j < x; j++) {

				if(j < i)
					dp[i][j] = binpow(j+1, i+1, MOD);
				else {

					dp[i][j] += dp[i][j-1];

					for(int k = i; k > 0; k--) {

						if(j-i == 0)
							dp[i][j] = (dp[i][j] + binpow(i, i-k, MOD) * dp[k][j-i] * binomial_coefficient(i+1, k+1)) % MOD;
						else {

							long min = (dp[k][j-i] - dp[k][-1+j-i]) % MOD;

							if(min < 0)
								min += MOD;

							dp[i][j] = (dp[i][j] + binpow(i, i-k, MOD) * min * binomial_coefficient(i+1, k+1)) % MOD;

						}

					}
				}

			}

		}

		/*for(int i = 0; i < x; i++) {
			for(int j = 0; j < n; j++)
				System.out.print(dp[j][i] + " ");
		System.out.println();
		}*/

		System.out.println(dp[n-1][x-1]);

	}

	static long binpow(long a, long b, long m) {

	    a %= m;

	    long res = 1;

	    while (b > 0) {

	        if ((b & 1) == 1)
	            res = res * a % m;

	        a = a * a % m;
	        b >>= 1;

	    }

	    return res;

	}

	static long binomial_coefficient(int n, int k) {

		if(n == k)
			return 1;

		return (factorial[n] * inverse_fac[k] % MOD) * inverse_fac[n - k] % MOD;

	}

}


import java.util.Scanner;
public class Q1606E {

	final static long N = 998244353;
	static long C[][] = new long[501][501];
	static long ans[][] = new long[501][501];

	public static void main(String[] args) {

		Scanner s = new Scanner(System.in);
		int n = s.nextInt();
		int x = s.nextInt();
		for(int i=2;i<=n;i++)
		{
			for(int j=1;j<=x;j++)
			{
				System.out.printf("%9d ",calculate(i,j));
			}
			System.out.println("");
		}
		//System.out.println(calculate(n,x));
	}

	public static long ncr(int n, int r)
	{
		if(C[n][r]!=0) return C[n][r];
		else
		{
			if(r==0||n==r)
			{
				C[n][r] = 1;
				return 1;
			}
			else
			{
				C[n][r] = (ncr(n-1,r-1)+ncr(n-1,r))%N;
				return C[n][r];
			}
		}
	}

	public static long calculate(int n, int x)
	{
		if(ans[n][x]!=0) return ans[n][x];
		else
		{
			if(n==2)
			{
				ans[n][x] = x;
				return x;
			}
			if(x<=n-1)
			{
				long j = 1;
				for(int k=1; k<=n; k++)
				{
					j*=x;
					j%=N;
				}
				ans[n][x] = j;
				return j;
			}
			for(int i=2; i<=n; i++)
			{
				long j = (ncr(n,i)*calculate(i,x-n+1))%N;
				for(int k=1;k<=n-i;k++)
				{
					j*=(n-1);
					j%=N;
				}
				ans[n][x] += j;
				ans[n][x] %=N;
			}
			long j=1;
			for(int k=1;k<=n;k++)
			{
				j*=(n-1);
				j%=N;
			}
			ans[n][x] += j;
			ans[n][x] %= N;
			return ans[n][x];
		}
	}
}


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

public class Main {
	static PrintWriter out;
	static Reader in;
	public static void main(String[] args) throws Exception {
		input_output();
		Main solver = new Main();
		solver.solve();
		out.close();

		out.flush();
	}

	static int INF = (int)1e9;
	static int MAXN = 500;
	static int MOD = 998244353;
	static int q, t, m, n, k;

	static long[][] dp, remove, c;

	void solve() throws Exception {
		n = in.nextInt();
		k = in.nextInt();

		dp = new long[k+1][n];
		for (int i = 0; i <= k; i++)
			for (int j = 0; j < n; j++)
				dp[i][j] = -1;

		remove = new long[n][n]; // remove[left][removed] = left^removed;
		for (int i = 1; i < n; i++) remove[i][0] = 1;
		remove[0][0] = 1;
		for (int i = 1; i < n; i++) {
			for (int j = 1; j <= i; j++) {
				remove[i][j] = (remove[i][j-1] * i) % MOD;
			}
		}

		c = new long[MAXN+1][MAXN+1];
		c[0][0] = 1;
		c[1][0] = 1;
		c[1][1] = 1;
		for (int i = 1; i <= MAXN; i++) {
			c[i][0] = 1;
			for (int j = 1; j <= i; j++) {
				c[i][j] = (c[i-1][j]+c[i-1][j-1]) % MOD;
			}
		}

		long ans = 0;
		for (int i = 1; i <= k; i++) rec(i, n-1);

		for (int i = 1; i <= k; i++) {
			ans = (ans + dp[i][n-1]) % MOD;
		}

		ans = (ans * n) % MOD;
		long all = 1;
		for (int i = 1; i <= n; i++) all = (all * k) % MOD;
		ans = (all-ans+MOD) % MOD;
		out.println(ans);
	}

	static long rec(int val, int left) {
		if (val <= 0) return 0;
		if (dp[val][left] != -1) return dp[val][left];

		if (left == 0) return dp[val][left] = 1;
		long res = 0;
		for (int i = 0; i <= left; i++) {
			res += (rec(val-left, left-i) * ((remove[left][i] * c[left][i]) % MOD)) % MOD;
		}

		return dp[val][left] = res;
	}

	static class Reader {
		private InputStream mIs;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;

		public Reader() {
			this(System.in);
		}

		public Reader(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 next() {
			int c = read();
			while (isSpaceChar(c)) {
				c = read();
			}
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = read();
			} while (!isSpaceChar(c));
			return res.toString();
		}

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

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

	}
	static void input_output() throws IOException {
		File f = new File("in.txt");
		if (f.exists() && !f.isDirectory()) {
			in = new Reader(new FileInputStream("in.txt"));
		} else in = new Reader();
		f = new File("out.txt");
		if (f.exists() && !f.isDirectory()) {
			out = new PrintWriter(new File("out.txt"));
		} else out = new PrintWriter(System.out);
	}
}


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

public class E1646 {
    static final int MAX = (int) 1e6 + 1;

    static int gcd(int a, int b) {
        return a == 0 ? b : gcd(b % a, a);
    }

    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        PrintWriter pw = new PrintWriter(System.out);
        int[] lp = new int[MAX];
        for (int i = 2; i < lp.length; i++) {
            if (lp[i] == 0) {
                for (int j = i; j < lp.length; j += i) {
                    if (lp[j] == 0) {
                        lp[j] = i;
                    }
                }
            }
        }
        int n = sc.nextInt();
        int m = sc.nextInt();
        int[] val = new int[25];
        HashSet<Long> hs = new HashSet<>();
        for (int i = 1; i < val.length; i++) {
            for (int j = 1; j <= m; j++) {
                hs.add(1L * j * i);
            }
            val[i] = hs.size();
        }
        long ans = 1;
        for (int i = 2; i <= n; i++) {
            int x = i;
            int curP = lp[x];
            int cnt = 0;
            ArrayList<Integer> factors = new ArrayList<>();
            while (x > 1) {
                if (lp[x] == curP) {
                    cnt++;
                } else {
                    factors.add(cnt);
                    curP = lp[x];
                    cnt = 1;
                }
                x /= lp[x];
            }
            factors.add(cnt);
//            System.out.println(factors);
            int gcd = 0;
            for (int f : factors) {
                gcd = gcd(f, gcd);
            }
            ans += val[gcd];
        }
        pw.println(ans);
        pw.close();
    }

    static class Scanner {
        BufferedReader br;
        StringTokenizer st;

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

        public Scanner(FileReader f) {
            br = new BufferedReader(f);
        }

        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 double nextDouble() throws IOException {
            return Double.parseDouble(next());
        }

        public int[] nextIntArr(int n) throws IOException {
            int[] arr = new int[n];
            for (int i = 0; i < n; i++) {
                arr[i] = Integer.parseInt(next());
            }
            return arr;
        }

    }
}


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

public class C774E {

    static StringBuffer ans1 = new StringBuffer("");
    static FastScanner sc = new FastScanner();
    static PrintWriter printWriter = new PrintWriter(System.out);

    public static void solve(int n, int m) {
        int depth = 0, temp = n;
        while(temp > 1) {
            temp /= 2;
            depth++;
        }
        int[] dp = new int[depth + 1];
        boolean[] visited = new boolean[m * depth + 1];
        int size = 0;
        for (int i = 1; i <= depth; i++) {
            for(int j = 1; j <= m; j++) {
                if(!visited[i * j]) size++;
                visited[i * j] = true;
            }
            dp[i] = size;
            printWriter.println(i + " " + dp[i]);
        }
        long res = 1;
        boolean[] used = new boolean[n + 1];
        for(int i = 2; i <= n; i++) {
            if(used[i]) continue;
            int k = i, count = 0;
            while(k <= n) {
                used[k] = true;
                count++;
                if(k * 1L * i != k * i) break;
                k *= i;
            }
            res += dp[count];
        }
        printWriter.println(res);
    }

    public static void main(String[] args) {
        int n = sc.nextInt();
        int m = sc.nextInt();
        solve(n, m);
        printWriter.flush();
    }

    /*****************************************************************
     ******************** DO NOT READ AFTER THIS LINE *****************
     *****************************************************************/
    static class FastScanner {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer("");

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

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

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

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

        int[][] read2dArray(int n, int m) {
            int arr[][] = new int[n][m];
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < m; j++) {
                    arr[i][j] = nextInt();
                }
            }
            return arr;
        }

        ArrayList<Integer> readArrayList(int n) {
            ArrayList<Integer> arr = new ArrayList<Integer>();
            for (int i = 0; i < n; i++) {
                int a = nextInt();
                arr.add(a);
            }
            return arr;
        }

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


//package com.example.practice.codeforces.sc2200;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.StringTokenizer;

//E. Power Board
public class Solution2 {
    final static int D = 20;
    final static int M = 1 << D;
    final static boolean[] nonPrime = new boolean[M+1];
    final static ArrayList<Integer> primes = new ArrayList<>();
    static {
        for (int i=2, k=(int)Math.sqrt(M); i<=k; ++i){
            if (!nonPrime[i]){
                primes.add(i);
                int t = i*i;
                while(t <= M){
                    nonPrime[t] = true;
                    t += i;
                }
            }
        }
    }
    public static void main (String [] args) throws IOException {
        // Use BufferedReader rather than RandomAccessFile; it's much faster
        final BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
        // input file name goes above
        //PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("inflate.out")));

        StringTokenizer st = new StringTokenizer(input.readLine());
        int n = Integer.parseInt(st.nextToken()), m = Integer.parseInt(st.nextToken());
        System.out.println(calc(n, m));
        //out.close();       // close the output file
    }

    private static long calc(final int n, final int m) {
        final int[] rd = new int[D+1];
        boolean[] seen = new boolean[D*m+1];
        for (int i=1;i<=D;++i){
            int t = 0;
            for (int j=i*i,k=i;k<=m;++k,j+=i){
                if(!seen[j]){
                    t++;
                    seen[j] = true;
                }
            }
            rd[i] = t;
        }
        long res = 1;
        for (int i=2;i<=n;++i){
            int t = i, gcd = 0;
            for (int a : primes){
                int c = 0;
                while (t%a == 0){
                    t /= a;
                    c++;
                }
                gcd = GCD(c, gcd);
                if (t==1)break;
                if (!nonPrime[t]){
                    gcd = 1;
                    break;
                }
            }
            res += rd[gcd];
        }
        return res;
    }

    private static int GCD(int x, int y){
        if(x>y)return GCD(y, x);
        if (x==0)return y;
        return GCD(y%x, x);
    }
}


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

public class Contest1646E
{
    static class InputReader {
        BufferedReader reader;
        StringTokenizer tokenizer;
        public InputReader(InputStream stream) {
            reader = new BufferedReader(new InputStreamReader(stream), 32768);
            tokenizer = null;
        }
        String next() { // reads in the next string
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }
        public int nextInt() { // reads in the next int
            return Integer.parseInt(next());
        }
        public long nextLong() { // reads in the next long
            return Long.parseLong(next());
        }
        public double nextDouble() { // reads in the next double
            return Double.parseDouble(next());
            }
        }
    static InputReader r = new InputReader(System.in);
    static PrintWriter pw = new PrintWriter(System.out);
    static long mod = 1000000007;
    public static void main(String[] args)
    {
    	int n = r.nextInt();
    	int m = r.nextInt();
    	int[] count = new int[n+5];
    	boolean[] seen = new boolean[n+5];
    	for (int i = 2; i <= n; i ++)
    	{
    		long j = i;
    		if (!seen[(int)j])
    		{
    			while (j <= n)
    			{
    				seen[(int)j] = true;
    				j *= i;
    				count[i] ++;
    			}
    		}
    	}
    	long ans = 1;
    	long[] hi = new long[22];
    	hi[0] = 0;
    	hi[1] = m;
    	for (int i = 2; i <= 20; i ++)
    	{
    		hi[i] = hi[i-1] + m - ((i-1)*m)/i;
    	}
    	for (int x = 2; x <= n; x ++)
    	{
    		ans += hi[count[x]];
    	}
    	pw.println(ans);
    	/*
    	1 1 1 1 1
    	2 4 8 16 32
    	3 9 27 81 243
    	4 16 64 256 1024
    	 */
        pw.close();
    }
}


import java.io.*;
import java.lang.reflect.Array;
import java.math.*;
import java.util.*;

public class Main {
    private final BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
    private final BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
    private StringTokenizer st;
    private final Long MOD = 1000000007L;
    private final String endl = "\n";

    boolean isConsonant(char c) {
        return !isVowel(c);
    }

    boolean isVowel(char c) {
        return c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U';
    }

    // IO UTILS

    void log(Object... args) {
        if (!TESTING) return;
        for (Object s : args) System.out.print(s.toString() + " ");
        System.out.println();
    }

    String line() throws IOException {
        return in.readLine().trim();
    }

    StringTokenizer tokens() throws IOException {
        return new StringTokenizer(line());
    }

    long l(String s) {
        return Long.parseLong(s);
    }

    long rl() throws IOException {
        return l(line());
    }

    long[] rla(int n) throws IOException {
        long[] arr = new long[n];
        st = tokens();
        for (int i = 0; i < n; i++)
            arr[i] = l(st.nextToken());
        return arr;
    }

    int i(String s) {
        return Integer.parseInt(s);
    }

    int ri() throws IOException {
        return i(line());
    }

    int[] ria(int n) throws IOException {
        int[] arr = new int[n];
        st = tokens();
        for (int i = 0; i < n; i++)
            arr[i] = i(st.nextToken());
        return arr;
    }

    String rs() throws IOException {
        return line();
    }

    String[] rsa(int n) throws IOException {
        String[] s = new String[n];
        st = tokens();
        for (int i = 0; i < n; i++)
            s[i] = st.nextToken();
        return s;
    }

    double d(String s) {
        return Double.parseDouble(s);
    }

    double rd() throws IOException {
        return d(line());
    }

    double[] rda(int n) throws IOException {
        double[] arr = new double[n];
        st = tokens();
        for (int i = 0; i < n; i++) {
            arr[i] = d(st.nextToken());
        }
        return arr;
    }
    // IO UTILS END

    // MATH UTILS

    long gcd(long a, long b) {
        return b == 0 ? a : gcd(b, a % b);
    }

    long lcm(long a, long b) {
        long g = gcd(a, b);
        return (a / g) * b; // directly multiply a and b can overflow
    }

    public long modInv(long a, long MOD) {
        return new BigInteger(a + "").modPow(new BigInteger((MOD - 2) + ""), new BigInteger(MOD + "")).longValue();
    }

    public long modPro(long a, long b, long MOD) {
        return ((a % MOD) * (b % MOD)) % MOD;
    }

    private long factorialMod(int n, long MOD) {
        long pro = 1;
        for (long i = 1; i <= n; i++) {
            pro = pro * i;
            pro %= MOD;
        }
        return pro;
    }

    static void ruffleSort(int[] a) {
        // ruffle
        int n = a.length;
        Random r = new Random();
        for (int i = 0; i < a.length; i++) {
            int oi = r.nextInt(n), temp = a[i];
            a[i] = a[oi];
            a[oi] = temp;
        }
        Arrays.sort(a);
    }

    static void ruffleSort(long[] a) {
        // ruffle
        int n = a.length;
        Random r = new Random();
        for (int i = 0; i < a.length; i++) {
            int oi = r.nextInt(n);
            long temp = a[i];
            a[i] = a[oi];
            a[oi] = temp;
        }
        Arrays.sort(a);
    }

    boolean[] sieveOfEratosthenes(int n) {
        boolean[] prime = new boolean[n + 1];
        for (int i = 0; i < n; i++)
            prime[i] = true;
        prime[0] = false;
        prime[1] = false;
        for (int i = 4; i <= n; i += 2) {
            prime[i] = false;
        }
        for (int p = 3; p * p <= n; p += 2) {
            // If prime[p] is not changed, then it is a prime
            if (prime[p]) {
                // Update all multiples of p
                for (int i = p * p; i <= n; i += p)
                    prime[i] = false;
            }
        }
        return prime;
    }

    // MATH UTILS END
    private final boolean TESTING = false;

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

    private void solve() throws Exception {
        int testCases = 1;
//        testCases = Integer.parseInt(in.readLine().trim());
        preProcess();
        for (int i = 1; i <= testCases; i++) {
            solveTestCase(i);
        }
        out.flush();
        out.close();
    }

    void preProcess() {

    }

    private void solveTestCase(int testCaseNumber) throws Exception {
        int[] arr = ria(2);
        int n = arr[0];
        int m = arr[1];
        int log = 0;
        int two = 2;
        while (true) {
            if (two > n)
                break;
            two *= 2;
            log++;
        }

//999439867182
        boolean set[] = new boolean[log * n + 1];
        long hash[] = new long[log + 1];
        int count = 0;
        for (int i = 1; i <= log; i++) {
            for (int j = 1; j <= m; j++) {
                if (!set[i*j]) {
                    set[i*j] = true;
                    count += 1;
                }
            }
            hash[i] = count;
        }
//        System.out.println(set + endl + Arrays.toString(hash));

        long ans = 0;
        boolean[] done = new boolean[n + 1];
        for (int i = 2; i <= n; i++) {
            if (!done[i]) {

                long pow = 1;
                done[i] = true;
                long temp = i;
                while (true) {
                    temp *= i;
                    if (temp > n)
                        break;
                    done[(int) temp] = true;
                    pow++;

                }
//								System.out.println( i+ " " + pow+ " " + hash[(int)pow]);
                ans += hash[(int) pow];

            }
        }

        out.write(ans + 1 + endl);

    }

}