Problem: 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.

Solution (in JAVA):

Solution:
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Set;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

public class q5 {
	static long aa,bb;
	static long score1,score2,steps;
	static ArrayList<NoD>[] arr;
	static Stack<Integer> finalans,tempans;
	//static HashSet<Integer> vis;
	static int[] ans;
	static long[] dist;
	
	long gcd(long a,long b) {
		if(b==0) return a;
		else return gcd(b,a%b);
	}
	
	
	static int prod(String s, int ii) {
		int a=s.length();
		int ans=1;
		for(int i=0;i<s.length();i++) {
			int r=s.charAt(i)-48;
			if(r!=0) ans*=r;
		}
		if(ans<=9) {
			q5.ans[ii]=ans;
		}
		else {
			ans=prod(Integer.toString(ans),ans);
			q5.ans[ii]=ans;
		}
		return ans;
		
	}
	
	
	public static void main(String[] args) throws IOException {
		
		Reader.init(System.in);
		StringBuffer output=new StringBuffer("");
		PrintWriter out=new PrintWriter(System.out);
		long n=Reader.nextLong();int k=Reader.nextInt();
		long mod=1000000007;
		long[][] dp=new long[k+1][k+1];
		dp[0][0]=1;
		for(int i=1;i<=k;i++) {
			for(int j=1;j<=i;j++) {
				dp[i][j]=dp[i-1][j-1]+j*dp[i-1][j];
				dp[i][j]%=mod;
			}
		}
		long tomul=n;
		int steps=1;
		long ans=0;
		BigInteger t=BigInteger.valueOf(2);
		BigInteger mm=BigInteger.valueOf(mod);
		for(int j=1;j<=k;j++) {
			long a=dp[k][j];
			long b=tomul;
			BigInteger p=BigInteger.valueOf(n-j);
			p=t.modPow(p, mm);
			a*=b;
			a%=mod;
			a*=p.longValue();
			a%=mod;
			ans+=a;
			ans%=mod;
			tomul*=(n-steps);
			tomul%=mod;
			steps++;
			
		}
		output.append(ans);
		out.write(output.toString());
		out.flush();
		
	}
}

class NoD{
	int a;long b,c;
	NoD(int aa,long bb){
		a=aa;b=bb;
	}
	
}

class Dis {
	int[] arr;
	int[] parent;
	int[] rank;
	int[] size;
	Dis(int n){
		arr=new int[n+1];
		parent=new int[n+1];
		rank=new int[n+1];
		size=new int[n+1];
		for(int i=1;i<=n;i++) {
			arr[i]=i;
			parent[i]=i;
			rank[i]=0;
			size[i]=1;
		}
	}

	int find(int value) {
		int par=parent[value];
		if(par==value)
			return par;
		parent[value]=find(par);
		return parent[value];
	}
	
	void union(int data1,int data2) {
		int parent1=find(data1);
		int parent2=find(data2);
		if(parent1!=parent2) {
			if(rank[parent1]>=rank[parent2]) {
				parent[parent2]=parent1;
				if(rank[parent1]==rank[parent2])
					rank[parent1]++;
				size[parent1]+=size[parent2];
			}
			else {
				parent[parent1]=parent2;
				size[parent2]+=size[parent1];
			}
		}
		
	}


}
class Reader {
    static BufferedReader reader;
    static StringTokenizer tokenizer;
 
    /** call this method to initialize reader for InputStream */
    static void init(InputStream input) {
        reader = new BufferedReader(
                     new InputStreamReader(input) );
        tokenizer = new StringTokenizer("");
    }
 
    /** get next word */
    static String nextLine() throws IOException{
    	return reader.readLine();
    }
    static String next() throws IOException {
        while ( ! tokenizer.hasMoreTokens() ) {
            //TODO add check for eof if necessary
            tokenizer = new StringTokenizer(
                   reader.readLine() );
        }
        return tokenizer.nextToken();
    }
    
    static int nextInt() throws IOException {
        return Integer.parseInt( next() );
    }
    static long nextLong() throws IOException {
        return Long.parseLong( next() );
    }
    static double nextDouble() throws IOException {
        return Double.parseDouble( next() );
    }
}