You have a team of N people. For a particular task, you can pick any non-empty subset of people. The cost of having x people for the task is xk. 

Output the sum of costs over all non-empty subsets of people.

Input

Only line of input contains two integers N (1 ≤ N ≤ 109) representing total number of people and k (1 ≤ k ≤ 5000).

Output

Output the sum of costs for all non empty subsets modulo 109 + 7.

Examples

Input

1 1


Output

1


Input

3 2


Output

24

Note

In the first example, there is only one non-empty subset {1} with cost 11 = 1.

In the second example, there are seven non-empty subsets.

- {1} with cost 12 = 1

- {2} with cost 12 = 1

- {1, 2} with cost 22 = 4

- {3} with cost 12 = 1

- {1, 3} with cost 22 = 4

- {2, 3} with cost 22 = 4

- {1, 2, 3} with cost 32 = 9

The total cost is 1 + 1 + 4 + 1 + 4 + 4 + 9 = 24.
/*
 * Author Ayub Subhaniya
 * Institute DA-IICT
 */

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

public class E
{
	
	InputStream in;
	PrintWriter out;
	
	long mod=(long)1e9+7;
	int MAX=(int)1e6;
	String high="";
	
	long[][] nCr;
		
	void choose(int maxN, int maxR) {
		nCr = new long[maxN + 1][maxR + 1];
		for (int i = 0; i <= maxN; i++) {
			for (int j = 0; j <= i; j++) {
				if (j == 0 || j == i || i == 0) {
					nCr[i][j] = 1;
				} else {
					nCr[i][j] = (nCr[i - 1][j - 1] + nCr[i - 1][j]) % mod;
				}
			}
		}
	}
	
	long nCr(int n, int r) {
		if (n == r) {
			return 1;
		}
		if (n < 0 || r < 0) {
			return 0;
		}
		return nCr[n][r];
	}
	
	void solve() 
	{
		long n=nl();
		long k=nl();
		long sum=0;
		if (k==1)
		{
			sum=mul(n,pow(2,n-1,mod));
		}
		else if (n<=k)
		{
			choose((int)n,(int)n);
			for (int i=1;i<=n;i++)
			{
				sum=add(sum, mul(pow(i,k,mod),nCr((int)n,i)));
			}
		}
		else
		{
			
			long cf[]=new long[(int) (k+1)];
			cf[1]=1;
			for (long i=1;i<k;i++)
			{
				for (int j=(int) (k-1);j>=1;j--)
				{
					cf[j+1]=add(cf[j+1],cf[j]);
					cf[j]=mul(cf[j],j);
				}
			}
			tr(cf);
			long p1=n;
			for (long i=1;i<=k;i++)
			{
				sum=add(sum, mul(p1,mul(cf[(int) i],pow(2,n-i,mod))));
				p1=mul(p1,n-i);
			}
		}
		out.println(sum);
	}
	
	class Pair implements Comparable<Pair>
	{
		int x;
		int y;
		Pair(int a,int b)
		{
			x=a;
			y=b;
		}
		
		@Override
		public boolean equals(Object o) 
		{
			Pair other = (Pair)o;
			return x == other.x && y == other.y;
		}
		public String toString()
		{
			return x+" "+y;
		}
		
		@Override
		public int compareTo(Pair o) 
		{
			if (x==o.x)
				return Integer.compare(y, o.y);
			else
				return Integer.compare(x, o.x);
		}
		@Override public int hashCode() 
		{
			return Objects.hash(x, y);
		}
	}
	
	long pow(long x, long n, long M) {
		x%=M;
		long result = 1;
		while (n > 0) {
			if (n % 2 == 1)
				result = (result * x) % M;
			x = (x * x) % M;
			n = n / 2;
		}
		return result;
	}
	
	long modInverse(long A, long M) {
		extendedEuclid(A, M);
		return (EEx % M + M) % M;
	}
	long EEd, EEx, EEy;
	
	void extendedEuclid(long A, long B) {
		if (B == 0) {
			EEd = A;
			EEx = 1;
			EEy = 0;
		} else {
			extendedEuclid(B, A % B);
			long temp = EEx;
			EEx = EEy;
			EEy = temp - (A / B) * EEy;
		}
	}
	
	int max(int a,int b)
	{
		if(a>b)
			return a;
		else
			return b;
	}
	
	int min(int a,int b)
	{
		if(a>b)
			return b;
		else 
			return a;
	}
	
	long max(long a,long b)
	{
		if(a>b)
			return a;
		else
			return b;
		
	}
	
	
	long min(long a,long b)
	{
		if(a>b)
			return b;
		else 
			return a;
		
	}
	
	long add(long a,long b)
	{
		long x=(a+b);
		while(x>=mod) x-=mod;
		return x;
		
	}
	
	
	long sub(long a,long b)
	{
		long x=(a-b);
		while(x<0) x+=mod;
		return x;
		
	}
	
	
	long mul(long a,long b)
	{
		a%=mod;
		b%=mod;
		long x=(a*b);
		return x%mod;
		
	}
	
	void run() throws Exception 
	{
		String INPUT = "C:/Users/ayubs/Desktop/input.txt";
		oj=high.length()==0;
		in = oj ? System.in : new FileInputStream(INPUT);
		out = new PrintWriter(System.out);
		
		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis() - s + "ms");
		
	}
	public static void main(String[] args) throws Exception 
	{
		new E().run();
	}
	
	private byte[] inbuf = new byte[1024];
	public int lenbuf = 0, ptrbuf = 0;
	
	private int readByte() 
	{
		if (lenbuf == -1)
			throw new InputMismatchException();
		if (ptrbuf >= lenbuf) 
		{
			ptrbuf = 0;
			try 
			{
				lenbuf = in.read(inbuf);
			}
			catch (IOException e) 
			{
				throw new InputMismatchException();
			}
			if (lenbuf <= 0)
				return -1;
		}
		return inbuf[ptrbuf++];
	}
	
	private boolean inSpaceChar(int c) 
	{
		return !(c >= 33 && c <= 126);
	}
	
	private int skip() 
	{
		int b;
		while ((b = readByte()) != -1 && inSpaceChar(b))
			;
		return b;
	}
	
	private double nd() 
	{
		return Double.parseDouble(ns());
	}
	
	private char nc() 
	{
		return (char) skip();
	}
	
	private String ns() 
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while (!(inSpaceChar(b))) 
		{ // when nextLine, (inSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}
	
	private char[] ns(int n) 
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while (p < n && !(inSpaceChar(b))) 
		{
			buf[p++] = (char) b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}
	
	private char[][] nm(int n, int m) 
	{
		char[][] map = new char[n][];
		for (int i = 0; i < n; i++)
			map[i] = ns(m);
		return map;
	}
	
	private int[] na(int n) 
	{
		int[] a = new int[n];
		for (int i = 0; i < n; i++)
			a[i] = ni();
		return a;
	}
	
	private int ni() 
	{
		int num = 0, b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') 
		{
			minus = true;
			b = readByte();
		}
		
		while (true) 
		{
			if (b >= '0' && b <= '9') 
			{
				num = num * 10 + (b - '0');
			} 
			else 
			{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}
	
	private long nl() 
	{
		long num = 0;
		int b;
		boolean minus = false;
		while ((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'))
			;
		if (b == '-') 
		{
			minus = true;
			b = readByte();
		}
		
		while (true) 
		{
			if (b >= '0' && b <= '9') 
			{
				num = num * 10 + (b - '0');
			}
			else 
			{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}
	
	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	
	private void tr(Object... o) 
	{
		if (!oj)
			System.out.println(Arrays.deepToString(o));
	}
	
}