```#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;
}