#include <bits/stdc++.h>
#define int long long
using namespace std;

inline int read(){
    int s=0,w=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')w=-1;ch=getchar();
    }
    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    return s*w;
}

inline bool read(int& a){
int s=0,w=1;
    char ch=getchar();
    if(ch==EOF){
        return false;
    }
    while(ch<'0'||ch>'9'){
        if(ch=='-')w=-1;ch=getchar();
    }
    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    a=s*w;
    return true;
}

inline void write(int x){
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
}

inline void writeln(int x){
    if(x<0) putchar('-'),x=-x;
    if(x>9) write(x/10);
    putchar(x%10+'0');
    puts("");
}

const int MOD=998244353;

int n,k;
int f[3010][3010];

signed main(){
    read(n),read(k);
    f[1][1]=1;

    for(int i=2;i<=n;i++){
        for(int j=i;j>=1;j--){
            f[i][j]=(f[i-1][j-1]+f[i][j*2])%MOD;
        }
    }

    writeln(f[n][k]%MOD);

    return 0;
}
#include <bits/stdc++.h>
#define REP(i, n) for(ll i = 0; i < (n); i++)
#define REP1(i, n) for(ll i = 1; i <= (n); i++)
#define REPD(i,a,b) for (ll i=(a);i<=(b);i++)
#define ALL(v) (v).begin(), (v).end()
using namespace std;
typedef long long ll;
typedef double d;
typedef long double ld;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<d> vd;
typedef vector<ld> vld;
typedef set<int> si;
typedef vector<si> vsi;
typedef vector<ll> vll;
typedef vector<vll> vvll;
typedef pair<int, int> pi;
typedef queue<int> qi;
typedef queue<pi> qpi;
typedef pair<ll, ll> pll;
typedef queue<pll> qpll;
typedef vector<pi> vpi;
typedef vector<pll> vpll;
const int MOD = 1000000007;
const int INF = 1001001001;
// 小数点 << fixed << setprecision(10) <<
// sort降順 sort(ALL(),greater<int>());
// 円周率 M_PI
// 文字判定 isupper islower
// 順列 do {} while(next_permutation(ALL(X)));
// 最大値 LLONG_MAX
// a内でx以上 auto iter = lower_bound(ALL(a), x);
// a内でxより大きい auto iter = upper_bound(ALL(a), x);
int dx[8] = {1, 0, -1, 0, 1, 1, -1, -1};
int dy[8] = {0, 1, 0, -1, 1, -1, 1, -1};
struct edge {
    int from; //出発点
    int to;   //到達点
    int cost; //移動コスト
};
typedef struct edge se;
typedef vector<edge> ve;

// 重複した要素を取り除いて返す
vll deleteDuplication(vll &numberlist) {
  sort(ALL(numberlist));
  numberlist.erase(unique(ALL(numberlist)),numberlist.end());
  return numberlist;
}

// 2つの数の最大公約数を求める
unsigned Euclidean_gcd(unsigned a, unsigned b) {
  if(a < b) return Euclidean_gcd(b, a);
  unsigned r;
  while ((r=a%b)) {
    a = b;
    b = r;
  }
  return b;
}

// 各桁の数を合計
int digit_sum(int n) {
  int sum=n%10;
  while(n!=0) {
    n/=10;
    sum+=n%10;
  }
  return sum;
}

// 素因数分解してペアのリストを返す
vpll PrimeFactorization(ll n) {
  vpll res;
  for (ll i=2; i*i<=n; i++) {
    if(n%i!=0) continue;
    ll ex=0;
    while(n%i==0) {
      ex++;
      n/=i;
    }
    res.push_back(pll(i,ex));
  }
  if(n!=1) res.push_back(pll(n,1));
  return res;
}



int main() {
  int h,w;
  cin >> h >> w;
  char s[h+1][w+1];
  vvll dp(h+1,vll(w+1,0)),X(h+1,vll(w+1,0)),Y(h+1,vll(w+1,0)),Z(h+1,vll(w+1,0));
  REP1(i,h) {
    REP1(j,w) {
      cin >> s[i][j];
    }
  }
  dp[1][1]=1;
  REP1(i,h) {
    REP1(j,w) {
      if(i==1&&j==1) continue;
      if(s[i][j]=='#') continue;
      X[i][j]=X[i][j-1]+dp[i][j-1]%MOD;
      Y[i][j]=Y[i-1][j]+dp[i-1][j]%MOD;
      Z[i][j]=Z[i-1][j-1]+dp[i-1][j-1]%MOD;
      dp[i][j]=(X[i][j]+Y[i][j]+Z[i][j])%MOD;
    }
  }
  cout << dp[h][w] << endl;
  return 0;
}
