Problem p03134 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <chrono>
#include <complex>
#include <cstdio>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#define REP(i, x, y) for (ll i = x; i <= y; i++)
#define SIZE(a) ll(a.size())
#define vll vector<ll>
#define vvll vector<vector<ll>>
#define vtype(type) vector<type>
#define vvtype(type) vector<vector<type>>
#define MEMSET(a, n, m)                                                        \
  for (ll i = 0; i <= n; i++)                                                  \
  a[i] = m
#define BIT(n) (ll(1) << n)
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end())
#define UNIQUE_ARRAY(a, x) unique(a + 1, a + x + 1) - a - 1
#define SORT(a, n) sort(a + 1, a + n + 1)
#define SORT_O(a, n, order) sort(a + 1, a + n + 1, order)
#define PER(i, y, x) for (ll i = y; i >= x; i--)
typedef long long ll;
using namespace std;

ll const MOD = 998244353;
ll mod_p(ll x, ll y) {
  x %= MOD;
  y %= MOD;
  return (x + y + MOD) % MOD;
}

ll mod_m(ll x, ll y) {
  x %= MOD;
  y %= MOD;
  return x * y % MOD;
}

ll mod_pow(ll x, ll t) {
  x %= MOD;
  if (t == 0) {
    return 1;
  } else {
    ll v = mod_pow(x, t / 2);
    if (t % 2 == 0) {
      return v * v % MOD;
    } else {
      return v * v % MOD * x % MOD;
    }
  }
}

ll mod_inv(ll x) { return mod_pow(x, MOD - 2); }

struct edge {
  long long to;
  ll name;
  bool operator<(const edge &rhs) const { return name > rhs.name; }
};

ll const MAX = 2e3 + 5;
ll dp[MAX][MAX] = {};

int main() {
  string s;
  cin >> s;
  ll n = s.size();
  ll bl = 0;
  ll rd = 0;
  dp[0][0] = 1;
  REP(i, 0, n * 2 - 1) {
    if (i < n) {
      bl += s[i] - '0';
      rd += -(s[i] - '2');
    }
    REP(j, 0, n * 2 - 1) {
      if (j < bl) {
        dp[i + 1][j + 1] = mod_p(dp[i + 1][j + 1], dp[i][j]);
      }
      if (i - j < rd) {
        dp[i + 1][j] = mod_p(dp[i + 1][j], dp[i][j]);
      }
    }
  }
  cout << dp[n * 2][bl] << endl;
}

Fixed submission:
#include <algorithm>
#include <bitset>
#include <chrono>
#include <complex>
#include <cstdio>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#define REP(i, x, y) for (ll i = x; i <= y; i++)
#define SIZE(a) ll(a.size())
#define vll vector<ll>
#define vvll vector<vector<ll>>
#define vtype(type) vector<type>
#define vvtype(type) vector<vector<type>>
#define MEMSET(a, n, m)                                                        \
  for (ll i = 0; i <= n; i++)                                                  \
  a[i] = m
#define BIT(n) (ll(1) << n)
#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end())
#define UNIQUE_ARRAY(a, x) unique(a + 1, a + x + 1) - a - 1
#define SORT(a, n) sort(a + 1, a + n + 1)
#define SORT_O(a, n, order) sort(a + 1, a + n + 1, order)
#define PER(i, y, x) for (ll i = y; i >= x; i--)
typedef long long ll;
using namespace std;

ll const MOD = 998244353;
ll mod_p(ll x, ll y) {
  x %= MOD;
  y %= MOD;
  return (x + y + MOD) % MOD;
}

ll mod_m(ll x, ll y) {
  x %= MOD;
  y %= MOD;
  return x * y % MOD;
}

ll mod_pow(ll x, ll t) {
  x %= MOD;
  if (t == 0) {
    return 1;
  } else {
    ll v = mod_pow(x, t / 2);
    if (t % 2 == 0) {
      return v * v % MOD;
    } else {
      return v * v % MOD * x % MOD;
    }
  }
}

ll mod_inv(ll x) { return mod_pow(x, MOD - 2); }

struct edge {
  long long to;
  ll name;
  bool operator<(const edge &rhs) const { return name > rhs.name; }
};

ll const MAX = 4e3 + 5;
ll dp[MAX][MAX] = {};

int main() {
  string s;
  cin >> s;
  ll n = s.size();
  ll bl = 0;
  ll rd = 0;
  dp[0][0] = 1;
  REP(i, 0, n * 2 - 1) {
    if (i < n) {
      bl += s[i] - '0';
      rd += -(s[i] - '2');
    }
    REP(j, 0, n * 2 - 1) {
      if (j < bl) {
        dp[i + 1][j + 1] = mod_p(dp[i + 1][j + 1], dp[i][j]);
      }
      if (i - j < rd) {
        dp[i + 1][j] = mod_p(dp[i + 1][j], dp[i][j]);
      }
    }
  }
  cout << dp[n * 2][bl] << endl;
}