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

public class A {

	static long dp[][][];
	static int R,C;
	static long mod = 1_000_000_007;
	public static void main(String[] args) {
		FS in = new FS();
		PrintWriter out = new PrintWriter(System.out);
		
		R = in.nextInt();
		C = in.nextInt();
		dp = new long[2][2][C];
		for(long a[][] : dp)
			for(long b[] : a)
				Arrays.fill(b, -1);
		
		long dubs = (2*go(0,1,1))%mod;
		
		long other = 2;
		for(int i = 1; i < R; i++) other = (other*2)%mod;
		long res = (dubs+other)%mod;
		out.println(res);
		out.close();
	}
	
	static long go(int b, int nd, int id) {
		if(id >= C) return nd == 1 ? 0 : 1;
		if(dp[b][nd][id] != -1) return dp[b][nd][id];
		long res = 0;
		if(b == 0) {
			// not bounded
			res += go(0, nd, id+1);
			res += go(1, 0, id+1);
		}
		else {
			// bounded
			res += go(0,nd,id+1);
		}
		return dp[b][nd][id] = res%mod;
	}

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