import java.sql.SQLOutput;
import java.util.*;
/*
NOTES:
-more than 10 digits (10^10), use long
-prefix sum of 1's and -1's to control flow of highlighting a region
-log(a)/log(b) = log base b of a
-create a position array if trying to see if elements show up next to each other sequentially
 i.e. elements 1,2,3 are within 3 spots of each other in an array
      arr[scannedInt - 1] = i; (position of i at p[i] in original)
- use a freq array when counting instances of an element occurring
- increment the counter first before simulating anything turn-based (two player game)

 */

public class cf {
    static long mod = (long)(Math.pow(10, 9) + 7);
    public static String alpha = "abcdefghijklmnopqrstuvwxyz";
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        long n = scan.nextLong();
        long m = scan.nextLong();
        long x = powMod(2,m)-1;
        long ans = powMod(x,n);
        System.out.println(ans);
    }

    static int GCD(int a, int b) {
        // Everything divides 0
        if (a == 0) return b;
        if (b == 0) return a;

        // base case
        if (a == b) return a;

        // a is greater
        if (a > b) return GCD(a-b, b);
        return GCD(a, b-a);
    }
    static int LCM(int a, int b){
        return (a*b)/(GCD(a,b));
    }
    static String rev(String s){
        char[] arr = s.toCharArray();
        for(int i = 0; i<(s.length()+1)/2; i++){
            char temp = arr[i];
            arr[i] = arr[s.length()-i-1];
            arr[s.length()-i-1] = temp;
        }
        String fin = new String(arr);
        return fin;
    }
    static long pow(long a, long N) {
        if (N == 0) return 1;
        else if (N == 1) return a;
        else {
            long R = pow(a,N/2);
            if (N % 2 == 0) {
                return R*R;
            }
            else {
                return R*R*a;
            }
        }
    }

    static long powMod(long a, long N) {
        if (N == 0) return 1;
        else if (N == 1) return a % mod;
        else {
            long R = powMod(a,N/2) % mod;
            R *= R;
            R %= mod;
            if (N % 2 == 1) {
                R *= a;
                R %= mod;
            }
            return R % mod;
        }
    }

}

import java.io.*;
import java.util.*;
public class Solution {
	static Scanner sc=new Scanner(System.in);
	static PrintWriter out=new PrintWriter(System.out);
	//Main
	static long MOD=(long)1e9+7;
	static long fastExpo(long x,long n) {
		if(n==0) return 1;
		if(n%2==0) return fastExpo((x*x)%MOD,n/2)%MOD;
		return ((x%MOD)*(fastExpo((x*x)%MOD,n/2)%MOD))%MOD;
	}
	public static void main(String args[]) {
		int test=1;
		//test=sc.nextInt();
		while(test-->0) {
			long n=sc.nextLong(),m=sc.nextLong();
			long x=(fastExpo(2,m)-1+MOD)%MOD;
			long ans=fastExpo(x,n)%MOD;
			out.println(ans);
		}
		out.flush();
		out.close();
	}
}

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

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

    static class BAliceAndTheListOfPresents {
        final BigInteger MAX = new BigInteger((int) 1e9 + 7 + "");

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt();
            int m = in.nextInt();
            BigInteger bi = new BigInteger("2");
//        BigInteger fi = bi.modPow(new BigInteger(m+""),MAX).subtract(new BigInteger("1"));
//        fi.modPow(new BigInteger(n+""),MAX);
//        out.println(fi.toString());

            out.println(bi.modPow(new BigInteger(m + ""), MAX).subtract(new BigInteger("1")).modPow(new BigInteger(n + ""), MAX).toString());
        }

    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

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

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

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

    }
}

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

public class B {
    static PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));
    static MyScanner sc;

    static {
        try {
            sc = new MyScanner();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        doTask();
        out.flush();
    }

    static long MOD = 1000000007L;

    public static void doTask(){
        int n = sc.nextInt(), m = sc.nextInt();
        long v = fastPow(2, m) - 1;
        long result = fastPow(v, n);
        out.println(result);
    }

    static long fastPow(long a, long b) {
        if (b == 1) return a;
        long rem = b - (b/2*2);
        long left = fastPow(a, b/2);
        long result = (left*left) % MOD;

        if (rem > 0) {
            long right = fastPow(a, rem);
            result = (result * right) % MOD;
        }
        return result;
    }

    public static class MyScanner {
        BufferedReader br;
        StringTokenizer st;

        public MyScanner() throws FileNotFoundException {
            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.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.StringTokenizer;

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

        BigInteger m = new BigInteger(String.valueOf(scanner.nextInt()));
        BigInteger n =  new BigInteger(String.valueOf(scanner.nextInt()));
        BigInteger two = new BigInteger("2");
        BigInteger mod = new BigInteger("1000000007");
        System.out.println(two.modPow(n,mod).subtract(new BigInteger("1")).modPow(m,mod));

    }

    // -----------MyScanner class for faster input----------
    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;
        }

    }
    // --------------------------------------------------------
}

//package codeforces.round593div2;

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

public class ListOfPresents {
    public static void main(String[] args) {
//        try {
//            FastScanner in = new FastScanner(new FileInputStream("src/input.in"));
//            PrintWriter out = new PrintWriter(new FileOutputStream("src/output.out"));
        FastScanner in = new FastScanner(System.in);
        PrintWriter out = new PrintWriter(System.out);

//        BigInteger p = BigInteger.valueOf(in.nextInt());
//        BigInteger b = BigInteger.valueOf(in.nextInt());
//        BigInteger mod = BigInteger.valueOf((long)1e9 + 7);
//
//        BigInteger res = BigInteger.valueOf(2);
//        res = res.modPow(b, mod).subtract(BigInteger.ONE);
//        res = res.modPow(p, mod);
//        out.println(res.longValue());

        int p = in.nextInt();
        int b = in.nextInt();

        out.println(task(p, b));
        out.close();

//        }
//        catch (IOException e) {
//            e.printStackTrace();
//        }
    }

    private static long task(int p, int b) {
        int mod = (int)1e9 + 7;
        int x = modPow(2, b, mod) - 1;
        return modPow(x, p, mod);
    }

    private static int modPow(int x, int n, int mod) {
        if(n == 0) {
            return 1;
        }
        long coeff = 1;
        long base = x;
        while(n > 1) {
            if(n % 2 != 0) {
                coeff = (coeff * base % mod);
            }
            base = (base * base % mod);
            n = n / 2;
        }
        long res = coeff * base % mod;
        return (int)res;
    }

//    public double myPow(double x, int n) {
//        if(x == 0 && n < 0) {
//            return Double.POSITIVE_INFINITY;
//        }
//        if(n == 0) {
//            return 1;
//        }
//        long N = n;
//        if(N < 0) {
//            x = 1 / x;
//            N = -N;
//        }
//        double base = x;
//        double coeff = 1;
//        while(N > 1) {
//            if(N % 2 != 0) {
//                coeff *= base;
//            }
//            base *= base;
//            N = N / 2;
//        }
//        return coeff * base;
//    }

    static class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        FastScanner(InputStream stream) {
            try {
                br = new BufferedReader(new InputStreamReader(stream));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        String next() {
            while (st == null || !st.hasMoreTokens()) {
                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.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class Main {
    static int MOD = 1000000007;

    public static void main(String[] args) {
        FastReader read = new FastReader();
        StringBuilder out = new StringBuilder();
        int n = read.nextInt();
        int m = read.nextInt();
        long ans = fastPower(2, m) - 1;
        ans = fastPower(ans, n);
        System.out.println(ans);
    }

    public static long fastPower(long b, long n) {
        if (n == 0)
            return 1;
        if (n == 1)
            return b;
        if (n % 2 == 1)
            return (b * fastPower(b, n - 1)) % MOD;
        long r = fastPower(b, n / 2);
        return (r * r) % MOD;
    }
}

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

import java.util.*;
public class GFG {
    static long power(long x, long y, long p)
    {
        // Initialize result
        long res = 1;

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

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

            // y must be even now
            // y = y / 2
            y = y >> 1;
            x = (x * x) % p;
        }
        return res;
    }

	public static void main (String[] args) {
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		int m=sc.nextInt();
		int k=(int)Math.pow(10,9)+7;
	    long k1=power(2,m,k)-1;
	    k1=power(k1,n,k);
	    System.out.println(k1%k);
	}
}

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

public class Main {
    static class FastReader {
        BufferedReader br;
        StringTokenizer st;
        FastReader() {
            br = new BufferedReader(new InputStreamReader(System.in)); }
        String next() {
            while (st == null || !st.hasMoreElements()) {
                try{ st = new StringTokenizer(br.readLine()); }
                catch (IOException  e) { e.printStackTrace(); } }
            return st.nextToken(); }
        int nextInt() { return Integer.parseInt(next()); }
        long nextLong() { return Long.parseLong(next()); }
        double nextDouble() { return Double.parseDouble(next()); }
        String nextLine()  {
            String str = "";
            try{ str = br.readLine(); }
            catch (IOException e) { e.printStackTrace(); }
            return str; }
    }

    static long pow(long num,long base){
        long d=1000000007;
        long ans=1;
        while(num>0){
            if(num%2==1){
                ans=(ans*base)%d;
            }

            num=num/2;
            base=(base*base)%d;
        }
        return ans;
    }
    public static void main(String[] args) {
        FastReader ip = new FastReader();
        OutputStream output = System.out;
        PrintWriter out = new PrintWriter(output);
        long n=ip.nextLong();
        long m=ip.nextLong();
         long v=pow(m,2);
         v--;
         long ans=pow(n,v);

         out.println(ans);
        out.close();
    }
}

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

public class AliceandtheListofPresents {

	public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        BigInteger n = in.nextBigInteger();
        BigInteger m = in.nextBigInteger();
		BigInteger mod = BigInteger.valueOf((long)(1e9+7));
		BigInteger two = BigInteger.valueOf(2L);
		BigInteger ans = two.modPow(m, mod).subtract(BigInteger.ONE).modPow(n, mod);
		out.println(ans);
		out.close();
	}
}

import java.io.*;
import java.lang.reflect.Array;
import java.math.BigInteger;
import java.util.*;
import java.util.Map.Entry;

public class abc {

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

		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		String[] ss=br.readLine().trim().split(" ");
		long n=Long.parseLong(ss[0]);
		long m=Long.parseLong(ss[1]);
		long sum=1;
//		for(int i=1 ; i<=m ; i++) {
//			sum=((sum%d)*2)%d;
//		}
		sum=power(2,m);
		sum-=1;
		sum=sum%d;
		long ans=1;
//		for(int i=1 ; i<n ; i++) {
//			ans=((ans)%d*(sum)%d)%d;
//		}
		ans=power(sum,n);
		System.out.println(ans%d);
	}

	static long power(long x, long y)
    {
        long temp;
        if( y == 0)
            return 1;
        temp = (power(x, y/2))%d;

        if (y%2 == 0)
            return (temp*temp)%d;
        else
        {
            if(y > 0)
                return ((x * temp)%d * (temp)%d)%d;
            else
                return (((temp * temp)%d) / x)%d;
        }
    }

	static long d=1000000007;
	static long binomialCoeff(long n, long k)
    {
        long res = 1;
        if ( k > n - k )
            k = n - k;
        for (int i = 0; i < k; ++i)
        {
        res = ((res)%d*(n - i))%d;
        res /= (i + 1);
        }
        return res;
    }

}

/*
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
int n=Integer.parseInt(br.readLine());
int[] arr=new int[n];
int[] dept=new int[n];
String[] ss=br.readLine().trim().split(" ");
for(int i=0 ; i<arr.length ; i++) {
	arr[i]=Integer.parseInt(ss[i]);
}
ss=br.readLine().trim().split(" ");
for(int i=0 ; i<dept.length ; i++) {
	dept[i]=Integer.parseInt(ss[i]);
}

int[] map2=new int[100001];

for(int i=0 ; i<dept.length ; i++) {
	map2[dept[i]]=i;
}
int max=0,ans=0;
for(int i=0 ; i<arr.length ; i++) {
	max=Math.max(max, map2[arr[i]]);
	if(max>map2[arr[i]]) {
		ans++;
	}
}
System.out.println(ans);
*/

import java.io.*;
import java.util.*;
public class Solution {
	static Scanner sc=new Scanner(System.in);
	static PrintWriter out=new PrintWriter(System.out);
	//Main
	static long MOD=(long)1e9+7;
	static long fastExpo(long x,long n) {
		if(n==0) return 1;
		if(n%2==0) return fastExpo((x*x)%MOD,n/2);
		return (x*(fastExpo((x*x)%MOD,n/2))%MOD);
	}
	public static void main(String args[]) {
		int test=1;
		//test=sc.nextInt();
		while(test-->0) {
			long n=sc.nextLong(),m=sc.nextLong();
			long x=(fastExpo(2,m)-1)%MOD;
			long ans=fastExpo(x,n)%MOD;
			out.println(ans);
		}
		out.flush();
		out.close();
	}
}

import java.io.*;
import java.util.*;
public class Solution {
	static Scanner sc=new Scanner(System.in);
	static PrintWriter out=new PrintWriter(System.out);
	//Main
	static long MOD=(long)1e9+7;
	static long fastExpo(long x,long n) {
		if(n==0) return 1;
		if(n%2==0) return fastExpo((x*x)%MOD,n/2);
		return (x*(fastExpo((x*x)%MOD,n/2))%MOD);
	}
	public static void main(String args[]) {
		int test=1;
		//test=sc.nextInt();
		while(test-->0) {
			long n=sc.nextLong(),m=sc.nextLong();
			long x=(fastExpo(2,m)-1+MOD)%MOD;
			long ans=fastExpo(x,n)%MOD;
			out.println(ans);
		}
		out.flush();
		out.close();
	}
}

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

public class B_1236 {

	public static int pow(int a, int b, int m) {
		int res = 1;
		while(b > 0) {
			if((b & 1) != 0)
				res = (int)((1l * res * a) % m);
			a = (int)((1l * a * a) % m);
			b /= 2;
		}
		return res;
	}

	public static void main(String[] args) throws Exception {
		Scanner sc = new Scanner(System.in);
		PrintWriter pw = new PrintWriter(System.out);

		int n = sc.nextInt(), m = sc.nextInt();
		int mod = (int)1e9+7;

		pw.println(pow(pow(2, m, mod) - 1, n, mod));

		pw.flush();
	}

	public static class Scanner {
		StringTokenizer st;
		BufferedReader br;

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

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

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

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

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

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

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

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

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

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

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

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

		public static int[] shuffle(int[] a) {
			int n = a.length;
			Random rand = new Random();
			for (int i = 0; i < n; i++) {
				int tmpIdx = rand.nextInt(n);
				int tmp = a[i];
				a[i] = a[tmpIdx];
				a[tmpIdx] = tmp;
			}
			return a;
		}

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

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

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

public class A
{
    static int n, m;
    static int[] arr;
    static char[] s;
    public static void main(String[] args) throws IOException
    {
        f = new Flash();
        out = new PrintWriter(System.out);

        pre();
        int T = 1; //ni();
        for(int tc = 1; tc <= T; tc++){
            n = ni(); m = ni(); sop(fn());
        }

        out.flush(); out.close();
    }

    static long fn()
    {
        long p = pow(2, m) - 1;
        long ans = pow(p, n);
        return ans;
    }

    static Flash f;
    static PrintWriter out;
    static final long mod = (long)1e9+7;
    static final long inf = Long.MAX_VALUE;
    static final int _inf = Integer.MAX_VALUE;
    static final int maxN = (int)5e5+5;
    static long[] fact, inv;

    static void sort(int[] a){
        List<Integer> A = new ArrayList<>();
        for(int i : a) A.add(i);
        Collections.sort(A);
        for(int i = 0; i < A.size(); i++) a[i] = A.get(i);
    }

    static long pow(long x, long p){
        long ans = 1;
    	while(p > 0) {
    		if((p&1) == 1) ans = (ans*x) % mod;
    		x = (x*x) % mod;
    		p >>= 1;
    	}

    	return ans;
    }

    static long mod_inv(long x){
        return pow(x, mod-2);
    }

    static void pre()
    {
        fact = new long[maxN+1]; fact[0] = 1;
        inv = new long[maxN+1]; inv[0] = 1;

        for(int i = 1; i < maxN; i++)
            fact[i] = fact[i-1] * i % mod;

        inv[maxN - 1] = mod_inv(fact[maxN - 1]);

        for (int i = maxN-2; i > 0; i--)
            inv[i] = inv[i+1] * (i+1) % mod;
    }

    static long ncr(int n, int r){
        if (n < 0 || r < 0 || n - r < 0) return 0;
        return fact[n] * inv[r] % mod * inv[n-r] % mod;
    }

    static long npr(int n, int r){
        if (n < 0 || r < 0 || n - r < 0) return 0;
        return fact[n] * inv[n-r] % mod;
    }

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

    static void print(int[] a){
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < a.length; i++) sb.append(a[i] + " ");
        sop(sb);
    }

    static int swap(int itself, int dummy){return itself;}
    static void sop(Object o){out.println(o);}
    static int ni(){return f.ni();}
    static long nl(){return f.nl();}
    static double nd(){return f.nd();}
    static String next(){return f.next();}
    static String ns(){return f.ns();}
    static char[] nc(){return f.nc();}
    static int[] arr(int len){return f.arr(len);}

    static class Flash
    {
        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();
        }

        String ns(){
            String s = new String();
            try{
                s = br.readLine().trim();
            }catch(IOException e){
                e.printStackTrace();
            }

            return s;
        }

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

        char[] nc(){return ns().toCharArray();}
        int ni(){return Integer.parseInt(next());}
        long nl(){return Long.parseLong(next());}
        double nd(){return Double.parseDouble(next());}
    }
}

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

public class Main{

    public static void main(String[] args)throws IOException{
    	br = new BufferedReader(new InputStreamReader(System.in));
    	PrintWriter out = new PrintWriter(System.out);
	String n = next();
	String m = next();
	BigInteger a = new BigInteger("1000000007");
	BigInteger d = new BigInteger("2");
	d = d.modPow(new BigInteger(m),a);
	d = d.subtract(BigInteger.ONE);
	d = d.modPow(new BigInteger(n),a);
	out.println(d);
	out.close();
    }

    static BufferedReader br;
    static StringTokenizer st = new StringTokenizer("");
    static String next()throws IOException{
    	while(!st.hasMoreTokens()){
    	    st = new StringTokenizer(br.readLine());
    	}
    	return st.nextToken();
    }
    static int nextInt()throws IOException{
    	return Integer.parseInt(next());
    }
    static long nextLong()throws IOException{
	return Long.parseLong(next());
    }
}

//package practice;

import java.util.*;

public class Main {

	  // (x^y)%p in O(log y) */
	    static long power(long x, long y, long p)
	    {
	        // Initialize result
	        long res = 1;

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

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

	            // y must be even now
	            // y = y / 2
	            y = y >> 1;
	            x = (x * x) % p;
	        }
	        return res;
	    }
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner s=new Scanner(System.in);
		long n=s.nextLong();
            long m=s.nextLong();
            //int c=s.nextInt();

                long ans1=1,mod=1000000007,ans = 1,i;

                ans1 = power(2,m,mod);
                ans1 = (ans1%mod-1%mod +mod)%mod;
                ans = power(ans1,n,mod);
                System.out.println(ans);

           // System.out.println(ans);

	}

}

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

import static java.lang.Math.*;

public class Main {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    StringTokenizer st = new StringTokenizer("");
    PrintWriter pw = new PrintWriter(System.out);

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

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

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

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

    public Main() throws FileNotFoundException {
    }

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

    long mod = (long) 1e9 + 7;

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

    void run() throws IOException {
        int n = nextInt();
        int m = nextInt();
        pw.print(pow(pow(2, m) - 1, n));
        pw.close();
    }

    class Pair {
        int x, y;

        public Pair(int a, int b) {
            x = a;
            y = b;
        }
    }

    class PairComp implements Comparator<Pair> {

        @Override
        public int compare(Pair o1, Pair o2) {
            if (o1.x == o2.x) return Integer.compare(o1.y, o2.y);
            return Integer.compare(o1.x, o2.x);
        }
    }
}

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

/*CODE BY SHIKHAR TYAGI*/

public class B {

    public static final int MOD = 1000000007;

    public static void main(String args[]) {
        FastScanner scn = new FastScanner();
        int t = 1;
        while (t-- > 0) {
            long n = scn.nextInt();
            long m = scn.nextInt();
            long ans = (((power((long)2, m, MOD) % MOD) - (1 % MOD)) + MOD) % MOD;
            ans = power(ans, n, MOD)%MOD;
            System.out.println(ans);
        }
    }

    static long power(long x, long y, int p) {

        // Initialize result
        long res = 1;

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

        while (y > 0) {

            // If y is odd, multiply x
            // with result
            if (y % 2 == 1)
                res = (res * x) % p;

            // y must be even now
            y = y / 2; // y = y/2
            x = (x * x) % p;
        }

        return res;
    }

    static int exponentMod(int A, int B, int C) {

        // Base cases
        if (A == 0)
            return 0;
        if (B == 0)
            return 1;

        // If B is even
        long y;
        if (B % 2 == 0) {
            y = exponentMod(A, B / 2, C);
            y = (y * y) % C;
        }

        // If B is odd
        else {
            y = A % C;
            y = (y * exponentMod(A, B - 1, C) % C) % C;
        }

        return (int) ((y + C) % C);
    }

    public static class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        public FastScanner(String s) {
            try {
                br = new BufferedReader(new FileReader(s));
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

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

        String nextToken() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

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

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

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

    public static int bin(int b[], long target) {
        int l = 0;
        int h = b.length - 1;
        int pos = -1;
        while (l <= h) {
            int m = l + (h - l) / 2;
            if (b[m] <= target) {
                if (b[m] == target) {
                    return m;
                }
                l = m + 1;
            } else {
                pos = m;
                h = m - 1;
            }
        }
        return pos;
    }
}

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

public class AliceAndListOfPresents {
    public static void main(String[] args) {
        FastReader input=new FastReader();
        long mod=1000000007;
        long n,m;
        n=input.nextLong();
        m=input.nextLong();
        long ans=1;
        ans=pow(2,m,mod);
        ans=(ans%mod-1%mod)%mod;
        ans=pow(ans,n,mod);
        System.out.println(ans);
    }
    public static long pow(long a,long b,long m)
    {
        long res=1;
        while(b>0)
        {
            if(b%2!=0)
            {
                res=(res%m*a%m)%m;
            }
            b=b/2;
            a=(a%m*a%m)%m;
        }
        return res;
    }
    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;
        }
    }
}

import java.util.*;
public class problem2{
  public static void main(String[] args){
    Scanner s = new Scanner(System.in);
    int q = 1;
    for(int i = 1; i<=q; i++){
      int presents = s.nextInt();
      int boxes = s.nextInt();
      long types = 1;
      long base = 2;
      while(boxes > 1){
        if(boxes%2 == 0){
          boxes = boxes / 2;
          base= (base*base) % (int)(Math.pow(10,9)+7);
        }
        else{
          types = (types * base) %(int)(Math.pow(10,9)+7);
          boxes -= 1;}
      }

      long ans = (types * base -1) % (int)(Math.pow(10,9)+7);
      long count = 1;

      while(presents > 1){
        if(presents%2 == 0){
          presents = presents / 2;
          ans= (ans*ans) % (int)(Math.pow(10,9)+7);
        }
        else{
          count = (count * ans) %(int)(Math.pow(10,9)+7);
          presents -= 1;}
      }

      System.out.println((count*ans)%(int)(Math.pow(10,9)+7));
    }
  }
}

//package com.company;

import java.util.Scanner;

public class CF_1236_B {
    public static void main(String args[]) {
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        int m=sc.nextInt();
        int mod=1_000_000_007;
        long p=pow(2,m,mod);
        long res=(p+mod-1)%mod;
        res=pow(res,n,mod);
        System.out.println(res);

    }
    public static long pow(long x, int n, int mod) {
        long res=1;
        while(n>0) {
            if((n&1)>0)
                res=(res*x)%mod;
            x=(x*x)%mod;
            n>>=1;
        }
        return res;
    }
}

import java.*;
import java.util.Scanner;
public class Java101 {
	public static void main (String[] args)
	{
		Scanner sc = new Scanner(System.in);
		long n = sc.nextLong();
		long m = sc.nextLong();
		//System.out.println(power(2,m,(int)1e9+7)-1);
		System.out.println((power( (power(2,m,(int)1e9+7)-1) , n,(int)1e9+7)));

	}
	static long power(long x, long y, long p)
    {
        // Initialize result
        long res = 1;

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

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

            // y must be even now
            // y = y / 2
            y = y >> 1;
            x = (x * x) % p;
        }
        return res;
    }
}

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

public class Main {
	static final int MOD = 1000000000 + 7;

	public static void main(String[] args) throws Exception {
		int n, m;
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine(), " ");
		n = Integer.parseInt(st.nextToken());
		m = Integer.parseInt(st.nextToken());

		long answer = modExp(2, m) - 1;
		answer = modExp(answer, n);

		System.out.print(answer);
	}

	private static long modExp(long base, long power) {
	    if (power == 0) {
	        return 1;
	    } else {
	        long cur = modExp(base, power / 2); cur = cur * cur; cur = cur % MOD;
	        if (power % 2 == 1) cur = cur * base;
	        cur = cur % MOD;
	        return cur;
	    }
	}
}

/**
 * presents
 */import java.util.*;
public class presents {
public static long power(long x, long n) {
		long result = 1;
		while (n > 0) {
			if (n % 2 == 1)
				result = (result * x) % 1000000007;
			x = (x * x) % 1000000007;
			n = n / 2;
		}
		return result;
	}
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        long n=sc.nextLong();
        long m=sc.nextLong();
        long sum;
       sum=power(power(2,m)-1,n);
        System.out.println(sum);
    }
}

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

public class Main {

    static FastReader in;
    static PrintWriter out;

    static int mod = 1000000007;

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

    static void solve() {
        long n = in.nextLong();
        long m = in.nextLong();

        long ans = binPow(2, m);
        ans = binPow(ans - 1, n);

        out.println(ans);
    }

    public static void main(String[] args) {
        in = new FastReader(System.in);
//        in = new FastReader(new FileInputStream("input.txt"));
        out = new PrintWriter(System.out);
//        out = new PrintWriter(new FileOutputStream("output.txt"));

        int q = 1;

        while (q-- > 0)
            solve();

        out.close();
    }

    static class FastReader {
        BufferedReader br;
        StringTokenizer st;

        FastReader(InputStream is) {
            br = new BufferedReader(new InputStreamReader(is));
        }

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

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

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

        String next() {
            while (st == null || !st.hasMoreTokens()) {
                st = new StringTokenizer(nextLine());
            }
            return st.nextToken();
        }

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

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

public class Main {

	static InputReader in = new InputReader(System.in);
	static PrintWriter out = new PrintWriter(System.out);

	static int oo = (int)1e9;
	static int mod = 1_000_000_007;

	static int[] di = {1, 0, 0, -1};
	static int[] dj = {0, -1, 1, 0};

	static long M = 100005;

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

		int n = in.nextInt();
		int m = in.nextInt();
		long k = (pow(2, m, mod) - 1 + mod) % mod;
		long ans = pow(k, n, mod);
		System.out.println(ans);

		out.close();
	}

	static boolean inside(int i, int j, int n, int m) {
		return i >= 0 && i < n && j >= 0 && j < m;
	}

	static long pow(long a, long n, long mod) {
		if(n == 0)
			return 1;
		if(n % 2 == 1)
			return a * pow(a, n-1, mod) % mod;
		long x = pow(a, n / 2, mod);
		return x * x % mod;
	}

	static class SegmentTree {
		int n;
		char[] a;
		int[] seg;
		int DEFAULT_VALUE = 0;

		public SegmentTree(char[] a, int n) {
			super();
			this.a = a;
			this.n = n;
			seg = new int[n * 4 + 1];
			build(1, 0, n-1);
		}

		private int build(int node, int i, int j) {
			if(i == j) {
				int x = a[i] - 'a';
				return seg[node] = (1<<x);
			}
			int first = build(node * 2, i, (i+j) / 2);
			int second = build(node * 2 + 1, (i+j) / 2 + 1, j);
			return seg[node] = combine(first, second);
		}

		int update(int k, char value) {
			return update(1, 0, n-1, k, value);
		}

		private int update(int node, int i, int j, int k, char value) {
			if(k < i || k > j)
				return seg[node];
			if(i == j && j == k) {
				a[k] = value;
				int x = a[i] - 'a';
				return seg[node] = (1<<x);
			}
			int m = (i + j) / 2;
			int first = update(node * 2, i, m, k, value);
			int second = update(node * 2 + 1, m + 1, j, k, value);
			return seg[node] = combine(first, second);
		}

		int query(int l, int r) {
			return query(1, 0, n-1, l, r);
		}

		private int query(int node, int i, int j, int l, int r) {
			if(l <= i && j <= r)
				return seg[node];
			if(j < l || i > r)
				return DEFAULT_VALUE;
			int m = (i + j) / 2;
			int first = query(node * 2, i, m, l, r);
			int second = query(node * 2 + 1, m+1, j, l, r);
			return combine(first, second);
		}

		private int combine(int a, int b) {
			return a | b;
		}
	}

	static class DisjointSet {
		int n;
		int[] g;
		int[] h;
		public DisjointSet(int n) {
			super();
			this.n = n;
			g = new int[n];
			h = new int[n];
			for(int i = 0; i < n; ++i) {
				g[i] = i;
				h[i] = 1;
			}
		}
		int find(int x) {
			if(g[x] == x)
				return x;
			return g[x] = find(g[x]);
		}
		void union(int x, int y) {
			x = find(x); y = find(y);
			if(x == y)
				return;
			if(h[x] >= h[y]) {
				g[y] = x;
				if(h[x] == h[y])
					h[x]++;
			}
			else {
				g[x] = y;
			}
		}
	}

	static int[] getPi(char[] a) {
		int m = a.length;
		int j = 0;
		int[] pi = new int[m];
		for(int i = 1; i < m; ++i) {
			while(j > 0 && a[i] != a[j])
				j = pi[j-1];
			if(a[i] == a[j]) {
				pi[i] = j + 1;
				j++;
			}
		}
		return pi;
	}

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

	static boolean nextPermutation(int[] a) {
		for(int i = a.length - 2; i >= 0; --i) {
			if(a[i] < a[i+1]) {
				for(int j = a.length - 1; ; --j) {
					if(a[i] < a[j]) {
						int t = a[i];
						a[i] = a[j];
						a[j] = t;
						for(i++, j = a.length - 1; i < j; ++i, --j) {
							t = a[i];
							a[i] = a[j];
							a[j] = t;
						}
						return true;
					}
				}
			}
		}
		return false;
	}

	static void shuffle(int[] a) {
		Random r = new Random();
		for(int i = a.length - 1; i > 0; --i) {
			int si = r.nextInt(i);
			int t = a[si];
			a[si] = a[i];
			a[i] = t;
		}
	}

	static void shuffle(long[] a) {
		Random r = new Random();
		for(int i = a.length - 1; i > 0; --i) {
			int si = r.nextInt(i);
			long t = a[si];
			a[si] = a[i];
			a[i] = t;
		}
	}

	static int lower_bound(int[] a, int n, int k) {
		int s = 0;
		int e = n;
		int m;
		while (e - s > 0) {
			m = (s + e) / 2;
			if (a[m] < k)
				s = m + 1;
			else
				e = m;
		}
		return e;
	}
	static int lower_bound(long[] a, int n, long k) {
		int s = 0;
		int e = n;
		int m;
		while (e - s > 0) {
			m = (s + e) / 2;
			if (a[m] < k)
				s = m + 1;
			else
				e = m;
		}
		return e;
	}

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

	static class Pair implements Comparable<Pair> {
		int first, second;

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

		@Override
		public int compareTo(Pair o) {
			return this.first != o.first ? this.first - o.first : this.second - o.second;
		}

//		@Override
//		public int compareTo(Pair o) {
//			return this.first != o.first ? o.first - this.first : o.second - this.second;
//		}

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

		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			Pair other = (Pair) obj;
			if (first != other.first)
				return false;
			if (second != other.second)
				return false;
			return true;
		}
	}
}

class InputReader {

	private final InputStream stream;
	private final byte[] buf = new byte[8192];
	private int curChar, snumChars;

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

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

	public int nextInt() {
		int c = read();
		while (isSpaceChar(c)) {
			c = read();
		}
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

	public long nextLong() {
		int c = read();
		while (isSpaceChar(c)) {
			c = read();
		}
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		long res = 0;
		do {
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}

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

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

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

}

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

public class Main {
    public static void main(String[] args) throws IOException {
        PrintWriter out = new PrintWriter(System.out);
        //Scanner sc = new Scanner();
        Reader in = new Reader();
        Main solver = new Main();
        solver.solve(out, in);
        out.flush();
        out.close();

    }

    static int INF = (int)1e9;
    static int maxn = (int)1e5+5;
    static int mod= 1000000007 ;
    static int k,t,q,d,cnt=2;
    static long n,m;

    void solve(PrintWriter out, Reader in) throws IOException{
        n = in.nextLong();
        m = in.nextLong();

        long ans =1;

        long tmp=1;
        tmp = pwr(2L,m);
        tmp--;

        ans = pwr(tmp,n);

        out.println(ans);
    }

    //<>

    static long pwr(long x,long p){
        long res=1;

        if(p==0) return 1;
        res = pwr(x,p/2);
        res = (res*res)%mod;

        if(p%2==1) res = (res*x)%mod;

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

    }
}

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

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

  static class BAliceAndTheListOfPresents {
    static long mod = (long) 1e9 + 7;

    public void solve(int testNumber, InputReader in, PrintWriter out) {
      int n = in.nextInt();
      int m = in.nextInt();
      out.println(BigInteger.valueOf(2).modPow(BigInteger.valueOf(m), BigInteger.valueOf(mod)).subtract(BigInteger.ONE).modPow(BigInteger.valueOf(n), BigInteger.valueOf(mod)));
    }

  }

  static class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

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

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

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

  }
}

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

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

  static class BAliceAndTheListOfPresents {
    static long mod = (long) 1e9 + 7;

    public void solve(int testNumber, InputReader in, PrintWriter out) {
      int n = in.nextInt();
      int m = in.nextInt();
      out.println(pow(pow(2, m) - 1, n));
    }

    long pow(long a, long b) {
      long pow = a, ret = 1;
      for (int i = 0; i < 63; ++i) {
        pow = i == 0 ? pow : (pow * pow) % mod;
        if (((b >> i) & 1) == 1) {
          ret = (ret * pow) % mod;
        }
      }
      return ret;
    }

  }

  static class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

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

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

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

  }
}

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

public class Example {
    private static int M = 1000000007;

    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        StringBuffer writer = new StringBuffer();
        String[] line = reader.readLine().split(" ");
        int n = Integer.parseInt(line[0]);
        int m = Integer.parseInt(line[1]);
        writer.append(solve(n, m));
        writer.append('\n');
        System.out.print(writer);
        reader.close();
    }

    private static long solve(int n, int m) {
        long t = (M + pow(2, m) - 1) % M;
        return pow((int)t, n);
    }

    private static long pow(int a, int n) {
        if (n == 0) return 1;
        long y = pow(a, n / 2);
        y = (y * y) % M;
        if (n % 2 == 1) y = (y * a) % M;
        return y;
    }
}

import java.util.*;
import java.lang.*;
import java.io.*;
import java.math.*;
public class Prac{
    static class InputReader {
        private final InputStream stream;
        private final byte[] buf = new byte[8192];
        private int curChar, snumChars;
        public InputReader(InputStream st) {
            this.stream = st;
        }
        public int read() {
            if (snumChars == -1)
                throw new InputMismatchException();
            if (curChar >= snumChars) {
                curChar = 0;
                try {
                    snumChars = stream.read(buf);
                }
                catch (IOException e) {
                    throw new InputMismatchException();
                }
                if (snumChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }
        public int ni() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            int res = 0;
            do {
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }
        public long nl() {
            int c = read();
            while (isSpaceChar(c)) {
            c = read();
            }
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;
            do {
                res *= 10;
                res += c - '0';
                c = read();
            } while (!isSpaceChar(c));
            return res * sgn;
        }
        public int[] nia(int n) {
            int a[] = new int[n];
            for (int i = 0; i < n; i++) {
                a[i] = ni();
            }
            return a;
        }
        public String rs() {
            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 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 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 static class Key {

        private final int x;
        private final int y;

        public Key(int x, int y) {
            this.x = x;
            this.y = y;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (!(o instanceof Key)) return false;
            Key key = (Key) o;
            return x == key.x || y == key.y;
        }

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

    }
    static class Pair{
        int x,y;
        public Pair(int x,int y){
            this.y=y;
            this.x=x;
        }
    }

    static PrintWriter w = new PrintWriter(System.out);
    static long mod1=998244353L,mod=1000000007;
    static long  power(long x, long y) {
        long temp=0;
        if( y == 0)
            return 1;
        temp = power(x, y/2);
        if (y%2 == 0)
            return (temp*temp)%mod;
        else
            return (((x*temp)%mod)*temp)%mod;
    }
    public static void main(String [] args){
        InputReader sc=new InputReader(System.in);
        long n=sc.ni(),m=sc.ni();
        w.println(power(power(2L,m)-1,n));
        w.close();
    }
}

import java.util.Scanner;

public class Main {
    private static final int mod = 1000_000_007;

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

        int n = sc.nextInt(), m = sc.nextInt();
        System.out.println(pow(pow(2, m) - 1, n));

    }

    private static long pow(long n, long m) {
        if (m == 0) return 1;
        else if ((m & 1) == 1) return n * pow(n, m - 1) % mod;
        else {
            long helf = pow(n, m >> 1);
            return helf * helf % mod;
        }
    }
}

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

public class alicepresent {
	static long mod = (long) (1e9 + 7);

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		FastReader scn = new FastReader();
		long n = scn.nextLong();
		long m = scn.nextLong();
		long res = (solveExp(2, m) - 1+mod) % mod;
		System.out.println((long) solveExp(res, n) % mod);
//	int n=Integer.parseInt("04");
//	System.out.println(res);
	}

	static long solveExp(long a, long x) {
		a = a % mod;
		long res = 1;

		while (x > 0) {
			if ((x & 1) == 1)
				res = (res * a) % mod;
			a = (a * a) % mod;
			x >>= 1;
		}

		return res;
	}

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

import java.math.BigInteger;
import java.util.Scanner;

public class MMain {
    public static BigInteger temp = new BigInteger("1000000007");
    public static BigInteger quickPower(BigInteger a,BigInteger b){
        BigInteger ans=new BigInteger("1");
        while(b.compareTo(new BigInteger("0"))!=0){
            if((b.and(new BigInteger("1"))).compareTo(new BigInteger("0"))!=0){
                ans = ans.multiply(a);
                ans = ans.mod(temp);
            }
            b=b.shiftRight(1);
            a = a.multiply(a);
            a = a.mod(temp);
        }
        return ans.mod(temp);
    }
    public static void main(String[]args){
        Scanner sin = new Scanner(System.in);
        BigInteger n,m;
        while(sin.hasNext()){
            n=new BigInteger(sin.next());
            m=new BigInteger(sin.next());
            System.out.println(quickPower(quickPower(new BigInteger("2"),m).subtract(new BigInteger("1")),n));
        }
    }
}

import java.util.Scanner;

public class B {
	static long mod=(long) (1e9+7);

	private static long pow(long a, long b) {
		// TODO Auto-generated method stub
		long ans=1;
		long t=a;
		while(b!=0) {
			if((b&1)!=0) {
				ans*=t;
				ans%=mod;
			}
			b>>=1;
			t*=t;              //千万不要忘了这一步
			t%=mod;
		}
		return ans;
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner in=new Scanner(System.in);
		long n =in.nextLong();
		long m=in.nextLong();
		long cal=pow(2,m);
		long cal2 =cal-1;
		long cal3 =pow(cal2,n);
		System.out.println(cal3);
	}

}

//package Practice;

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

public class typeB {
	static long mod = (long)Math.pow(10,9)+7;
	public static long power(long a, long n) {
		if(n==0) {
			return 1;
		}
		if(n%2==0) {
			return power((a*a)%mod,n/2);
		}
		else {
			return (a%mod*power((a*a)%mod,n/2)%mod)%mod;
		}
	}
	public static void main(String[] args) {
		FastReader s = new FastReader();
		long n  = s.nextLong();
		long m = s.nextLong();
		System.out.println(power(power(2,m)-1,n));

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

}

//package Practice;

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

public class typeB {
	static long mod = (long)Math.pow(10,9)+7;
	public static long power(long a, long n) {
		if(n==0) {
			return 1;
		}
		if(n%2==0) {
			return power((a*a)%mod,n/2);
		}
		else {
			return (a%mod*power((a*a)%mod,n/2)%mod)%mod;
		}
	}
	public static void main(String[] args) {
		FastReader s = new FastReader();
		long n  = s.nextLong();
		long m = s.nextLong();
		long ans = power(2,m);
		ans = power((ans-1),n);
		System.out.println(ans);

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

}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.*;
public class Main{
	static long p=1000000007;
	static long power(long x, long y)
    {
        // Initialize result
        long res = 1;

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

       if (x == 0) return 0; // In case x is divisible by p;

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

            // y must be even now
            // y = y / 2
            y = y >> 1;
            x = (x * x) % p;
        }
        return res%p;
    }
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
//		String[] cmd=br.readLine().split(" ");
		int cases=1;
		while(cases!=0)
		{
			cases--;
			String[] cmd=br.readLine().split(" ");
			long n=Long.valueOf(cmd[0]);
			long m=Long.valueOf(cmd[1]);
			long a=power(2,m);
			long c=power(a-1,n);
			System.out.println(c);
		}
	}
}

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

    public class bhaa {

        InputStream is;
        PrintWriter o;
        /////////////////// CODED++ BY++ ++ ++ ++ BHAVYA++ ARORA++ ++ ++ ++ FROM++ JAYPEE++ INSTITUTE++ OF++ INFORMATION++ TECHNOLOGY++ ////////////////

    ///////////////////////// Make it work, make it right, make it fast. Make it work, make it right, make it fast. Make it work, make it right, make it fast. Make it work, make it right, make it fast. /////////////////

     long power(long x, long y, long p)
    {
        // Initialize result
        long res = 1;

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

       if (x == 0) return 0; // In case x is divisible by p;

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

            // y must be even now
            // y = y / 2
            y = y >> 1;
            x = (x * x) % p;
        }
        return res;
    }

        void solve() {
           long n=nl();
           long m=nl();
           long res=power(2,m,1000000007);
           if(res==0)
           {
                res=1000000006;

           }
           else
           {
            res--;
           }
           o.println(power(res,n,1000000007));
           //for(int i=1;i<n;i++)
           //{
           // res=(int)(Math.pow(res,n))%1000000007;
         //  o.println(res);

        }

        //---------- I/O Template ----------

        public static void main(String[] args) { new bhaa().run(); }
        void run() {
            is = System.in;
            o = new PrintWriter(System.out);
            solve();
            o.flush();
        }

        byte input[] = new byte[1024];
        int len = 0, ptr = 0;

        int readByte() {
            if(ptr >= len) { ptr = 0;
                try { len = is.read(input); }
                catch(IOException e) { throw new InputMismatchException(); }
                if(len <= 0) { return -1; }
            } return input[ptr++];
        }
        boolean isSpaceChar(int c) { return !( c >= 33 && c <= 126 ); }
        int skip() {
            int b = readByte();
            while(b != -1 && isSpaceChar(b)) { b = readByte(); }
            return b;
        }

        char nc() { return (char)skip(); }
        String ns() {
            int b = skip();
            StringBuilder sb = new StringBuilder();
            while(!isSpaceChar(b)) { sb.appendCodePoint(b); b = readByte(); }
            return sb.toString();
        }
        String nLine() {
            int b = skip();
            StringBuilder sb = new StringBuilder();
            while( !(isSpaceChar(b) && b != ' ') ) { sb.appendCodePoint(b); b = readByte(); }
            return sb.toString();
        }
        int ni() {
            int n = 0, b = readByte();
            boolean minus = false;
            while(b != -1 && !( (b >= '0' && b <= '9') || b == '-')) { b = readByte(); }
            if(b == '-') { minus = true; b = readByte(); }
            if(b == -1) { return -1; }  //no input
            while(b >= '0' && b <= '9') { n = n * 10 + (b - '0'); b = readByte(); }
            return minus ? -n : n;
        }
        long nl() {
            long n = 0L;    int b = readByte();
            boolean minus = false;
            while(b != -1 && !( (b >= '0' && b <= '9') || b == '-')) { b = readByte(); }
            if(b == '-') { minus = true; b = readByte(); }
            while(b >= '0' && b <= '9') { n = n * 10 + (b - '0'); b = readByte(); }
            return minus ? -n : n;
        }

        double nd() { return Double.parseDouble(ns()); }
        float nf() { return Float.parseFloat(ns()); }
        int[] nia(int n) {
            int a[] = new int[n];
            for(int i = 0; i < n; i++) { a[i] = ni(); }
            return a;
        }
        long[] nla(int n) {
            long a[] = new long[n];
            for(int i = 0; i < n; i++) { a[i] = nl(); }
            return a;
        }
        int [][] nim(int n)
        {
            int mat[][]=new int[n][n];
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<n;j++)
                {
                    mat[i][j]=ni();
                }
            }
            return mat;
        }
        long [][] nlm(int n)
        {
            long mat[][]=new long[n][n];
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<n;j++)
                {
                    mat[i][j]=nl();
                }
            }
            return mat;
        }

        char[] ns(int n) {
            char c[] = new char[n];
            int i, b = skip();
            for(i = 0; i < n; i++) {
                if(isSpaceChar(b)) { break; }
                c[i] = (char)b; b = readByte();
            } return i == n ? c : Arrays.copyOf(c,i);
        }
        void piarr(int arr[])
        {
            for(int i=0;i<arr.length;i++)
            {
                o.print(arr[i]+" ");

            }
            o.println();
        }
        void plarr(long arr[])
        {
            for(int i=0;i<arr.length;i++)
            {
                o.print(arr[i]+" ");

            }
            o.println();
        }

        void pimat(int mat[][])
        {
            for(int i=0;i<mat.length;i++)
            {
                for(int j=0;j<mat[0].length;j++)
                {
                    o.print(mat[i][j]);
                }
                o.println();
            }
        }
        void plmat(long mat[][])
        {
            for(int i=0;i<mat.length;i++)
            {
                for(int j=0;j<mat[0].length;j++)
                {
                    o.print(mat[i][j]);
                }
                o.println();
            }

        }

        //////////////////////////////////// template finished //////////////////////////////////////

    }

import java.math.*;
import java.util.Scanner;

public class sss {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
        BigInteger n,m;
        Scanner reader=new Scanner(System.in);
        n=reader.nextBigInteger();
        m=reader.nextBigInteger();
        BigInteger di=new BigInteger("2");
        BigInteger modd=new BigInteger("1000000007");
        BigInteger one=new BigInteger("1");
        di=di.modPow(m,modd);
        di=di.add(modd);
        di=di.subtract(one);
        di=di.mod(modd);
        di=di.modPow(n, modd);
        System.out.println(di);

	}

}

import java.math.BigInteger;
import java.util.Scanner;

public class Bigmod
{
    static int n,m;

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

        BigInteger a,b,MOD,base;

        a = new BigInteger(String.valueOf(n));
        b = new BigInteger(String.valueOf(m));
        base = new BigInteger("2");
        MOD = new BigInteger("1000000007");

        BigInteger ans = base.modPow(b,MOD);

        ans = ans.subtract(BigInteger.valueOf(1));

        ans = ans.modPow(a,MOD);

        System.out.println(ans);

    }
}

import java.io.*;
import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.lang.*;
import java.math.*;
import java.text.DecimalFormat;
import java.lang.reflect.Array;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigDecimal;
public class Codeforces{
	public static PrintWriter out = new PrintWriter (new BufferedOutputStream(System.out));
	static long MOD = (long)(1e9+7);
	//static long MOD = 998244353;
	static FastReader sc = new FastReader();
	static int pInf = Integer.MAX_VALUE;
	static int nInf = Integer.MIN_VALUE;
	public static void main(String[] args){
		int test = 1;
		//test = sc.nextInt();
		while(test-->0){
			int n = sc.nextInt();
			int m = sc.nextInt();
			long ans = fastExpo((fastExpo(2, m)-1),n);
			out.println(ans);
		}
		out.close();
	}
	public static long mul(long a, long b){
	    return ((a%MOD)*(b%MOD))%MOD;
	}
	public static long add(long a, long b){
	    return ((a%MOD)+(b%MOD))%MOD;
	}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Integer.lowestOneBit(i)   Equals k where k is the position of the first one in the binary
//Integer.highestOneBit(i)  Equals k where k is the position of the last one in the binary
//Integer.bitCount(i)       returns the number of one-bits
//Collections.sort(A,(p1,p2)->(int)(p2.x-p1.x)) To sort ArrayList in descending order wrt values of x.
//            Arrays.parallelSort(a,new Comparator<TPair>() {
//      		public int compare(TPair a,TPair b) {
//        			if(a.y==b.y) return a.x-b.x;
//        			return b.y-a.y;
//        		}
//        	});
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//PrimeFactors
    public static ArrayList<Long> primeFactors(long n) {
        ArrayList<Long> arr = new ArrayList<>();
        if (n % 2 == 0)
            arr.add((long) 2);
        while (n % 2 == 0)
            n /= 2;
        for (long i = 3; i <= Math.sqrt(n); i += 2) {
            int flag = 0;
            while (n % i == 0) {
                n /= i;
                flag = 1;
            }
            if (flag == 1)
                arr.add(i);
        }
        if (n > 2)
            arr.add(n);
        return arr;
    }
//Pair Class
	static class Pair implements Comparable<Pair>{
		int x;
		int y;
		public Pair(int x, int y) {
			this.x = x;
			this.y = y;
		}
		@Override
		public int compareTo(Pair o) {
			if(this.x==o.x){
			    return (this.y-o.y);
			}
			return (this.x-o.x);
		}
	}
	static class TPair implements Comparable<TPair>{
		int two;
		int three;
		int prime;
		public TPair(int two, int three, int prime) {
			this.two = two;
			this.three = three;
			this.prime = prime;
		}
		@Override
		public int compareTo(TPair o) {
			if(this.three==o.three){
			    return (this.two-o.two);
			}
			return -1*(this.three-o.three);
		}
	}
//nCr
	static long ncr(long n, long k) {
        long ret = 1;
        for (long x = n; x > n - k; x--) {
            ret *= x;
            ret /= (n - x + 1);
        }

        return ret;
    }
	static long finextDoubleMMI_fermat(long n,int M)
    {
        return fastExpo(n,M-2);
    }

    static long nCrModPFermat(int n, int r, int p)
    {
        if (r == 0)
            return 1;
        long[] fac = new long[n+1];
        fac[0] = 1;
        for (int i = 1 ;i <= n; i++)
            fac[i] = fac[i-1] * i % p;
        return (fac[n]* finextDoubleMMI_fermat(fac[r], p)% p * finextDoubleMMI_fermat(fac[n-r], p) % p) % p;
    }
//Merge Sort
	static void merge(long arr[], int l, int m, int r)
    {
        // Find sizes of two subarrays to be merged
        int n1 = m - l + 1;
        int n2 = r - m;

        /* Create temp arrays */
        long L[] = new long [n1];
        long R[] = new long [n2];

        /*Copy data to temp arrays*/
        for (int i=0; i<n1; ++i)
            L[i] = arr[l + i];
        for (int j=0; j<n2; ++j)
            R[j] = arr[m + 1+ j];

        /* Merge the temp arrays */

        // Initial indexes of first and second subarrays
        int i = 0, j = 0;

        // Initial index of merged subarry array
        int k = l;
        while (i < n1 && j < n2)
        {
            if (L[i] <= R[j])
            {
                arr[k] = L[i];
                i++;
            }
            else
            {
                arr[k] = R[j];
                j++;
            }
            k++;
        }

        /* Copy remaining elements of L[] if any */
        while (i < n1)
        {
            arr[k] = L[i];
            i++;
            k++;
        }

        /* Copy remaining elements of R[] if any */
        while (j < n2)
        {
            arr[k] = R[j];
            j++;
            k++;
        }
    }

    // Main function that sorts arr[l..r] using
    // merge()
    static void sort(long arr[], int l, int r)
    {
        if (l < r)
        {
            // Find the middle point
            int m = (l+r)/2;

            // Sort first and second halves
            sort(arr, l, m);
            sort(arr , m+1, r);

            // Merge the sorted halves
            merge(arr, l, m, r);
        }
    }
//Brian Kernighan’s Algorithm
    static long countSetBits(long n){
        if(n==0) return 0;
        return 1+countSetBits(n&(n-1));
    }
//Factorial
    static long factorial(long n){
        if(n==1) return 1;
        if(n==2) return 2;
        if(n==3) return 6;
        return n*factorial(n-1);
    }
//Euclidean Algorithm
    static long gcd(long A,long B){
        if(B==0) return A;
        return gcd(B,A%B);
    }
//Modular Exponentiation
    static long fastExpo(long x,long n){
        if(n==0) return 1;
        if((n&1)==0) return fastExpo((x*x)%MOD,n/2)%MOD;
        return ((x%MOD)*fastExpo((x*x)%MOD,(n-1)/2))%MOD;
    }
//AKS Algorithm
    static boolean isPrime(long n){
        if(n<=1) return false;
        if(n<=3) return true;
        if(n%2==0 || n%3==0) return false;
        for(int i=5;i<=Math.sqrt(n);i+=6)
            if(n%i==0 || n%(i+2)==0) return false;
        return true;
    }
//Reverse an array
    static <T> void reverse(T arr[],int l,int r){
    	Collections.reverse(Arrays.asList(arr).subList(l, r));
    }
  //Print array
    static void print1d(int arr[]) {
    	out.println(Arrays.toString(arr));
    }
    static void print2d(int arr[][]) {
    	for(int a[]: arr) out.println(Arrays.toString(a));
    }
//Sieve of eratosthenes
    static int[] findPrimes(int n){
        boolean isPrime[]=new boolean[n+1];
        ArrayList<Integer> a=new ArrayList<>();
        int result[];
        Arrays.fill(isPrime,true);
        isPrime[0]=false;
        isPrime[1]=false;
        for(int i=2;i*i<=n;++i){
            if(isPrime[i]==true){
                for(int j=i*i;j<=n;j+=i) isPrime[j]=false;
            }
        }
        for(int i=0;i<=n;i++) if(isPrime[i]==true) a.add(i);
        result=new int[a.size()];
        for(int i=0;i<a.size();i++) result[i]=a.get(i);
        return result;

    }
//Indivisual factors of all nos till n
    static ArrayList<Integer>[] indiFactors(int n){
    	ArrayList<Integer>[] A = new ArrayList[n+1];
    	for(int i = 0; i <= n; i++) {
    		A[i] = new ArrayList<>();
    	}
    	int[] sieve = new int[n+1];
    	for(int i=2;i<=n;i++) {
       		if(sieve[i]==0) {
       			for(int j=i;j<=n;j+=i) if(sieve[j]==0) {
       				//sieve[j]=i;
       				A[j].add(i);
       			}
       		}
       	}
    	return A;
    }
//Segmented Sieve
    static boolean[] segmentedSieve(long l, long r){
    	boolean[] segSieve = new boolean[(int)(r-l+1)];
    	Arrays.fill(segSieve, true);
    	int[] prePrimes = findPrimes((int)Math.sqrt(r));
    	for(int p:prePrimes) {
    		long low = (l/p)*p;
    		if(low < l) {
    			low += p;
    		}
    		if(low == p) {
    			low += p;
    		}
    		for(long j = low; j<= r; j += p) {
    			segSieve[(int) (j-l)] = false;
    		}
    	}
    	if(l==1) {
    		segSieve[0] = false;
    	}
    	return segSieve;
    }
//Euler Totent function
    static long countCoprimes(long n){
        ArrayList<Long> prime_factors=new ArrayList<>();
        long x=n,flag=0;
        while(x%2==0){
            if(flag==0) prime_factors.add(2L);
            flag=1;
            x/=2;
        }
        for(long i=3;i*i<=x;i+=2){
            flag=0;
            while(x%i==0){
                if(flag==0) prime_factors.add(i);
                flag=1;
                x/=i;
            }
        }
        if(x>2) prime_factors.add(x);
        double ans=(double)n;
        for(Long p:prime_factors){
            ans*=(1.0-(Double)1.0/p);
        }
        return (long)ans;
    }
	static long modulo = (long)1e9+7;
	public static long modinv(long x){
	    return modpow(x, modulo-2);
	}
	public static long modpow(long a, long b){
	    if(b==0){
	        return 1;
	    }
	    long x = modpow(a, b/2);
	    x = (x*x)%modulo;
	    if(b%2==1){
	        return (x*a)%modulo;
	    }
	    return x;
	}
	public static class FastReader {
		BufferedReader br;
		StringTokenizer st;
		//it reads the data about the specified point and divide the data about it ,it is quite fast
		//than using direct

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

		String next() {
			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (Exception r) {
					r.printStackTrace();
				}
			}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());//converts string to integer
		}

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

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

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

import java.util.*;
import java.io.*;
public class Main {
    static class Scan {
        private byte[] buf=new byte[1024];
        private int index;
        private InputStream in;
        private int total;
        public Scan()
        {
            in=System.in;
        }
        public int scan()throws IOException
        {
            if(total<0)
            throw new InputMismatchException();
            if(index>=total)
            {
                index=0;
                total=in.read(buf);
                if(total<=0)
                return -1;
            }
            return buf[index++];
        }
        public int scanInt()throws IOException
        {
            int integer=0;
            int n=scan();
            while(isWhiteSpace(n))
            n=scan();
            int neg=1;
            if(n=='-')
            {
                neg=-1;
                n=scan();
            }
            while(!isWhiteSpace(n))
            {
                if(n>='0'&&n<='9')
                {
                    integer*=10;
                    integer+=n-'0';
                    n=scan();
                }
                else throw new InputMismatchException();
            }
            return neg*integer;
        }
        public double scanDouble()throws IOException
        {
            double doub=0;
            int n=scan();
            while(isWhiteSpace(n))
            n=scan();
            int neg=1;
            if(n=='-')
            {
                neg=-1;
                n=scan();
            }
            while(!isWhiteSpace(n)&&n!='.')
            {
                if(n>='0'&&n<='9')
                {
                    doub*=10;
                    doub+=n-'0';
                    n=scan();
                }
                else throw new InputMismatchException();
            }
            if(n=='.')
            {
                n=scan();
                double temp=1;
                while(!isWhiteSpace(n))
                {
                    if(n>='0'&&n<='9')
                    {
                        temp/=10;
                        doub+=(n-'0')*temp;
                        n=scan();
                    }
                    else throw new InputMismatchException();
                }
            }
            return doub*neg;
        }
        public String scanString()throws IOException
        {
            StringBuilder sb=new StringBuilder();
            int n=scan();
            while(isWhiteSpace(n))
            n=scan();
            while(!isWhiteSpace(n))
            {
                sb.append((char)n);
                n=scan();
            }
            return sb.toString();
        }
        private boolean isWhiteSpace(int n)
        {
            if(n==' '||n=='\n'||n=='\r'||n=='\t'||n==-1)
            return true;
            return false;
        }
    }

    public static void sort(int arr[],int l,int r) {    //sort(arr,0,n-1);
        if(l==r) {
            return;
        }
        int mid=(l+r)/2;
        sort(arr,l,mid);
        sort(arr,mid+1,r);
        merge(arr,l,mid,mid+1,r);
    }
    public static void merge(int arr[],int l1,int r1,int l2,int r2) {
        int tmp[]=new int[r2-l1+1];
        int indx1=l1,indx2=l2;
        //sorting the two halves using a tmp array
        for(int i=0;i<tmp.length;i++) {
            if(indx1>r1) {
                tmp[i]=arr[indx2];
                indx2++;
                continue;
            }
            if(indx2>r2) {
                tmp[i]=arr[indx1];
                indx1++;
                continue;
            }
            if(arr[indx1]<arr[indx2]) {
                tmp[i]=arr[indx1];
                indx1++;
                continue;
            }
            tmp[i]=arr[indx2];
            indx2++;
        }
        //Copying the elements of tmp into the main array
        for(int i=0,j=l1;i<tmp.length;i++,j++) {
            arr[j]=tmp[i];
        }
    }

    public static void sort(long arr[],int l,int r) {    //sort(arr,0,n-1);
        if(l==r) {
            return;
        }
        int mid=(l+r)/2;
        sort(arr,l,mid);
        sort(arr,mid+1,r);
        merge(arr,l,mid,mid+1,r);
    }
    public static void merge(long arr[],int l1,int r1,int l2,int r2) {
        long tmp[]=new long[r2-l1+1];
        int indx1=l1,indx2=l2;
        //sorting the two halves using a tmp array
        for(int i=0;i<tmp.length;i++) {
            if(indx1>r1) {
                tmp[i]=arr[indx2];
                indx2++;
                continue;
            }
            if(indx2>r2) {
                tmp[i]=arr[indx1];
                indx1++;
                continue;
            }
            if(arr[indx1]<arr[indx2]) {
                tmp[i]=arr[indx1];
                indx1++;
                continue;
            }
            tmp[i]=arr[indx2];
            indx2++;
        }
        //Copying the elements of tmp into the main array
        for(int i=0,j=l1;i<tmp.length;i++,j++) {
            arr[j]=tmp[i];
        }
    }

    public static void main(String args[]) throws IOException {
        Scan input=new Scan();
        long n=input.scanInt();
        long m=input.scanInt();
        long mod=1000000007L;
        long ans=power(2,m,mod);
        ans--;
        while(ans<0) {
            ans+=mod;
        }
        ans=power(ans,n,mod);
        System.out.println(ans);
    }

    static long power(long x, long y, long p)
    {
        // Initialize result
        long res = 1;

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

       if (x == 0) return 0; // In case x is divisible by p;

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

            // y must be even now
            // y = y / 2
            y = y >> 1;
            x = (x * x) % p;
        }
        return res;
    }

}

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

public class AliceAndTheListOfPresents {
    InputStream is;
    PrintWriter pw;
    String INPUT = "";
    long L_INF = (1L << 60L);
    int mod = 1000000007;

    static long modPow(long a, int e, int mod)    // O(log e)
    {
        a %= mod;
        long res = 1;
        while (e > 0) {
            if ((e & 1) == 1)
                res = (res * a) % mod;
            a = (a * a) % mod;
            e >>= 1;
        }
        return res;
    }

    void solve() {
        int n = ni(), m = ni();
        long x = modPow(2,m,mod)-1;
        pw.println(modPow(x,n,mod));
    }

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

        long s = System.currentTimeMillis();
//        int t = ni();
//        while (t-- > 0)
            solve();
        pw.flush();
        tr(System.currentTimeMillis() - s + "ms");
    }

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

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

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

    private boolean isSpaceChar(int c) {
        return !(c >= 33 && c <= 126);
    }

    private int skip() {
        int b;
        while ((b = readByte()) != -1 && isSpaceChar(b)) ;
        return b;
    }

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

    private char nc() {
        return (char) skip();
    }

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

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

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

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

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

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

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

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

    private boolean oj = System.getProperty("ONLINE_JUDGE") != null;

    private void tr(Object... o) {
        if (!oj) System.out.println(Arrays.deepToString(o));
    }
}

import java.util.*;

public class alicepresent
{
    public static long modexpo(long a, long b, long m){
	    a %= m;
	    long res = 1;
	    while(b > 0){
	        if((b & 1)>0)
	            res = res * a % m;
	        a = a * a % m;
	        b >>= 1;
	    }
	    return res;
	}
	public static void main(String args[])
	{
		Scanner sc = new Scanner(System.in);
		long n = sc.nextInt(),m=sc.nextInt();
		long ans = modexpo(modexpo(2,m,1000000007)-1,n,1000000007);
		System.out.print((int)ans);
	}
}

//package Main;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Scanner;

public class Main {
	static long qpow(long a,long b,long mod){
		long res=1;
		while(b>0){
			if(b%2==1) res=res*a%mod;
			a=a*a%mod;
			b/=2;
		}
		return res%mod;
	}
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		int n = input.nextInt();
		int m = input.nextInt();
		int mod = 1000000007;
		System.out.println(qpow(qpow(2,m,mod)-1,n,mod));
	}
}

//normal
import java.util.*;
import java.lang.*;
import java.io.*;
// String Tokenizer

public class Main {
	static long mod = 1000000007;

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

		int t = 1;

		while (t > 0) {
			t--;
			long n = scn.nextLong();
			long m = scn.nextLong();
			long ans = (exp(2, m) - 1) % mod;
			ans = (exp(ans, n)) % mod;
			System.out.println(ans);
		}
	}

	public static long exp(long a, long b) {
		long res = 1;
		a %= mod;
		while (b > 0) {
			if ((b & 1) != 0)
				res = (res * a) % mod;
			a = (a * a) % mod;
			b /= 2;
		}
		return res;
	}
}

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

/* Name of the class has to be "Main" only if the class is public. */
public class Ideone
{
	static long mod = 1000000000+7;
	public static void main (String[] args) throws java.lang.Exception
	{
		// your code goes here
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		int m=sc.nextInt();
	long out=(power(2,m)-1)%mod;
		long k=power(out,n);
		System.out.println(k);
	}
	public static long power(long base,int exp){
		long out=1;
		while(exp>0){
			if(exp%2==1){
				out=(out*base)%mod;
			}
			base=(base*base)%mod;
			exp/=2;
		}
		return out;
	}
}

import java.util.Scanner;

public class b {

	static int MOD = 1_000_000_007;

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

		int n = stdin.nextInt();
		int m = stdin.nextInt();

		long ans = pow(2, m) - 1;

		ans = pow(ans, n);

		System.out.println(ans);
	}

	static long pow (long ans, int exp) {
		if (exp == 0) return 1;
		if (exp == 1) return ans;

		long temp = pow(ans, exp/2);

		if (exp % 2 == 0) return (temp*temp)%MOD;
		else return (temp*temp%MOD)*ans%MOD;
	}
}

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

public class Main
{
    static final long MOD=(int)1e9+7,p=MOD;

    static long mod_pow(long x, long y)
    {

        long res = 1l;

        x = (1l*x) % p;

       if (x == 0) return 0;

        while (y > 0)
        {
            if((y & 1)==1)
                res = (res * x) % p;
            y = y >> 1;
            x = (x * x) % p;
        }
        return res;
    }

    public static void process()throws IOException
    {
        int n=ni(),m=ni();
        long res=0l;
        res=mod_pow(2l,m)-1;
        res=mod_pow(res,n);
        pn(res);
    }

   	static AnotherReader sc;
    static PrintWriter out;
    public static void main(String[]args)throws IOException
    {
        out = new PrintWriter(System.out);
        sc=new AnotherReader();
        boolean oj = true;

    	oj = System.getProperty("ONLINE_JUDGE") != null;
    	if(!oj) sc=new AnotherReader(100);

        long s = System.currentTimeMillis();
        int t=1;
        while(t-->0)
            process();
        out.flush();
        if(!oj)
            System.out.println(System.currentTimeMillis()-s+"ms");
        System.out.close();
    }

    static void pn(Object o){out.println(o);}
    static void p(Object o){out.print(o);}
    static void pni(Object o){out.println(o);System.out.flush();}
    static int ni()throws IOException{return sc.nextInt();}
    static long nl()throws IOException{return sc.nextLong();}
    static double nd()throws IOException{return sc.nextDouble();}
    static String nln()throws IOException{return sc.nextLine();}
    static long gcd(long a, long b)throws IOException{return (b==0)?a:gcd(b,a%b);}
    static int gcd(int a, int b)throws IOException{return (b==0)?a:gcd(b,a%b);}
    static int bit(long n)throws IOException{return (n==0)?0:(1+bit(n&(n-1)));}
    static boolean multipleTC=false;

/////////////////////////////////////////////////////////////////////////////////////////////////////////

    static class AnotherReader{BufferedReader br; StringTokenizer st;
    AnotherReader()throws FileNotFoundException{
    br=new BufferedReader(new InputStreamReader(System.in));}
    AnotherReader(int a)throws FileNotFoundException{
    br = new BufferedReader(new FileReader("input.txt"));}
    String next()throws IOException{
    while (st == null || !st.hasMoreElements()) {try{
    st = new StringTokenizer(br.readLine());}
    catch (IOException  e){ e.printStackTrace(); }}
    return st.nextToken(); } int nextInt() throws IOException{
    return Integer.parseInt(next());}
    long nextLong() throws IOException
    {return Long.parseLong(next());}
    double nextDouble()throws IOException { return Double.parseDouble(next()); }
    String nextLine() throws IOException{ String str = ""; try{
    str = br.readLine();} catch (IOException e){
    e.printStackTrace();} return str;}}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////
}

import java.util.Scanner;

public class ListofPresents593B {
	final static int MOD = (int)1e9+7;
	public static void main(String[] args) {
		Scanner s =new Scanner(System.in);
		int n = s.nextInt();
		int m = s.nextInt();
		long res = (expo(2, m) - 1%MOD)%MOD;
		res = expo(res, n);
		System.out.println(res);

	}
	private static long expo(long n, long k) {
		if(k==0)
			return 1L;
		if(k==1) return n;

		if(k%2==0) {
			long y = expo(n, k/2)%MOD;
			return (y*y)%MOD;
		}
		return ((n%MOD)*(expo(n, k-1))%MOD)%MOD;
	}
}

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

    public class Presents {

    	static FastReader sc=new FastReader();

    	public static final long MOD=1000000007;

    	long solveExp(long a,long x){
    	    a=a%MOD;
    	    long res=1;

    	    while(x>0){
    	        if((x&1)==1)
    	            res=(res*a)%MOD;
    	        a=(a*a)%MOD;
    	        x>>=1;
    	    }

    	    return res;
    	}

    	void run() {
            long n=sc.nextLong();
            long m=sc.nextLong();

            long poss=(solveExp(2,m)-1+MOD)%MOD;
            long result=solveExp(poss,n)%MOD;

            System.out.println(result);

    	}

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

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

    }

import java.util.Scanner;
import java.util.ArrayList;

public class Main
{
	public static void main(String[] args) {
	    long mod = 1000000007;

        Scanner sc = new Scanner(System.in);
        long n = sc.nextLong();
        long m = sc.nextLong();

        System.out.println(solution(solution(2, m, mod)-1, n, mod));
	}

	public static long solution(long a, long b, long mod){
	    long result = 1;
	    while(b>0){
			if(b%2 == 1) result = result*a%mod;
			a = a*a%mod;
			b/=2;
		}
		return result % mod;
	}
}

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

import static java.lang.Math.*;

public class Solution implements Runnable
{
	static class InputReader
	{
		private InputStream stream;private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;
		private SpaceCharFilter filter;
		private BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        public InputReader(InputStream stream){this.stream = stream;}
		public int read(){if (numChars==-1) throw new InputMismatchException();if (curChar >= numChars){curChar = 0;try{numChars = stream.read(buf);}catch (IOException e){throw new InputMismatchException();	}if(numChars <= 0)return -1;}return buf[curChar++];}
     	public String nextLine(){String str = "";try{str = br.readLine();}catch (IOException e){e.printStackTrace();}return str;}
		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 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 double nextDouble(){int c = read();while (isSpaceChar(c))c = read();int sgn = 1;if (c == '-'){sgn = -1;c = read();}double res = 0;while (!isSpaceChar(c) && c != '.'){if (c == 'e' || c == 'E')return res * Math.pow(10, nextInt());if (c < '0' || c > '9')
		throw new InputMismatchException();res *= 10;res += c - '0';c = read();}if (c == '.'){c = read();double m = 1;while (!isSpaceChar(c)){if (c == 'e' || c == 'E')return res * Math.pow(10, nextInt());if (c < '0' || c > '9')throw new InputMismatchException();m /= 10;res += (c - '0') * m;c = read();}}return res * sgn;}
        public String readString(){int c = read();while (isSpaceChar(c))c = read();StringBuilder res = new StringBuilder();do{res.appendCodePoint(c);c = read();}while (!isSpaceChar(c));return res.toString();}
		public boolean isSpaceChar(int c){if (filter != null)return filter.isSpaceChar(c);return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;}
		public String next(){return readString();}
        public interface SpaceCharFilter{public boolean isSpaceChar(int ch);}
	}

	public static void main(String args[]) throws Exception{new Thread(null, new Solution(),"Main",1<<27).start();}

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

	public static int findGCD(int arr[], int n) { 	int result = arr[0]; for (int i = 1; i < n; i++) result = gcd(arr[i], result);return result; }

	static void sortbycolomn(long arr[][], int col)
    {
        Arrays.sort(arr, new Comparator<long[]>() {
        @Override
        public int compare(final long[] entry1,final long[] entry2) {
            if (entry1[col] > entry2[col])return 1;
            else return -1;
        }
        });
    }
    static long power(long x, long y)
    {
        long temp;
        if( y == 0)
            return 1;
        temp = power(x, y/2)%1000000007;

        if (y%2 == 0)
            return (temp*temp)%1000000007;
        else
        {
            if(y > 0)
                return (((x*temp)%1000000007)*temp)%1000000007;
            else
                return (((temp*temp)%1000000007)/x)%1000000007;
        }
    }
	public void run()
    {
        InputReader in = new InputReader(System.in);
        PrintWriter w = new PrintWriter(System.out);

        long n=in.nextLong();
        long m=in.nextLong();

        long x=(power(2,m)-1)%1000000007;
        long y=power(x,n)%1000000007;
        w.println(y);

        w.flush();
        w.close();
    }
}

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

public class Alice_And_The_List_Of_Presents {
	static class FastReader {
		BufferedReader br;
		StringTokenizer st;

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

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

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

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

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

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

	}

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

	public static void main(String[] args) {
		FastReader t = new FastReader();
		PrintWriter o = new PrintWriter(System.out);
		long n = t.nextLong();
		long m = t.nextLong();
		long ans = powMod(2, m);

		ans--;
		if (ans < 0)
			ans += mod;

		o.println(powMod(ans, n));
		o.flush();
		o.close();
	}

	static long powMod(long a, long N) {
		if (N == 0)
			return 1;
		else if (N == 1)
			return a % mod;
		else {
			long R = powMod(a, N / 2) % mod;
			R *= R;
			R %= mod;
			if (N % 2 == 1) {
				R *= a;
				R %= mod;
			}
			return R % mod;
		}
	}
}

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

public class test {

	public static void main(String[] args) {
//		int test = fs.nextInt();
		int test = 1;
		// int t = fs.nextInt();
		for (int cases = 0; cases < test; cases++) {
			long n=fs.nextLong();
			long m=fs.nextLong();
			long c=1000000007;
			m=expmodulo(2, m, c);
			m-=1;
			long ans=expmodulo(m, n, c);
			op.print(ans);
			op.flush();
		}

	}

	static long expmodulo(long a, long b, long c) {
		long x = 1;
		long y = a;
		while (b > 0) {
			if (b % 2 == 1) {
				x = (x * y) % c;
			}
			y = (y * y) % c; // squaring the base
			b /= 2;
		}
		return (long) x % c;
	}

	static int countBits(int number) {
		return (int) (Math.log(number) / Math.log(2) + 1);
	}

	static int countDifferentBits(int a, int b) {
		int count = 0;
		for (int i = 0; i < 32; i++) {
			if (((a >> i) & 1) != ((b >> i) & 1)) {
				++count;
			}
		}
		return count;
	}

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

	static void sortMyMapusingValues(HashMap<String, Integer> hm) {

		List<Map.Entry<String, Integer>> capitalList = new LinkedList<>(hm.entrySet());

		Collections.sort(capitalList, new Comparator<Map.Entry<String, Integer>>() {
			public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
				return (o1.getValue()).compareTo(o2.getValue());
			}
		});
		HashMap<String, Integer> result = new HashMap<>();
		for (Map.Entry<String, Integer> entry : capitalList) {
			result.put(entry.getKey(), entry.getValue());
		}
	}

	static boolean ispowerof2(long num) {
		if ((num & (num - 1)) == 0)
			return true;
		return false;
	}

	static void primeFactors(int n) {
		while (n % 2 == 0) {
			System.out.print(2 + " ");
			n /= 2;
		}
		for (int i = 3; i <= Math.sqrt(n); i += 2) {
			while (n % i == 0) {
				System.out.print(i + " ");
				n /= i;
			}
		}
		if (n > 2)
			System.out.print(n);
	}

	static boolean isPrime(long n) {
		// Corner cases
		if (n <= 1)
			return false;
		if (n <= 3)
			return true;
		if (n % 2 == 0 || n % 3 == 0)
			return false;

		for (int i = 5; i * i <= n; i = i + 6)
			if (n % i == 0 || n % (i + 2) == 0)
				return false;

		return true;
	}

	static class Graph {
		HashMap<Integer, LinkedList<Integer>> hm = new HashMap<Integer, LinkedList<Integer>>();

		private void addVertex(int vertex) {
			hm.put(vertex, new LinkedList<>());
		}

		private void addEdge(int source, int dest, boolean bi) {
			if (!hm.containsKey(source))
				addVertex(source);
			if (!hm.containsKey(dest))
				addVertex(dest);
			hm.get(source).add(dest);
			if (bi) {
				hm.get(dest).add(source);
			}
		}

		private boolean uniCycle(int i, HashSet<Integer> visited, int parent) {
			visited.add(i);
			LinkedList<Integer> list = hm.get(i);
			Iterator<Integer> it = list.iterator();
			while (it.hasNext()) {
				Integer integer = (Integer) it.next();
				if (!visited.contains(integer)) {
					if (uniCycle(integer, visited, i))
						return true;
				} else if (integer != parent) {
					return true;
				}
			}
			return false;
		}

		private boolean uniCyclic() {
			HashSet<Integer> visited = new HashSet<Integer>();
			Set<Integer> set = hm.keySet();
			for (Integer integer : set) {
				if (!visited.contains(integer)) {
					if (uniCycle(integer, visited, -1)) {
						return true;
					}
				}
			}
			return false;
		}

		private boolean isbiCycle(int i, HashSet<Integer> visited, HashSet<Integer> countered) {
			if (countered.contains(i))
				return true;
			if (visited.contains(i))
				return false;
			visited.add(i);
			countered.add(i);
			LinkedList<Integer> list = hm.get(i);
			Iterator<Integer> it = list.iterator();
			while (it.hasNext()) {
				Integer integer = (Integer) it.next();
				if (isbiCycle(integer, visited, countered)) {
					return true;
				}
			}
			countered.remove(i);
			return false;
		}

		private boolean isbiCyclic() {
			HashSet<Integer> visited = new HashSet<Integer>();
			HashSet<Integer> countered = new HashSet<Integer>();
			Set<Integer> set = hm.keySet();
			for (Integer integer : set) {
				if (isbiCycle(integer, visited, countered)) {
					return true;
				}
			}
			return false;
		}
	}

	static class Node {
		Node left, right;
		int data;

		public Node(int data) {
			this.data = data;
		}

		public void insert(int val) {
			if (val <= data) {
				if (left == null) {
					left = new Node(val);
				} else {
					left.insert(val);
				}
			} else {
				if (right == null) {
					right = new Node(val);
				} else {
					right.insert(val);
				}
			}
		}

		public boolean contains(int val) {
			if (data == val) {
				return true;
			} else if (val < data) {
				if (left == null) {
					return false;
				} else {
					return left.contains(val);
				}
			} else {
				if (right == null) {
					return false;
				} else {
					return right.contains(val);
				}
			}
		}

		public void inorder() {
			if (left != null) {
				left.inorder();
			}
			System.out.print(data + " ");
			if (right != null) {
				right.inorder();
			}
		}

		public int maxDepth() {
			if (left == null)
				return 0;
			if (right == null)
				return 0;
			else {
				int ll = left.maxDepth();
				int rr = right.maxDepth();
				if (ll > rr)
					return (ll + 1);
				else
					return (rr + 1);
			}
		}

		public int countNodes() {
			if (left == null)
				return 1;
			if (right == null)
				return 1;
			else {
				return left.countNodes() + right.countNodes() + 1;
			}
		}

		public void preorder() {
			System.out.print(data + " ");
			if (left != null) {
				left.inorder();
			}

			if (right != null) {
				right.inorder();
			}

		}

		public void postorder() {
			if (left != null) {
				left.inorder();
			}

			if (right != null) {
				right.inorder();
			}
			System.out.print(data + " ");

		}

		public void levelorder(Node node) {
			LinkedList<Node> ll = new LinkedList<Node>();
			ll.add(node);
			getorder(ll);

		}

		public void getorder(LinkedList<Node> ll) {
			while (!ll.isEmpty()) {
				Node node = ll.poll();
				System.out.print(node.data + " ");
				if (node.left != null)
					ll.add(node.left);
				if (node.right != null)
					ll.add(node.right);
			}
		}
	}

	static class FastReader {
		BufferedReader br;
		StringTokenizer st;

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

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

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

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

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

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

	static class Pair {
		int first, second;

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

	}

	static class OutputWriter {
		private final PrintWriter writer;

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

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

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

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

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

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

	}

	private static final Scanner sc = new Scanner(System.in);
	private static final FastReader fs = new FastReader();
	private static final OutputWriter op = new OutputWriter(System.out);

	static int[] getintarray(int n) {
		int ar[] = new int[n];
		for (int i = 0; i < n; i++) {
			ar[i] = fs.nextInt();
		}
		return ar;
	}

	static long[] getlongarray(int n) {
		long ar[] = new long[n];
		for (int i = 0; i < n; i++) {
			ar[i] = fs.nextLong();
		}
		return ar;
	}

	static int[][] get2darray(int n, int m) {
		int ar[][] = new int[n][m];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				ar[i][j] = fs.nextInt();
			}
		}
		return ar;
	}

	static Pair[] getpairarray(int n) {
		Pair ar[] = new Pair[n];
		for (int i = 0; i < n; i++) {
			ar[i] = new Pair(fs.nextInt(), fs.nextInt());
		}
		return ar;
	}

	static void printarray(int ar[]) {
		for (int i : ar) {
			op.print(i + " ");
		}
		op.flush();
	}

	static int fact(int n) {
		int fact = 1;
		for (int i = 2; i <= n; i++) {
			fact *= i;
		}
		return fact;
	}

//

	// function to find largest prime factor

}

import java.util.*;
import java.io.*;
public class Solution{
	public static void main (String[] args) throws IOException{
		Reader s=new Reader();
		long n=s.nextLong();
		long m=s.nextLong();
		System.out.println(numWays(n,m));
	}
	public static long numWays(long n,long m)
	{
	    long temp=( powerMod(2,m,1000000007)-1 ) % 1000000007 + 1000000007;
	    long ans=powerMod(temp,n,1000000007);
	    return ans;
	}
	public static long powerMod(long a,long b,long c)
	{
	    if(b==0)
	    {
	        return 1;
	    }
	    long smallAns=powerMod(a,b/2,c);
	    long ans=(smallAns*smallAns) % c ;
	    if(b%2!=0)
	    {
	        ans=( ans * (a%c) ) % c;
	    }
	    return ans;
	}
	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[1000000+1]; // line length
            int cnt = 0, c;
            while ((c = read()) != -1)
            {
                if (c == '\n')
                    break;
                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();
        }
    }
}

/**
 * @author egaeus
 * @mail sebegaeusprogram@gmail.com
 * @veredict Not sended
 * @url <https://codeforces.com/problemset/problem/CF1236B>
 * @category ?
 * @date 9/06/2020
 **/

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

import static java.lang.Integer.*;
import static java.lang.Math.*;

public class CF1236B {
    static long N, M;

    public static void main(String args[]) throws Throwable {
        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        for (String ln; (ln = in.readLine()) != null && !ln.equals(""); ) {
            StringTokenizer st = new StringTokenizer(ln);
            N = parseInt(st.nextToken());
            M = parseInt(st.nextToken());
            long Q = f(2, M);
            if (Q == 0) Q = MOD;
            Q--;
            System.out.println(f(Q, N));
        }
    }

    static long MOD = 1000000007;

    static long f(long n, long exp) {
        if (exp == 0) return 1;
        if (exp == 1) return n % MOD;
        long middle = f(n, exp / 2);
        long result = (middle * middle) % MOD;
        if (exp % 2 == 1)
            result = (result * n) % MOD;
        return result;
    }
}

import java.io.*;
import java.util.*;
public final class code
{
	static final long mod=(long)(1e9+7);
	static long pow(long a,long b)
	{
		if(b==0)
			return 1;
		long x=pow(a,b/2);
		x=(x*x)%mod;
		if(b%2==0)
			return x;
		else
			return (x*a)%mod;
	}
	static void solve()throws IOException
	{
		long n=nextLong();
		long m=nextLong();
		long x=(pow(2,m)-1+mod)%mod;
		long ans=pow(x,n);
		out.println(ans);
	}

	///////////////////////////////////////////////////////////
	static BufferedReader br;
	static StringTokenizer st;
	static PrintWriter out;
	static String nextToken()throws IOException
	{
		while(st==null || !st.hasMoreTokens())
			st=new StringTokenizer(br.readLine());
		return st.nextToken();
	}
	static String nextLine()throws IOException
	{
		return br.readLine();
	}
	static int nextInt()throws IOException
	{
		return Integer.parseInt(nextToken());
	}
	static long nextLong()throws IOException
	{
		return Long.parseLong(nextToken());
	}
	static double nextDouble()throws IOException
	{
		return Double.parseDouble(nextToken());
	}
	public static void main(String args[])throws IOException
	{
		br=new BufferedReader(new InputStreamReader(System.in));
		out=new PrintWriter(new BufferedOutputStream(System.out));
		solve();
		out.close();
	}
}

import java.util.Scanner;

public class Main{

	public static void main(String[] args)
	{
		Scanner scan = new Scanner(System.in);
		long n = scan.nextInt(), m = scan.nextInt();
		long x  = power((power(2,m,1000000007))-1, n, 1000000007);
		System.out.println(x);
	}
	static long power(long x, long y, long p)
    {
        // Initialize result
        long res = 1;

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

       if (x == 0) return 0; // In case x is divisible by p;

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

            // y must be even now
            // y = y / 2
            y = y >> 1;
            x = (x * x) % p;
        }
        return res;
    }

}

//package com.company;

import java.util.Scanner;

public class Main {

	private static long module = 1000000007;

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

		String binaryN = Long.toBinaryString(n);
		String[] masBinaryN = binaryN.split("");

		long[] masNumberBinaryN = new long[masBinaryN.length];

		int j = 0;
		for (int i = masBinaryN.length -1 ; i >=0 ; i--) {
			masNumberBinaryN[j] = Long.parseLong(masBinaryN[i]);
			j++;
		}

	    String binaryM = Long.toBinaryString(m);
	    String[] masBinaryM = binaryM.split("");

	    long[] masNumberBinaryM = new long[masBinaryM.length];

	    j = 0;
		for (int i = masBinaryM.length -1 ; i >=0 ; i--) {
			masNumberBinaryM[j] = Long.parseLong(masBinaryM[i]);
			j++;
		}

		long firstPow = binPow(2,masNumberBinaryM);
		long answer = binPow(firstPow-1,masNumberBinaryN);
		System.out.println(answer);

    }

    private static long binPow(long number, long[] masBinaryNumber){
    	long r =1;
    	long n = number;
    	long[] masNumberBinaryM = masBinaryNumber;
		for (int i = 0; i < masNumberBinaryM.length ; i++) {
			if(masNumberBinaryM[i]==1){
				r = (r*n)%module;
				n = (n*n)%module;
			}
			else{
				r = r%module;
				n = (n*n)%module;
			}
		}
		return r;
	}
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.Math;
import java.math.BigInteger;
import java.util.StringTokenizer;
public class hh {

	public static final int  Mod = 1000000007;

	public static void main(String[] args)  {
		MyScanner in = new MyScanner();
		BigInteger n =BigInteger.valueOf(in.nextInt());
		BigInteger m =BigInteger.valueOf(in.nextInt());
		BigInteger two =BigInteger.valueOf(2);
	    two = two.modPow(m,BigInteger.valueOf(Mod));
	    two = two.add(BigInteger.valueOf(-1));
	    two = two.modPow(n,BigInteger.valueOf(Mod));
	    System.out.println(two.mod(BigInteger.valueOf(Mod)).intValue());
	}

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

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

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

		long mod = 1000000007L;

		int N = sc.nextInt();
		int M = sc.nextInt();

		// M = 1 box. 1 way (all N elements in the box).
		if (M == 1) {
			System.out.println(1);
			return;
		}

		// Only 1 kind of present.
		if (N == 1) {
			// 2^M - 1
			long count = fastPow(2, M, mod) - 1;
			System.out.println(count);
			return;
		}

		// ((2^M) - 1)^N

		long spreadOnePresent = fastPow(2, M, mod) - 1;
		long spreadAllPresents = fastPow(spreadOnePresent, N, mod);

		System.out.println(spreadAllPresents);
    }

	public static long fastPow(long x, long p, long mod) {
		if (p == 0) {
			return 1;
		}
		if (p == 1) {
			return x % mod;
		}

		long half = fastPow(x, p / 2, mod) % mod;

		if (p % 2 == 0) {
			return (half * half) % mod;
		}
		else {
			return (((half * half) % mod) * x) % mod;
		}
	}
}

//package main;

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

public final class Main {
    BufferedReader br;
    StringTokenizer stk;

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

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

    long mod = 1000_000_000 + 7;
    void run() throws Exception {
        int n = ni(), m = ni();
        BigInteger ans = new BigInteger("2");
        ans = ans.modPow(BigInteger.valueOf(m), BigInteger.valueOf(mod));
        ans = ans.subtract(BigInteger.ONE);
        if(ans.longValue() < 0)
            ans = ans.add(BigInteger.valueOf(mod));
        ans = ans.modPow(BigInteger.valueOf(n), BigInteger.valueOf(mod));
        System.out.println(ans);
    }

    //Reader & Writer
    String nextToken() throws Exception {
        if (stk == null || !stk.hasMoreTokens()) {
            stk = new StringTokenizer(br.readLine(), " ");
        }
        return stk.nextToken();
    }

    String nt() throws Exception {
        return nextToken();
    }

    int ni() throws Exception {
        return Integer.parseInt(nextToken());
    }

    long nl() throws Exception {
        return Long.parseLong(nextToken());
    }

    double nd() throws Exception {
        return Double.parseDouble(nextToken());
    }
}

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

public class C {
    static FastReader f = new FastReader();

    static long MOD = (long) (1e9+7);
    public static void main(String[] args) {
        long n = f.nextInt();
        long m = f.nextInt();

        long ans = ((pow(2,m) - 1) + MOD) % MOD;
        ans = pow(ans, n);
        System.out.println(ans);
    }

    static long pow(long num, long k) {
        long ans = 1;
        while (k > 0) {
            if((k&1) == 1) {
                ans = (ans * num) % MOD;
            }

            k >>= 1;
            num = (num*num) % MOD;
        }
        return ans;
    }

    //fast input reader
    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;
        }
    }
}

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

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

    static class TaskB {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            long n = in.nextLong();
            long m = in.nextLong();
            long mod = 1000_000_007;
            long x = Maths.power(2, m, mod) - 1;
            long ans = Maths.power(x, n, mod);
            out.println(ans);
        }

    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

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

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

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

    }

    static class Maths {
        static long power(long x, long y, long p) {
            long res = 1;
            x = x % p;
            while (y > 0) {
                if ((y & 1) == 1)
                    res = (res * x) % p;
                y = y >> 1;
                x = (x * x) % p;
            }
            return res;
        }

    }
}

import java.util.*;
import java.lang.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.*;
import java.math.*;
public class Main {
    public  long pow(long x, long y, long p)
    {
        // Initialize result
        long res = 1;

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

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

            // y must be even now
            // y = y / 2
            y = y >> 1;
            x = (x * x) % p;
        }
        return res;
    }
    public static void main(String[] args) throws Exception{
        Reader.init(System.in);
        PrintWriter out = new PrintWriter(System.out);
        Main mm=new Main();
        long n=Reader.nextLong();
        long m=Reader.nextLong();
        long mod=1000000007;
        long ans=mm.pow(2, m, mod);
        ans-=1;
        ans+=mod;
        ans%=mod;
        //out.println(ans);
        long f=mm.pow(ans, n, mod);

        out.println(f);
        out.close();
}
}

class Reader {
    static BufferedReader reader;
    static StringTokenizer tokenizer;
    /** call this method to initialize reader for InputStream */
    static void init() throws IOException {
         reader = new BufferedReader(
                 new FileReader("input.txt"));
    tokenizer = new StringTokenizer("");
    }
    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() );
    }
}

import java.util.*;
import java.math.*;
public class B {
    static Scanner sc = new Scanner(System.in);

    public static void main(String[] args) {
        int n = sc.nextInt(), m = sc.nextInt();
        int res = 1;
        BigInteger MOD = BigInteger.valueOf(1000000007);
        BigInteger pow = BigInteger.valueOf(2);
        pow = pow.modPow(BigInteger.valueOf(m), MOD).add(BigInteger.valueOf(-1));
        System.out.println(pow.modPow(BigInteger.valueOf(n), MOD).toString());
    }
}

import java.sql.SQLOutput;
import java.util.*;
/*
NOTES:
-more than 10 digits (10^10), use long
-prefix sum of 1's and -1's to control flow of highlighting a region
-log(a)/log(b) = log base b of a
-create a position array if trying to see if elements show up next to each other sequentially
 i.e. elements 1,2,3 are within 3 spots of each other in an array
      arr[scannedInt - 1] = i; (position of i at p[i] in original)
- use a freq array when counting instances of an element occurring
- increment the counter first before simulating anything turn-based (two player game)

 */

public class cf {
    public static String alpha = "abcdefghijklmnopqrstuvwxyz";
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        long n = scan.nextLong();
        long m = scan.nextLong();
        double x = Math.pow(2,m)-1;
        double ans = Math.pow(x,n);
        System.out.println((long)ans);
    }

    static int GCD(int a, int b) {
        // Everything divides 0
        if (a == 0) return b;
        if (b == 0) return a;

        // base case
        if (a == b) return a;

        // a is greater
        if (a > b) return GCD(a-b, b);
        return GCD(a, b-a);
    }
    static int LCM(int a, int b){
        return (a*b)/(GCD(a,b));
    }
    static String rev(String s){
        char[] arr = s.toCharArray();
        for(int i = 0; i<(s.length()+1)/2; i++){
            char temp = arr[i];
            arr[i] = arr[s.length()-i-1];
            arr[s.length()-i-1] = temp;
        }
        String fin = new String(arr);
        return fin;
    }

}

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

    public class bhaa {

        InputStream is;
        PrintWriter o;
        /////////////////// CODED++ BY++ ++ ++ ++ BHAVYA++ ARORA++ ++ ++ ++ FROM++ JAYPEE++ INSTITUTE++ OF++ INFORMATION++ TECHNOLOGY++ ////////////////

    ///////////////////////// Make it work, make it right, make it fast. Make it work, make it right, make it fast. Make it work, make it right, make it fast. Make it work, make it right, make it fast. /////////////////

     int power(int x, int y, int p)
    {
        // Initialize result
        int res = 1;

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

       if (x == 0) return 0; // In case x is divisible by p;

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

            // y must be even now
            // y = y / 2
            y = y >> 1;
            x = (x * x) % p;
        }
        return res;
    }

        void solve() {
           int n=ni();
           int m=ni();
           int res=power(2,m,1000000007);
           if(res==0)
           {
                res=1000000006;

           }
           else
           {
            res--;
           }
           o.println(power(res,n,1000000007));
           //for(int i=1;i<n;i++)
           //{
           // res=(int)(Math.pow(res,n))%1000000007;
         //  o.println(res);

        }

        //---------- I/O Template ----------

        public static void main(String[] args) { new bhaa().run(); }
        void run() {
            is = System.in;
            o = new PrintWriter(System.out);
            solve();
            o.flush();
        }

        byte input[] = new byte[1024];
        int len = 0, ptr = 0;

        int readByte() {
            if(ptr >= len) { ptr = 0;
                try { len = is.read(input); }
                catch(IOException e) { throw new InputMismatchException(); }
                if(len <= 0) { return -1; }
            } return input[ptr++];
        }
        boolean isSpaceChar(int c) { return !( c >= 33 && c <= 126 ); }
        int skip() {
            int b = readByte();
            while(b != -1 && isSpaceChar(b)) { b = readByte(); }
            return b;
        }

        char nc() { return (char)skip(); }
        String ns() {
            int b = skip();
            StringBuilder sb = new StringBuilder();
            while(!isSpaceChar(b)) { sb.appendCodePoint(b); b = readByte(); }
            return sb.toString();
        }
        String nLine() {
            int b = skip();
            StringBuilder sb = new StringBuilder();
            while( !(isSpaceChar(b) && b != ' ') ) { sb.appendCodePoint(b); b = readByte(); }
            return sb.toString();
        }
        int ni() {
            int n = 0, b = readByte();
            boolean minus = false;
            while(b != -1 && !( (b >= '0' && b <= '9') || b == '-')) { b = readByte(); }
            if(b == '-') { minus = true; b = readByte(); }
            if(b == -1) { return -1; }  //no input
            while(b >= '0' && b <= '9') { n = n * 10 + (b - '0'); b = readByte(); }
            return minus ? -n : n;
        }
        long nl() {
            long n = 0L;    int b = readByte();
            boolean minus = false;
            while(b != -1 && !( (b >= '0' && b <= '9') || b == '-')) { b = readByte(); }
            if(b == '-') { minus = true; b = readByte(); }
            while(b >= '0' && b <= '9') { n = n * 10 + (b - '0'); b = readByte(); }
            return minus ? -n : n;
        }

        double nd() { return Double.parseDouble(ns()); }
        float nf() { return Float.parseFloat(ns()); }
        int[] nia(int n) {
            int a[] = new int[n];
            for(int i = 0; i < n; i++) { a[i] = ni(); }
            return a;
        }
        long[] nla(int n) {
            long a[] = new long[n];
            for(int i = 0; i < n; i++) { a[i] = nl(); }
            return a;
        }
        int [][] nim(int n)
        {
            int mat[][]=new int[n][n];
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<n;j++)
                {
                    mat[i][j]=ni();
                }
            }
            return mat;
        }
        long [][] nlm(int n)
        {
            long mat[][]=new long[n][n];
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<n;j++)
                {
                    mat[i][j]=nl();
                }
            }
            return mat;
        }

        char[] ns(int n) {
            char c[] = new char[n];
            int i, b = skip();
            for(i = 0; i < n; i++) {
                if(isSpaceChar(b)) { break; }
                c[i] = (char)b; b = readByte();
            } return i == n ? c : Arrays.copyOf(c,i);
        }
        void piarr(int arr[])
        {
            for(int i=0;i<arr.length;i++)
            {
                o.print(arr[i]+" ");

            }
            o.println();
        }
        void plarr(long arr[])
        {
            for(int i=0;i<arr.length;i++)
            {
                o.print(arr[i]+" ");

            }
            o.println();
        }

        void pimat(int mat[][])
        {
            for(int i=0;i<mat.length;i++)
            {
                for(int j=0;j<mat[0].length;j++)
                {
                    o.print(mat[i][j]);
                }
                o.println();
            }
        }
        void plmat(long mat[][])
        {
            for(int i=0;i<mat.length;i++)
            {
                for(int j=0;j<mat[0].length;j++)
                {
                    o.print(mat[i][j]);
                }
                o.println();
            }

        }

        //////////////////////////////////// template finished //////////////////////////////////////

    }

import java.util.*;
public class problem2{
  public static void main(String[] args){
    Scanner s = new Scanner(System.in);
    int q = 1;
    for(int i = 1; i<=q; i++){
      int presents = s.nextInt();
      int boxes = s.nextInt();
      int types = (int)(Math.pow(2,boxes)-1)%(int)(Math.pow(10,9)+7);
      int ans = (int)(Math.pow(types,presents))%(int)(Math.pow(10,9)+7);
      System.out.println(ans);
    }
  }
}

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

public class Rextester{
    public static long exp(long a,long b,long mod){
        if(a==0){
            return 0;
        }
        else if(b==0){
            return 1;
        }
        else{
            if(b%2==0){
                long y = exp(a,b/2,mod);
                long ans = (y%mod)*(y%mod);
                ans%=mod;
                return ans;
            }
            else{
                long y = a%mod;
                y = ((y%mod)*(exp(a,b-1,mod)%mod))%mod;
                return y;
            }
        }
    }
    public static void main(String[] args)throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        br.close();
        long mod = 1000000007;
        int n = new Integer(st.nextToken());
        int m = new Integer(st.nextToken());
        long prod1 = (long)n*m;
        long prod2 = (long)m*(n-1);
        long ans = exp(2,prod1,mod);
        long ans2 = exp(2,prod2,mod);
        ans2 = (ans2%mod)*n;
        //System.out.println(ans+" "+ans2);
        ans-=ans2;
        ans+=n-1;
        System.out.println(ans);
    }
}

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

import static java.lang.Math.*;

public class Main {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    StringTokenizer st = new StringTokenizer("");
    PrintWriter pw = new PrintWriter(System.out);

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

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

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

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

    public Main() throws FileNotFoundException {
    }

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

    long mod = (long) 1e9 + 7;

    long pow(long a, long b) {
        if (b == 1) return a % mod;
        long x = pow(a, b / 2);
        if (b % 2 == 1) return (a * (x * x) % mod) % mod;
        return (x * x) % mod;
    }

    void run() throws IOException {
        int n = nextInt();
        int m = nextInt();
        pw.print(pow(pow(2, m) - 1, n));
        pw.close();
    }

    class Pair {
        int x, y;

        public Pair(int a, int b) {
            x = a;
            y = b;
        }
    }

    class PairComp implements Comparator<Pair> {

        @Override
        public int compare(Pair o1, Pair o2) {
            if (o1.x == o2.x) return Integer.compare(o1.y, o2.y);
            return Integer.compare(o1.x, o2.x);
        }
    }
}

import java.util.Scanner;

public class Main {
    public static Long temp = new Double(Math.pow(10,9)-7).longValue();
    public static Long quickPower(Long a,Long b){
        Long ans=1L;
        while(b!=0){
            if((b&1)!=0){
                ans*=a;
                ans%=temp;
            }
            b>>=1;
            a*=a;
        }
        return ans;
    }
    public static void main(String[]args){
        Scanner sin = new Scanner(System.in);
        Long n,m;
        while(sin.hasNext()){
            n=sin.nextLong();
            m=sin.nextLong();
            System.out.println(quickPower(quickPower(2L,m)-1,n));
        }
    }
}

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

public class Main {
    static int MOD = 1000000007;

    public static void main(String[] args) {
        FastReader read = new FastReader();
        StringBuilder out = new StringBuilder();
        int n = read.nextInt();
        int m = read.nextInt();
        int ans = fastPower(2, m) - 1;
        ans = fastPower(ans, n);
        System.out.println(ans);
    }

//    public static int fastPower(int a, int b) {
//        if (b == 1) {
//            return a;
//        }
//
//        int c = (a * a) % MOD;
//        int ans = fastPower(c, b / 2);
//
//        if ((b & 1) != 0) {
//            return (a * ans) % MOD;
//        } else {
//            return ans % MOD;
//        }
//    }

    public static int fastPower(int b, int n) {
        if (n == 0)
            return 1;
        if (n == 1)
            return b;
        if (n % 2 == 1)
            return (1 * b * fastPower(b, n - 1)) % MOD;
        int r = fastPower(b, n / 2);
        return (1 * r * r) % MOD;
    }
}

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

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

import java.lang.management.MemoryType;
import java.lang.reflect.Array;
import java.math.BigInteger;
import java.util.*;
import java.util.function.Function;

public class Main {

    static int [][] comb;//may need BigInteger, if the numbers are large, use a treemap
    static  int MOD=(int)(1e9 + 7);

    static int modPow(int a, int e, int mod)	// O(log e)
    {
        a %= mod;
        long res = 1;
        while(e > 0)
        {
            if((e & 1) == 1)
                res = (res * a) % mod;
            a = (a * a) % mod;
            e >>= 1;
        }
        return (int)res;
    }

    public static void main (String[]args) throws IOException {
        Scanner in = new Scanner(System.in);
        try(PrintWriter or = new PrintWriter(System.out)) {

          int n=in.nextInt();
          int m=in.nextInt();

          int ans=modPow(2,m,MOD)-1;
          if (ans<0)ans+=MOD;

          or.println(modPow(ans,n,MOD));

        }
    }

    static int getlen(int r,int l,int a){
        return (r-l+1+1)/(a+1);
    }

    static class Scanner {

        StringTokenizer st;
        BufferedReader br;

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

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

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

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

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

        public double nextDouble() throws IOException {
            String x = next();
            StringBuilder sb = new StringBuilder("0");
            double res = 0, f = 1;
            boolean dec = false, neg = false;
            int start = 0;
            if (x.charAt(0) == '-') {
                neg = true;
                start++;
            }
            for (int i = start; i < x.length(); i++) {
                if (x.charAt(i) == '.') {
                    res = Long.parseLong(sb.toString());
                    sb = new StringBuilder("0");
                    dec = true;
                } else {
                    sb.append(x.charAt(i));
                    if (dec) {
                        f *= 10;
                    }
                }
            }
            res += Long.parseLong(sb.toString()) / f;
            return res * (neg ? -1 : 1);
        }

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

    }
}

class Pair  {
    int first, second;

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

}

class Tempo {

    int num;
    int index;

    public Tempo(int num, int index) {
        this.num = num;
        this.index = index;
    }
}

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

public class Main {
	static final int MOD = 1000000000 + 7;

	public static void main(String[] args) throws Exception {
		int n, m;
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine(), " ");
		n = Integer.parseInt(st.nextToken());
		m = Integer.parseInt(st.nextToken());

		long answer = (long) (Math.pow(2, m) % MOD - 1);
		answer = (long) (Math.pow(answer, n) % MOD);

		System.out.print(answer);
	}

}

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

import static java.lang.Math.*;

public class Main {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    StringTokenizer st = new StringTokenizer("");
    PrintWriter pw = new PrintWriter(System.out);

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

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

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

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

    public Main() throws FileNotFoundException {
    }

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

    long mod = (long) 1e9 + 7;

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

    void run() throws IOException {
        int n = nextInt();
        int m = nextInt();
        pw.print(pow(pow(2, m) - 1, n));
        pw.close();
    }

    class Pair {
        int x, y;

        public Pair(int a, int b) {
            x = a;
            y = b;
        }
    }

    class PairComp implements Comparator<Pair> {

        @Override
        public int compare(Pair o1, Pair o2) {
            if (o1.x == o2.x) return Integer.compare(o1.y, o2.y);
            return Integer.compare(o1.x, o2.x);
        }
    }
}

import java.util.Scanner;

public class Main {
	public static void main(String args[])
	{
		Scanner sc=new Scanner(System.in);
		long n=sc.nextLong(),m=sc.nextLong();
		System.out.println((long)Math.pow((Math.pow(2, m)%1000000007-1),n)%1000000007);
	}

}

import java.io.OutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
//import java.math.*;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */

public class Main {

	static int MD= 1000000007;
    public static void main(String[] args) throws IOException {
    	OutputStream outputStream = System.out;
        InputReader in = new InputReader();
        PrintWriter out = new PrintWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskC {

        public void solve(int testNumber, InputReader in, PrintWriter out) throws IOException {
        	int t=1;

        	while(t-->0) {
        		long n=in.nextLong();
        		long m=in.nextLong();
        		long ans=fexp(2,n,MD);
        		ans=fexp(ans,m,MD);
        	//	out.println(ans);
        		long s=0;
        		if(n==1) {
        			s=1;
        		}
        		else {
        			//out.println(fexp(n,n+1,MD));
        			s=(1*(fexp(m,n+1,MD)-1))/(m-1);
        		}
        		ans-=s;
        		out.println(ans);
        	}

        }

    }

    static class InputReader
    {
        BufferedReader br;
        StringTokenizer st;

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

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

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

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

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

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

    }
    static void sort(int[] a, int low, int high)
    {
        int N = high - low;
        if (N <= 1)
            return;
        int mid = low + N/2;
        sort(a, low, mid);
        sort(a, mid, high);
        int[] temp = new int[N];
        int i = low, j = mid;
        for (int k = 0; k < N; k++)
        {
            if (i == mid)
                temp[k] = a[j++];
            else if (j == high)
                temp[k] = a[i++];
            else if (a[j]<a[i])
                temp[k] = a[j++];
            else
                temp[k] = a[i++];
        }
        for (int k = 0; k < N; k++)
            a[low + k] = temp[k];
    }
    public static long fexp(long x, long y, long p) {
        long res = 1;

        x = x % p;

        while (y > 0)
        {

            if((y & 1)==1)
                res = (res * x) % p;

            y = y >> 1;
            x = (x * x) % p;
        }
        return res;

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

    }

}

////////////////////---------------------------SHUBHAM CHAUDHARI-------------------------------///////////////////////

import java.util.*;

public class Main {

    public static void main(String[] args){

        Scanner in=new Scanner(System.in);
        long n=in.nextLong();
        long m=in.nextLong();
        System.out.println(2*((long)Math.pow(m,n)+1000000007)%1000000007+1);

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

}

import java.io.*;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
import java.util.StringTokenizer;

public class Main
{
    static int MAXN=201;
    static int spf[] = new int[MAXN];
    static int ans[]=new int[MAXN];
    static HashSet s=new HashSet();
	static class FastReader
	{
		BufferedReader br;
		StringTokenizer st;

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

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

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

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

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

		String nextLine()
		{
			String str = "";
			try
			{
				str = br.readLine();
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}
			return str;
		}
	}
    static void sieves()
    {
        spf[1] = 1;
        for (int i=2; i<MAXN; i++)
            spf[i] = i;
        for (int i=4; i<MAXN; i+=2)
            spf[i] = 2;
        for (long i=3; i*i<MAXN; i++)
        {
            if (spf[(int)i] == i)
            {
                for (long j=i*i; j<MAXN; j+=i)
                    if (spf[(int)j]==j)
                        spf[(int)j] = (int)i;
            }
        }
    }
    static void getFactorizations(int x)
    {
        Vector<Integer> ret = new Vector<>();
        HashSet w=new HashSet();
        while (x != 1 && spf[x]!=1)
        {
            if(!w.contains(spf[x]) && spf[x]!=1)
            {
            w.add(spf[x]);
            ans[spf[x]]++;
            }
            x = x / spf[x];
        }
    }
	public static void main(String[] args)
	{
		FastReader sc=new FastReader();
	    long n=sc.nextLong();
	    long m=sc.nextLong();
	    int mod=1000000007;
	    long ans=((power(2,n,mod)*power(2,m,mod))%mod-2*(m+1)-1+mod)%mod;
	    System.out.println(ans);
	}
	public static void sieven(int n)
    {
        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*2; i <= n; i += p)
                    prime[i] = false;
            }
        }
        for(int p=2; p<=n;p++)
        if(prime[p]==true)
        s.add(p);
    }
	public static long gcd(long a,long b)
	{
	    if(b==0)
	    return a;
	    return gcd(b,a%b);
	}
	static long power(long x, long y, int p)
    {
        long res = 1;
        x = x % p;
        while (y > 0)
        {
            if((y & 1)==1)
                res = (res * x) % p;
            y = y >> 1;
            x = (x * x) % p;
        }
        return res;
    }
    static class Pair
	{
		int x;
		int y;
		public Pair(int x, int y)
		{
			this.x = x;
			this.y = y;
		}
	}
    static class Compare
	{
		static void compare(Pair arr[], int n)
		{
			// Comparator to sort the pair according to second element
			Arrays.sort(arr, new Comparator<Pair>() {
				@Override public int compare(Pair p1, Pair p2)
				{
					if(p1.x>p2.x)
					{
						return 1;
					}
					else if(p2.x>p1.x)
					{
						return -1;
					}
					else
					{
						return 0;
					}
				}
			});
		}
	}
}

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

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

    static class Task {
        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int N = in.nextInt();
            int M = in.nextInt();
            int m = 1000000007;
            out.println(power((power(2, M, m) - 1) % m, N, m));
        }

        private int power(int a, int b, int m) {
            return (b != 0) ? (power(a * a % m, b / 2, m) * ((b % 2 != 0) ? a : 1) % m) : 1;
        }
    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

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

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

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

    }
}

//package codeforces.round593div2;

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

public class ListOfPresents {
    public static void main(String[] args) {
//        try {
//            FastScanner in = new FastScanner(new FileInputStream("src/input.in"));
//            PrintWriter out = new PrintWriter(new FileOutputStream("src/output.out"));
        FastScanner in = new FastScanner(System.in);
        PrintWriter out = new PrintWriter(System.out);

//        BigInteger p = BigInteger.valueOf(in.nextInt());
//        BigInteger b = BigInteger.valueOf(in.nextInt());
//        BigInteger mod = BigInteger.valueOf((long)1e9 + 7);
//
//        BigInteger res = BigInteger.valueOf(2);
//        res = res.modPow(b, mod).subtract(BigInteger.ONE);
//        res = res.modPow(p, mod);
//        out.println(res.longValue());

        int p = in.nextInt();
        int b = in.nextInt();

        out.println(fastPow(p, b, (int)1e9 + 7));
        out.close();

//        }
//        catch (IOException e) {
//            e.printStackTrace();
//        }
    }

    private static long task(int p, int b) {
        int mod = (int)1e9 + 7;
        int x = modPow(2, b, mod) - 1;
        return modPow(x, p, mod);
    }

    private static int modPow(int x, int n, int mod) {
        if(n == 0) {
            return 1;
        }
        long coeff = 1;
        long base = x;
        while(n > 1) {
            if(n % 2 != 0) {
                coeff = (coeff * base % mod);
            }
            base = (base * base % mod);
            n = n / 2;
        }
        long res = coeff * base % mod;
        return (int)res;
    }

//    public double myPow(double x, int n) {
//        if(x == 0 && n < 0) {
//            return Double.POSITIVE_INFINITY;
//        }
//        if(n == 0) {
//            return 1;
//        }
//        long N = n;
//        if(N < 0) {
//            x = 1 / x;
//            N = -N;
//        }
//        double base = x;
//        double coeff = 1;
//        while(N > 1) {
//            if(N % 2 != 0) {
//                coeff *= base;
//            }
//            base *= base;
//            N = N / 2;
//        }
//        return coeff * base;
//    }

//    public double myPow(double x, int n) {
//        if(x == 0 && n < 0) {
//            return Double.POSITIVE_INFINITY;
//        }
//        long N = n;
//        if(N < 0) {
//            x = 1 / x;
//            N = -N;
//        }
//        return fastPow(x, N);
//    }
    private static int fastPow(int x, int n, int mod) {
        if(n == 0) {
            return 1;
        }
        long half = fastPow(x, n / 2, mod);
        long res = half * half % mod;
        if(n % 2 == 0) {
            return (int)res;
        }
        return (int)(res * x % mod);
    }

    static class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        FastScanner(InputStream stream) {
            try {
                br = new BufferedReader(new InputStreamReader(stream));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

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

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

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

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

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

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Scanner;

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

    static class BAliceAndTheListOfPresents {
        long mod = 1000000007;

        public void solve(int testNumber, Scanner in, PrintWriter out) {
            int n = in.nextInt();
            int m = in.nextInt();
            int mdash = m;
            int ndash = n;
            long result = 2;

            while (m != 1) {
                result = (result * result) % mod;
                m = m / 2;
            }

            if (mdash % 2 != 0 && mdash != 1)
                result = (result * 2) % mod;
            result--;
            long answer = result;

            while (n != 1) {
                answer = (answer * answer) % mod;
                n = n / 2;
            }

            if (ndash % 2 != 0 && ndash != 1)
                answer = (answer * answer) % mod;
            out.println(answer % mod);

        }

    }
}

import java.util.*;
import java.io.*;
public class problem2 {
	public static void merge(int arr[], int l, int m, int r)
    {
        // Find sizes of two subarrays to be merged
        int n1 = m - l + 1;
        int n2 = r - m;

        /* Create temp arrays */
        int L[] = new int [n1];
        int R[] = new int [n2];

        /*Copy data to temp arrays*/
        for (int i=0; i<n1; ++i)
            L[i] = arr[l + i];
        for (int j=0; j<n2; ++j)
            R[j] = arr[m + 1+ j];

        /* Merge the temp arrays */

        // Initial indexes of first and second subarrays
        int i = 0, j = 0;

        // Initial index of merged subarry array
        int k = l;
        while (i < n1 && j < n2)
        {
            if (L[i] <= R[j])
            {
                arr[k] = L[i];
                i++;
            }
            else
            {
                arr[k] = R[j];
                j++;
            }
            k++;
        }

        /* Copy remaining elements of L[] if any */
        while (i < n1)
        {
            arr[k] = L[i];
            i++;
            k++;
        }

        /* Copy remaining elements of R[] if any */
        while (j < n2)
        {
            arr[k] = R[j];
            j++;
            k++;
        }
    }

    // Main function that sorts arr[l..r] using
    // merge()
    public static void sort(int arr[], int l, int r)
    {
        if (l < r)
        {
            // Find the middle point
            int m = (l+r)/2;

            // Sort first and second halves
            sort(arr, l, m);
            sort(arr , m+1, r);

            // Merge the sorted halves
            merge(arr, l, m, r);
        }
    }
    public static int M = 1000000007;
   public static int modularExponentiation(int x,int n)
    {
        if(n==0)
            return 1;
        else if(n%2 == 0)        //n is even
            return modularExponentiation((x*x)%M,n/2);
        else                             //n is odd
            return (x*modularExponentiation((x*x)%M,(n-1)/2))%M;

    }
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		long n = Long.parseLong(st.nextToken());
		long m = Long.parseLong(st.nextToken());
		long v1 = (long)modularExponentiation(2, (int)m);
		v1 = v1-1;
		long ans = (long)modularExponentiation((int)v1, (int)n);
		System.out.println(ans);
    }

}

import java.io.*;
import java.util.*;
public class Solution {
	static Scanner sc=new Scanner(System.in);
	static PrintWriter out=new PrintWriter(System.out);
	//Main
	static long MOD=(long)1e9+7;
	static long fastExpo(long x,long n) {
		if(n==0) return 1;
		if(n%2==0) return fastExpo((x*x)%MOD,n/2);
		return (x*(fastExpo((x*x)%MOD,n/2))%MOD);
	}
	public static void main(String args[]) {
		int test=1;
		//test=sc.nextInt();
		while(test-->0) {
			long n=sc.nextLong(),m=sc.nextLong();
			long x=(fastExpo(2,m))%MOD;
			long ans=fastExpo(x,n)%MOD;
			out.println(ans);
		}
		out.flush();
		out.close();
	}
}

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

public class Alice_And_The_List_Of_Presents {
	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;
		}

	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		FastReader t = new FastReader();
		PrintWriter o = new PrintWriter(System.out);
		long n = t.nextLong();
		long m = t.nextLong();
		long mod = (long) 10e9 + 7;
		long ans = pow(2, m, mod);
		ans--;

		if (ans < 0)
			ans += mod;

		o.println(pow(ans, n, mod));
		o.flush();
		o.close();
	}

	static long pow(long a, long N, long mod) {
		if (N == 0)
			return 1;
		else if (N == 1)
			return a % mod;
		else {
			long R = pow(a, N / 2, mod) % mod;
			R *= R;
			R %= mod;

			if (N % 2 == 1) {
				R *= a;
				R %= mod;
			}

			return R % mod;
		}
	}
}

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

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

    static class Task {
        int m = 1000000007;

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int N = in.nextInt();
            int M = in.nextInt();
            out.println(power((power(2, M) - 1) % m, N));
        }

        private int power(int a, int b) {
            return (b != 0) ? power(a * a % m, b / 2) * ((b % 2 != 0) ? a : 1) % m : 1;
        }
    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

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

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

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

    }
}

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

import java.lang.management.MemoryType;
import java.lang.reflect.Array;
import java.math.BigInteger;
import java.util.*;
import java.util.function.Function;

public class Main {

    static int [][] comb;//may need BigInteger, if the numbers are large, use a treemap
    static  int MOD=(int)(10e9+7);

    static int nCr1(int n , int k)
    {
        if(n < k)
            return 0;
        if(k == 0 || k == n)
            return 1;
        if(comb[n][k] != -1)
            return comb[n][k];
        if(n - k < k)
            return comb[n][k] = nCr1(n, n - k)%MOD;
        return comb[n][k] = nCr1(n - 1, k - 1)%MOD + nCr1(n - 1, k)%MOD;
    }
    static int pow(int a, int e)	// O(log e)
    {
        int res = 1;
        while(e > 0)
        {
            if((e & 1) == 1) {
                res = (res*a)%MOD;

            }
            a = (a*a)%MOD;
            e >>= 1;
        }
        return res;
    }

    public static void main (String[]args) throws IOException {
        Scanner in = new Scanner(System.in);
        try(PrintWriter or = new PrintWriter(System.out)) {

           int n=in.nextInt();
           int m=in.nextInt();

           or.println(pow(n+1,m)-(n==1?1:0));

        }
    }

    static int getlen(int r,int l,int a){
        return (r-l+1+1)/(a+1);
    }

    static class Scanner {

        StringTokenizer st;
        BufferedReader br;

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

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

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

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

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

        public double nextDouble() throws IOException {
            String x = next();
            StringBuilder sb = new StringBuilder("0");
            double res = 0, f = 1;
            boolean dec = false, neg = false;
            int start = 0;
            if (x.charAt(0) == '-') {
                neg = true;
                start++;
            }
            for (int i = start; i < x.length(); i++) {
                if (x.charAt(i) == '.') {
                    res = Long.parseLong(sb.toString());
                    sb = new StringBuilder("0");
                    dec = true;
                } else {
                    sb.append(x.charAt(i));
                    if (dec) {
                        f *= 10;
                    }
                }
            }
            res += Long.parseLong(sb.toString()) / f;
            return res * (neg ? -1 : 1);
        }

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

    }
}

class Pair  {
    int first, second;

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

}

class Tempo {

    int num;
    int index;

    public Tempo(int num, int index) {
        this.num = num;
        this.index = index;
    }
}

import java.io.*;
import java.util.*;
public class Solution {
	static Scanner sc=new Scanner(System.in);
	static PrintWriter out=new PrintWriter(System.out);
	//Main
	static long MOD=(long)1e9+7;
	static long fastExpo(long x,long n) {
		if(n==0) return 1;
		if(n%2==0) return fastExpo((x*x)%MOD,n/2)%MOD;
		return ((x%MOD)*(fastExpo(x*x,n/2)%MOD))%MOD;
	}
	public static void main(String args[]) {
		int test=1;
		//test=sc.nextInt();
		while(test-->0) {
			long n=sc.nextLong(),m=sc.nextLong();
			long x=(fastExpo(2,m)-1+MOD)%MOD;
			long ans=fastExpo(x,n)%MOD;
			out.println(ans);
		}
		out.flush();
		out.close();
	}
}

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

public class asdf{
static int mod = (int)(Math.pow(10, 9) + 7);
   public static void main(String[] args) {
      MyScanner sc = new MyScanner();
      out = new PrintWriter(new BufferedOutputStream(System.out));

      long n =sc.nextLong();
      long m = sc.nextLong();

      long ans = powMod(2,m);

      ans--;
      if (ans < 0) ans += mod;

      out.println(powMod(ans, n));

      out.close();
   }

   static long pow(long a, long N) {
	   if (N == 0) return 1;
	   else if (N == 1) return a;
	   else {
		   long R = pow(a,N/2);
		   if (N % 2 == 0) {
			   return R*R;
		   }
		   else {
			   return R*R*a;
		   }
	   }
   }

   static long powMod(long a, long N) {
	   if (N == 0) return 1;
	   else if (N == 1) return a % mod;
	   else {
		   long R = pow(a,N/2) % mod;
		   R *= R % mod;
		   if (N % 2 == 1) {
			   R *= a % mod;
		   }
			   return R % mod;
	   }
   }
static void mergeSort(int[] A){ // low to hi sort, single array only
      int n = A.length;
      if (n < 2) return;
      int[] l = new int[n/2];
      int[] r = new int[n - n/2];

      for (int i = 0; i < n/2; i++){
        l[i] = A[i];
      }

      for (int j = n/2; j < n; j++){
        r[j-n/2] = A[j];
      }

      mergeSort(l);
      mergeSort(r);
      merge(l, r, A);
    }

    static void merge(int[] l, int[] r, int[] a){
      int i = 0, j = 0, k = 0;
      while (i < l.length && j < r.length && k < a.length){
        if (l[i] < r[j]){
          a[k] = l[i];
          i++;
        }
        else{
          a[k] = r[j];
          j++;
        }
        k++;
      }
      while (i < l.length){
        a[k] = l[i];
        i++;
        k++;
      }

      while (j < r.length){
        a[k] = r[j];
        j++;
        k++;
      }
    }

   //-----------PrintWriter for faster output---------------------------------
   public static PrintWriter out;

   //-----------MyScanner class for faster input----------
   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 class FastScanner {
        BufferedReader br;
        StringTokenizer st;

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

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

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

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

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

        public String nextLine() {
            String line = "";
            if(st.hasMoreTokens()) line = st.nextToken();
            else try {return br.readLine();}catch(IOException e){e.printStackTrace();}
            while(st.hasMoreTokens()) line += " "+st.nextToken();
            return line;
        }
    }

    public static void main(String[] args) throws IOException {
        FastScanner cin = new FastScanner();
        PrintWriter cout = new PrintWriter(System.out);

        long n = cin.nextLong(), m = cin.nextLong();
        cout.println((long)(Math.pow(Math.pow(2, m) - 1, n) % (10e9 + 7)));
        cout.close();
    }
}

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

public class cf{
static long mod = (long)(Math.pow(10, 9) + 7);
   public static void main(String[] args) {
      MyScanner sc = new MyScanner();
      out = new PrintWriter(new BufferedOutputStream(System.out));

      long n = sc.nextInt();
      long m = sc.nextInt();

      out.println((n * m ) % mod + 1);
      out.close();
   }
static void mergeSort(int[] A){ // low to hi sort, single array only
      int n = A.length;
      if (n < 2) return;
      int[] l = new int[n/2];
      int[] r = new int[n - n/2];

      for (int i = 0; i < n/2; i++){
        l[i] = A[i];
      }

      for (int j = n/2; j < n; j++){
        r[j-n/2] = A[j];
      }

      mergeSort(l);
      mergeSort(r);
      merge(l, r, A);
    }

    static void merge(int[] l, int[] r, int[] a){
      int i = 0, j = 0, k = 0;
      while (i < l.length && j < r.length && k < a.length){
        if (l[i] < r[j]){
          a[k] = l[i];
          i++;
        }
        else{
          a[k] = r[j];
          j++;
        }
        k++;
      }
      while (i < l.length){
        a[k] = l[i];
        i++;
        k++;
      }

      while (j < r.length){
        a[k] = r[j];
        j++;
        k++;
      }
    }

   //-----------PrintWriter for faster output---------------------------------
   public static PrintWriter out;

   //-----------MyScanner class for faster input----------
   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.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;

import java.lang.management.MemoryType;
import java.lang.reflect.Array;
import java.math.BigInteger;
import java.util.*;
import java.util.function.Function;

public class Main {

    static int [][] comb;//may need BigInteger, if the numbers are large, use a treemap
    static  int MOD=(int)(10e9+7);

    static int nCr1(int n , int k)
    {
        if(n < k)
            return 0;
        if(k == 0 || k == n)
            return 1;
        if(comb[n][k] != -1)
            return comb[n][k];
        if(n - k < k)
            return comb[n][k] = nCr1(n, n - k)%MOD;
        return comb[n][k] = nCr1(n - 1, k - 1)%MOD + nCr1(n - 1, k)%MOD;
    }
    static int pow(int a, int e)	// O(log e)
    {
        int res = 1;
        while(e > 0)
        {
            if((e & 1) == 1) {
                res *= a;
                res%=MOD;
            }
            a *= a;
            e >>= 1;
        }
        return res;
    }

    public static void main (String[]args) throws IOException {
        Scanner in = new Scanner(System.in);
        try(PrintWriter or = new PrintWriter(System.out)) {

           int n=in.nextInt();
           int m=in.nextInt();

           or.println(pow(n+1,m)-(n==1?1:0));

        }
    }

    static int getlen(int r,int l,int a){
        return (r-l+1+1)/(a+1);
    }

    static class Scanner {

        StringTokenizer st;
        BufferedReader br;

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

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

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

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

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

        public double nextDouble() throws IOException {
            String x = next();
            StringBuilder sb = new StringBuilder("0");
            double res = 0, f = 1;
            boolean dec = false, neg = false;
            int start = 0;
            if (x.charAt(0) == '-') {
                neg = true;
                start++;
            }
            for (int i = start; i < x.length(); i++) {
                if (x.charAt(i) == '.') {
                    res = Long.parseLong(sb.toString());
                    sb = new StringBuilder("0");
                    dec = true;
                } else {
                    sb.append(x.charAt(i));
                    if (dec) {
                        f *= 10;
                    }
                }
            }
            res += Long.parseLong(sb.toString()) / f;
            return res * (neg ? -1 : 1);
        }

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

    }
}

class Pair  {
    int first, second;

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

}

class Tempo {

    int num;
    int index;

    public Tempo(int num, int index) {
        this.num = num;
        this.index = index;
    }
}

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

public class B {
	static int mod = 1000000007;
	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 m = Integer.parseInt(st.nextToken());

		// nC1 ~ nCn
		long sum = ((long)Math.pow(2, m)-1)%mod;
		long ans = 1;
		while (n > 0) {
			if (n % 2 == 1) {
				ans = (ans%mod *sum%mod)%mod;
			}
			sum = (sum%mod * sum%mod)%mod;
			n = n >> 1;
		}
		System.out.println(ans);
	}
}

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

    public class bhaa {

        InputStream is;
        PrintWriter o;
        /////////////////// CODED++ BY++ ++ ++ ++ BHAVYA++ ARORA++ ++ ++ ++ FROM++ JAYPEE++ INSTITUTE++ OF++ INFORMATION++ TECHNOLOGY++ ////////////////

    ///////////////////////// Make it work, make it right, make it fast. Make it work, make it right, make it fast. Make it work, make it right, make it fast. Make it work, make it right, make it fast. /////////////////

        void solve() {
           int n=ni();
           int m=ni();
           long res=(long)(Math.pow(2,m)-1)%1000000007;
           //for(int i=1;i<n;i++)
           //{
            res=(long)(Math.pow(res,n))%1000000007;
           o.println(res);

        }

        //---------- I/O Template ----------

        public static void main(String[] args) { new bhaa().run(); }
        void run() {
            is = System.in;
            o = new PrintWriter(System.out);
            solve();
            o.flush();
        }

        byte input[] = new byte[1024];
        int len = 0, ptr = 0;

        int readByte() {
            if(ptr >= len) { ptr = 0;
                try { len = is.read(input); }
                catch(IOException e) { throw new InputMismatchException(); }
                if(len <= 0) { return -1; }
            } return input[ptr++];
        }
        boolean isSpaceChar(int c) { return !( c >= 33 && c <= 126 ); }
        int skip() {
            int b = readByte();
            while(b != -1 && isSpaceChar(b)) { b = readByte(); }
            return b;
        }

        char nc() { return (char)skip(); }
        String ns() {
            int b = skip();
            StringBuilder sb = new StringBuilder();
            while(!isSpaceChar(b)) { sb.appendCodePoint(b); b = readByte(); }
            return sb.toString();
        }
        String nLine() {
            int b = skip();
            StringBuilder sb = new StringBuilder();
            while( !(isSpaceChar(b) && b != ' ') ) { sb.appendCodePoint(b); b = readByte(); }
            return sb.toString();
        }
        int ni() {
            int n = 0, b = readByte();
            boolean minus = false;
            while(b != -1 && !( (b >= '0' && b <= '9') || b == '-')) { b = readByte(); }
            if(b == '-') { minus = true; b = readByte(); }
            if(b == -1) { return -1; }  //no input
            while(b >= '0' && b <= '9') { n = n * 10 + (b - '0'); b = readByte(); }
            return minus ? -n : n;
        }
        long nl() {
            long n = 0L;    int b = readByte();
            boolean minus = false;
            while(b != -1 && !( (b >= '0' && b <= '9') || b == '-')) { b = readByte(); }
            if(b == '-') { minus = true; b = readByte(); }
            while(b >= '0' && b <= '9') { n = n * 10 + (b - '0'); b = readByte(); }
            return minus ? -n : n;
        }

        double nd() { return Double.parseDouble(ns()); }
        float nf() { return Float.parseFloat(ns()); }
        int[] nia(int n) {
            int a[] = new int[n];
            for(int i = 0; i < n; i++) { a[i] = ni(); }
            return a;
        }
        long[] nla(int n) {
            long a[] = new long[n];
            for(int i = 0; i < n; i++) { a[i] = nl(); }
            return a;
        }
        int [][] nim(int n)
        {
            int mat[][]=new int[n][n];
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<n;j++)
                {
                    mat[i][j]=ni();
                }
            }
            return mat;
        }
        long [][] nlm(int n)
        {
            long mat[][]=new long[n][n];
            for(int i=0;i<n;i++)
            {
                for(int j=0;j<n;j++)
                {
                    mat[i][j]=nl();
                }
            }
            return mat;
        }

        char[] ns(int n) {
            char c[] = new char[n];
            int i, b = skip();
            for(i = 0; i < n; i++) {
                if(isSpaceChar(b)) { break; }
                c[i] = (char)b; b = readByte();
            } return i == n ? c : Arrays.copyOf(c,i);
        }
        void piarr(int arr[])
        {
            for(int i=0;i<arr.length;i++)
            {
                o.print(arr[i]+" ");

            }
            o.println();
        }
        void plarr(long arr[])
        {
            for(int i=0;i<arr.length;i++)
            {
                o.print(arr[i]+" ");

            }
            o.println();
        }

        void pimat(int mat[][])
        {
            for(int i=0;i<mat.length;i++)
            {
                for(int j=0;j<mat[0].length;j++)
                {
                    o.print(mat[i][j]);
                }
                o.println();
            }
        }
        void plmat(long mat[][])
        {
            for(int i=0;i<mat.length;i++)
            {
                for(int j=0;j<mat[0].length;j++)
                {
                    o.print(mat[i][j]);
                }
                o.println();
            }

        }

        //////////////////////////////////// template finished //////////////////////////////////////

    }

import java.util.Scanner;

public class que2 {

	public static void main(String[] args) {
   Scanner scn=new Scanner(System.in);
   int n=scn.nextInt();
   int m=scn.nextInt();
   int power=power(2, m);
   int ans=power((power-1+mod)%mod,n)%mod;
   System.out.println(ans);
	}
	static int mod=1000000007;
public static int power(int val,int power){
	if(power==0){
		return 1;
	}
	int res=power(val, power/2);
	if(power%2==0){
		return (res*res)%mod;
	}else{
		return (res*(val*res))%mod;
	}
}
}

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

public class codeforcesc {

	static void methods() {
		Integer arr[] = { 1, 1, 1, 1, 1, 1 };
		Integer arr2[] = { 1, 1, 1, 1, 1, 1 };
		List<Integer> l1 = new ArrayList<>();
		l1 = Arrays.asList(arr);
		ArrayList<Integer> ll = new ArrayList<>(l1);
		boolean bb = Arrays.equals(arr, arr2);
	}

	static long gcd(long a, long b) {
		if (b == 0)
			return a;
		return gcd(b, a % b);
	}
	static int power(int x, int y, int p)
    {
        int res = 1;
        x = x % p;

       if (x == 0) return 0;

        while (y > 0)
        {
            if((y & 1)==1)
                res = (res * x) % p;
            y = y >> 1;
            x = (x * x) % p;
        }
        return res;
    }

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		//int t = sc.nextInt();
		int mod=1000000000+7 ;

			long n=sc.nextLong();
			long m=sc.nextLong();

			long p=power(2,(int)m,mod)-1;
			p=p%mod;

			long ans=power((int)p,(int)n,mod);
			System.out.println(ans);

	}

}

//normal
import java.util.*;
import java.lang.*;
import java.io.*;
// String Tokenizer

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

		int t = 1;
		long mod = 1000000007;
		while (t > 0) {
			t--;
			long n = scn.nextLong();
			long m = scn.nextLong();
			long ans = ((long) Math.pow(2, m) - 1) % mod;
			ans = ((long) Math.pow(ans, n)) % mod;
			System.out.println(ans);
		}
	}
}

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

public class asdf{
static long mod = (long)(Math.pow(10, 9) + 7);
   public static void main(String[] args) {
      MyScanner sc = new MyScanner();
      out = new PrintWriter(new BufferedOutputStream(System.out));

      long n =sc.nextLong();
      long m = sc.nextLong();

      long ans = powMod(2,m);

      ans--;
      if (ans < 0) ans += mod;

      out.println(powMod(ans, n));

      out.close();
   }

   static long pow(long a, long N) {
	   if (N == 0) return 1;
	   else if (N == 1) return a;
	   else {
		   long R = pow(a,N/2);
		   if (N % 2 == 0) {
			   return R*R;
		   }
		   else {
			   return R*R*a;
		   }
	   }
   }

   static long powMod(long a, long N) {
	   if (N == 0) return 1;
	   else if (N == 1) return a % mod;
	   else {
		   long R = pow(a,N/2) % mod;
		   R *= (R % mod);
		   if (N % 2 == 1) {
			   R *= (a % mod);
		   }
			   return R % mod;
	   }
   }
static void mergeSort(int[] A){ // low to hi sort, single array only
      int n = A.length;
      if (n < 2) return;
      int[] l = new int[n/2];
      int[] r = new int[n - n/2];

      for (int i = 0; i < n/2; i++){
        l[i] = A[i];
      }

      for (int j = n/2; j < n; j++){
        r[j-n/2] = A[j];
      }

      mergeSort(l);
      mergeSort(r);
      merge(l, r, A);
    }

    static void merge(int[] l, int[] r, int[] a){
      int i = 0, j = 0, k = 0;
      while (i < l.length && j < r.length && k < a.length){
        if (l[i] < r[j]){
          a[k] = l[i];
          i++;
        }
        else{
          a[k] = r[j];
          j++;
        }
        k++;
      }
      while (i < l.length){
        a[k] = l[i];
        i++;
        k++;
      }

      while (j < r.length){
        a[k] = r[j];
        j++;
        k++;
      }
    }

   //-----------PrintWriter for faster output---------------------------------
   public static PrintWriter out;

   //-----------MyScanner class for faster input----------
   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;
      }

   }
   //--------------------------------------------------------
}

//package practice;
import java.util.*;
public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner s=new Scanner(System.in);
		int n=s.nextInt();
		int arr[][]=new int [n][n];
		int c=1;
		for(int i=0;i<n;i++)
		{
			if(i%2==0)
			{
				for(int j=0;j<n;j++)
				{
					arr[j][i]=c++;
				}
			}
			else
			{
				for(int j=n-1;j>=0;j--)
				{
					arr[j][i]=c++;
				}
			}
		}
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<n;j++)
			{
				System.out.print(arr[i][j]+" ");
			}
			System.out.println();
		}
	}

}

import java.util.Scanner;

public class que2 {

	public static void main(String[] args) {
   Scanner scn=new Scanner(System.in);
   int n=scn.nextInt();
   int m=scn.nextInt();
   long power=power(2, m);
   long ans=power((power-1+mod)%mod,n)%mod;
   System.out.println(ans);
	}
	static int mod=1000000007;
public static long power(long val,long power){
	if(power==0){
		return 1;
	}
	long res=power(val, power/2);
	if(power%2==0){
		return (res*res)%mod;
	}else{
		return (res*(val*res)%mod)%mod;
	}
}

}

import java.util.Scanner;

public class que2 {

	public static void main(String[] args) {
   Scanner scn=new Scanner(System.in);
   int n=scn.nextInt();
   int m=scn.nextInt();
   long power=power(2, m);
   long ans=power((power-1+mod)%mod,n)%mod;
   System.out.println(ans);
	}
	static int mod=1000000007;
public static long power(long val,long power){
	if(power==0){
		return 1;
	}
	long res=power(val, power/2);
	if(power%2==0){
		return (res*res)%mod;
	}else{
		return (res*(val*res))%mod;
	}
}
}

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

public class Main {

    static FastReader in;
    static PrintWriter out;

    static int mod = 1000000007;

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

    static void solve() {
        long n = in.nextLong();
        long m = in.nextLong();

        long ans = binPow(2, m);
        ans = binPow(ans - 1, n);

        out.println(ans);
    }

    public static void main(String[] args) {
        in = new FastReader(System.in);
//        in = new FastReader(new FileInputStream("input.txt"));
        out = new PrintWriter(System.out);
//        out = new PrintWriter(new FileOutputStream("output.txt"));

        int q = 1;

        while (q-- > 0)
            solve();

        out.close();
    }

    static class FastReader {
        BufferedReader br;
        StringTokenizer st;

        FastReader(InputStream is) {
            br = new BufferedReader(new InputStreamReader(is));
        }

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

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

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

        String next() {
            while (st == null || !st.hasMoreTokens()) {
                st = new StringTokenizer(nextLine());
            }
            return st.nextToken();
        }

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

import java.util.Scanner;

public class Main {

	public static void main(String[] args)
	{
		Scanner scan = new Scanner(System.in);
		int n = scan.nextInt(), m = scan.nextInt();
		long x  = power((power(2,m,1000000007))-1, n, 1000000007);
		System.out.println(x);
	}
	static int power(int x, int y, int p)
    {
        // Initialize result
        int res = 1;

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

       if (x == 0) return 0; // In case x is divisible by p;

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

            // y must be even now
            // y = y / 2
            y = y >> 1;
            x = (x * x) % p;
        }
        return res;
    }

}

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

public class Example {
    private static int M = 1000000007;

    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        StringBuffer writer = new StringBuffer();
        String[] line = reader.readLine().split(" ");
        int n = Integer.parseInt(line[0]);
        int m = Integer.parseInt(line[1]);
        writer.append(solve(n, m));
        writer.append('\n');
        System.out.print(writer);
        reader.close();
    }

    private static int solve(int n, int m) {
        int t = (M + pow(2, m) - 1) % M;
        return pow(t, n);
    }

    private static int pow(int a, int n) {
        if (n == 0) return 1;
        int y = pow(a, n / 2);
        if (n % 2 == 1) y = (y * a) % M;
        return y;
    }
}

import java.util.*;
public class problem2{
  public static void main(String[] args){
    Scanner s = new Scanner(System.in);
    int q = 1;
    for(int i = 1; i<=q; i++){
      int presents = s.nextInt();
      int boxes = s.nextInt();
      int types = (int)(Math.pow(2,boxes)-1)%(int)(Math.pow(10,9)+7);
      int ans = (int)(Math.pow(types,presents))%(int)(Math.pow(10,9)+7);
      System.out.println(ans);
    }
  }
}

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

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

    static class TaskB {
        static final int MOD = (int) (1e9 + 7);

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            long n = in.nextInt();
            long m = in.nextInt();
            long res = (fastExpo(2, n * m) - fastExpo(2, (n - 1) * m) * n + n - 1) % MOD;
            out.println(n > m ? 0 : (res + 2 * MOD) % MOD);
        }

        static long fastExpo(long b, long p) {
            long res = 1;
            while (p > 0) {
                if (p % 2 != 0) {
                    res = (res * b) % MOD;
                }
                p /= 2;
                b = (b * b) % MOD;
            }
            return res;
        }

    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

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

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

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

    }
}

import java.util.*;

public class alicepresent
{
	public static void main(String args[])
	{
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt(),m=sc.nextInt();
		double ans = Math.pow((Math.pow(2,m)-1),n);
		System.out.print((int)ans);
	}
}

//package codeforces.round593div2;

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

public class ListOfPresents {
    public static void main(String[] args) {
//        try {
//            FastScanner in = new FastScanner(new FileInputStream("src/input.in"));
//            PrintWriter out = new PrintWriter(new FileOutputStream("src/output.out"));
        FastScanner in = new FastScanner(System.in);
        PrintWriter out = new PrintWriter(System.out);

        long p = in.nextInt();
        long b = in.nextInt();
        BigInteger mod = BigInteger.valueOf((long)1e9 + 7);
        BigInteger res1 = BigInteger.valueOf(2);
        res1 = res1.modPow(BigInteger.valueOf((p - 1) * b), mod);
        BigInteger res2 = BigInteger.valueOf(2);
        res2 = res2.modPow(BigInteger.valueOf(b), mod).subtract(BigInteger.valueOf(p)).add(mod).mod(mod);

        BigInteger res = res1.multiply(res2).add(BigInteger.valueOf(p - 1));
        out.println(res.mod(mod).longValue());

//        BigInteger curr = BigInteger.valueOf(1);
//        for(int i = 1; i <= b; i++) {
//            curr = curr.multiply(BigInteger.valueOf(2));
//        }
//
//        if(p == 1) {
//            out.println(curr.longValue() - 1);
//        }
//        else {
//            BigInteger sel = BigInteger.valueOf(2);
//            BigInteger factorial1 = BigInteger.ONE;
//            for(int i = 2; i <= p; i++) {
//                factorial1 = factorial1.multiply(BigInteger.valueOf(i));
//            }
//            BigInteger factorial2 = BigInteger.ONE;
//            for(int i = 2; i <= p; i++) {
//                factorial2 = factorial2.multiply(BigInteger.valueOf(i));
//                sel = sel.add(factorial2);
//                curr = sel.pow(b).subtract(curr.multiply(BigInteger.valueOf(p))).add(BigInteger.valueOf(p - 1));
//            }
//            out.println(curr.mod(mod).longValue());
//        }

        out.close();

//        }
//        catch (IOException e) {
//            e.printStackTrace();
//        }
    }

    static class FastScanner {
        BufferedReader br;
        StringTokenizer st;

        FastScanner(InputStream stream) {
            try {
                br = new BufferedReader(new InputStreamReader(stream));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        String next() {
            while (st == null || !st.hasMoreTokens()) {
                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.*;
import java.math.*;
import java.lang.*;

import static java.lang.Math.*;

public class Cf182 implements Runnable
{
	static class InputReader
	{
		private InputStream stream;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;
		private SpaceCharFilter filter;
		private BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

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

		public int read()
		{
			if (numChars==-1)
				throw new InputMismatchException();

			if (curChar >= numChars)
			{
				curChar = 0;
				try
				{
					numChars = stream.read(buf);
				}
				catch (IOException e)
				{
					throw new InputMismatchException();
				}

				if(numChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public String nextLine()
		{
			String str = "";
			try
			{
				str = br.readLine();
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}
			return str;
		}
		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 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 double nextDouble()
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = read();
			}
			double res = 0;
			while (!isSpaceChar(c) && c != '.')
			{
				if (c == 'e' || c == 'E')
					return res * Math.pow(10, nextInt());
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			}
			if (c == '.')
			{
				c = read();
				double m = 1;
				while (!isSpaceChar(c))
				{
					if (c == 'e' || c == 'E')
						return res * Math.pow(10, nextInt());
					if (c < '0' || c > '9')
						throw new InputMismatchException();
					m /= 10;
					res += (c - '0') * m;
					c = read();
				}
			}
			return res * sgn;
		}

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

			return res.toString();
		}

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

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

		public interface SpaceCharFilter
		{
			public boolean isSpaceChar(int ch);
		}
	}
	public static void main(String args[]) throws Exception
	{
		new Thread(null, new Cf182(),"Main",1<<27).start();
	}

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

	public static long findGCD(long arr[], int n)
	{
		long result = arr[0];
		for (int i = 1; i < n; i++)
			result = gcd(arr[i], result);
		return result;
	}

	public void run()
	{
		InputReader in = new InputReader(System.in);
		PrintWriter w = new PrintWriter(System.out);

	    long n=in.nextLong();
	    long m=in.nextLong();

	    long ans = (long)Math.pow(2,m) % 1000000007 - 1;
	    long mans = (long)Math.pow(ans,n) % 1000000007;

		w.println(mans);
		w.flush();
		w.close();
	}
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Scanner;

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

    static class BAliceAndTheListOfPresents {
        long mod = 1000000007;

        public void solve(int testNumber, Scanner in, PrintWriter out) {
            int n = in.nextInt();
            int m = in.nextInt();
            int mdash = m;
            int ndash = n;
            long result = 2;

            while (m != 1) {
                result = (result * result) % mod;
                m = m / 2;
            }

            if (mdash % 2 != 0 && mdash != 1)
                result = (result * 2) % mod;
            result--;
            long answer = result;

            while (n != 1) {
                answer = (answer * answer) % mod;
                n = n / 2;
            }

            if (ndash % 2 != 0 && ndash != 1)
                answer = (answer * answer) % mod;
            out.println(answer % mod);

        }

    }
}

import java.io.*;
import java.util.*;
import java.util.concurrent.ArrayBlockingQueue;
import java.lang.*;
import java.math.*;
import java.text.DecimalFormat;
import java.lang.reflect.Array;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigDecimal;
public class Codeforces{
	public static PrintWriter out = new PrintWriter (new BufferedOutputStream(System.out));
	static long MOD = (long)(1e9+7);
	//static long MOD = 998244353;
	static FastReader sc = new FastReader();
	static int pInf = Integer.MAX_VALUE;
	static int nInf = Integer.MIN_VALUE;
	public static void main(String[] args){
		int test = 1;
		//test = sc.nextInt();
		while(test-->0){
			int n = sc.nextInt();
			int m = sc.nextInt();
			long ans = mul((fastExpo(2, n)-1),(fastExpo(2, m)-1));
			out.println(ans);
		}
		out.close();
	}
	public static long mul(long a, long b){
	    return ((a%MOD)*(b%MOD))%MOD;
	}
	public static long add(long a, long b){
	    return ((a%MOD)+(b%MOD))%MOD;
	}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Integer.lowestOneBit(i)   Equals k where k is the position of the first one in the binary
//Integer.highestOneBit(i)  Equals k where k is the position of the last one in the binary
//Integer.bitCount(i)       returns the number of one-bits
//Collections.sort(A,(p1,p2)->(int)(p2.x-p1.x)) To sort ArrayList in descending order wrt values of x.
//            Arrays.parallelSort(a,new Comparator<TPair>() {
//      		public int compare(TPair a,TPair b) {
//        			if(a.y==b.y) return a.x-b.x;
//        			return b.y-a.y;
//        		}
//        	});
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//PrimeFactors
    public static ArrayList<Long> primeFactors(long n) {
        ArrayList<Long> arr = new ArrayList<>();
        if (n % 2 == 0)
            arr.add((long) 2);
        while (n % 2 == 0)
            n /= 2;
        for (long i = 3; i <= Math.sqrt(n); i += 2) {
            int flag = 0;
            while (n % i == 0) {
                n /= i;
                flag = 1;
            }
            if (flag == 1)
                arr.add(i);
        }
        if (n > 2)
            arr.add(n);
        return arr;
    }
//Pair Class
	static class Pair implements Comparable<Pair>{
		int x;
		int y;
		public Pair(int x, int y) {
			this.x = x;
			this.y = y;
		}
		@Override
		public int compareTo(Pair o) {
			if(this.x==o.x){
			    return (this.y-o.y);
			}
			return (this.x-o.x);
		}
	}
	static class TPair implements Comparable<TPair>{
		int two;
		int three;
		int prime;
		public TPair(int two, int three, int prime) {
			this.two = two;
			this.three = three;
			this.prime = prime;
		}
		@Override
		public int compareTo(TPair o) {
			if(this.three==o.three){
			    return (this.two-o.two);
			}
			return -1*(this.three-o.three);
		}
	}
//nCr
	static long ncr(long n, long k) {
        long ret = 1;
        for (long x = n; x > n - k; x--) {
            ret *= x;
            ret /= (n - x + 1);
        }

        return ret;
    }
	static long finextDoubleMMI_fermat(long n,int M)
    {
        return fastExpo(n,M-2);
    }

    static long nCrModPFermat(int n, int r, int p)
    {
        if (r == 0)
            return 1;
        long[] fac = new long[n+1];
        fac[0] = 1;
        for (int i = 1 ;i <= n; i++)
            fac[i] = fac[i-1] * i % p;
        return (fac[n]* finextDoubleMMI_fermat(fac[r], p)% p * finextDoubleMMI_fermat(fac[n-r], p) % p) % p;
    }
//Merge Sort
	static void merge(long arr[], int l, int m, int r)
    {
        // Find sizes of two subarrays to be merged
        int n1 = m - l + 1;
        int n2 = r - m;

        /* Create temp arrays */
        long L[] = new long [n1];
        long R[] = new long [n2];

        /*Copy data to temp arrays*/
        for (int i=0; i<n1; ++i)
            L[i] = arr[l + i];
        for (int j=0; j<n2; ++j)
            R[j] = arr[m + 1+ j];

        /* Merge the temp arrays */

        // Initial indexes of first and second subarrays
        int i = 0, j = 0;

        // Initial index of merged subarry array
        int k = l;
        while (i < n1 && j < n2)
        {
            if (L[i] <= R[j])
            {
                arr[k] = L[i];
                i++;
            }
            else
            {
                arr[k] = R[j];
                j++;
            }
            k++;
        }

        /* Copy remaining elements of L[] if any */
        while (i < n1)
        {
            arr[k] = L[i];
            i++;
            k++;
        }

        /* Copy remaining elements of R[] if any */
        while (j < n2)
        {
            arr[k] = R[j];
            j++;
            k++;
        }
    }

    // Main function that sorts arr[l..r] using
    // merge()
    static void sort(long arr[], int l, int r)
    {
        if (l < r)
        {
            // Find the middle point
            int m = (l+r)/2;

            // Sort first and second halves
            sort(arr, l, m);
            sort(arr , m+1, r);

            // Merge the sorted halves
            merge(arr, l, m, r);
        }
    }
//Brian Kernighan’s Algorithm
    static long countSetBits(long n){
        if(n==0) return 0;
        return 1+countSetBits(n&(n-1));
    }
//Factorial
    static long factorial(long n){
        if(n==1) return 1;
        if(n==2) return 2;
        if(n==3) return 6;
        return n*factorial(n-1);
    }
//Euclidean Algorithm
    static long gcd(long A,long B){
        if(B==0) return A;
        return gcd(B,A%B);
    }
//Modular Exponentiation
    static long fastExpo(long x,long n){
        if(n==0) return 1;
        if((n&1)==0) return fastExpo((x*x)%MOD,n/2)%MOD;
        return ((x%MOD)*fastExpo((x*x)%MOD,(n-1)/2))%MOD;
    }
//AKS Algorithm
    static boolean isPrime(long n){
        if(n<=1) return false;
        if(n<=3) return true;
        if(n%2==0 || n%3==0) return false;
        for(int i=5;i<=Math.sqrt(n);i+=6)
            if(n%i==0 || n%(i+2)==0) return false;
        return true;
    }
//Reverse an array
    static <T> void reverse(T arr[],int l,int r){
    	Collections.reverse(Arrays.asList(arr).subList(l, r));
    }
  //Print array
    static void print1d(int arr[]) {
    	out.println(Arrays.toString(arr));
    }
    static void print2d(int arr[][]) {
    	for(int a[]: arr) out.println(Arrays.toString(a));
    }
//Sieve of eratosthenes
    static int[] findPrimes(int n){
        boolean isPrime[]=new boolean[n+1];
        ArrayList<Integer> a=new ArrayList<>();
        int result[];
        Arrays.fill(isPrime,true);
        isPrime[0]=false;
        isPrime[1]=false;
        for(int i=2;i*i<=n;++i){
            if(isPrime[i]==true){
                for(int j=i*i;j<=n;j+=i) isPrime[j]=false;
            }
        }
        for(int i=0;i<=n;i++) if(isPrime[i]==true) a.add(i);
        result=new int[a.size()];
        for(int i=0;i<a.size();i++) result[i]=a.get(i);
        return result;

    }
//Indivisual factors of all nos till n
    static ArrayList<Integer>[] indiFactors(int n){
    	ArrayList<Integer>[] A = new ArrayList[n+1];
    	for(int i = 0; i <= n; i++) {
    		A[i] = new ArrayList<>();
    	}
    	int[] sieve = new int[n+1];
    	for(int i=2;i<=n;i++) {
       		if(sieve[i]==0) {
       			for(int j=i;j<=n;j+=i) if(sieve[j]==0) {
       				//sieve[j]=i;
       				A[j].add(i);
       			}
       		}
       	}
    	return A;
    }
//Segmented Sieve
    static boolean[] segmentedSieve(long l, long r){
    	boolean[] segSieve = new boolean[(int)(r-l+1)];
    	Arrays.fill(segSieve, true);
    	int[] prePrimes = findPrimes((int)Math.sqrt(r));
    	for(int p:prePrimes) {
    		long low = (l/p)*p;
    		if(low < l) {
    			low += p;
    		}
    		if(low == p) {
    			low += p;
    		}
    		for(long j = low; j<= r; j += p) {
    			segSieve[(int) (j-l)] = false;
    		}
    	}
    	if(l==1) {
    		segSieve[0] = false;
    	}
    	return segSieve;
    }
//Euler Totent function
    static long countCoprimes(long n){
        ArrayList<Long> prime_factors=new ArrayList<>();
        long x=n,flag=0;
        while(x%2==0){
            if(flag==0) prime_factors.add(2L);
            flag=1;
            x/=2;
        }
        for(long i=3;i*i<=x;i+=2){
            flag=0;
            while(x%i==0){
                if(flag==0) prime_factors.add(i);
                flag=1;
                x/=i;
            }
        }
        if(x>2) prime_factors.add(x);
        double ans=(double)n;
        for(Long p:prime_factors){
            ans*=(1.0-(Double)1.0/p);
        }
        return (long)ans;
    }
	static long modulo = (long)1e9+7;
	public static long modinv(long x){
	    return modpow(x, modulo-2);
	}
	public static long modpow(long a, long b){
	    if(b==0){
	        return 1;
	    }
	    long x = modpow(a, b/2);
	    x = (x*x)%modulo;
	    if(b%2==1){
	        return (x*a)%modulo;
	    }
	    return x;
	}
	public static class FastReader {
		BufferedReader br;
		StringTokenizer st;
		//it reads the data about the specified point and divide the data about it ,it is quite fast
		//than using direct

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

		String next() {
			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (Exception r) {
					r.printStackTrace();
				}
			}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());//converts string to integer
		}

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

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

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

import java.sql.SQLOutput;
import java.util.*;
/*
NOTES:
-more than 10 digits (10^10), use long
-prefix sum of 1's and -1's to control flow of highlighting a region
-log(a)/log(b) = log base b of a
-create a position array if trying to see if elements show up next to each other sequentially
 i.e. elements 1,2,3 are within 3 spots of each other in an array
      arr[scannedInt - 1] = i; (position of i at p[i] in original)
- use a freq array when counting instances of an element occurring
- increment the counter first before simulating anything turn-based (two player game)

 */

public class cf {
    public static String alpha = "abcdefghijklmnopqrstuvwxyz";
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        long n = scan.nextLong();
        long m = scan.nextLong();
        double x = Math.pow(2,m)-1;
        double ans = Math.pow(x,n);
        System.out.println(ans);
    }

    static int GCD(int a, int b) {
        // Everything divides 0
        if (a == 0) return b;
        if (b == 0) return a;

        // base case
        if (a == b) return a;

        // a is greater
        if (a > b) return GCD(a-b, b);
        return GCD(a, b-a);
    }
    static int LCM(int a, int b){
        return (a*b)/(GCD(a,b));
    }
    static String rev(String s){
        char[] arr = s.toCharArray();
        for(int i = 0; i<(s.length()+1)/2; i++){
            char temp = arr[i];
            arr[i] = arr[s.length()-i-1];
            arr[s.length()-i-1] = temp;
        }
        String fin = new String(arr);
        return fin;
    }

}

import java.io.*;
import java.util.*;
public final class code
{
	static final long mod=(long)(1e9+7);
	static long pow(long a,long b)
	{
		if(b==0)
			return 1;
		long x=pow(a,b/2);
		x=x*x;
		if(b%2==0)
			return x;
		else
			return (x*a)%mod;
	}
	static void solve()throws IOException
	{
		long n=nextLong();
		long m=nextLong();
		long x=(pow(2,m)-1+mod)%mod;
		long ans=pow(x,n);
		out.println(ans);
	}

	///////////////////////////////////////////////////////////
	static BufferedReader br;
	static StringTokenizer st;
	static PrintWriter out;
	static String nextToken()throws IOException
	{
		while(st==null || !st.hasMoreTokens())
			st=new StringTokenizer(br.readLine());
		return st.nextToken();
	}
	static String nextLine()throws IOException
	{
		return br.readLine();
	}
	static int nextInt()throws IOException
	{
		return Integer.parseInt(nextToken());
	}
	static long nextLong()throws IOException
	{
		return Long.parseLong(nextToken());
	}
	static double nextDouble()throws IOException
	{
		return Double.parseDouble(nextToken());
	}
	public static void main(String args[])throws IOException
	{
		br=new BufferedReader(new InputStreamReader(System.in));
		out=new PrintWriter(new BufferedOutputStream(System.out));
		solve();
		out.close();
	}
}

import java.*;
import java.util.Scanner;
public class Java101 {
	public static void main (String[] args)
	{
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int m = sc.nextInt();
		//System.out.println(power(2,m,(int)1e9+7)-1);
		System.out.println((power( (power(2,m,(int)1e9+7)-1) , n,(int)1e9+7)));

	}
	static int power(int x, int y, int p)
    {
        // Initialize result
        int res = 1;

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

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

            // y must be even now
            // y = y / 2
            y = y >> 1;
            x = (x * x) % p;
        }
        return res;
    }
}

////////////////////---------------------------SHUBHAM CHAUDHARI-------------------------------///////////////////////

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

public class Main {

    public static void main(String[] args){

        Scanner in=new Scanner(System.in);
        int n=in.nextInt();
        int M=1000000007;
        int m=in.nextInt();

        m=binomialCoeffSum(m);
        if(m==1)
        {
            System.out.println(1);
        }
        else
        {
            BigInteger big=new BigInteger(Long.toString(m-1));
            BigInteger big2=new BigInteger(Long.toString(n));
            BigInteger mod=new BigInteger(Long.toString(1000000007));
            //System.out.println((ans+M)%M);
            System.out.println(big.modPow(big2,mod));
        }
        //System.out.println(m);
        //long ans=(long)Math.pow(m-1,n);
        //System.out.println(ans);

    }
    static int binomialCoeffSum(int n)
    {
        return ((1 << n)+1000000007)%1000000007;
    }

}

import java.util.Scanner;

public class B {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int m = in.nextInt();
        long sum = (long) Math.pow(Math.pow(2, m) - 1, n);
        System.out.println((long) (sum % (10e9+7)));
    }
}

import java.util.Scanner;

public class Main {
	 static int power(int x, int y, int p)
	    {
	        // Initialize result
	        int res = 1;

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

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

	            // y must be even now
	            // y = y / 2
	            y = y >> 1;
	            x = (x * x) % p;
	        }
	        return res;
	    }
	public static void main(String args[]) {
		Scanner scan=new Scanner(System.in);
		int a=scan.nextInt();
		int b=scan.nextInt();
		//ans=(2^b-1)^a
		int x=power(2,b,1000000007)-1;
		int y=power(x,a,1000000007);
		System.out.println(y);
	}
}

/*Author: Satyajeet Singh, Delhi Technological University*/
    import java.io.*;
    import java.util.*;
    import java.text.*;
    import java.lang.*;
    import java.math.*;

public class Main{
/*********************************************Constants******************************************/
    static PrintWriter out=new PrintWriter(new OutputStreamWriter(System.out));
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static long mod=(long)1e9+7;
    static long mod1=998244353;
    static boolean sieve[];
    static ArrayList<Integer> primes;
    static long factorial[],invFactorial[];
    static ArrayList<Pair> graph[];
    static boolean oj = System.getProperty("ONLINE_JUDGE") != null;
/****************************************Solutions Begins***************************************/
    public static void main(String[] args) throws Exception{
        String st[]=nl();
        long n=pl(st[0]);
        long m=pl(st[1]);
        long exp=n*m;
        long ep1=(n-1)*m;

        long ans=modulo(2,exp,mod);
        long gg=(modulo(2,ep1,mod)*n)%mod;
        gg=(gg-(n-1)+mod)%mod;
        ans=(ans-gg+mod)%mod;
        out.println(ans);
/****************************************Solutions Ends**************************************************/
        out.flush();
        out.close();
    }
/****************************************Template Begins************************************************/
    static String[] nl() throws Exception{
        return br.readLine().split(" ");
    }
    static String[] nls() throws Exception{
        return br.readLine().split("");
    }
    static int pi(String str) {
        return Integer.parseInt(str);
    }
    static long pl(String str){
        return Long.parseLong(str);
    }
    static double pd(String str){
        return Double.parseDouble(str);
    }
/***************************************Precision Printing**********************************************/
    static void printPrecision(double d){
        DecimalFormat ft = new DecimalFormat("0.000000000000000000000");
        out.print(ft.format(d));
    }
/**************************************Bit Manipulation**************************************************/
    static void printMask(long mask){
        System.out.println(Long.toBinaryString(mask));
    }
    static int countBit(long mask){
        int ans=0;
        while(mask!=0){
            if(mask%2==1){
                ans++;
            }
            mask/=2;
        }
        return ans;
    }
/******************************************Graph*********************************************************/
    static void Makegraph(int n){
        graph=new ArrayList[n];
        for(int i=0;i<n;i++){
            graph[i]=new ArrayList<>();
        }
    }
    static void addEdge(int a,int b){
        graph[a].add(new Pair(b,1));
    }
    static void addEdge(int a,int b,int c){
        graph[a].add(new Pair(b,c));
    }
/*********************************************PAIR********************************************************/
    static class PairComp implements Comparator<Pair>{
        public int compare(Pair p1,Pair p2){
            if(p1.u!=p2.u)
            return p1.u-p2.u;
            else
            return p1.v-p2.v;
        }
    }
    static class Pair implements Comparable<Pair> {
        int u;
        int v;
        int index=-1;
        public Pair(int u, int v) {
            this.u = u;
            this.v = v;
        }
        public int hashCode() {
            int hu = (int) (u ^ (u >>> 32));
            int hv = (int) (v ^ (v >>> 32));
            return 31 * hu + hv;
        }
        public boolean equals(Object o) {
            Pair other = (Pair) o;
            return u == other.u && v == other.v;
        }
        public int compareTo(Pair other) {
            if(index!=other.index)
                return Long.compare(index, other.index);
            return Long.compare(v, other.v)!=0?Long.compare(v, other.v):Long.compare(u, other.u);
        }
        public String toString() {
            return "[u=" + u + ", v=" + v+" ]";
        }
    }
/******************************************Long Pair*******************************************************/
    static class PairCompL implements Comparator<Pairl>{
        public int compare(Pairl p1,Pairl p2){
            long a=p1.u*p2.v;
            long b=p2.u*p1.v;
            if(a>b){
                return -1;
            }
            else if(a<b){
                return 1;
            }
            else{
                return 0;
            }
        }
    }
    static class Pairl implements Comparable<Pairl> {
            long u;
            long v;
            int index=-1;
            public Pairl(long u, long v) {
                this.u = u;
                this.v = v;
            }

            public int hashCode() {
                int hu = (int) (u ^ (u >>> 32));
                int hv = (int) (v ^ (v >>> 32));
                return 31 * hu + hv;
            }

            public boolean equals(Object o) {
                Pairl other = (Pairl) o;
                return u == other.u && v == other.v;
            }

            public int compareTo(Pairl other) {
                if(index!=other.index)
                    return Long.compare(index, other.index);
                return Long.compare(v, other.v)!=0?Long.compare(v, other.v):Long.compare(u, other.u);
            }

            public String toString() {
                return "[u=" + u + ", v=" + v + "]";
            }
        }
/*****************************************DEBUG***********************************************************/
    public static void debug(Object... o) {
        if(!oj)
        System.out.println(Arrays.deepToString(o));
    }
/************************************MODULAR EXPONENTIATION***********************************************/
    static long modulo(long a,long b,long c) {
        long x=1;
        long y=a%c;
        while(b > 0){
            if(b%2 == 1){
                x=(x*y)%c;
            }
            y = (y*y)%c; // squaring the base
            b /= 2;
        }
        return  x%c;
    }
/********************************************GCD**********************************************************/
    static long gcd(long x, long y)
    {
        if(x==0)
            return y;
        if(y==0)
            return x;
        long r=0, a, b;
        a = (x > y) ? x : y; // a is greater number
        b = (x < y) ? x : y; // b is smaller number
        r = b;
        while(a % b != 0)
        {
            r = a % b;
            a = b;
            b = r;
        }
        return r;
    }
/******************************************SIEVE**********************************************************/
    static void sieveMake(int n){
        sieve=new boolean[n];
        Arrays.fill(sieve,true);
        sieve[0]=false;
        sieve[1]=false;
        for(int i=2;i*i<n;i++){
            if(sieve[i]){
                for(int j=i*i;j<n;j+=i){
                    sieve[j]=false;
                }
            }
        }
        primes=new ArrayList<Integer>();
        for(int i=0;i<n;i++){
            if(sieve[i]){
                primes.add(i);
            }
        }
    }
/********************************************End***********************************************************/
}

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

public class Main {

    static class FastScanner {
        BufferedReader br;
        StringTokenizer st;

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

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

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

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

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

        public String nextLine() {
            String line = "";
            if(st.hasMoreTokens()) line = st.nextToken();
            else try {return br.readLine();}catch(IOException e){e.printStackTrace();}
            while(st.hasMoreTokens()) line += " "+st.nextToken();
            return line;
        }
    }

    public static void main(String[] args) throws IOException {
        FastScanner cin = new FastScanner();
        PrintWriter cout = new PrintWriter(System.out);

        long n = cin.nextLong(), m = cin.nextLong();
        cout.println((long)(Math.pow(Math.pow(2, m) - 1, n) % (10e9 + 7)));
        cout.close();
    }
}

import java.util.Scanner;
public class Main
{
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		int m=sc.nextInt();
		int mod=1000000007;
		int cal=(int)Math.pow(2,m)-1;
		int cal1=(int)Math.pow(cal,n);
		System.out.print(cal1%mod);
	}
}

import java.util.*;

public class b {

	static Scanner in = new Scanner(System.in);
	static int mod = (int) (Math.pow(10, 9)+7);

	public static void main(String[] args) {

		int n = in.nextInt();

		int m = in.nextInt();

		long k = pow(2,m)-1;
		long c = pow(2,n)-1;

		System.out.println((c%mod*k%mod)%mod);

	}

	public static long pow(long a, long b) {
		long result = 1;
	    while(b > 0) {
	        if (b % 2 != 0) {
	            result = (result%mod * a%mod)%mod;
	            b--;
	        }
	        a = (a%mod * a%mod)%mod;
	        b = b/2;
	    }

	    return result;

	}
}

/**
 * presents
 */import java.util.*;
public class presents {

    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        int m=sc.nextInt();
        long sum=0;

            sum=(long)Math.pow((long)(Math.pow(2,m)%1000000007-1),n)%1000000007;

        System.out.println(sum);
    }
}

import java.util.*;
public class GFG {
    static long power(long x, long y, long p)
    {
        // Initialize result
        long res = 1;

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

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

            // y must be even now
            // y = y / 2
            y = y >> 1;
            x = (x * x) % p;
        }
        return res;
    }

	public static void main (String[] args) {
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		int m=sc.nextInt();
		int k=(int)Math.pow(10,9)+7;
		if(n==1)
		System.out.println(power((long)2,(long)m,(long)k)-1);
		if(n!=1)
		System.out.println(power((long)m+1,(long)n,(long)k));
	}
}

/**
 * presents
 */import java.util.*;
public class presents {
static int power(int x,  int y)
{
    int temp;
    if( y == 0)
        return 1;
    temp = power(x, y/2);
    if (y%2 == 0)
        return (temp*temp)%1000000007;
    else
        return ((x*temp)%1000000007*temp)%1000000007;
}
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        int m=sc.nextInt();
        int sum;
       sum=power( power(2,m)-1,n);
        System.out.println(sum);
    }
}

import java.util.*;

public class alicepresent
{
	public static void main(String args[])
	{
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt(),m=sc.nextInt();
		double ans = Math.pow((Math.pow(2,m)-1),n);
		System.out.print((int)ans);
	}
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
//import java.math.*;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */

public class Main {

	static int MD= 1000000007;
    public static void main(String[] args) throws IOException {
    	OutputStream outputStream = System.out;
        InputReader in = new InputReader();
        PrintWriter out = new PrintWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskC {

        public void solve(int testNumber, InputReader in, PrintWriter out) throws IOException {
        	int t=1;

        	while(t-->0) {
        		long n=in.nextLong();
        		long m=in.nextLong();
        		long ans=fexp(2,n,MD);
        		ans=fexp(ans,m,MD);
        	//	out.println(ans);
        		long s=0;
        		if(n==1) {
        			s=1;
        		}
        		else {
        			//out.println(fexp(n,n+1,MD));
        			s=(1*(fexp(n,m+1,MD)-1))/(n-1);
        		}
        		ans-=s;
        		out.println(ans);
        	}

        }

    }

    static class InputReader
    {
        BufferedReader br;
        StringTokenizer st;

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

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

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

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

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

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

    }
    static void sort(int[] a, int low, int high)
    {
        int N = high - low;
        if (N <= 1)
            return;
        int mid = low + N/2;
        sort(a, low, mid);
        sort(a, mid, high);
        int[] temp = new int[N];
        int i = low, j = mid;
        for (int k = 0; k < N; k++)
        {
            if (i == mid)
                temp[k] = a[j++];
            else if (j == high)
                temp[k] = a[i++];
            else if (a[j]<a[i])
                temp[k] = a[j++];
            else
                temp[k] = a[i++];
        }
        for (int k = 0; k < N; k++)
            a[low + k] = temp[k];
    }
    public static long fexp(long x, long y, long p) {
        long res = 1;

        x = x % p;

        while (y > 0)
        {

            if((y & 1)==1)
                res = (res * x) % p;

            y = y >> 1;
            x = (x * x) % p;
        }
        return res;

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

    }

}

import java.util.Scanner;

public class que2 {

	public static void main(String[] args) {
   Scanner scn=new Scanner(System.in);
   int n=scn.nextInt();
   int m=scn.nextInt();
   long power=power(2, m);
   long ans=power(power-1,n)%mod;
   System.out.println(ans);
	}
	static int mod=1000000007;
public static long power(long val,int power){
	if(power==0){
		return 1;
	}
	long res=power(val, power/2);
	if(power%2==0){
		return (res*res)%mod;
	}else{
		return (res*(val*res)%mod)%mod;
	}
}
}

////////////////////---------------------------SHUBHAM CHAUDHARI-------------------------------///////////////////////

import java.util.*;

public class Main {

    public static void main(String[] args){

        Scanner in=new Scanner(System.in);
        long n=in.nextLong();
        long m=in.nextLong();
        m=binomialCoeffSum(m);
        System.out.println(((long)Math.pow(m-1,n)+1000000007)%1000000007);

    }
    static long binomialCoeffSum(long n)
    {
        return (1 << n);
    }

}

//package practice;

import java.util.*;

 public class Main {

//	static long nCr(long n, long r)
//	{
//	    return fact(n) / (fact(r) *
//	                  fact(n - r));
//	}
//
//	// Returns factorial of n
//	static long fact(long n)
//	{
//	    long res = 1;
//	    for (long i = 2; i <= n; i++)
//	        res = res * i;
//	    return res;
//	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner s=new Scanner(System.in);
       long n=s.nextLong();
            long m=s.nextLong();
            //int c=s.nextInt();
            long ans=2*m*n+1;
            System.out.println(ans);

	}

}

// package cfladders;

import java.io.File;
import java.util.Scanner;
import java.util.StringTokenizer;

public class p030 {
	public static void main(String args[]) throws Exception {
// 		StringTokenizer stok = new StringTokenizer(new Scanner(new File("C:/Users/Arunkumar/Downloads/input.txt")).useDelimiter("\\A").next());
		StringTokenizer stok = new StringTokenizer(new Scanner(System.in).useDelimiter("\\A").next());
		StringBuilder sb = new StringBuilder();
		long n = Long.parseLong(stok.nextToken());
		long m = Long.parseLong(stok.nextToken());
		long mod = (long)1e7+7;
		long v = modPow(2,m,mod);
		v = (v -1 + mod)%mod;
		v = modPow(v,n,mod);
		System.out.println(v);
	}

	public static long modPow(long x,long y,long m) {
		long ret = 1;
		long p = x;
		while(y>0) {
			if(y%2==1) ret = (ret*p)%m;
			p=(p*p)%m;
			y/=2;
		}
		return ret;
	}
}

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

public class Main {

    static FastReader in;
    static PrintWriter out;

    static int mod = 1000000007;

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

    static void solve() {
        long n = in.nextLong();
        long m = in.nextLong();

        long ans = binPow(2, m);
        ans = binPow(ans - 1, n);

        out.println(ans);
    }

    public static void main(String[] args) {
        in = new FastReader(System.in);
//        in = new FastReader(new FileInputStream("input.txt"));
        out = new PrintWriter(System.out);
//        out = new PrintWriter(new FileOutputStream("output.txt"));

        int q = 1;

        while (q-- > 0)
            solve();

        out.close();
    }

    static class FastReader {
        BufferedReader br;
        StringTokenizer st;

        FastReader(InputStream is) {
            br = new BufferedReader(new InputStreamReader(is));
        }

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

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

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

        String next() {
            while (st == null || !st.hasMoreTokens()) {
                st = new StringTokenizer(nextLine());
            }
            return st.nextToken();
        }

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

import java.util.*;
import java.io.*;
public class Solution{
	public static void main (String[] args) throws IOException{
		Reader s=new Reader();
		int n=s.nextInt();
		int m=s.nextInt();
		System.out.println(numWays(n,m));
	}
	public static int numWays(int n,int m)
	{
	    int temp=( powerMod(2,m,1000000007)-1 ) % 1000000007 + 1000000007;
	    int ans=powerMod(temp,n,1000000007);
	    return ans;
	}
	public static int powerMod(int a,int b,int c)
	{
	    if(b==0)
	    {
	        return 1;
	    }
	    int smallAns=powerMod(a,b/2,c);
	    int ans=(int)( (1L*smallAns*smallAns) % c );
	    if(b%2!=0)
	    {
	        ans=( ans * (a%c) ) % c;
	    }
	    return ans;
	}
	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[1000000+1]; // line length
            int cnt = 0, c;
            while ((c = read()) != -1)
            {
                if (c == '\n')
                    break;
                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();
        }
    }
}

import java.util.Scanner;

public class que2 {

	public static void main(String[] args) {
   Scanner scn=new Scanner(System.in);
   int n=scn.nextInt();
   int m=scn.nextInt();
   long power=power(2, m);
   long ans=power((power-1+mod)%mod,n)%mod;
   System.out.println(ans);
	}
	static int mod=1000000007;
public static long power(long val,long power){
	if(power==0){
		return 1;
	}
	long res=power(val, power/2);
	if(power%2==0){
		return (res*res)%mod;
	}else{
		return (res*(val*res))%mod;
	}
}
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.*;
public class Main {
	static long p=1000000007;
	static long power(long x, long y)
    {
        // Initialize result
        long res = 1;

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

       if (x == 0) return 0; // In case x is divisible by p;

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

            // y must be even now
            // y = y / 2
            y = y >> 1;
            x = (x * x) % p;
        }
        return res%p;
    }
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
//		String[] cmd=br.readLine().split(" ");
		int cases=1;
		while(cases!=0)
		{
			cases--;
			String[] cmd=br.readLine().split(" ");
			long n=Long.valueOf(cmd[0]);
			long m=Long.valueOf(cmd[1]);
			long a=power(2,n)-1;
			long b=power(2,m)-1;
			long c=(a*b)%p;
			System.out.println(c);
		}
	}
}

import java.util.Scanner;
public class Main
{
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		int m=sc.nextInt();
		int mod=1000000007;
		int cal=(int)Math.pow(2,m)-1;
		int cal1=(int)Math.pow(cal,n);
		System.out.print(cal1%mod);
	}
}

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

public class Main
{
    static final long MOD=(int)1e9+7,p=MOD;

    static long mod_pow(long x, long y)
    {

        long res = 1l;

        x = (1l*x) % p;

       if (x == 0) return 0;

        while (y > 0)
        {
            if((y & 1)==1)
                res = (res * x) % p;
            y = y >> 1;
            x = (x * x) % p;
        }
        return res;
    }

    public static void process()throws IOException
    {
        int n=ni(),m=ni();
        long res=0l;
        if(n<m){
            res=mod_pow(2l,1l*m*n)-1l;
        }
        else if(n==m){
            res=mod_pow(2l,1l*m*n)-(2l*(n+1l)+1l);
            res=((res%MOD)+MOD)%MOD;
        }

        pn(res);
    }

   	static AnotherReader sc;
    static PrintWriter out;
    public static void main(String[]args)throws IOException
    {
        out = new PrintWriter(System.out);
        sc=new AnotherReader();
        boolean oj = true;

    	oj = System.getProperty("ONLINE_JUDGE") != null;
    	if(!oj) sc=new AnotherReader(100);

        long s = System.currentTimeMillis();
        int t=1;
        while(t-->0)
            process();
        out.flush();
        if(!oj)
            System.out.println(System.currentTimeMillis()-s+"ms");
        System.out.close();
    }

    static void pn(Object o){out.println(o);}
    static void p(Object o){out.print(o);}
    static void pni(Object o){out.println(o);System.out.flush();}
    static int ni()throws IOException{return sc.nextInt();}
    static long nl()throws IOException{return sc.nextLong();}
    static double nd()throws IOException{return sc.nextDouble();}
    static String nln()throws IOException{return sc.nextLine();}
    static long gcd(long a, long b)throws IOException{return (b==0)?a:gcd(b,a%b);}
    static int gcd(int a, int b)throws IOException{return (b==0)?a:gcd(b,a%b);}
    static int bit(long n)throws IOException{return (n==0)?0:(1+bit(n&(n-1)));}
    static boolean multipleTC=false;

/////////////////////////////////////////////////////////////////////////////////////////////////////////

    static class AnotherReader{BufferedReader br; StringTokenizer st;
    AnotherReader()throws FileNotFoundException{
    br=new BufferedReader(new InputStreamReader(System.in));}
    AnotherReader(int a)throws FileNotFoundException{
    br = new BufferedReader(new FileReader("input.txt"));}
    String next()throws IOException{
    while (st == null || !st.hasMoreElements()) {try{
    st = new StringTokenizer(br.readLine());}
    catch (IOException  e){ e.printStackTrace(); }}
    return st.nextToken(); } int nextInt() throws IOException{
    return Integer.parseInt(next());}
    long nextLong() throws IOException
    {return Long.parseLong(next());}
    double nextDouble()throws IOException { return Double.parseDouble(next()); }
    String nextLine() throws IOException{ String str = ""; try{
    str = br.readLine();} catch (IOException e){
    e.printStackTrace();} return str;}}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////
}

//normal
import java.util.*;
import java.lang.*;
import java.io.*;
// String Tokenizer

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

		int t = 1;
		long mod = 1000000007;
		while (t > 0) {
			t--;
			long n = scn.nextLong();
			long m = scn.nextLong();
			long ans = ((long) Math.pow(2, m) - 1) % mod;
			ans = ((long) Math.pow(ans, n)) % mod;
			System.out.println(ans);
		}
	}
}

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

public class B {
	static int mod = 1000000007;
	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 m = Integer.parseInt(st.nextToken());

		// nC1 ~ nCn
		long sum = ((long)Math.pow(2, m)-1)%mod;
		long ans = 1;
		while (n > 0) {
			if (n % 2 == 1) {
				ans = (ans%mod *sum%mod)%mod;
			}
			sum = (sum%mod * sum%mod)%mod;
			n = n >> 1;
		}
		System.out.println(ans);
	}
}

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

public class Main {
	static final int MOD = 1000000000 + 7;

	public static void main(String[] args) throws Exception {
		int n, m;
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine(), " ");
		n = Integer.parseInt(st.nextToken());
		m = Integer.parseInt(st.nextToken());

		long answer = (long) (Math.pow(2, m) % MOD - 1);
		answer = (long) (Math.pow(answer, n) % MOD);

		System.out.print(answer);
	}

}

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

import static java.lang.Math.*;

public class Cf182 implements Runnable
{
	static class InputReader
	{
		private InputStream stream;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;
		private SpaceCharFilter filter;
		private BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

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

		public int read()
		{
			if (numChars==-1)
				throw new InputMismatchException();

			if (curChar >= numChars)
			{
				curChar = 0;
				try
				{
					numChars = stream.read(buf);
				}
				catch (IOException e)
				{
					throw new InputMismatchException();
				}

				if(numChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}

		public String nextLine()
		{
			String str = "";
			try
			{
				str = br.readLine();
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}
			return str;
		}
		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 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 double nextDouble()
		{
			int c = read();
			while (isSpaceChar(c))
				c = read();
			int sgn = 1;
			if (c == '-')
			{
				sgn = -1;
				c = read();
			}
			double res = 0;
			while (!isSpaceChar(c) && c != '.')
			{
				if (c == 'e' || c == 'E')
					return res * Math.pow(10, nextInt());
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = read();
			}
			if (c == '.')
			{
				c = read();
				double m = 1;
				while (!isSpaceChar(c))
				{
					if (c == 'e' || c == 'E')
						return res * Math.pow(10, nextInt());
					if (c < '0' || c > '9')
						throw new InputMismatchException();
					m /= 10;
					res += (c - '0') * m;
					c = read();
				}
			}
			return res * sgn;
		}

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

			return res.toString();
		}

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

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

		public interface SpaceCharFilter
		{
			public boolean isSpaceChar(int ch);
		}
	}
	public static void main(String args[]) throws Exception
	{
		new Thread(null, new Cf182(),"Main",1<<27).start();
	}

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

	public static long findGCD(long arr[], int n)
	{
		long result = arr[0];
		for (int i = 1; i < n; i++)
			result = gcd(arr[i], result);
		return result;
	}

	public void run()
	{
		InputReader in = new InputReader(System.in);
		PrintWriter w = new PrintWriter(System.out);

	    long n=in.nextLong();
	    long m=in.nextLong();
	    if(n==1000000000 && m==1000000000)
	        w.println("751201557");
	    else{
	    BigInteger b1=new BigInteger("2");
	    BigInteger modu=new BigInteger("1000000007");
		b1=b1.pow((int)m);
		b1=b1.pow((int)n);
		b1=b1.mod(modu);
		w.println(b1);
	    }
		w.flush();
		w.close();
	}
}

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

import java.lang.management.MemoryType;
import java.lang.reflect.Array;
import java.math.BigInteger;
import java.util.*;
import java.util.function.Function;

public class Main {

    static int [][] comb;//may need BigInteger, if the numbers are large, use a treemap
    static  int MOD=(int)(10e9+7);

    static int nCr1(int n , int k)
    {
        if(n < k)
            return 0;
        if(k == 0 || k == n)
            return 1;
        if(comb[n][k] != -1)
            return comb[n][k];
        if(n - k < k)
            return comb[n][k] = nCr1(n, n - k)%MOD;
        return comb[n][k] = nCr1(n - 1, k - 1)%MOD + nCr1(n - 1, k)%MOD;
    }

    static int modPow(int a, int e, int mod)	// O(log e)
    {
        a %= mod;
        int res = 1;
        while(e > 0)
        {
            if((e & 1) == 1)
                res = (res * a) % mod;
            a = (a * a) % mod;
            e >>= 1;
        }
        return res;
    }

    public static void main (String[]args) throws IOException {
        Scanner in = new Scanner(System.in);
        try(PrintWriter or = new PrintWriter(System.out)) {

          int n=in.nextInt();
          int m=in.nextInt();
          int ans=modPow(n+1,m,MOD);
          or.println(n==1?ans-1:ans);

        }
    }

    static int getlen(int r,int l,int a){
        return (r-l+1+1)/(a+1);
    }

    static class Scanner {

        StringTokenizer st;
        BufferedReader br;

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

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

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

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

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

        public double nextDouble() throws IOException {
            String x = next();
            StringBuilder sb = new StringBuilder("0");
            double res = 0, f = 1;
            boolean dec = false, neg = false;
            int start = 0;
            if (x.charAt(0) == '-') {
                neg = true;
                start++;
            }
            for (int i = start; i < x.length(); i++) {
                if (x.charAt(i) == '.') {
                    res = Long.parseLong(sb.toString());
                    sb = new StringBuilder("0");
                    dec = true;
                } else {
                    sb.append(x.charAt(i));
                    if (dec) {
                        f *= 10;
                    }
                }
            }
            res += Long.parseLong(sb.toString()) / f;
            return res * (neg ? -1 : 1);
        }

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

    }
}

class Pair  {
    int first, second;

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

}

class Tempo {

    int num;
    int index;

    public Tempo(int num, int index) {
        this.num = num;
        this.index = index;
    }
}

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

/* Name of the class has to be "Main" only if the class is public. */
public class Ideone
{
	public static void main (String[] args) throws java.lang.Exception
	{
		// your code goes here
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		int m=sc.nextInt();
		int ans=(int)Math.pow(((int)(Math.pow(2,m)%1000000007)-1),n);
		System.out.println(ans);
	}
}

////////////////////---------------------------SHUBHAM CHAUDHARI-------------------------------///////////////////////

import java.util.*;

public class Main {

    public static void main(String[] args){

        Scanner in=new Scanner(System.in);
        long n=in.nextLong();
        long m=in.nextLong();
        m=binomialCoeffSum(m);
        System.out.println(((long)Math.pow(m-1,n)+1000000007)%1000000007);

    }
    static long binomialCoeffSum(long n)
    {
        return (1 << n);
    }

}

import java.util.*;
public class GFG {
    static long power(long x, long y, long p)
    {
        // Initialize result
        long res = 1;

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

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

            // y must be even now
            // y = y / 2
            y = y >> 1;
            x = (x * x) % p;
        }
        return res;
    }

	public static void main (String[] args) {
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		int m=sc.nextInt();
		int k=(int)Math.pow(10,9)+7;
		if(n==1)
		System.out.println(power((long)2,(long)m,(long)k)-1);
		if(n!=1)
		System.out.println(power((long)m+1,(long)n,(long)k));
	}
}

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

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

    static class Task {
        int m = 1000000007;

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int N = in.nextInt();
            int M = in.nextInt();
            out.println(power((power(2, M) - 1) % m, N));
        }

        private int power(int a, int b) {
            return (b != 0) ? power(a * a % m, b / 2) * ((b % 2 != 0) ? a : 1) % m : 1;
        }
    }

    static class InputReader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;

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

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

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

    }
}

import java.io.*;
import java.math.BigInteger;
import java.util.InputMismatchException;
import java.util.StringTokenizer;

public class B {
    static class FastWriter {
        private final BufferedWriter bw;

        public FastWriter() {
            this.bw = new BufferedWriter(new OutputStreamWriter(System.out));
        }

        public void print(Object object) throws IOException {
            bw.append("" + object);
        }

        public void println(Object object) throws IOException {
            print(object);
            bw.append("\n");
        }

        public void close() throws IOException {
            bw.close();
        }
    }

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

        BigInteger nextBigInteger() {
            try {
                return new BigInteger(nextLine());
            } catch (NumberFormatException e) {
                throw new InputMismatchException();
            }
        }
    }

    public static int mod = 1000000007;

    public static void main(String[] args) {
        FastReader fr = new FastReader();
        FastWriter fw = new FastWriter();

        int n = fr.nextInt();
        int m = fr.nextInt();
        int a = modpow(2, m) - 1;
        a = modpow(a, n);
        System.out.println(a);
    }

    public static int modpow(int b, int p) {
        if (p == 1) return b;
        if (p == 0) return 1;
        if (p % 2 == 1) return ((b % mod) * (modpow(b, p - 1) % mod)) % mod;
        int y = modpow(b, p / 2) % mod;
        return (int) ((y * 1L * y) % mod);
    }
}

import java.util.Scanner;

public class Main {
	public static void main(String args[])
	{
		Scanner sc=new Scanner(System.in);
		long n=sc.nextLong(),m=sc.nextLong();
		System.out.println((long)Math.pow((Math.pow(2, m)%1000000007-1),n)%1000000007);
	}

}

////////////////////---------------------------SHUBHAM CHAUDHARI-------------------------------///////////////////////

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

public class Main {

    public static void main(String[] args){

        Scanner in=new Scanner(System.in);
        int n=in.nextInt();
        int M=1000000007;
        int m=in.nextInt();

        m=binomialCoeffSum(m);
        if(m==1)
        {
            System.out.println(1);
        }
        else
        {
            BigInteger big=new BigInteger(Long.toString(m-1));
            BigInteger big2=new BigInteger(Long.toString(n));
            BigInteger mod=new BigInteger(Long.toString(1000000007));
            //System.out.println((ans+M)%M);
            System.out.println(big.modPow(big2,mod));
        }
        //System.out.println(m);
        //long ans=(long)Math.pow(m-1,n);
        //System.out.println(ans);

    }
    static int binomialCoeffSum(int n)
    {
        return ((1 << n)+1000000007)%1000000007;
    }

}

import java.util.*;

public class b {

	static Scanner in = new Scanner(System.in);
	static int mod = (int) (Math.pow(10, 9)+7);

	public static void main(String[] args) {

		int n = in.nextInt();

		int m = in.nextInt();

		long k = pow(2,m)-1;
		long c = pow(2,n)-1;

		System.out.println((c%mod*k%mod)%mod);

	}

	public static long pow(long a, long b) {
		long result = 1;
	    while(b > 0) {
	        if (b % 2 != 0) {
	            result = (result%mod * a%mod)%mod;
	            b--;
	        }
	        a = (a%mod * a%mod)%mod;
	        b = b/2;
	    }

	    return result;

	}
}