Problem p02962 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); i++)
#define MOD 1000000007
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3f
#define EPS (1e-10)
using namespace std;
typedef long long ll;
typedef pair<int, int> P;

template <class T, uint mod> struct RollingHash_ {
  vector<uint> hashed, power;

  inline uint mul(uint a, uint b) { return a * (unsigned long long)b % mod; }
  RollingHash_() {}
  RollingHash_(T s, uint base = 10007) {
    int sz = (int)s.size();
    hashed.assign(sz + 1, 0);
    power.assign(sz + 1, 0);
    power[0] = 1;
    for (int i = 0; i < sz; i++) {
      power[i + 1] = mul(power[i], base);
      hashed[i + 1] = mul(hashed[i], base) + s[i];
      if (hashed[i + 1] >= mod)
        hashed[i + 1] -= mod;
    }
  }

  uint get(int l, int r) {
    uint ret = hashed[r] + mod - mul(hashed[l], power[r - l]);
    if (ret >= mod)
      ret -= mod;
    return ret;
  }
};

typedef pair<uint, uint> Hash;

template <class T> struct RollingHash {
  RollingHash_<T, 998244353> RH1;
  RollingHash_<T, 1000000007> RH2;

  RollingHash(T s) {
    RH1 = RollingHash_<T, 998244353>(s);
    RH2 = RollingHash_<T, 1000000007>(s);
  }

  Hash get(int l, int r) { return make_pair(RH1.get(l, r), RH2.get(l, r)); }
};

char S[600000], T[600000];
int nx[600000], prv[600000];
bool used[600000];

int main() {
  scanf("%s%s", S, T);
  string s = S, t = T;
  while (s.size() < t.size())
    s += S;
  string ss = s + s;
  RollingHash<string> rh1(ss), rh2(t);
  memset(nx, -1, sizeof(nx));
  memset(prv, -1, sizeof(prv));
  rep(i, s.size()) {
    Hash h1 = rh1.get(i, i + t.size()), h2 = rh2.get(0, t.size());
    if (h1 == h2) {
      nx[i] = (i + t.size()) % s.size();
      prv[nx[i]] = i;
    }
  }
  int Max = 0;
  rep(i, s.size()) {
    if (used[i])
      continue;
    if (prv[i] != -1)
      continue;
    int x = i;
    int cnt = 0;
    while (1) {
      used[x] = true;
      if (nx[x] == -1)
        break;
      x = nx[x];
      cnt++;
    }
    Max = max(Max, cnt);
  }
  rep(i, s.size()) {
    if (!used[i]) {
      puts("-1");
      return 0;
    }
  }
  cout << Max << endl;
}

Fixed submission:
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); i++)
#define MOD 1000000007
#define INF 0x3f3f3f3f
#define INFL 0x3f3f3f3f3f3f3f3f
#define EPS (1e-10)
using namespace std;
typedef long long ll;
typedef pair<int, int> P;

template <class T, uint mod> struct RollingHash_ {
  vector<uint> hashed, power;

  inline uint mul(uint a, uint b) { return a * (unsigned long long)b % mod; }
  RollingHash_() {}
  RollingHash_(T s, uint base = 10007) {
    int sz = (int)s.size();
    hashed.assign(sz + 1, 0);
    power.assign(sz + 1, 0);
    power[0] = 1;
    for (int i = 0; i < sz; i++) {
      power[i + 1] = mul(power[i], base);
      hashed[i + 1] = mul(hashed[i], base) + s[i];
      if (hashed[i + 1] >= mod)
        hashed[i + 1] -= mod;
    }
  }

  uint get(int l, int r) {
    uint ret = hashed[r] + mod - mul(hashed[l], power[r - l]);
    if (ret >= mod)
      ret -= mod;
    return ret;
  }
};

typedef pair<uint, uint> Hash;

template <class T> struct RollingHash {
  RollingHash_<T, 998244353> RH1;
  RollingHash_<T, 1000000007> RH2;

  RollingHash(T s) {
    RH1 = RollingHash_<T, 998244353>(s);
    RH2 = RollingHash_<T, 1000000007>(s);
  }

  Hash get(int l, int r) { return make_pair(RH1.get(l, r), RH2.get(l, r)); }
};

char S[600000], T[600000];
int nx[1200000], prv[1200000];
bool used[1200000];

int main() {
  scanf("%s%s", S, T);
  string s = S, t = T;
  while (s.size() < t.size())
    s += S;
  string ss = s + s;
  RollingHash<string> rh1(ss), rh2(t);
  memset(nx, -1, sizeof(nx));
  memset(prv, -1, sizeof(prv));
  rep(i, s.size()) {
    Hash h1 = rh1.get(i, i + t.size()), h2 = rh2.get(0, t.size());
    if (h1 == h2) {
      nx[i] = (i + t.size()) % s.size();
      prv[nx[i]] = i;
    }
  }
  int Max = 0;
  rep(i, s.size()) {
    if (used[i])
      continue;
    if (prv[i] != -1)
      continue;
    int x = i;
    int cnt = 0;
    while (1) {
      used[x] = true;
      if (nx[x] == -1)
        break;
      x = nx[x];
      cnt++;
    }
    Max = max(Max, cnt);
  }
  rep(i, s.size()) {
    if (!used[i]) {
      puts("-1");
      return 0;
    }
  }
  cout << Max << endl;
}