Problem p02962 (C++)

Buggy submission (status: Time Limit Exceeded):
// https://atcoder.jp/contests/abc135/tasks/abc135_f
#include <bits/stdc++.h>
#include <sys/types.h>
#include <unistd.h>
#define CIN_ONLY
#define DECIMAL_DIGITS 10
#define STATIC_MOD 1e9 + 7

#ifdef BTK
/*<head>*/
#include "Template.hpp"
#include "string/RollingHash.hpp"
/*</head>*/
#else
/*<body>*/
/* #region auto includes */
/* #region stl */
/*<stl>*/
#include <bits/stdc++.h>
#include <sys/types.h>
#include <unistd.h>
using namespace std;
/*</stl>*/
/* #endregion */
/* #region template/IncludeSTL.hpp*/
/**
 * @file IncludeSTL.hpp
 * @author btk
 * @brief 標準ライブラリをincludeするだけ
 * @version 0.1
 * @date 2019-07-21
 *
 * @copyright Copyright (c) 2019
 *
 */

/*<head>*/
#pragma once
/*</head>*/

/*<stl>*/
#include <bits/stdc++.h>
#include <sys/types.h>
#include <unistd.h>
using namespace std;
/*</stl>*/
/* #endregion */
/* #region template/Macro.hpp*/
/**
 * @file Macro.hpp
 * @author btk
 * @brief マクロとか，LLとか
 * @version 0.1
 * @date 2019-07-13
 *
 * @copyright Copyright (c) 2019
 *
 */

//! LL
using LL = long long;

/**
 * @def DEBUG
 * @brief デバッグ用のif文 提出時はif(0)で実行されない
 */

/*</head>*/
#ifdef BTK
#define DEBUG if (1)
#else
#ifdef CIN_ONLY
#define FAST_IO
#endif
#define DEBUG if (0)
#endif
/**
 * @def ALL(v)
 * @brief
 * ALLマクロ
 */
#define ALL(v) (v).begin(), (v).end()

/**
 * @def REC(ret, ...)
 * @brief
 * 再帰ラムダをするためのマクロ
 */
#define REC(ret, ...) std::function<ret(__VA_ARGS__)>

/**
 * @def VAR_NAME(var)
 * @brief 変数名を取得する
 */
#define VAR_NAME(var) #var

/**
 * @brief
 * rangeで生まれる使わない変数を消す用（警告消し）
 */
template <typename T> inline T &unused_var(T &v) { return v; }
/* #endregion */
/* #region template/IO.hpp*/
/**
 * @file IO.hpp
 * @author btk
 * @brief cin高速化とか，出力の小数桁固定とか
 * @version 0.1
 * @date 2019-07-13
 *
 * @copyright Copyright (c) 2019
 */

/**
 * @brief 入出力の設定を行うための構造体
 */
struct cww {
  /**
   * @brief Construct a new cww::cww object
   * @details
   * CIN_ONLYを定義すると，submit時にcinとscanfの同期を切る設定が走る
   * DECIMAL_DIGITSを定義すると，doubleの出力時指定した桁数分小数部を吐くようになる
   */
  cww() {
#ifdef FAST_IO
    ios::sync_with_stdio(false);
    cin.tie(0);
#endif
#ifdef DECIMAL_DIGITS
    cout << fixed;
    cout << setprecision(DECIMAL_DIGITS);
#endif
  }
};

//! 入出力設定構造体を実体化
cww star;

/**
 * @brief
 * vectorに直接cin流すためのやつ
 * @tparam T
 * @param is
 * @param v
 * @return istream&
 */
template <typename T>
std::istream &operator>>(std::istream &is, std::vector<T> &v) {
  for (auto &it : v)
    is >> it;
  return is;
}
/* #endregion */
/* #region template/Loop.hpp*/
/**
 * @file Loop.hpp
 * @author btk
 * @brief rangeとかループ系のクラス
 * @version 0.1
 * @date 2019-07-13
 *
 * @copyright Copyright (c) 2019
 *
 */

/**
 * @brief
 * rangeを逆向きに操作したいとき用
 * @details
 * ループの範囲は[bg,ed)なので注意
 * @see range
 */
class reverse_range {
private:
  struct I {
    int x;
    int operator*() { return x - 1; }
    bool operator!=(I &lhs) { return x > lhs.x; }
    void operator++() { --x; }
  };
  I i, n;

public:
  /**
   * @brief Construct a new reverse range object
   *
   * @param n
   */
  reverse_range(int n) : i({0}), n({n}) {}
  /**
   * @brief Construct a new reverse range object
   *
   * @param i
   * @param n
   */
  reverse_range(int i, int n) : i({i}), n({n}) {}
  /**
   * @brief
   * begin iterator
   * @return I&
   */
  I &begin() { return n; }
  /**
   * @brief
   * end iterator
   * @return I&
   */
  I &end() { return i; }
};
/**
 * @brief
 * python みたいな range-based for を実現
 * @details
 * ループの範囲は[bg,ed)なので注意
 * !つけると逆向きにループが回る (reverse_range)
 * 空間計算量はO(1)
 * 使わない変数ができて警告が出がちなので，unused_varとかを使って警告消しするとよい
 */
class range {
private:
  struct I {
    int x;
    int operator*() { return x; }
    bool operator!=(I &lhs) { return x < lhs.x; }
    void operator++() { ++x; }
  };
  I i, n;

public:
  /**
   * @brief Construct a new range object
   *
   * @param n
   */
  range(int n) : i({0}), n({n}) {}
  /**
   * @brief Construct a new range object
   *
   * @param i
   * @param n
   */
  range(int i, int n) : i({i}), n({n}) {}
  /**
   * @brief
   * begin iterator
   * @return I&
   */
  I &begin() { return i; }
  /**
   * @brief
   * end iterator
   * @return I&
   */
  I &end() { return n; }
  /**
   * @brief
   * 逆向きに参照するrange(reverse_rangeを取得できるs)
   * @return reverse_range
   */
  reverse_range operator!() { return reverse_range(*i, *n); }
};
/* #endregion */
/* #region template/MinMaxOperation.hpp*/
/**
 * @file MinMaxOperation.hpp
 * @author btk
 * @brief 最大値とか最小値を求める
 * @version 0.1
 * @date 2019-07-04
 *
 * @copyright Copyright (c) 2019
 *
 */

/**
 * @brief 2項の最小値求める
 *
 * @tparam T
 */
template <typename T> struct min_op {
  /**
   * @brief 本体
   *
   * @param l
   * @param r
   * @return T
   */
  static T exec(const T l, const T r) { return l < r ? l : r; }
};

/**
 * @brief 2項の最大値求める
 *
 * @tparam T
 */
template <typename T> struct max_op {
  /**
   * @brief 本体
   *
   * @param l
   * @param r
   * @return T
   */
  static T exec(const T l, const T r) { return l > r ? l : r; }
};

/**
 * @brief テンプレート再帰の末尾
 *
 * @tparam F 二項演算
 * @tparam T
 * @param v
 * @return T
 */
template <typename F, typename T> inline T multi_op(T &&v) { return v; }

/**
 * @brief 複数項における演算の結果を返す
 *
 * @tparam F
 * @tparam T
 * @tparam Ts
 * @param head
 * @param tail
 * @return T
 */
template <typename F, typename T, typename... Ts>
inline T multi_op(const T head, Ts &&...tail) {
  return F::exec(head, multi_op<F>(tail...));
}

/**
 * @brief 複数項の最小値
 * @see multi_op
 * @tparam T
 * @tparam Ts
 * @param head
 * @param tail
 * @return T
 */
template <typename T, typename... Ts>
inline T multi_min(T &&head, Ts &&...tail) {
  return multi_op<min_op<T>>(head, tail...);
}

/**
 * @brief 複数項の最大値
 * @see multi_op
 * @tparam T
 * @tparam Ts
 * @param head
 * @param tail
 * @return T
 */
template <typename T, typename... Ts>
inline T multi_max(T &&head, Ts &&...tail) {
  return multi_op<max_op<T>>(head, tail...);
}

/**
 * @brief
 * 先頭の値をFで参照する関数に基づいて変更できたらする
 * @tparam F
 * @tparam T
 * @tparam Ts
 * @param target
 * @param candidates
 * @return true
 * @return false
 */
template <typename F, typename T, typename... Ts>
inline bool ch_op(T &target, Ts &&...candidates) {
  const T old = target;
  target = multi_op<F>(target, candidates...);
  return old != target;
}

/**
 * @brief change min
 * @tparam T 型
 * @param target 変更する値
 * @param candidates
 * @return 更新があればtrue
 */
template <typename T, typename... Ts>
inline bool chmin(T &target, Ts &&...candidates) {
  return ch_op<min_op<T>>(target, candidates...);
}

/**
 * @brief chminのmax版
 * @see chmin
 *  @tparam T 型
 * @param target 変更する値
 * @param candidates
 * @return 更新があればtrue
 */
template <typename T, typename... Ts>
inline bool chmax(T &target, Ts &&...candidates) {
  return ch_op<max_op<T>>(target, candidates...);
}
/* #endregion */
/* #region template/Random.hpp*/
/**
 * @file Random.hpp
 * @author btk
 * @brief 乱数生成系
 * @version 0.1
 * @date 2019-07-13
 * @copyright Copyright (c) 2019
 */

//! 乱数のシード値をプロセスIDとして取得
const pid_t pid = getpid();

/**
 * @brief XorShift32の実装
 */
class XorShift32 {
private:
  //! XorShiftの現在の値
  unsigned value;

  /**
   * @brief XorShift32のアルゴリズムに基づいて value を更新
   */
  inline void update() {
    value = value ^ (value << 13);
    value = value ^ (value >> 17);
    value = value ^ (value << 5);
  }

  /**
   * @brief 値を更新し，更新前の値を返却
   * @return unsigned 呼び出し時の value を用いる
   */
  inline unsigned get() {
    unsigned v = value;
    update();
    return v;
  }

public:
  /**
   * @brief [0, 2^bit) の範囲の乱数値を取り出す
   * @tparam デフォルトは31
   * @return int
   */
  template <int bit = 31> inline int next_int() {
    return (int)(get() >> (32 - bit));
  }

  /**
   * @brief [-2^bit,2^bit)の範囲の乱数値を取り出す
   * @tparam デフォルトは31
   * @return int
   */
  template <int bit = 31> inline int next_signed() {
    unsigned v = get();
    return (int)((v >> (31 - bit)) - (1 << (bit)));
  }

  /**
   * @brief next_int呼び出し時の最大値を取得
   * @tparam 31
   * @return int
   */
  template <int bit = 31> inline int range_max() {
    return (int)((1u << bit) - 1);
  };

  /**
   * @brief Construct a new XorShift32 object
   * @param seed
   * @details 初期シードをvalueとするXorShift32のインスタンスを生成
   */
  XorShift32(const unsigned seed) {
    value = seed;
    update();
  }

  /**
   * @brief Construct a new XorShift 32 object
   * @details 初期シードをプロセスIDとするXorShift32のインスタンスを生成
   */
  XorShift32() : XorShift32(pid) {}
};
/* #endregion */
/* #region Template.hpp*/
/**
 * @file Template.hpp
 * @brief 競技プログラミング用テンプレート
 * @author btk15049
 * @date 2019/05/02
 */

/* #endregion */
/* #region string/RollingHash.hpp*/
/**
 * @file RollingHash.hpp
 * @brief ローリングハッシュ
 * @author btk15049
 * @date 2019/03/08
 * @details
 *  verify: CSA12E，RUPC day3 E
 */

#include <string>
#include <vector>

/**
 * @brief ローリングハッシュ
 * @details
 * ハッシュされている文字列のハッシュ値とポテンシャル（長さ）を管理．
 */
template <int base = 90001, int mod = 999999937> class RollingHash {
public:
  //! 文字列のハッシュ値
  long long hash;
  //! ハッシュ化されている文字列長をnとすると，base^n %mod
  long long potential;

  /**
   * @brief コンストラクタ
   * @details 引数無しで呼び出しは，空文字列のハッシュ化に相当する。
   */
  RollingHash(long long hash = 0, long long potential = 1)
      : hash(hash % mod), potential(potential) {}

  /**
   * @brief concatenation
   * @details
   *   ハッシュ値の合成を行う．ハッシュ化前の文字列を接続する操作にあたる．
   *   hash(s)+hash(t) == hash(s+t)
   */
  inline RollingHash operator+(const RollingHash o) const {
    return RollingHash((hash * o.potential + o.hash) % mod,
                       potential * o.potential % mod);
  }

  /**
   * @brief ハッシュ値の等価判定
   */
  inline bool operator==(const RollingHash o) const {
    return hash == o.hash && potential == o.potential;
  }

  /**
   * @brief 文字列をハッシュ化した配列を管理するクラス．
   */
  class Table {
  private:
    //! str[i] := hash(s[0,i))
    std::vector<RollingHash> str;

  public:
    /**
     * @brief デフォルトコンストラクタ
     */
    Table() {}
    /**
     * @brief コンストラクタ
     * @details O(n)でhash(s[0,i))を全部求める．
     */
    Table(const std::string s) {
      const int n = s.size();
      str.resize(n + 1);
      for (int i = 0; i < n; i++) {
        str[i + 1] = str[i] + RollingHash(s[i], base);
      }
    }

    /**
     * @brief 部分文字列のハッシュ値を取り出す
     * @details
     *   ハッシュ値の合成を行う．ハッシュ化前の文字列を接続する操作にあたる．
     *   hashtable(s).substr(lb,ub) == hash(s[lb,ub))
     */
    RollingHash substr(int lb, int ub) {
      return RollingHash(str[ub].hash -
                             str[lb].hash * str[ub - lb].potential % mod + mod,
                         str[ub - lb].potential);
    }
  };
};
/* #endregion */
/* #endregion */
/*</body>*/
#endif

constexpr LL INF = 1e7;
using RH = RollingHash<>;
string s, t;

RH::Table S, T;
using I = __int128;

LL ret = 0;

RH rep(RH rh, I rep_num) {
  RH ret;
  while (rep_num > 0) {
    if (rep_num & 1) {
      ret = ret + rh;
    }
    rh = rh + rh;
    rep_num >>= 1;
  }
  return ret;
}

bool check(int t_bg, LL s_rep) {
  I s_size = s.size();
  RH target = rep(S.substr(0, s.size()), s_rep);

  if (t_bg + s_size * s_rep <= t.size()) {
    return T.substr(t_bg, (int)(t_bg + s_size * s_rep)) == target;
  } else {
    I t_rep = (t_bg + s_size * s_rep) / t.size() - 1;
    int t_mod = (int)((t_bg + (I)s.size() * s_rep) % t.size());
    return T.substr(t_bg, t.size()) + rep(T.substr(0, t.size()), t_rep) +
               T.substr(0, t_mod) ==
           target;
  }
}

LL solve(int t_bg) {
  LL ok = ret;
  LL ng = INF + 1;
  while (abs(ok - ng) > 1) {
    const LL md = (ok + ng) / 2;
    (check(t_bg, md) ? ok : ng) = md;
  }
  return ok;
}

int main() {
  cin >> t >> s;
  // s = string(512345, 'a');
  // t = string(512345, 'a');
  // XorShift32 gen;
  // for (int i : range(512345)) {
  //    s[i] = gen.next_int() % 26 + 'a';
  //    t[i] = gen.next_int() % 26 + 'a';
  //}

  S = RH::Table(s);
  T = RH::Table(t);
  for (int i : range(t.size())) {
    if (t[i] != s[0])
      continue;
    chmax(ret, solve(i));
  }
  if (ret == INF)
    ret = -1;
  cout << ret << endl;
  return 0;
}

Fixed submission:
// https://atcoder.jp/contests/abc135/tasks/abc135_f
#include <bits/stdc++.h>
#include <sys/types.h>
#include <unistd.h>
#define CIN_ONLY
#define DECIMAL_DIGITS 10
#define STATIC_MOD 1e9 + 7

#ifdef BTK
/*<head>*/
#include "Template.hpp"
#include "string/RollingHash.hpp"
/*</head>*/
#else
/*<body>*/
/* #region auto includes */
/* #region stl */
/*<stl>*/
#include <bits/stdc++.h>
#include <sys/types.h>
#include <unistd.h>
using namespace std;
/*</stl>*/
/* #endregion */
/* #region template/IncludeSTL.hpp*/
/**
 * @file IncludeSTL.hpp
 * @author btk
 * @brief 標準ライブラリをincludeするだけ
 * @version 0.1
 * @date 2019-07-21
 *
 * @copyright Copyright (c) 2019
 *
 */

/*<head>*/
#pragma once
/*</head>*/

/*<stl>*/
#include <bits/stdc++.h>
#include <sys/types.h>
#include <unistd.h>
using namespace std;
/*</stl>*/
/* #endregion */
/* #region template/Macro.hpp*/
/**
 * @file Macro.hpp
 * @author btk
 * @brief マクロとか，LLとか
 * @version 0.1
 * @date 2019-07-13
 *
 * @copyright Copyright (c) 2019
 *
 */

//! LL
using LL = long long;

/**
 * @def DEBUG
 * @brief デバッグ用のif文 提出時はif(0)で実行されない
 */

/*</head>*/
#ifdef BTK
#define DEBUG if (1)
#else
#ifdef CIN_ONLY
#define FAST_IO
#endif
#define DEBUG if (0)
#endif
/**
 * @def ALL(v)
 * @brief
 * ALLマクロ
 */
#define ALL(v) (v).begin(), (v).end()

/**
 * @def REC(ret, ...)
 * @brief
 * 再帰ラムダをするためのマクロ
 */
#define REC(ret, ...) std::function<ret(__VA_ARGS__)>

/**
 * @def VAR_NAME(var)
 * @brief 変数名を取得する
 */
#define VAR_NAME(var) #var

/**
 * @brief
 * rangeで生まれる使わない変数を消す用（警告消し）
 */
template <typename T> inline T &unused_var(T &v) { return v; }
/* #endregion */
/* #region template/IO.hpp*/
/**
 * @file IO.hpp
 * @author btk
 * @brief cin高速化とか，出力の小数桁固定とか
 * @version 0.1
 * @date 2019-07-13
 *
 * @copyright Copyright (c) 2019
 */

/**
 * @brief 入出力の設定を行うための構造体
 */
struct cww {
  /**
   * @brief Construct a new cww::cww object
   * @details
   * CIN_ONLYを定義すると，submit時にcinとscanfの同期を切る設定が走る
   * DECIMAL_DIGITSを定義すると，doubleの出力時指定した桁数分小数部を吐くようになる
   */
  cww() {
#ifdef FAST_IO
    ios::sync_with_stdio(false);
    cin.tie(0);
#endif
#ifdef DECIMAL_DIGITS
    cout << fixed;
    cout << setprecision(DECIMAL_DIGITS);
#endif
  }
};

//! 入出力設定構造体を実体化
cww star;

/**
 * @brief
 * vectorに直接cin流すためのやつ
 * @tparam T
 * @param is
 * @param v
 * @return istream&
 */
template <typename T>
std::istream &operator>>(std::istream &is, std::vector<T> &v) {
  for (auto &it : v)
    is >> it;
  return is;
}
/* #endregion */
/* #region template/Loop.hpp*/
/**
 * @file Loop.hpp
 * @author btk
 * @brief rangeとかループ系のクラス
 * @version 0.1
 * @date 2019-07-13
 *
 * @copyright Copyright (c) 2019
 *
 */

/**
 * @brief
 * rangeを逆向きに操作したいとき用
 * @details
 * ループの範囲は[bg,ed)なので注意
 * @see range
 */
class reverse_range {
private:
  struct I {
    int x;
    int operator*() { return x - 1; }
    bool operator!=(I &lhs) { return x > lhs.x; }
    void operator++() { --x; }
  };
  I i, n;

public:
  /**
   * @brief Construct a new reverse range object
   *
   * @param n
   */
  reverse_range(int n) : i({0}), n({n}) {}
  /**
   * @brief Construct a new reverse range object
   *
   * @param i
   * @param n
   */
  reverse_range(int i, int n) : i({i}), n({n}) {}
  /**
   * @brief
   * begin iterator
   * @return I&
   */
  I &begin() { return n; }
  /**
   * @brief
   * end iterator
   * @return I&
   */
  I &end() { return i; }
};
/**
 * @brief
 * python みたいな range-based for を実現
 * @details
 * ループの範囲は[bg,ed)なので注意
 * !つけると逆向きにループが回る (reverse_range)
 * 空間計算量はO(1)
 * 使わない変数ができて警告が出がちなので，unused_varとかを使って警告消しするとよい
 */
class range {
private:
  struct I {
    int x;
    int operator*() { return x; }
    bool operator!=(I &lhs) { return x < lhs.x; }
    void operator++() { ++x; }
  };
  I i, n;

public:
  /**
   * @brief Construct a new range object
   *
   * @param n
   */
  range(int n) : i({0}), n({n}) {}
  /**
   * @brief Construct a new range object
   *
   * @param i
   * @param n
   */
  range(int i, int n) : i({i}), n({n}) {}
  /**
   * @brief
   * begin iterator
   * @return I&
   */
  I &begin() { return i; }
  /**
   * @brief
   * end iterator
   * @return I&
   */
  I &end() { return n; }
  /**
   * @brief
   * 逆向きに参照するrange(reverse_rangeを取得できるs)
   * @return reverse_range
   */
  reverse_range operator!() { return reverse_range(*i, *n); }
};
/* #endregion */
/* #region template/MinMaxOperation.hpp*/
/**
 * @file MinMaxOperation.hpp
 * @author btk
 * @brief 最大値とか最小値を求める
 * @version 0.1
 * @date 2019-07-04
 *
 * @copyright Copyright (c) 2019
 *
 */

/**
 * @brief 2項の最小値求める
 *
 * @tparam T
 */
template <typename T> struct min_op {
  /**
   * @brief 本体
   *
   * @param l
   * @param r
   * @return T
   */
  static T exec(const T l, const T r) { return l < r ? l : r; }
};

/**
 * @brief 2項の最大値求める
 *
 * @tparam T
 */
template <typename T> struct max_op {
  /**
   * @brief 本体
   *
   * @param l
   * @param r
   * @return T
   */
  static T exec(const T l, const T r) { return l > r ? l : r; }
};

/**
 * @brief テンプレート再帰の末尾
 *
 * @tparam F 二項演算
 * @tparam T
 * @param v
 * @return T
 */
template <typename F, typename T> inline T multi_op(T &&v) { return v; }

/**
 * @brief 複数項における演算の結果を返す
 *
 * @tparam F
 * @tparam T
 * @tparam Ts
 * @param head
 * @param tail
 * @return T
 */
template <typename F, typename T, typename... Ts>
inline T multi_op(const T head, Ts &&...tail) {
  return F::exec(head, multi_op<F>(tail...));
}

/**
 * @brief 複数項の最小値
 * @see multi_op
 * @tparam T
 * @tparam Ts
 * @param head
 * @param tail
 * @return T
 */
template <typename T, typename... Ts>
inline T multi_min(T &&head, Ts &&...tail) {
  return multi_op<min_op<T>>(head, tail...);
}

/**
 * @brief 複数項の最大値
 * @see multi_op
 * @tparam T
 * @tparam Ts
 * @param head
 * @param tail
 * @return T
 */
template <typename T, typename... Ts>
inline T multi_max(T &&head, Ts &&...tail) {
  return multi_op<max_op<T>>(head, tail...);
}

/**
 * @brief
 * 先頭の値をFで参照する関数に基づいて変更できたらする
 * @tparam F
 * @tparam T
 * @tparam Ts
 * @param target
 * @param candidates
 * @return true
 * @return false
 */
template <typename F, typename T, typename... Ts>
inline bool ch_op(T &target, Ts &&...candidates) {
  const T old = target;
  target = multi_op<F>(target, candidates...);
  return old != target;
}

/**
 * @brief change min
 * @tparam T 型
 * @param target 変更する値
 * @param candidates
 * @return 更新があればtrue
 */
template <typename T, typename... Ts>
inline bool chmin(T &target, Ts &&...candidates) {
  return ch_op<min_op<T>>(target, candidates...);
}

/**
 * @brief chminのmax版
 * @see chmin
 *  @tparam T 型
 * @param target 変更する値
 * @param candidates
 * @return 更新があればtrue
 */
template <typename T, typename... Ts>
inline bool chmax(T &target, Ts &&...candidates) {
  return ch_op<max_op<T>>(target, candidates...);
}
/* #endregion */
/* #region template/Random.hpp*/
/**
 * @file Random.hpp
 * @author btk
 * @brief 乱数生成系
 * @version 0.1
 * @date 2019-07-13
 * @copyright Copyright (c) 2019
 */

//! 乱数のシード値をプロセスIDとして取得
const pid_t pid = getpid();

/**
 * @brief XorShift32の実装
 */
class XorShift32 {
private:
  //! XorShiftの現在の値
  unsigned value;

  /**
   * @brief XorShift32のアルゴリズムに基づいて value を更新
   */
  inline void update() {
    value = value ^ (value << 13);
    value = value ^ (value >> 17);
    value = value ^ (value << 5);
  }

  /**
   * @brief 値を更新し，更新前の値を返却
   * @return unsigned 呼び出し時の value を用いる
   */
  inline unsigned get() {
    unsigned v = value;
    update();
    return v;
  }

public:
  /**
   * @brief [0, 2^bit) の範囲の乱数値を取り出す
   * @tparam デフォルトは31
   * @return int
   */
  template <int bit = 31> inline int next_int() {
    return (int)(get() >> (32 - bit));
  }

  /**
   * @brief [-2^bit,2^bit)の範囲の乱数値を取り出す
   * @tparam デフォルトは31
   * @return int
   */
  template <int bit = 31> inline int next_signed() {
    unsigned v = get();
    return (int)((v >> (31 - bit)) - (1 << (bit)));
  }

  /**
   * @brief next_int呼び出し時の最大値を取得
   * @tparam 31
   * @return int
   */
  template <int bit = 31> inline int range_max() {
    return (int)((1u << bit) - 1);
  };

  /**
   * @brief Construct a new XorShift32 object
   * @param seed
   * @details 初期シードをvalueとするXorShift32のインスタンスを生成
   */
  XorShift32(const unsigned seed) {
    value = seed;
    update();
  }

  /**
   * @brief Construct a new XorShift 32 object
   * @details 初期シードをプロセスIDとするXorShift32のインスタンスを生成
   */
  XorShift32() : XorShift32(pid) {}
};
/* #endregion */
/* #region Template.hpp*/
/**
 * @file Template.hpp
 * @brief 競技プログラミング用テンプレート
 * @author btk15049
 * @date 2019/05/02
 */

/* #endregion */
/* #region string/RollingHash.hpp*/
/**
 * @file RollingHash.hpp
 * @brief ローリングハッシュ
 * @author btk15049
 * @date 2019/03/08
 * @details
 *  verify: CSA12E，RUPC day3 E
 */

#include <string>
#include <vector>

/**
 * @brief ローリングハッシュ
 * @details
 * ハッシュされている文字列のハッシュ値とポテンシャル（長さ）を管理．
 */
template <int base = 90001, int mod = 999999937> class RollingHash {
public:
  //! 文字列のハッシュ値
  long long hash;
  //! ハッシュ化されている文字列長をnとすると，base^n %mod
  long long potential;

  /**
   * @brief コンストラクタ
   * @details 引数無しで呼び出しは，空文字列のハッシュ化に相当する。
   */
  RollingHash(long long hash = 0, long long potential = 1)
      : hash(hash % mod), potential(potential) {}

  /**
   * @brief concatenation
   * @details
   *   ハッシュ値の合成を行う．ハッシュ化前の文字列を接続する操作にあたる．
   *   hash(s)+hash(t) == hash(s+t)
   */
  inline RollingHash operator+(const RollingHash o) const {
    return RollingHash((hash * o.potential + o.hash) % mod,
                       potential * o.potential % mod);
  }

  /**
   * @brief ハッシュ値の等価判定
   */
  inline bool operator==(const RollingHash o) const {
    return hash == o.hash && potential == o.potential;
  }

  /**
   * @brief 文字列をハッシュ化した配列を管理するクラス．
   */
  class Table {
  private:
    //! str[i] := hash(s[0,i))
    std::vector<RollingHash> str;

  public:
    /**
     * @brief デフォルトコンストラクタ
     */
    Table() {}
    /**
     * @brief コンストラクタ
     * @details O(n)でhash(s[0,i))を全部求める．
     */
    Table(const std::string s) {
      const int n = s.size();
      str.resize(n + 1);
      for (int i = 0; i < n; i++) {
        str[i + 1] = str[i] + RollingHash(s[i], base);
      }
    }

    /**
     * @brief 部分文字列のハッシュ値を取り出す
     * @details
     *   ハッシュ値の合成を行う．ハッシュ化前の文字列を接続する操作にあたる．
     *   hashtable(s).substr(lb,ub) == hash(s[lb,ub))
     */
    RollingHash substr(int lb, int ub) {
      return RollingHash(str[ub].hash -
                             str[lb].hash * str[ub - lb].potential % mod + mod,
                         str[ub - lb].potential);
    }
  };
};
/* #endregion */
/* #endregion */
/*</body>*/
#endif

constexpr LL INF = 1e6;
using RH = RollingHash<>;
string s, t;

RH::Table S, T;
using I = __int128;

LL ret = 0;

RH rep(RH rh, I rep_num) {
  RH ret;
  while (rep_num > 0) {
    if (rep_num & 1) {
      ret = ret + rh;
    }
    rh = rh + rh;
    rep_num >>= 1;
  }
  return ret;
}

bool check(int t_bg, LL s_rep) {
  I s_size = s.size();
  RH target = rep(S.substr(0, s.size()), s_rep);

  if (t_bg + s_size * s_rep <= t.size()) {
    return T.substr(t_bg, (int)(t_bg + s_size * s_rep)) == target;
  } else {
    I t_rep = (t_bg + s_size * s_rep) / t.size() - 1;
    int t_mod = (int)((t_bg + (I)s.size() * s_rep) % t.size());
    return T.substr(t_bg, t.size()) + rep(T.substr(0, t.size()), t_rep) +
               T.substr(0, t_mod) ==
           target;
  }
}

LL solve(int t_bg) {
  LL ok = ret;
  LL ng = INF + 1;
  while (abs(ok - ng) > 1) {
    const LL md = (ok + ng) / 2;
    (check(t_bg, md) ? ok : ng) = md;
  }
  return ok;
}

int main() {
  cin >> t >> s;
  // s = string(512345, 'a');
  // t = string(512345, 'a');
  // XorShift32 gen;
  // for (int i : range(512345)) {
  //    s[i] = gen.next_int() % 26 + 'a';
  //    t[i] = gen.next_int() % 26 + 'a';
  //}

  S = RH::Table(s);
  T = RH::Table(t);
  for (int i : range(t.size())) {
    if (t[i] != s[0])
      continue;
    chmax(ret, solve(i));
  }
  if (ret == INF)
    ret = -1;
  cout << ret << endl;
  return 0;
}