Problem p01497 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rep1(i, n) for (int i = 1; i <= (int)(n); i++)
#define all(c) c.begin(), c.end()
#define pb push_back
#define fs first
#define sc second
#define show(x) cout << #x << " = " << x << endl
#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vv;
typedef pair<int, ll> P;
int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
bool is(int x, int y) { return 0 <= x && x < 4 && 0 <= y && y < 4; }
inline ll toll(vv b) {
  ll x = 0;
  rep(i, 4) rep(j, 4) x = x * 8 + b[i][j];
  return x;
}
inline vv tovv(ll x) {
  vv b(4, vi(4, 0));
  rep(i, 4) rep(j, 4) {
    b[3 - i][3 - j] = x % 8;
    x /= 8;
  }
  return b;
}
int main() {
  ll s = 0;
  rep(i, 4) rep(j, 4) {
    ll x;
    cin >> x;
    s = s * 8 + x;
  }
  queue<P> que;
  que.push(P(0, s));
  while (!que.empty()) {
    P p = que.front();
    que.pop();
    if (p.fs >= 5) {
      puts("-1");
      return 0;
    }
    vv b = tovv(p.sc);
    rep(i, 4) rep(j, 4) {
      vv nb = b;
      if (nb[i][j] == 0)
        continue;
      nb[i][j]++;
      if (nb[i][j] == 5) {
        vv waters;
        rep(d, 4) waters.pb(vi{i, j, d});
        while (!waters.empty()) {
          vv nwaters;
          for (vi w : waters) {
            int x = w[0], y = w[1], d = w[2];
            int nx = x + dx[d], ny = y + dy[d];
            if (!is(nx, ny))
              continue;
            if (nb[nx][ny] == 0) {
              nwaters.pb(vi{nx, ny, d});
              continue;
            } else {
              nb[nx][ny]++;
              if (nb[nx][ny] == 5) {
                rep(di, 4) nwaters.pb(vi{nx, ny, di});
              }
            }
          }
          waters = nwaters;
          rep(e, 4) rep(f, 4) if (nb[e][f] >= 5) nb[e][f] = 0;
        }
      }
      ll nx = toll(nb);
      if (nx == 0) {
        cout << p.fs + 1 << endl;
        return 0;
      }
      que.push(P(p.fs + 1, nx));
    }
  }
  assert(0);
}

Fixed submission:
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rep1(i, n) for (int i = 1; i <= (int)(n); i++)
#define all(c) c.begin(), c.end()
#define pb push_back
#define fs first
#define sc second
#define show(x) cout << #x << " = " << x << endl
#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vv;
typedef pair<int, ll> P;
int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
bool is(int x, int y) { return 0 <= x && x < 4 && 0 <= y && y < 4; }
inline ll toll(vv b) {
  ll x = 0;
  rep(i, 4) rep(j, 4) x = x * 8 + b[i][j];
  return x;
}
inline vv tovv(ll x) {
  vv b(4, vi(4, 0));
  rep(i, 4) rep(j, 4) {
    b[3 - i][3 - j] = x % 8;
    x /= 8;
  }
  return b;
}
int main() {
  ll s = 0;
  rep(i, 4) rep(j, 4) {
    ll x;
    cin >> x;
    s = s * 8 + x;
  }
  if (s == 0) {
    puts("0");
    return 0;
  }
  queue<P> que;
  que.push(P(0, s));
  while (!que.empty()) {
    P p = que.front();
    que.pop();
    if (p.fs >= 5) {
      puts("-1");
      return 0;
    }
    vv b = tovv(p.sc);
    rep(i, 4) rep(j, 4) {
      vv nb = b;
      if (nb[i][j] == 0)
        continue;
      nb[i][j]++;
      if (nb[i][j] == 5) {
        vv waters;
        rep(d, 4) waters.pb(vi{i, j, d});
        while (!waters.empty()) {
          vv nwaters;
          for (vi w : waters) {
            int x = w[0], y = w[1], d = w[2];
            int nx = x + dx[d], ny = y + dy[d];
            if (!is(nx, ny))
              continue;
            if (nb[nx][ny] == 0) {
              nwaters.pb(vi{nx, ny, d});
              continue;
            } else {
              nb[nx][ny]++;
              if (nb[nx][ny] == 5) {
                rep(di, 4) nwaters.pb(vi{nx, ny, di});
              }
            }
          }
          waters = nwaters;
          rep(e, 4) rep(f, 4) if (nb[e][f] >= 5) nb[e][f] = 0;
        }
      }
      ll nx = toll(nb);
      if (nx == 0) {
        cout << p.fs + 1 << endl;
        return 0;
      }
      que.push(P(p.fs + 1, nx));
    }
  }
  assert(0);
}