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 Rust (1.15.1) (judge verdict: Accepted)

#[macro_use]
mod input_mcr {
    // ref: tanakh <https://qiita.com/tanakh/items/0ba42c7ca36cd29d0ac8>
    // diff: using Parser
    #[macro_export(local_inner_macros)]
    macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut parser = Parser::from_str($s);
        input_inner!{parser, $($r)*}
    };
    (parser = $parser:ident, $($r:tt)*) => {
        input_inner!{$parser, $($r)*}
    };
    (new_stdin_parser = $parser:ident, $($r:tt)*) => {
        let stdin = std::io::stdin();
        let reader = std::io::BufReader::new(stdin.lock());
        let mut $parser = Parser::new(reader);
        input_inner!{$parser, $($r)*}
    };
    ($($r:tt)*) => {
        input!{new_stdin_parser = parser, $($r)*}
    };
}

    #[macro_export(local_inner_macros)]
    macro_rules! input_inner {
    ($parser:ident) => {};
    ($parser:ident, ) => {};
    ($parser:ident, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($parser, $t);
        input_inner!{$parser $($r)*}
    };
}

    #[macro_export(local_inner_macros)]
    macro_rules! read_value {
    ($parser:ident, ( $($t:tt),* )) => {
        ( $(read_value!($parser, $t)),* )
    };
    ($parser:ident, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($parser, $t)).collect::<Vec<_>>()
    };
    ($parser:ident, chars) => {
        read_value!($parser, String).chars().collect::<Vec<char>>()
    };
    ($parser:ident, char_) => {
        read_value!($parser, String).chars().collect::<Vec<char>>()[0]
    };
    ($parser:ident, usize1) => {
        read_value!($parser, usize) - 1
    };
    ($parser:ident, line) => {
        $parser.next_line()
    };
    ($parser:ident, line_) => {
        $parser.next_line().chars().collect::<Vec<char>>()
    };
    ($parser:ident, i64_) => {
        $parser.fast_i64()
    };
    ($parser:ident, usize_) => {
        $parser.fast_i64() as usize
    };
    ($parser:ident, usize1_) => {
        ($parser.fast_i64() - 1) as usize
    };
    ($parser:ident, $t:ty) => {
        $parser.next::<$t>().expect("Parse error")
    };
}

    use std::io;
    use std::io::BufRead;
    use std::str;

    // ref: tatsuya6502 <https://qiita.com/tatsuya6502/items/cd448486f7ef7b5b8c7e>
    // ref: wariuni <https://qiita.com/tatsuya6502/items/cd448486f7ef7b5b8c7e#comment-7040a5ae96305e884eb9>
    // diff: using std::io::BufRead::fill_buf()
    pub struct Parser<R> {
        pub reader: R,
        buf: Vec<u8>,
        pos: usize,
    }

    impl Parser<io::Empty> {
        pub fn from_str(s: &str) -> Parser<io::Empty> {
            Parser {
                reader: io::empty(),
                buf: s.as_bytes().to_vec(),
                pos: 0,
            }
        }
    }

    impl<R: BufRead> Parser<R> {
        pub fn new(reader: R) -> Parser<R> {
            Parser {
                reader: reader,
                buf: vec![],
                pos: 0,
            }
        }
        pub fn update_buf(&mut self) {
            self.buf.clear();
            self.pos = 0;
            loop {
                let (len, complete) = {
                    let buf2 = self.reader.fill_buf().unwrap();
                    self.buf.extend_from_slice(buf2);
                    let len = buf2.len();
                    (len, buf2[len - 1] <= 0x20)
                };
                self.reader.consume(len);
                if complete {
                    break;
                }
            }
        }
        pub fn next<T: str::FromStr>(&mut self) -> Result<T, T::Err> {
            loop {
                let mut begin = self.pos;
                while begin < self.buf.len() && (self.buf[begin] <= 0x20) {
                    begin += 1;
                }
                let mut end = begin;
                while end < self.buf.len() && (self.buf[end] > 0x20) {
                    end += 1;
                }
                if begin != self.buf.len() {
                    self.pos = end;
                    return unsafe { str::from_utf8_unchecked(&self.buf[begin..end]) }.parse::<T>();
                } else {
                    self.update_buf();
                }
            }
        }
        pub fn next_line(&mut self) -> String {
            loop {
                let mut begin = self.pos;
                if begin < self.buf.len() && (self.buf[begin] < 0x20) {
                    begin += 1;
                }
                let mut end = begin;
                while end < self.buf.len() && (self.buf[end] >= 0x20) {
                    end += 1;
                }
                if begin != self.buf.len() {
                    self.pos = end;
                    return unsafe { str::from_utf8_unchecked(&self.buf[begin..end]) }.to_string();
                } else {
                    self.update_buf();
                }
            }
        }
        pub fn fast_i64(&mut self) -> i64 {
            loop {
                let mut begin = self.pos;
                while begin < self.buf.len() && (self.buf[begin] <= 0x20) {
                    begin += 1;
                }
                if begin == self.buf.len() {
                    self.update_buf();
                    continue;
                }
                let mut res = 0;
                let (is_positive, mut end) = match self.buf[begin] {
                    b'+' => (true, begin + 1),
                    b'-' => (false, begin + 1),
                    _ => (true, begin),
                };
                while end < self.buf.len() && (self.buf[end] > 0x20) {
                    res = res * 10 + (self.buf[end] as i64 - '0' as i64);
                    end += 1;
                }
                if begin != self.buf.len() {
                    self.pos = end;
                    return if is_positive { res } else { -res };
                } else {
                    self.update_buf();
                }
            }
        }
    }
}

use input_mcr::*;
use std::cmp::*;

// ref: https://qiita.com/keymoon/items/11fac5627672a6d6a9f6
use std::ops::*;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct RollingHashValue(u64);

impl RollingHashValue {
    pub fn new(x: u64) -> RollingHashValue {
        RollingHashValue(x)
    }
    pub fn new_with_mod(x: u64) -> RollingHashValue {
        let m = (1 << 61) - 1;
        let xu = x >> 61;
        let xd = x & m;
        let res = xu + xd;
        RollingHashValue(if res >= m { res - m } else { res })
    }
}

impl Add for RollingHashValue {
    type Output = RollingHashValue;
    fn add(self, rhs: RollingHashValue) -> RollingHashValue {
        RollingHashValue((self.0 + rhs.0) % ((1 << 61) - 1))
    }
}

impl Sub for RollingHashValue {
    type Output = RollingHashValue;
    fn sub(self, rhs: RollingHashValue) -> RollingHashValue {
        let m = (1 << 61) - 1;
        RollingHashValue((self.0 + m - rhs.0) % m)
    }
}

impl Mul for RollingHashValue {
    type Output = RollingHashValue;
    fn mul(self, rhs: RollingHashValue) -> RollingHashValue {
        let x = self.0;
        let y = rhs.0;
        let (xu, xd) = (x >> 31, x & ((1 << 31) - 1));
        let (yu, yd) = (y >> 31, y & ((1 << 31) - 1));
        let zm = xd * yu + xu * yd;
        let zu = zm >> 30;
        let zd = zm & ((1 << 30) - 1);
        RollingHashValue::new_with_mod(xu * yu * 2 + zu + (zd << 31) + xd * yd)
    }
}

pub struct RollingHash {
    n: usize,
    hash: Vec<RollingHashValue>,
    pows: Vec<RollingHashValue>,
}

impl RollingHash {
    pub fn new(s: &Vec<char>, base: u64) -> RollingHash {
        let n = s.len();
        let base = RollingHashValue::new_with_mod(base);
        let mut pows = vec![RollingHashValue::new(1)];
        for i in 0..n {
            let t = pows[i] * base;
            pows.push(t);
        }
        let mut hash = vec![RollingHashValue::new(0)];
        for i in 0..n {
            let t = hash[i] * base + RollingHashValue::new(s[i] as u64);
            hash.push(t);
        }
        RollingHash {
            n: n,
            hash: hash,
            pows: pows,
        }
    }
    pub fn get(&self, i: usize, k: usize) -> RollingHashValue {
        let res = if i <= k {
            self.hash[k] - self.hash[i] * self.pows[k - i]
        } else {
            (self.hash[self.n] - self.hash[i] * self.pows[self.n - i]) * self.pows[k] + self.hash[k]
        };
        // eprintln!("l = {}, r = {}, res = {:?}", i, k, res);
        res
    }
    pub fn left(&self, i: usize, len: usize) -> RollingHashValue {
        self.get((i + self.n - len) % self.n, i)
    }
    pub fn right(&self, i: usize, len: usize) -> RollingHashValue {
        self.get(i, (i + len) % self.n)
    }
}

fn main() {
    input! {
        s: chars,
        t: chars,
    }
    let mut s = s;
    while s.len() < t.len() * 2 {
        for i in 0..s.len() {
            let t = s[i];
            s.push(t);
        }
    }
    let base = 128379174;
    let s_rh = RollingHash::new(&s, base);
    let t_rh = RollingHash::new(&t, base);
    let n = t.len();
    let key = t_rh.get(0, n);
    // eprintln!("key = {:?}", key);
    let mut xs = vec![0; s.len()];
    let mut next_id = 1;
    for i in 0..s.len() {
        // eprintln!("loop: i = {}", i);
        if xs[i] != 0 {
            continue;
        }
        xs[i] = next_id;
        let mut k = i;
        while s_rh.right(k, n) == key {
            if xs[(k + n) % s.len()] == next_id {
                println!("-1");
                return;
            }
            k = (k + n) % s.len();
            xs[k] = next_id;
        }
        let mut k = i;
        while s_rh.left(k, n) == key {
            if xs[(k + s.len() - n) % s.len()] == next_id {
                println!("-1");
                return;
            }
            k = (k + s.len() - n) % s.len();
            xs[k] = next_id;
        }
        next_id += 1;
    }
    // eprintln!("xs = {:?}", xs);
    let mut count = vec![0; s.len() + 1];
    for &x in &xs {
        count[x] += 1;
    }
    let res = count.iter().max().unwrap();
    println!("{}", res - 1);
}