Problem p01551 (C++) — buggy submission, verdict: Runtime Error

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

#define dump(n) cout << "# " << #n << '=' << (n) << endl
#define repi(i, a, b) for (int i = int(a); i < int(b); i++)
#define peri(i, a, b) for (int i = int(b); i-- > int(a);)
#define rep(i, n) repi(i, 0, n)
#define per(i, n) peri(i, 0, n)
#define all(c) begin(c), end(c)
#define mp make_pair
#define mt make_tuple

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;

const int INF = 1e9;
const int MOD = 1e9 + 7;
const double EPS = 1e-9;

template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  return os << '(' << p.first << ',' << p.second << ')';
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &a) {
  os << '[';
  rep(i, a.size()) os << (i ? " " : "") << a[i];
  return os << ']';
}

vs parse(const map<string, vs> &rules, const string &symb) {
  vs res;
  for (string s : rules.at(symb)) {
    if (res.size() > 200)
      throw "no solution";
    if (s[0] == '[')
      res.push_back(s);
    else {
      vs tmp = parse(rules, s);
      res.insert(end(res), all(tmp));
    }
  }
  return res;
}

bool over50(int x) {
  int a = x & 255, b = x >> 8 & 255, c = x >> 16 & 255, d = x >> 24 & 255;
  return a > 50 || b > 50 || c > 50 || d > 50;
}

int main() {
  for (int na, nt, ng, nc; cin >> na >> nt >> ng >> nc && na | nt | ng | nc;) {
    int m;
    cin >> m;
    cin.ignore();
    map<string, vs> rules;
    string symb0;
    rep(i, m) {
      string line;
      getline(cin, line);
      istringstream iss(line);
      string from;
      iss >> from;
      from.erase(from.size() - 1);
      vs to;
      for (string s; iss >> s;)
        to.push_back(s);
      rules[from] = to;
      if (i == 0)
        symb0 = from;
    }

    vs symbs;
    try {
      symbs = parse(rules, symb0);
    } catch (...) {
      cout << 0 << endl;
      continue;
    }

    vector<unordered_map<int, int>> dp(2);
    dp[0][0] = 1;
    for (auto symb : symbs) {
      dp[1].clear();
      repi(i, 1, symb.size() - 1) {
        int pos = string("ATGC").find(symb[i]) * 8;
        for (auto p : dp[0]) {
          ull key, val;
          tie(key, val) = p;
          if (over50(key += 1 << pos))
            continue;
          (dp[1][key] += val) %= MOD;
        }
      }
      swap(dp[0], dp[1]);
    }

    ull key = na + (nt << 8) + (ng << 16) + (nc << 24);
    cout << dp[0][key] << endl;
  }
}

Error: 0

Fixed submission:

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

#define dump(n) cout << "# " << #n << '=' << (n) << endl
#define repi(i, a, b) for (int i = int(a); i < int(b); i++)
#define peri(i, a, b) for (int i = int(b); i-- > int(a);)
#define rep(i, n) repi(i, 0, n)
#define per(i, n) peri(i, 0, n)
#define all(c) begin(c), end(c)
#define mp make_pair
#define mt make_tuple

typedef unsigned int uint;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<string> vs;

const int INF = 1e9;
const int MOD = 1e9 + 7;
const double EPS = 1e-9;

template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
  return os << '(' << p.first << ',' << p.second << ')';
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &a) {
  os << '[';
  rep(i, a.size()) os << (i ? " " : "") << a[i];
  return os << ']';
}

vs parse(const map<string, vs> &rules, const string &symb) {
  vs res;
  for (string s : rules.at(symb)) {
    assert(res.size() < 500);
    if (s[0] == '[')
      res.push_back(s);
    else {
      vs tmp = parse(rules, s);
      res.insert(end(res), all(tmp));
    }
  }
  return res;
}

bool over50(int x) {
  int a = x & 255, b = x >> 8 & 255, c = x >> 16 & 255, d = x >> 24 & 255;
  return a > 50 || b > 50 || c > 50 || d > 50;
}

int main() {
  for (int na, nt, ng, nc; cin >> na >> nt >> ng >> nc && na | nt | ng | nc;) {
    int m;
    cin >> m;
    cin.ignore();
    map<string, vs> rules;
    string symb0;
    rep(i, m) {
      string line;
      getline(cin, line);
      istringstream iss(line);
      string from;
      iss >> from;
      from.erase(from.size() - 1);
      vs to;
      for (string s; iss >> s;)
        to.push_back(s);
      rules[from] = to;
      if (i == 0)
        symb0 = from;
    }

    vs symbs = parse(rules, symb0);
    vector<unordered_map<int, int>> dp(2);
    dp[0][0] = 1;
    for (auto symb : symbs) {
      dp[1].clear();
      repi(i, 1, symb.size() - 1) {
        int pos = string("ATGC").find(symb[i]) * 8;
        for (auto p : dp[0]) {
          ull key, val;
          tie(key, val) = p;
          if (over50(key += 1 << pos))
            continue;
          (dp[1][key] += val) %= MOD;
        }
      }
      swap(dp[0], dp[1]);
    }

    ull key = na + (nt << 8) + (ng << 16) + (nc << 24);
    cout << dp[0][key] << endl;
  }
}