#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1002000, CAN = 34;
int n, m, p, vis[MAXN], pr[MAXN], pcnt;
char w1[MAXN], w2[MAXN];
vector<int> can[300];
int muln(int x, int y) { return 1LL * x * y % p; }
int mo(int x) {
  while (x >= p) x -= p;
  while (x < 0) x += p;
  return x;
}
int qpow(int x, int y) {
  int ret = 1;
  for (; y; y >>= 1, x = muln(x, x))
    if (y & 1) ret = muln(ret, x);
  return ret;
}
struct poly {
  int deg;
  vector<int> a;
  poly(int x = 0) : deg(x) { a.resize(x + 1, 0); }
  int& operator[](int idx) { return a[idx]; }
  void print(string s) {
    cerr << "Poly " << s << ": ";
    for (auto g : a) printf("%d ", g);
    cerr << endl;
  }
  int at(int x) {
    x = mo(x);
    int ret = 0;
    for (int i = deg; i >= 0; --i) ret = mo(muln(ret, x) + mo(a[i]));
    return ret;
  }
  void norm() {
    for (auto& g : a) g = mo(g);
  }
} I;
void sieve() {
  for (int i = 2; i <= 1000000; ++i) {
    if (!vis[i]) {
      pr[++pcnt] = i;
    }
    for (int j = 1; j <= pcnt && i * pr[j] <= 1000000; ++j) {
      vis[i * pr[j]] = true;
      if (i % pr[j] == 0) break;
    }
  }
  for (int k = 1, i = pr[k]; k <= pcnt; i = pr[++k]) {
    if (i > m)
      for (int j = 1; j <= CAN; ++j)
        if ((i - 1) % pr[j] == 0) can[j].push_back(i);
  }
}
void sol(int opt) {
  int d = pr[opt];
  poly a(d - 1);
  for (int i = 0; i < n; ++i) a[i % d] += I[i];
  for (auto pri : can[opt]) {
    p = pri;
    int rr = 2;
    while (qpow(rr, (p - 1) / d) == 1) rr++;
    rr = qpow(rr, (p - 1) / d);
    for (int Cnt = 1; Cnt < d; ++Cnt) {
      int r = qpow(rr, Cnt);
      if (r < 2 || r > p - 2) continue;
      int val = a.at(r);
      if (val == 0) {
        printf("%d %d\n", p, r);
        exit(0);
      }
    }
  }
}
int main() {
  scanf("%d%d%s%s", &n, &m, w1, w2);
  sieve();
  I = poly(n - 1);
  for (int i = 0; i < n; ++i) I[i] = w1[i] - w2[i];
  for (int i = 1; i <= CAN; ++i) sol(i);
  return 0;
}
