Problem:
Score : 600 points

Problem Statement

Given are two strings s and t consisting of lowercase English letters. Determine if the number of non-negative integers i satisfying the following condition is finite, and find the maximum value of such i if the number is finite.

There exists a non-negative integer j such that the concatenation of i copies of t is a substring of the concatenation of j copies of s.

Notes

A string a is a substring of another string b if and only if there exists an integer x (0 \leq x \leq |b| - |a|) such that, for any y (1 \leq y \leq |a|), a_y = b_{x+y} holds.

We assume that the concatenation of zero copies of any string is the empty string. From the definition above, the empty string is a substring of any string. Thus, for any two strings s and t, i = 0 satisfies the condition in the problem statement.

Constraints

1 \leq |s| \leq 5 \times 10^5

1 \leq |t| \leq 5 \times 10^5

s and t consist of lowercase English letters.

Input

Input is given from Standard Input in the following format:

s
t

Output

If the number of non-negative integers i satisfying the following condition is finite, print the maximum value of such i; if the number is infinite, print -1.

Sample Input 1

abcabab
ab

Sample Output 1

3

The concatenation of three copies of t, ababab, is a substring of the concatenation of two copies of s, abcabababcabab, so i = 3 satisfies the condition.

On the other hand, the concatenation of four copies of t, abababab, is not a substring of the concatenation of any number of copies of s, so i = 4 does not satisfy the condition.

Similarly, any integer greater than 4 does not satisfy the condition, either. Thus, the number of non-negative integers i satisfying the condition is finite, and the maximum value of such i is 3.

Sample Input 2

aa
aaaaaaa

Sample Output 2

-1

For any non-negative integer i, the concatenation of i copies of t is a substring of the concatenation of 4i copies of s. Thus, there are infinitely many non-negative integers i that satisfy the condition.

Sample Input 3

aba
baaab

Sample Output 3

0

As stated in Notes, i = 0 always satisfies the condition.

Solution in C# (Mono 4.6.2.0) (judge verdict: Time Limit Exceeded)

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;



class Myon
{
    public Myon() { }
    public static int Main()
    {
        cin = new Scanner();
        new Myon().calc();
        return 0;
    }

    static Scanner cin;

    void calc()
    {
        string S = cin.next();
        int N = S.Length;
        string T = cin.next();

        StringBuilder sb = new StringBuilder();
        sb.Append(S);
        sb.Append(S);
        sb.Append(S);
        while (T.Length * 2 > sb.Length) sb.Append(S);

        S = sb.ToString();

        bool[] ok = new bool[N];
        for (int i = 0; i < N; i++)
        {
            //okに、「S[i]から文字列Tがあるか」を入れる
            if (S.IndexOf(T, i) == i)
            {
                ok[i] = true;
            }
        }

        init(N);
        for (int i = 0; i < N; i++)
        {
            if (ok[i] && ok[(i + T.Length) % N])
            {
                if (!connect(i, (i + T.Length) % N))
                {
                    Console.WriteLine(-1);
                    return;
                }
            }
        }

        int ans = 0;
        for (int i = 0; i < N; i++)
        {
            if (ok[i])
            {
                int r = root(i);
                ans = Math.Max(ans, -uni[r]);
            }
        }

        Console.WriteLine(ans);
    }

    int[] uni;
    void init(int N)
    {
        uni = new int[N];
        for (int i = 0; i < N; i++)
        {
            uni[i] = -1;
        }
    }

    int root(int a)
    {
        if (uni[a] < 0) return a;
        else return uni[a] = root(uni[a]);
    }

    bool connect(int a, int b)
    {
        a = root(a);
        b = root(b);
        if (a == b) return false;
        if (uni[a] > uni[b]) swap(ref a, ref b);
        uni[a] += uni[b];
        uni[b] = a;
        return true;
    }

    void swap<T>(ref T a, ref T b)
    {
        T c = a;
        a = b;
        b = c;
    }  


}

class RollingHash<T> where T : IComparable<T>, IConvertible
{
    int[] mod = { (int)(1e9 + 7), (int)(1e9 + 9), 1234567891 };
    int[] K = { 1007, 1009, 1013 };
    public T[] S;
    long[,] hash;
    long[,] powTable;

    public RollingHash(T[] S)
    {
        this.S = S;
        hash = new long[mod.Length, S.Length + 1];
        for (int i = 0; i < mod.Length; i++)
        {
            for (int j = S.Length - 1; j >= 0; j--)
            {
                hash[i, j] = hash[i, j + 1] * K[i];
                hash[i, j] += Convert.ToInt64(S[j]);
                hash[i, j] %= mod[i];
            }
        }

        powTable = new long[mod.Length, S.Length + 1];
        for (int i = 0; i < mod.Length; i++)
        {
            powTable[i, 0] = 1;
            for (int j = 1; j < S.Length + 1; j++)
            {
                powTable[i, j] = (powTable[i, j - 1] * K[i]) % mod[i];
            }
        }
    }

    public long getHash(int t, int start, int end)
    {
        long r = hash[t, start] - hash[t, end] * powTable[t, end - start];
        r %= mod[t];
        if (r < 0) r += mod[t];
        return r;
    }

    public bool isSame(int Astart, int Bstart, int Aend, int Bend)
    {
        int len = Aend - Astart;
        if (len != Bend - Bstart) return false;
        for (int i = 0; i < mod.Length; i++)
        {
            if (getHash(i, Astart, Aend) != getHash(i, Bstart, Bend)) return false;
        }
        return true;
    }

    public bool isSame(int Astart, int Bstart, int Aend, int Bend, RollingHash<T> rh)
    {
        if (rh == null) return isSame(Astart, Bstart, Aend, Bend);
        int len = Aend - Astart;
        if (len != Bend - Bstart) return false;
        for (int i = 0; i < mod.Length; i++)
        {
            if (getHash(i, Astart, Aend) != rh.getHash(i, Bstart, Bend)) return false;
        }
        return true;
    }


    public int compare(int Astart, int Bstart, int Aend, int Bend, RollingHash<T> rh = null)
    {
        int Alen = Aend - Astart;
        int Blen = Bend - Bstart;

        int len = Math.Min(Alen, Blen);
        int maxlen = len + 1;
        int minlen = 0;
        while (minlen + 1 < maxlen)
        {
            int nextlen = (maxlen + minlen) / 2;
            if (isSame(Astart, Bstart, Astart + nextlen, Bstart + nextlen, rh))
            {
                minlen = nextlen;
            }
            else
            {
                maxlen = nextlen;
            }
        }

        if (Astart + minlen == Aend)
        {
            if (Bstart + minlen == Bend) return 0;
            else return -1;
        }
        else
        {
            if (Bstart + minlen == Bend) return 1;
            else return S[Astart + minlen].CompareTo(S[Bstart + minlen]);
        }
    }

    public int compare(int Astart, int Bstart)
    {
        if (revSA != null)
        {
            return revSA[Astart].CompareTo(revSA[Bstart]);
        }
        return compare(Astart, Bstart, S.Length, S.Length);
    }

    public int compare(int Astart, int Bstart, RollingHash<T> rh)
    {
        return compare(Astart, Bstart, S.Length, rh.S.Length);
    }

    public int[] SA;
    public int[] revSA;

    public int[] makeSuffixArray()
    {
        SA = new int[S.Length];
        for (int i = 0; i < S.Length; i++)
        {
            SA[i] = i;
        }
        Array.Sort(SA, compare);
        revSA = new int[S.Length];
        for (int i = 0; i < S.Length; i++)
        {
            revSA[SA[i]] = i;
        }
        return SA;
    }

}




class Scanner
{
    string[] s;
    int i;

    char[] cs = new char[] { ' ' };

    public Scanner()
    {
        s = new string[0];
        i = 0;
    }

    public string next()
    {
        if (i < s.Length) return s[i++];
        string st = Console.ReadLine();
        while (st == "") st = Console.ReadLine();
        s = st.Split(cs, StringSplitOptions.RemoveEmptyEntries);
        if (s.Length == 0) return next();
        i = 0;
        return s[i++];
    }

    public int nextInt()
    {
        return int.Parse(next());
    }
    public int[] ArrayInt(int N, int add = 0)
    {
        int[] Array = new int[N];
        for (int i = 0; i < N; i++)
        {
            Array[i] = nextInt() + add;
        }
        return Array;
    }

    public long nextLong()
    {
        return long.Parse(next());
    }

    public long[] ArrayLong(int N, long add = 0)
    {
        long[] Array = new long[N];
        for (int i = 0; i < N; i++)
        {
            Array[i] = nextLong() + add;
        }
        return Array;
    }

    public double nextDouble()
    {
        return double.Parse(next());
    }


    public double[] ArrayDouble(int N, double add = 0)
    {
        double[] Array = new double[N];
        for (int i = 0; i < N; i++)
        {
            Array[i] = nextDouble() + add;
        }
        return Array;
    }
}