Problem:
Score : 1800 points

Problem Statement

We have an N \times M grid. The square at the i-th row and j-th column will be denoted as (i,j).
Particularly, the top-left square will be denoted as (1,1), and the bottom-right square will be denoted as (N,M).
Takahashi painted some of the squares (possibly zero) black, and painted the other squares white.

We will define an integer sequence A of length N, and two integer sequences B and C of length M each, as follows:

A_i(1\leq i\leq N) is the minimum j such that (i,j) is painted black, or M+1 if it does not exist.

B_i(1\leq i\leq M) is the minimum k such that (k,i) is painted black, or N+1 if it does not exist.

C_i(1\leq i\leq M) is the maximum k such that (k,i) is painted black, or 0 if it does not exist.

How many triples (A,B,C) can occur? Find the count modulo 998244353.

Notice

In this problem, the length of your source code must be at most 20000 B.
Note that we will invalidate submissions that exceed the maximum length.

Constraints

1 \leq N \leq 8000

1 \leq M \leq 200

N and M are integers.

Partial Score

1500 points will be awarded for passing the test set satisfying N\leq 300.

Input

Input is given from Standard Input in the following format:

N M

Output

Print the number of triples (A,B,C), modulo 998244353.

Sample Input 1

2 3

Sample Output 1

64

Since N=2, given B_i and C_i, we can uniquely determine the arrangement of black squares in each column.
For each i, there are four possible pairs (B_i,C_i): (1,1), (1,2), (2,2) and (3,0). Thus, the answer is 4^M=64.

Sample Input 2

4 3

Sample Output 2

2588

Sample Input 3

17 13

Sample Output 3

229876268

Sample Input 4

5000 100

Sample Output 4

57613837

Solution in C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include<stdio.h>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 0x3f3f3f3f
#define ll long long
#define G 3
#define P 998244353
#define maxn 200005 
using namespace std;
int N,M;
ll f[maxn],g[maxn],dp[2][maxn];
ll invfac[maxn],fac[maxn];
int rev[maxn];
int Len,T;
ll add(ll a,ll b){a+=b;return a-((a>=P)?P:0);}
ll ksm(ll a,ll b){ll ret=1;while(b){if(b&1)ret=ret*a%P;b>>=1,a=a*a%P;}return ret;}
void prepare(){
	Len=1;
	while(Len<2*N)Len<<=1,T++;
	for(int i=0;i<Len;++i)rev[i]=(rev[i>>1]>>1)|((i&1)<<(T-1));
}
void init(int T){
	prepare();
	fac[0]=1;
	for(int i=1;i<=T+5;++i)fac[i]=fac[i-1]*i%P;
    invfac[T+5]=ksm(fac[T+5],P-2);
    for(int i=T+4;i>=0;--i)invfac[i]=invfac[i+1]*(i+1)%P;
}
ll cal(int n,int m){
	if(n<m)return 0;
	return fac[n]*invfac[m]%P*invfac[n-m]%P;
}
void NTT(ll *t,ll len,ll ty){
	for(int i=0;i<len;++i)if(i<rev[i])swap(t[i],t[rev[i]]);
	for(int m=1;m<len;m<<=1){
		ll wn=ksm(G,(ty*(P-1)/(m<<1)+P-1)%(P-1));
		for(int i=0;i<len;i+=m<<1){
			ll mul=1;
			for(int j=0;j<m;++j){
				ll x=t[i+j],y=t[i+j+m]*mul%P;
				t[i+j]=(x+y)%P,t[i+j+m]=(x-y+P)%P;
				mul=mul*wn%P;
			}
		}
	}
	if(ty==1)return;
	int inv=ksm(len,P-2);
	for(int i=0;i<len;++i)t[i]=t[i]*inv%P;
}
int main(){
	scanf("%d%d",&N,&M);
	init(N);
	int cur=0;
	for(int i=0;i<=N;++i)dp[cur][i]=1;
	for(int i=1;i<=N;++i)g[i]=invfac[i+2];
	NTT(g,Len,1);
	for(int i=2;i<=M;++i){
		memset(dp[cur^1],0,sizeof(dp[cur^1]));
		for(int j=0;j<=N;++j){
			ll tmp=dp[cur][j]*add(cal(j+1,2),1)%P;
			dp[cur^1][j]=add(dp[cur^1][j],tmp);
		}
		memset(f,0,sizeof(f));
		for(int j=0;j<=N;++j)f[j]=dp[cur][j]*invfac[j]%P;
		NTT(f,Len,1);
		for(int j=0;j<Len;++j)f[j]=f[j]*g[j]%P;
		NTT(f,Len,-1);
		for(int j=0;j<=N;++j){
			ll tmp=f[j]*fac[j+2]%P;
			dp[cur^1][j]=add(dp[cur^1][j],tmp);
		}
		cur^=1;
	}
	ll ret=0;
	for(int i=0;i<=N;++i){
		ll tmp=dp[cur][i]*cal(N,i)%P;
		ret=add(ret,tmp);
	}
	printf("%lld",ret);
	return 0;
}