#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
const double pi = acos(-1);
int gi() {
  int x = 0, o = 1;
  char ch = getchar();
  while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
  if (ch == '-') o = -1, ch = getchar();
  while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
  return x * o;
}
int len, r[N], mod, n, m, w[N];
char s1[N], s2[N];
int qpow(int a, int b) {
  int ret = 1;
  while (b) {
    if (b & 1) ret = 1ll * ret * a % mod;
    a = 1ll * a * a % mod;
    b >>= 1;
  }
  return ret;
}
struct E {
  double x, y;
  E() {}
  E(double x, double y) : x(x), y(y) {}
  E operator+(const E &A) const { return E(x + A.x, y + A.y); }
  E operator-(const E &A) const { return E(x - A.x, y - A.y); }
  E operator*(const E &A) const {
    return E(x * A.x - y * A.y, x * A.y + y * A.x);
  }
  E conj() const { return E(x, -y); }
} og[N];
void FFT(E *a) {
  for (int i = 0; i < len; i++)
    if (i < r[i]) swap(a[i], a[r[i]]);
  for (int i = 1; i < len; i <<= 1)
    for (int p = i << 1, j = 0; j < len; j += p)
      for (int k = 0; k < i; k++) {
        E x = a[j + k], y = og[len / i * k] * a[j + k + i];
        a[j + k] = x + y;
        a[j + k + i] = x - y;
      }
}
vector<int> operator*(vector<int> a, vector<int> b) {
  int n = int(a.size()), m = int(b.size()), l = 0;
  if (n < 50 || m < 50) {
    vector<int> c(n + m - 1);
    for (int i = 0; i < n; i++)
      for (int j = 0; j < m; j++)
        c[i + j] = (c[i + j] + 1ll * a[i] * b[j]) % mod;
    return c;
  }
  n += m - 1;
  for (len = 1; len < n; len <<= 1) ++l;
  for (int i = 0; i < len; i++)
    r[i] = (r[i >> 1] >> 1) | ((i & 1) << (l - 1)),
    og[i] = E(cos(pi / len * i), sin(pi / len * i));
  static E s1[N], s2[N], s3[N], s4[N], s5[N], s6[N];
  a.resize(len);
  b.resize(len);
  for (int i = 0; i < len; i++)
    s1[i] = E(a[i] & 32767, a[i] >> 15), s2[i] = E(b[i] & 32767, b[i] >> 15);
  FFT(s1);
  FFT(s2);
  for (int i = 0; i < len; i++) {
    int j = (len - 1) & (len - i);
    E da = (s1[i] + s1[j].conj()) * E(0.5, 0);
    E db = (s1[i] - s1[j].conj()) * E(0, -0.5);
    E dc = (s2[i] + s2[j].conj()) * E(0.5, 0);
    E dd = (s2[i] - s2[j].conj()) * E(0, -0.5);
    s3[i] = da * dc;
    s4[i] = da * dd;
    s5[i] = db * dc;
    s6[i] = db * dd;
  }
  for (int i = 0; i < len; i++)
    s1[i] = s3[i] + s4[i] * E(0, 1), s2[i] = s5[i] + s6[i] * E(0, 1);
  FFT(s1);
  FFT(s2);
  reverse(s1 + 1, s1 + len);
  reverse(s2 + 1, s2 + len);
  vector<int> c(n);
  for (int i = 0; i < n; i++) {
    long long da = (long long)(s1[i].x / len + 0.5) % mod;
    long long db = (long long)(s1[i].y / len + 0.5) % mod;
    long long dc = (long long)(s2[i].x / len + 0.5) % mod;
    long long dd = (long long)(s2[i].y / len + 0.5) % mod;
    c[i] = (da + ((db + dc) << 15) + (dd << 30)) % mod;
  }
  return c;
}
bool isprime(int n) {
  for (int i = 2; i * i <= n; i++)
    if (n % i == 0) return 0;
  return 1;
}
int getrt() {
  int x = mod - 1;
  static int pri[N];
  int tt = 0;
  for (int i = 2; i * i <= x; i++)
    if (x % i == 0) {
      pri[++tt] = i;
      while (x % i == 0) x /= i;
    }
  if (x > 1) pri[++tt] = x;
  for (int i = 2;; i++) {
    bool fl = 1;
    for (int j = 1; j <= tt; j++)
      if (qpow(i, (mod - 1) / pri[j]) == 1) {
        fl = 0;
        break;
      }
    if (fl) return i;
  }
}
long long C2(int n) { return (1ll * n * (n - 1) / 2) % (::n); }
int main() {
  cin >> n >> m;
  scanf("%s%s", s1, s2);
  mod = 141905;
  while (1) {
    ++mod;
    while (!isprime(mod)) ++mod;
    int g = getrt();
    n = mod - 1;
    w[0] = 1;
    for (int i = 1; i <= n; i++) w[i] = 1ll * w[i - 1] * g % mod;
    vector<int> A(n), B(n + n);
    for (int i = 0; i < n; i++)
      A[i] = 1ll * (s1[i] - s2[i] + mod) * w[n - C2(i)] % mod;
    reverse(A.begin(), A.end());
    for (int i = 0; i < n + n; i++) B[i] = w[C2(i)];
    A = A * B;
    for (int i = 0; i < n; i++)
      if (!A[i + n - 1] && w[i] > 1 && w[i] < mod - 1)
        return cout << mod << ' ' << w[i], 0;
  }
  return 0;
}
