Problem p02962 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <assert.h>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <typeinfo>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;
using ll = long long;
using ull = unsigned long long;

const ll INF = 1e18;
const ll MOD = 1e9 + 7;

#define REP(i, n) for (ll i = 0; i < n; i++)

class RollingHash {
private:
  using ull = unsigned long long;
  const ull base1;
  const ull base2;
  const ull mod1;
  const ull mod2;
  vector<ull> hash1;
  vector<ull> hash2;
  vector<ull> pow1;
  vector<ull> pow2;

  string s;

public:
  RollingHash(string &s)
      : s(s), base1(1009), base2(2009), mod1(1000000007), mod2(1000000009),
        hash1(s.size() + 1), hash2(s.size() + 1), pow1(s.size() + 1, 1),
        pow2(s.size() + 1, 1) {
    for (int i = 0; i < s.size(); i++) {
      hash1[i + 1] = (hash1[i] * base1 + s[i]) % mod1;
      hash2[i + 1] = (hash2[i] * base2 + s[i]) % mod2;
      pow1[i + 1] = (pow1[i] * base1) % mod1;
      pow2[i + 1] = (pow2[i] * base2) % mod2;
    }
  }

  // s の [l, r) のハッシュ値を返す
  ull get(int l, int r) {
    return (hash1[r] - ((hash1[l] * pow1[r - l]) % mod1) + mod1) % mod1;
  }

  ull get() { return get(0, s.size()); }

  ull operator()() { return get(0, s.size()); }

  ull operator()(int l, int r) { return get(l, r); }
};

int main() {
  string s, t;
  cin >> s >> t;
  ll n = s.size(), m = t.size();
  string ss;
  ll tmp = ((m % n == 0) ? m / n : m / n + 1);
  REP(i, max(tmp, 2LL)) { ss += s; }
  RollingHash roli1(ss), roli2(t);
  vector<bool> match(n);
  REP(i, n) {
    if (roli1(i, i + m) == roli2()) {
      match[i] = true;
    }
  }
  vector<ll> d(n);
  set<ll> st;
  auto f = [dfs = [&](auto &&dfs, ll now) -> ll {
    if (st.find(now) != st.end()) {
      cout << -1 << endl;
      exit(0);
    }
    if (d[now] != 0) {
      return d[now];
    }
    st.insert(now);
    if (match[now]) {
      d[now] = dfs(dfs, (now + m) % n) + 1;
    }
    st.erase(now);
    return d[now];
  }](ll start) { dfs(dfs, start); };
  REP(i, n) { f(i); }
  cout << *max_element(d.begin(), d.end()) << endl;
}

Fixed submission:
#include <algorithm>
#include <assert.h>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <typeinfo>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;
using ll = long long;
using ull = unsigned long long;

const ll INF = 1e18;
const ll MOD = 1e9 + 7;

#define REP(i, n) for (ll i = 0; i < n; i++)

class RollingHash {
private:
  using ull = unsigned long long;
  const ull base1;
  const ull base2;
  const ull mod1;
  const ull mod2;
  vector<ull> hash1;
  vector<ull> hash2;
  vector<ull> pow1;
  vector<ull> pow2;

  string s;

public:
  RollingHash(string &s)
      : s(s), base1(1009), base2(2009), mod1(1000000007), mod2(1000000009),
        hash1(s.size() + 1), hash2(s.size() + 1), pow1(s.size() + 1, 1),
        pow2(s.size() + 1, 1) {
    for (int i = 0; i < s.size(); i++) {
      hash1[i + 1] = (hash1[i] * base1 + s[i]) % mod1;
      hash2[i + 1] = (hash2[i] * base2 + s[i]) % mod2;
      pow1[i + 1] = (pow1[i] * base1) % mod1;
      pow2[i + 1] = (pow2[i] * base2) % mod2;
    }
  }

  // s の [l, r) のハッシュ値を返す
  ull get(int l, int r) {
    return (hash1[r] - ((hash1[l] * pow1[r - l]) % mod1) + mod1) % mod1;
  }

  ull get() { return get(0, s.size()); }

  ull operator()() { return get(0, s.size()); }

  ull operator()(int l, int r) { return get(l, r); }
};

int main() {
  string s, t;
  cin >> s >> t;
  ll n = s.size(), m = t.size();
  string ss;
  ll tmp = ((m % n == 0) ? m / n : m / n + 1);
  REP(i, max(tmp, 50LL)) { ss += s; }
  RollingHash roli1(ss), roli2(t);
  vector<bool> match(n);
  REP(i, n) {
    if (roli1(i, i + m) == roli2()) {
      match[i] = true;
    }
  }
  vector<ll> d(n);
  set<ll> st;
  auto f = [dfs = [&](auto &&dfs, ll now) -> ll {
    if (st.find(now) != st.end()) {
      cout << -1 << endl;
      exit(0);
    }
    if (d[now] != 0) {
      return d[now];
    }
    st.insert(now);
    if (match[now]) {
      d[now] = dfs(dfs, (now + m) % n) + 1;
    }
    st.erase(now);
    return d[now];
  }](ll start) { dfs(dfs, start); };
  REP(i, n) { f(i); }
  cout << *max_element(d.begin(), d.end()) << endl;
}