You are given two integers n and m. Calculate the number of pairs of arrays (a, b) such that:

  * the length of both arrays is equal to m; 
  * each element of each array is an integer between 1 and n (inclusive); 
  * a_i ≤ b_i for any index i from 1 to m; 
  * array a is sorted in non-descending order; 
  * array b is sorted in non-ascending order. 



As the result can be very large, you should print it modulo 10^9+7.

Input

The only line contains two integers n and m (1 ≤ n ≤ 1000, 1 ≤ m ≤ 10).

Output

Print one integer – the number of arrays a and b satisfying the conditions described above modulo 10^9+7.

Examples

Input


2 2


Output


5


Input


10 1


Output


55


Input


723 9


Output


157557417

Note

In the first test there are 5 suitable arrays: 

  * a = [1, 1], b = [2, 2]; 
  * a = [1, 2], b = [2, 2]; 
  * a = [2, 2], b = [2, 2]; 
  * a = [1, 1], b = [2, 1]; 
  * a = [1, 1], b = [1, 1]. 
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.StringTokenizer;
/*
 * Java Input / Output Class using Buffered/ Input Straem
 * Created by @neelbhallabos
 * File Created at: 4/6/2021
 */
public class CF1312D {
	public static BufferedReader sc = new BufferedReader(new InputStreamReader(System.in));
	public static StringTokenizer st;
	public static PrintWriter pw = new PrintWriter(System.out);
	final static boolean debugmode = true;
	public static long STMOD = 1_000_000_007 ; // 10^9 + k
	
	public static void main(String[] args) throws IOException {
		int n = getInt(); 
		int m = getInt();
		long[][] dpmax = new long[n][m];
		long[][] dpmin = new long[n][m];
		for(int i = 0; i < n;i++) {
			dpmax[i][0] = 1;
			dpmin[i][0] = 1;
		}
		
		for(int ix = 1; ix < m; ix++) {
			long cmax = 0; 
			for(int i = 0; i < n; i++) {
				cmax += dpmax[i][ix-1];
				cmax %= STMOD;
				dpmax[i][ix] = cmax;
			}
			
			long cmin = 0;
			for(int i = n-1; i >= 0; i--) {
				cmin += dpmin[i][ix-1];
				cmin %= STMOD;
				dpmin[i][ix] = cmin;
			}
		}
		
		
		long cprod = 0;
		for(int amax = 0; amax < n; amax ++) {
			for(int amin = amax; amin<n;amin++) {
				//System.out.println(amax + " " + amin + " " + (m-1));
				cprod += dpmax[amax][m-1] * dpmin[amin][m-1];
				cprod %= STMOD;
				
			}
		}
		
		submit(cprod, true);
		
		
	}





	public static void setInputFile(String fn) throws IOException {
		sc = new BufferedReader(new FileReader(fn));
	}
 
	public static void setOutputFile(String fn) throws IOException {
		pw = new PrintWriter(new BufferedWriter(new FileWriter(fn)));
	}
 
	public static int GCD(int a, int b) {
		if (b == 0)
			return a;
		return GCD(b, a % b);
	}
 
	public static double log(int k, int v) {
		return Math.log(k) / Math.log(v);
	}
 
	public static long longpower(int a, int b) {
		long[] vals = new long[(int) (log(b, 2) + 2)];
		vals[0] = a;
		vals[1] = a * a;
		for (int i = 1; i < vals.length; i++) {
			vals[i] = vals[i - 1] * vals[i - 1];
		}
		long ans = 1;
		int cindex = 0;
		while (b != 0) {
			if (b % 2 == 1) {
				ans *= vals[cindex];
			}
			cindex += 1;
			b /= 2;
		}
		return ans;
 
	}
 
	public static void debug(String toPrint) {
		if (!debugmode) {
			return;
		}
		pw.println("[DEBUG]: " + toPrint);
	}
 
	public static void submit(int[] k, boolean close) {
		pw.println(Arrays.toString(k));
		if (close) {
			pw.close();
		}
	}
 
	public static void submit(int p, boolean close) {
		pw.println(Integer.toString(p));
		if (close) {
			pw.close();
		}
	}
 
	public static void submit(String k, boolean close) {
		pw.println(k);
		if (close) {
			pw.close();
		}
	}
 
	public static void submit(double u, boolean close) {
		pw.println(Double.toString(u));
		if (close) {
			pw.close();
		}
	}
 
	public static void submit(long lng, boolean close) {
		pw.println(Long.toString(lng));
		if (close) {
			pw.close();
		}
 
	}
 
	public static void submit() {
		pw.close();
	}
 
	public static int getInt() throws IOException {
		if (st != null && st.hasMoreTokens()) {
			return Integer.parseInt(st.nextToken());
		}
		st = new StringTokenizer(sc.readLine());
		return Integer.parseInt(st.nextToken());
	}
 
	public static long getLong() throws IOException {
		if (st != null && st.hasMoreTokens()) {
			return Long.parseLong(st.nextToken());
		}
		st = new StringTokenizer(sc.readLine());
		return Long.parseLong(st.nextToken());
	}
 
	public static double getDouble() throws IOException {
		if (st != null && st.hasMoreTokens()) {
			return Double.parseDouble(st.nextToken());
		}
		st = new StringTokenizer(sc.readLine());
		return Double.parseDouble(st.nextToken());
	}
 
	public static String getString() throws IOException {
		if (st != null && st.hasMoreTokens()) {
			return st.nextToken();
		}
		st = new StringTokenizer(sc.readLine());
		return st.nextToken();
	}
 
	public static String getLine() throws IOException {
		return sc.readLine();
	}
 
	public static int[][] readMatrix(int lines, int cols) throws IOException {
		int[][] matrr = new int[lines][cols];
		for (int i = 0; i < lines; i++) {
			for (int j = 0; j < cols; j++) {
				matrr[i][j] = getInt();
			}
		}
		return matrr;
	}
 
	public static int[] readArray(int lines) throws IOException {
		int[] ar = new int[lines];
		for (int i = 0; i < lines; i++)
			ar[i] = getInt();
		return ar;
	}
	
	static class Pair {
		int x;
		int occ;
		public Pair(int vx, int iocc) {
			this.x = vx;
			this.occ = iocc;
		}
		
		public Pair increment() {
			return new Pair(this.x, this.occ + 1);
		}
	}
 
}