Problem p02962 (C++)

Buggy submission (status: Runtime Error):
/*
Though leaves are many , the root is one.
Through all the lying days of my youth
I swayed my leaves and flowers in the sun.
Now I may wither into the truth.
*/
// #pragma GCC optimize("Ofast,no-stack-protector")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")
// #pragma GCC target("avx,tune=native")
#include <bits/stdc++.h>
// #include<ext/pb_ds/assoc_container.hpp>
using namespace std;
// using namespace __gnu_pbds;
const int inf = 0x3f3f3f3f;
const double eps = 1e-6;
const int mod = 1000000007;
typedef long long ll;
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
inline string getstr(string &s, int l, int r) {
  string ret = "";
  for (int i = l; i <= r; i++)
    ret.push_back(s[i]);
  return ret;
}
int modpow(int x, int y, int md = mod) {
  if (y == 0)
    return 1;
  int ret = modpow(x, y >> 1, md);
  ret = (ll)ret * ret % md;
  if (y & 1)
    ret = (ll)ret * x % md;
  return ret;
}
#define SZ 5000005
int len[SZ], fail[SZ];
bool can[SZ];
string s, t;
int ans[SZ];
void build(string &p) {
  int len = p.size(), j = fail[0] = -1;
  for (int i = 1; i <= len; i++) {
    while (j >= 0 && p[j] != p[i - 1])
      j = fail[j];
    fail[i] = ++j; // if(p[fail[i]-1]==p[i-1])fail[i]=fail[fail[i]];
  }
}
bool kmp(string &_t, string &_s) {
  int n = _t.size(), m = _s.size();
  for (int i = 0, k = 0; i < n; i++) {
    while (k >= 0 && _s[k] != _t[i])
      k = fail[k];
    len[i] = ++k;
    if (len[i] == m)
      can[i] = 1;
    else
      can[i] = 0;
  }
  return (*max_element(len, len + n)) == m;
}
int main() {
  cin >> s >> t;
  const int size = 2 * ((int)s.size() + t.size());
  while (s.size() < size) {
    s = s + s;
  }
  s = s + s;
  build(t);
  kmp(s, t);
  //	cerr<<s<<" "<<t<<endl;
  //	for(int i=0;i<=s.size();i++){
  //		cerr<<i<<" "<<fail[i]<<endl;
  //	}
  for (int i = (int)s.size() - 1; i >= 0; i--) {
    if (can[i]) {
      ans[i - (int)t.size() + 1] =
          max(ans[i - (int)t.size() + 1], ans[i + 1] + 1);
    }
  }
  int final_ans = *max_element(ans, ans + (int)s.size() + 1);
  if (final_ans >= (int)s.size() / t.size() - 2) {
    puts("-1");
    return 0;
  }
  cout << final_ans << endl;
  return 0;
}

Fixed submission:
/*
Though leaves are many , the root is one.
Through all the lying days of my youth
I swayed my leaves and flowers in the sun.
Now I may wither into the truth.
*/
// #pragma GCC optimize("Ofast,no-stack-protector")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")
// #pragma GCC target("avx,tune=native")
#include <bits/stdc++.h>
// #include<ext/pb_ds/assoc_container.hpp>
using namespace std;
// using namespace __gnu_pbds;
const int inf = 0x3f3f3f3f;
const double eps = 1e-6;
const int mod = 1000000007;
typedef long long ll;
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
inline string getstr(string &s, int l, int r) {
  string ret = "";
  for (int i = l; i <= r; i++)
    ret.push_back(s[i]);
  return ret;
}
int modpow(int x, int y, int md = mod) {
  if (y == 0)
    return 1;
  int ret = modpow(x, y >> 1, md);
  ret = (ll)ret * ret % md;
  if (y & 1)
    ret = (ll)ret * x % md;
  return ret;
}
#define SZ 10000005
int len[SZ], fail[SZ];
bool can[SZ];
string s, t;
int ans[SZ];
void build(string &p) {
  int len = p.size(), j = fail[0] = -1;
  for (int i = 1; i <= len; i++) {
    while (j >= 0 && p[j] != p[i - 1])
      j = fail[j];
    fail[i] = ++j; // if(p[fail[i]-1]==p[i-1])fail[i]=fail[fail[i]];
  }
}
bool kmp(string &_t, string &_s) {
  int n = _t.size(), m = _s.size();
  for (int i = 0, k = 0; i < n; i++) {
    while (k >= 0 && _s[k] != _t[i])
      k = fail[k];
    len[i] = ++k;
    if (len[i] == m)
      can[i] = 1;
    else
      can[i] = 0;
  }
  return (*max_element(len, len + n)) == m;
}
int main() {
  cin >> s >> t;
  const int size = 2 * ((int)s.size() + t.size());
  while (s.size() < size) {
    s = s + s;
  }
  s = s + s;
  build(t);
  kmp(s, t);
  //	cerr<<s<<" "<<t<<endl;
  //	for(int i=0;i<=s.size();i++){
  //		cerr<<i<<" "<<fail[i]<<endl;
  //	}
  for (int i = (int)s.size() - 1; i >= 0; i--) {
    if (can[i]) {
      ans[i - (int)t.size() + 1] =
          max(ans[i - (int)t.size() + 1], ans[i + 1] + 1);
    }
  }
  int final_ans = *max_element(ans, ans + (int)s.size() + 1);
  if (final_ans >= (int)s.size() / t.size() - 2) {
    puts("-1");
    return 0;
  }
  cout << final_ans << endl;
  return 0;
}