//Code by Lucida
#include<bits/stdtr1c++.h>
typedef long long int64;

namespace IO {
#ifdef OI
	const int IN=1e7;
	char in[IN],*ip=in,*ie=in;
	#define getchar() ( (ip==ie && (ie=(ip=in)+fread(in,1,IN,stdin),ip==ie))?EOF:*ip++ )
#endif
	struct Ist {
		template <class T> Ist &operator >>(T &x);
		template <class T> Ist &operator >>(T *x);
		operator bool() const {return feof(stdin);}
	}is;
	template <class T> Ist &Ist::operator >>(T &x) {
		static bool f;static char ch;
		for(f=0,ch=0;ch<'0' || '9'<ch;ch=getchar()) f|=ch=='-';
		for(x=0;'0'<=ch && ch<='9';ch=getchar()) (x*=10)+=ch-'0';
		x=f?-x:x;
		return *this;
	}
	template <class T> Ist &Ist::operator >>(T *x) {
		while(*x=getchar(),(*x==' ' || *x=='\r' || *x=='\n' || *x==EOF));
		x++;
		while(*x=getchar(),(*x!=' ' && *x!='\r' && *x!='\n' && *x!=EOF))
			x++;
		*x=0;
		return *this;
	}
	template <> Ist &Ist::operator >>(double &x) {
		scanf("%lf",&x);
		return *this;
	}
	template <> Ist &Ist::operator >>(char &x) {
		while(x=getchar(),x=='\n' || x=='\r' || x==' ');
		return *this;
	}
#ifdef OO
	const int OUT=1e7;
	char out[OUT],*op=out,*oe=out+OUT;
	#define flush() (fwrite(out,1,op-out,stdout))
	#define putchar(x) ((op==oe?(flush(),*op++):*op++)=(x) )
#endif
	struct Ost {
		char doubleFormat[10];
		Ost() {
			sprintf(doubleFormat,"%%lf");
		}
#ifdef OO
		~Ost() {
			flush();
		}
#endif
		void precision(const int &a) {
			sprintf(doubleFormat,"%%.%dlf",a);
		}
		template <class T> Ost &operator <<(T x);
		template <class T> Ost &operator <<(T *x);

	}os;
	template <class T> Ost &Ost::operator <<(T x) {
		if(!x)
			putchar('0');
		else {
			if(x<0) putchar('-'),x=-x;
			static char stack[30]={0};
			char *top=stack;
			for(;x;x/=10) *++top=x%10+'0';
			while(*top) putchar(*top--);
		}
		return *this;
	}
	template <class T> Ost &Ost::operator <<(T* x) {
		while(*x) putchar(*x++);
		return *this;
	}
	template <>	Ost &Ost::operator <<(double x) {
		printf(doubleFormat,x);
		return *this;
	}
	template <> Ost &Ost::operator <<(char x) {
		putchar(x);
		return *this;
	}
}

template <class T> inline bool chkmx(T &a,const T &b) {return a<b?a=b,1:0;}
template <class T> inline bool chkmn(T &a,const T &b) {return a>b?a=b,1:0;}
template <class T,class C> inline T &operator +=(T &a,const C &b) {return a=a+b;}
template <class T,class C> inline T &operator -=(T &a,const C &b) {return a=a-b;}
template <class T,class C> inline T &operator *=(T &a,const C &b) {return a=a*b;}
template <class T,class C> inline T &operator /=(T &a,const C &b) {return a=a/b;}

using IO::is;
using IO::os;

#define alloc(T,c) (T*)malloc((c)*sizeof(T))
#define pass void(0)
#define import using std::
#define array std::vector
#define NAMESPACE_BEGIN(X) namespace X {
#define NAMESPACE_END(X) }

const int MAXN=3e3+11,P=1e9+7;

int main() {
//	freopen("input","r",stdin);
	static int64 f[MAXN][MAXN][2];
	int n,m;
	is>>n>>m;
	for(int i=0;i<=n;++i) {
		f[0][i][i==0]=1;
	}
	for(int i=0;i<=m-1;++i) {
		for(int rc=0;rc<=n;++rc) {
			int bc=n-rc;
			for(int met=0;met<=1;++met) {
				if(rc) {
					//RR
					(f[i+1][rc-1][met || (rc==1)]+=f[i][rc][met])%=P;
					//RB
					(f[i+1][rc][met || (rc==1)]+=f[i][rc][met])%=P;
				}
				if(bc) {
					//BR
					(f[i+1][rc][met]+=f[i][rc][met])%=P;
					//BB
					(f[i+1][rc+1][met]+=f[i][rc][met])%=P;
				}
			}
		}
	}
	int64 Ans=0;
	for(int rc=0;rc<=n;++rc) {
		(Ans+=f[m][rc][1])%=P;
	}
	os<<Ans<<'\n';
	return 0;
}



Measured memory_bytes: 141568