Problem:
Score : 300 points

Problem Statement

You are given a string S of length N and another string T of length M.
These strings consist of lowercase English letters.

A string X is called a good string when the following conditions are all met:

Let L be the length of X. L is divisible by both N and M.

Concatenating the 1-st, (\frac{L}{N}+1)-th, (2 \times \frac{L}{N}+1)-th, ..., ((N-1)\times\frac{L}{N}+1)-th characters of X, without changing the order, results in S.

Concatenating the 1-st, (\frac{L}{M}+1)-th, (2 \times \frac{L}{M}+1)-th, ..., ((M-1)\times\frac{L}{M}+1)-th characters of X, without changing the order, results in T.

Determine if there exists a good string. If it exists, find the length of the shortest such string.

Constraints

1 \leq N,M \leq 10^5

S and T consist of lowercase English letters.

|S|=N

|T|=M

Input

Input is given from Standard Input in the following format:

N M
S
T

Output

If a good string does not exist, print -1; if it exists, print the length of the shortest such string.

Sample Input 1

3 2
acp
ae

Sample Output 1

6

For example, the string accept is a good string.
There is no good string shorter than this, so the answer is 6.

Sample Input 2

6 3
abcdef
abc

Sample Output 2

-1

Sample Input 3

15 9
dnsusrayukuaiia
dujrunuma

Sample Output 3

45

Solution in Java8 (OpenJDK 1.8.0) (judge verdict: Runtime Error)

package A;

import java.io.PrintWriter;
import java.util.*;

/**
 * Hello AtCoder.
 *
 * @author kaito0228
 */
public class Main {
  public static void main(String[] args) {
    try (PrintWriter out = new PrintWriter(System.out);
         Scanner sc = new Scanner(System.in)) {
      Task task = new Task();
      task.solve(sc, out);
      out.flush();

    } catch (Exception e) {
      // DO NOT USE
      e.printStackTrace();
    }
  }

  private static class Task {
    private void solve(Scanner sc, PrintWriter out) {
      // TODO
      int n = nint(sc);
      int m = nint(sc);

      String s = nstr(sc);
      String t = nstr(sc);

      String[] ss = s.split("");
      String[] tt = t.split("");

      if (!ss[0].equals(tt[0])){
        out.println(-1);
        return;
      }

      long l = lcm(n,m);

      long ansn = l/n;
      long ansm = l/m;
      long minans;
      if (ansn > ansm){
        minans = ansm;
      }else {
        minans = ansn;
      }



      if (l == n || l == m){
        int min;
        if(n > m){
          min = m;
        }else {
          min = n;
        }
        for (int i = 0; i < min; i++) {
          if (ss[Math.toIntExact(i * ansm)].equals(tt[Math.toIntExact(i * ansn)])){
            continue;
          }else {
            out.println(-1);
            return;
          }
        }
      }


      if (n * m > l) {
        for (int i = 0; i < minans; i++) {
          if (ss[Math.toIntExact(i * ansm)].equals(tt[Math.toIntExact(i * ansn)])) {
            continue;
          } else {
            out.println(-1);
            return;
          }
        }
      }

      out.println(l);
    }

    // method
    /**
     * Returns an int. int値を受け取り、返します。
     *
     * @param sc Scanner
     * @return int
     */
    private static int nint(Scanner sc) {
      return Integer.parseInt(sc.next());
    }

    /**
     * Returns a long. long値を受け取り、返します。
     *
     * @param sc Scanner
     * @return long
     */
    private static long nlong(Scanner sc) {
      return Long.parseLong(sc.next());
    }

    /**
     * Returns a double. double値を受け取り、返します。
     *
     * @param sc Scanner
     * @return double
     */
    private static double ndouble(Scanner sc) {
      return Double.parseDouble(sc.next());
    }

    /**
     * Returns a String. 文字列を受け取り、返します。
     *
     * @param sc Scanner
     * @return String
     */
    private static String nstr(Scanner sc) {
      return sc.next();
    }

    /**
     * Returns a int array. int値を受け取り、配列にして返します。
     *
     * @param sc Scanner
     * @param length Array length
     * @return int array
     */
    private static int[] intLine(Scanner sc, int length) {
      int[] iLine = new int[length];
      for (int i = 0; i < length; i++) {
        iLine[i] = nint(sc);
      }
      return iLine;
    }

    /**
     * Returns a long array. long値を受け取り、配列にして返します。
     *
     * @param sc Scanner
     * @param length Array length
     * @return long array
     */
    private static long[] longLine(Scanner sc, int length) {
      long[] lLine = new long[length];
      for (int i = 0; i < length; i++) {
        lLine[i] = nlong(sc);
      }
      return lLine;
    }

    /**
     * Returns a String array. 文字列を受け取り、配列にして返します。
     *
     * @param sc Scanner
     * @param length Array length
     * @return String array
     */
    private static String[] strLine(Scanner sc, int length) {
      String[] strLine = new String[length];
      for (int i = 0; i < length; i++) {
        strLine[i] = nstr(sc);
      }
      return strLine;
    }

    /**
     * Returns the maximum value in the list. リスト内で最大値を返します。
     *
     * @param longList List
     * @return long maximum value
     */
    private static long maxFromList(List<Long> longList) {
      return longList.stream().max(Comparator.naturalOrder()).get();
    }

    /**
     * Returns the minimum value in the list. リスト内で最小値を返します。
     *
     * @param longList List
     * @return long minimum value
     */
    private static long minFromList(List<Long> longList) {
      return longList.stream().min(Comparator.naturalOrder()).get();
    }

    /**
     * Returns the sum of each digit. 各桁の和を返します。
     *
     * @param n int
     * @return sum of each digit
     */
    private static int sumDigits(int n) {
      int sum = 0;
      while (n != 0) {
        sum += n % 10;
        n /= 10;
      }
      return sum;
    }

    /**
     * Returns the sum of each digit. 各桁の和を返します。
     *
     * @param n long
     * @return sum of each digit
     */
    private static long sumDigits(long n) {
      long sum = 0;
      while (n != 0) {
        sum += n % 10;
        n /= 10;
      }
      return sum;
    }

    /**
     * Return a list of Integer. Integerのリストを返します。
     *
     * @param sc Scanner
     * @param size list size
     * @return list
     */
    private static List<Integer> getIntegerList(Scanner sc, int size) {
      List<Integer> list = new ArrayList<>();
      for (int i = 0; i < size; i++) {
        list.add(nint(sc));
      }
      return list;
    }

    /**
     * Return a list of Long. Longのリストを返します。
     *
     * @param sc Scanner
     * @param size list size
     * @return list
     */
    private static List<Long> getLongList(Scanner sc, int size) {
      List<Long> list = new ArrayList<>();
      for (int i = 0; i < size; i++) {
        list.add(nlong(sc));
      }
      return list;
    }

    /**
     * Returns the greatest common divisor of the two given values. 与えた2つの値の最大公約数を返します。
     *
     * @param m long
     * @param n long
     * @return greatest common divisor
     */
    private static long gcd(long m, long n) {
      if (m < n) return gcd(n, m);
      if (n == 0) return m;
      return gcd(n, m % n);
    }

    /**
     * Returns the least common multiple of the two given values. 与えた2つの値の最小公倍数を返します。
     *
     * @param m long
     * @param n long
     * @return least common multiple
     */
    private static long lcm(long m, long n) {
      return m * n / gcd(m, n);
    }

    /**
     * Returns the most frequent value in the list. リスト内で最頻出数値を返します。
     *
     * @param list List
     * @return most frequent value
     */
    private static Integer mode(List<Integer> list) {
      if (list.size() <= 0) {
        throw new IllegalArgumentException();
      }

      Map<Integer, Integer> modeMap = new HashMap<>();

      for (Integer x : list) {
        if (modeMap.containsKey(x)) {
          modeMap.put(x, modeMap.get(x) + 1);
        } else {
          modeMap.put(x, 1);
        }
      }

      int maxValue = 0;
      int maxKey = 0;

      for (Map.Entry<Integer, Integer> entry : modeMap.entrySet()) {
        if (maxValue < entry.getValue()) {
          maxValue = entry.getValue();
          maxKey = entry.getKey();
        }
      }

      return maxKey;
    }
  }
}