/*{{{*/
#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <unordered_map>
#include <unordered_set>
#include <cassert>
using namespace std;
typedef pair<int, int> PP;
typedef long long LL;
#define pb push_back
#define fr first
#define sc second
#define bitcnt __builtin_popcount
#define all(x) x.begin(), x.end()
inline LL ri() {LL x; scanf("%lld", &x); return x;}
#define rep2(i, n, ...) for (int i = 0; i < (n); i ++) 
#define rep3(i, a, b, ...) for (int i = (a); i < (b); i ++)
#define GET_MACRO(_1, _2, _3, NAME, ...) NAME
#define rep(...) GET_MACRO(__VA_ARGS__, rep3, rep2)(__VA_ARGS__)
#define drep2(i, n, ...) for (int i = (n) - 1; i >= 0; i --)
#define drep3(i, a, b) for (int i = (a) - 1; i >= (b); i --)
#define drep(...) GET_MACRO(__VA_ARGS__, drep3, drep2)(__VA_ARGS__)
template<typename T>inline bool smax(T&a, T b){if(a<b){a=b;return true;}return false;} 
template<typename T>inline bool smin(T&a, T b){if(a>b){a=b;return true;}return false;} 
/*}}}*/

//mod int
struct mint{
  const static long long mod = 998244353;
  int x;
  mint():x(0){}       
  mint(long long x):x(((x%mod)+mod)%mod){};
  mint operator+=(const mint&a){if((x+=a.x)>=mod) x-=mod; return *this;}
  mint operator-=(const mint&a){if((x+=mod-a.x)>=mod) x-=mod; return *this;}
  mint operator*=(const mint&a){x=((LL)x*a.x)%mod; return *this;}
  mint operator*(const mint&a){return mint(*this)*=a;}
  mint operator-(const mint&a){return mint(*this)-=a;}
  mint operator+(const mint&a){return mint(*this)+=a;}
  template<typename T>mint operator*(const T&a){return mint(*this)*=a;}
  template<typename T>mint operator-(const T&a){return mint(*this)-=a;}
  template<typename T>mint operator+(const T&a){return mint(*this)+=a;}
  template<typename T>friend mint operator*(T x,const mint&m){return mint(x)*=m;}
  template<typename T>friend mint operator-(T x,const mint&m){return mint(x)-=m;}
  template<typename T>friend mint operator+(T x,const mint&m){return mint(x)+=m;}
  bool operator==(const mint& a)const{ return x == a.x;}
  operator long long () const {return x;}
};
mint pw(mint a, long long b){mint res(1);while(b){if(b&1)res*=a;a*=a;b>>=1;}return res;}
mint inv(mint a){return pw(a, mint::mod - 2);}
//mod int

const int maxn = 5000;

mint p[maxn][maxn], C[maxn][maxn];

int c[maxn];
int main() {
  string s;
  cin >> s;
  int n = s.length();
  c[0] = 0;
  rep(i, n) {
    //c[i] = (i > 0 ? c[i - 1] : 0) + (s[i] - '0');
    c[i + 1] = (s[i] - '0') + c[i];
  }
  p[0][0] = 1;

  rep(i, maxn) {
    C[i][0] = C[i][i] = 1;
    rep(j, 1, i) {
      C[i][j] = C[i - 1][j] + C[i - 1][j - 1];
    }
  }

  rep(i, n) {
    rep(j, i + 1) {
      if (c[i + 1] >= (j + 1)) {
        p[i + 1][j + 1] += p[i][j];
      }
      if (2 * (i + 1) - c[i + 1] >= (i + 1 - j)) {
        p[i + 1][j] += p[i][j];
      }
    }
  }

  mint res = 0;
  rep(i, n + 1) {
    res += p[n][i] * (C[n][c[n] - i]); 
  }
  cout << res << endl;


  

  return 0;
}


Measured memory_bytes: 195712