// rabin karp single hash
const int mod = 1e9 + 7;
class Solution {
  long long hashValue(string str, long long radix, long long m) {
    long long ans = 0, factor = 1;
    for (long long i = m - 1; i >= 0; i--) {
      ans += ((str[i] - 'a') * factor) % mod;
      factor = (factor * radix) % mod;
    }
    return ans % mod;
  }
 
 public:
  int strStr(string haystack, string needle) {
    int n = haystack.size(), m = needle.size();
    if (n < m) return -1;
 
    long long radix = 26, max_w = 1;
    for (int i = 1; i <= m; i++) {
      max_w = (max_w * radix) % mod;
    }
    long long hashNeedle = hashValue(needle, radix, m), hashHay = 0;
 
    for (long long i = 0; i <= n - m; i++) {
      if (i == 0) {
        hashHay = hashValue(haystack, radix, m);
      } else {
        hashHay =
            ((hashHay * radix) % mod - ((haystack[i - 1] - 'a') * max_w) % mod +
             (haystack[i + m - 1] - 'a') + mod) %
            mod;
      }
 
      if (hashNeedle == hashHay) {
        for (int j = 0; j < m; j++) {
          if (needle[j] != haystack[j + i]) break;
          if (j == m - 1) return i;
        }
      }
    }
    return -1;
  }
};
 
// rabin karp double hashing
class Solution {
 public:
  const long long radix1 = 26, radix2 = 27, mod1 = 1e9 + 7, mod2 = 1e9 + 33;
 
  pair<long long, long long> hashPair(string str, int m) {
    long long hash1 = 0, hash2 = 0;
    long long factor1 = 1, factor2 = 1;
 
    for (int i = m - 1; i >= 0; i--) {
      hash1 += ((str[i] - 'a') * factor1) % mod1;
      factor1 = (factor1 * radix1) % mod1;
      hash2 += ((str[i] - 'a') * factor2) % mod2;
      factor2 = (factor2 * radix2) % mod2;
    }
    return {hash1 % mod1, hash2 % mod2};
  }
 
  int strStr(string haystack, string needle) {
    long long n = haystack.length(), m = needle.length();
    if (n < m) return -1;
 
    long long maxw1 = 1, maxw2 = 1;
    for (int i = 0; i < m; i++) {
      maxw1 = (maxw1 * radix1) % mod1;
      maxw2 = (maxw2 * radix2) % mod2;
    }
 
    pair<long long, long long> hashNeedle = hashPair(needle, m);
    pair<long long, long long> hashHay = {0, 0};
 
    for (long long i = 0; i <= n - m; i++) {
      if (i == 0) {
        hashHay = hashPair(haystack, m);
      } else {
        hashHay.first = ((hashHay.first * radix1) % mod1 -
                         ((haystack[i - 1] - 'a') * maxw1) % mod1 +
                         (haystack[i + m - 1] - 'a') + mod1) %
                        mod1;
 
        hashHay.second = ((hashHay.second * radix2) % mod2 -
                          ((haystack[i - 1] - 'a') * maxw2) % mod2 +
                          (haystack[i + m - 1] - 'a') + mod2) %
                         mod2;
      }
      if (hashNeedle.first == hashHay.first &&
          hashNeedle.second == hashHay.second)
        return i;
    }
    return -1;
  }
};