```#include<bits/stdc++.h>
using namespace std;
const int N=3010,mod=2333;
typedef long long ll;
ll ans[N][N],dp[N][N];
int n,m;
//快速读入模板
template<class T>inline void read(T &res)
{
char c;T flag=1;
while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
}
int main(){
int n,m;
read(n),read(m);
//对矩阵初始化赋值为零
memset(ans,0,sizeof(ans));
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
read(ans[i][j]);
//将树的位置赋值为-1 防止与后边道路数量处理发生冲突
if(ans[i][j]==1)
ans[i][j]=-1;
}
//起点赋值
ans[n][1]=1;
// //差分前缀思想
// //对第一列初始化
// for(int i=n-1;i>0;i--)
// ans[i][1]+=ans[i+1][1];
// // 对第n行初始化
// for(int j=2;j<=m;j++)
// ans[n][j]+=ans[n][j-1];
for(int i=n;i>0;i--)
for(int j=1;j<=m;j++){
//如果当前位置有树这无法到达 道路数量为零
if(ans[i][j]==-1)
ans[i][j]=0;
else
//道路个数为下方和左侧道路的的
ans[i][j]+=(ans[i+1][j]+ans[i][j-1])%mod;
}
// 输出每个到达每个点的道路数量
// for(int i=1;i<=n;i++){
// for(int j=1;j<=m;j++)
// cout<<ans[i][j]<<' ';
// cout<<endl;
// }
//输出可以到达终点道路的个数
cout<<ans[1][m]<<endl;
return 0;
}