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

public class design_ab implements Runnable {

	final int MAXN = 1000;
	final int MAXM = 6;
	final int MOD = 1000000007;
	
	
	private void solve() throws IOException {
		int n = in.nextInt();
		assert 1 <= n && n <= MAXN;
		int m = in.nextInt();
		assert 1 <= m && m <= MAXM;
	
		for (int i = 0; i < m; ++i) {
			emask |= 1 << (2 * i);			
		}
		omask = emask << 1;
		mask = emask | omask;
		hbit = (mask + 1) >> 1;
		
		ArrayList<Integer> pl = new ArrayList<Integer>();
		HashMap<Integer, Integer> p2n = new HashMap<Integer, Integer>();
		for (int prof = 0; prof <= mask; ++prof) {
			if (((prof & 1) != 0) || ((prof & hbit) == 0)) continue;
			int t = prof & emask;
			t |= t >> 1;
			t |= t << 1;
			if ((prof & t) != t) continue;			
			t = ~prof & omask;
			t |= t >> 1;
			t |= t << 1;
			if ((~prof & t) != t) continue;
			p2n.put(prof, pl.size());
			pl.add(prof);
//			System.out.println(Integer.toBinaryString(prof));
		}
		
		boolean[][] g = new boolean[pl.size()][pl.size()];
		for (int i = 0; i < pl.size(); ++i) {
			for (int j = 0; j < pl.size(); ++j) {
//				if (i == 2) {
//					i += 0;
//				}
				int pi = pl.get(i);
				int pj = pl.get(j);
				
				int tpi = (pi & (pi >> 1) & (pi << 1)) << 1;
				if ((pj & tpi) != tpi) continue;
				
				int tpj = (~pj & (~pj >> 1) & (~pj << 1)) >> 1;
				int fpj = (pj & ~tpi) >> 1;
				if ((tpj | fpj) != ~pi) continue;
				
				g[i][j] = true;
			}
		}
		
		int[][] D = new int[2][pl.size()]; 
		D[0][p2n.get(mask ^ 1)] = 1;
		int c = 0;
		for (int i = 0; i < n + m - 1; ++i) {
			Arrays.fill(D[1 - c], 0);
			for (int j = 0; j < g.length; ++j) {
				for (int k = 0; k < g[j].length; ++k) {
					if (g[j][k]) {
						D[1 - c][k] += D[c][j];
						if (D[1 - c][k] >= MOD) {
							D[1 - c][k] -= MOD;
						}
					}
				}
			}
			c = 1 - c;
			if (i + 1 < m) {
				for (int j = 0; j < pl.size(); ++j) {
					int p = pl.get(j) >> (2 * (i + 1) + 1);
					if (((p + 1) & p) != 0) {
						D[c][j] = 0;
					}
				}
			}
			if (i + 1 >= n) {
				for (int j = 0; j < pl.size(); ++j) {
					int p = pl.get(j)  & ((1 << (2 * (i + 1 - n) + 1)) - 1);
					if (p != 0) {
						D[c][j] = 0;
					}
				}
			}
		}
		out.println(D[c][p2n.get(hbit)]);
	}
	
	int mask, emask, omask, hbit;
	
	
	SimpleScanner in;
	PrintWriter out;

	@Override
	public void run() {
		try {
			in = new SimpleScanner(new FileReader("design.in"));
			out = new PrintWriter("design.out");
			solve();
			out.close();
		} catch (Throwable e) {
			e.printStackTrace();
			System.exit(-1);
		}
	}

	public static void main(String[] args) {
		new Thread(new design_ab()).start();
	}

	class SimpleScanner extends BufferedReader {

		private StringTokenizer st;
		private boolean eof;

		public SimpleScanner(Reader a) {
			super(a);
		}

		String next() {
			while (st == null || !st.hasMoreElements()) {
				try {
					st = new StringTokenizer(readLine());
				} catch (Exception e) {
					eof = true;
					return "";
				}
			}
			return st.nextToken();
		}

		boolean seekEof() {
			String s = next();
			if ("".equals(s) && eof)
				return true;
			st = new StringTokenizer(s + " " + st.toString());
			return false;
		}

		private String cnv(String s) {
			if (s.length() == 0)
				return "0";
			return s;
		}

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

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

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