#include <bits/stdc++.h>
using namespace std;
int MOD;
struct Mint {
  int val;
  Mint() { val = 0; }
  Mint(const long long& x) {
    val = (-MOD <= x && x < MOD) ? x : x % MOD;
    if (val < 0) val += MOD;
  }
  template <typename U>
  explicit operator U() const {
    return (U)val;
  }
  friend bool operator==(const Mint& a, const Mint& b) {
    return a.val == b.val;
  }
  friend bool operator!=(const Mint& a, const Mint& b) { return !(a == b); }
  friend bool operator<(const Mint& a, const Mint& b) { return a.val < b.val; }
  Mint& operator+=(const Mint& m) {
    if ((val += m.val) >= MOD) val -= MOD;
    return *this;
  }
  Mint& operator-=(const Mint& m) {
    if ((val -= m.val) < 0) val += MOD;
    return *this;
  }
  Mint& operator*=(const Mint& m) {
    val = (long long)val * m.val % MOD;
    return *this;
  }
  friend Mint modex(Mint a, long long p) {
    assert(p >= 0);
    Mint ans = 1;
    for (; p; p >>= 1, a *= a)
      if (p & 1) ans *= a;
    return ans;
  }
  Mint& operator/=(const Mint& m) { return *this *= modex(m, MOD - 2); }
  Mint& operator++() { return *this += 1; }
  Mint& operator--() { return *this -= 1; }
  Mint operator++(int) {
    Mint result(*this);
    *this += 1;
    return result;
  }
  Mint operator--(int) {
    Mint result(*this);
    *this -= 1;
    return result;
  }
  Mint operator-() const { return Mint(-val); }
  friend Mint operator+(Mint a, const Mint& b) { return a += b; }
  friend Mint operator-(Mint a, const Mint& b) { return a -= b; }
  friend Mint operator*(Mint a, const Mint& b) { return a *= b; }
  friend Mint operator/(Mint a, const Mint& b) { return a /= b; }
  friend ostream& operator<<(ostream& os, const Mint& x) { return os << x.val; }
};
namespace fft {
struct cpx {
  double r, i;
  cpx(double r = 0, double i = 0) : r(r), i(i) {}
  cpx operator+(cpx b) { return {r + b.r, i + b.i}; }
  cpx operator-(cpx b) { return {r - b.r, i - b.i}; }
  cpx operator*(cpx b) { return {r * b.r - i * b.i, r * b.i + i * b.r}; }
  cpx operator/(double b) { return {r / b, i / b}; }
  inline cpx conj() { return {r, -i}; }
};
const double PI = acos(-1);
vector<int> rev(1, 0);
vector<cpx> roots;
int base = 0;
void precompute(int nbase) {
  if (nbase <= base) return;
  rev.resize(1 << nbase);
  for (int i = 0; i < (1 << nbase); ++i) {
    rev[i] = rev[i >> 1] >> 1 | ((i & 1) << nbase - 1);
  }
  roots.resize(1 << nbase);
  for (; base < nbase; ++base) {
    int len = 1 << base;
    double angle = 2 * PI / (1 << (base + 1));
    for (int i = 0; i < len; ++i) {
      double cur = angle * i;
      roots[len + i] = cpx(cos(cur), sin(cur));
    }
  }
}
void fft(vector<cpx>& a, int n = -1) {
  if (n == -1) n = a.size();
  assert((n & (n - 1)) == 0);
  int zeros = __builtin_ctz(n);
  precompute(zeros);
  int shift = base - zeros;
  for (int i = 0; i < n; ++i) {
    if (i < (rev[i] >> shift)) swap(a[i], a[rev[i] >> shift]);
  }
  for (int len = 1; len < n; len <<= 1)
    for (int i = 0; i < n; i += 2 * len)
      for (int j = 0; j < len; ++j) {
        cpx u = a[i + j], v = a[i + j + len] * roots[len + j];
        a[i + j] = u + v;
        a[i + j + len] = u - v;
      }
}
vector<cpx> fa, fb;
vector<long long> multiply(const vector<int>& a, const vector<int>& b) {
  if (a.empty() || b.empty()) return {};
  int sz = a.size() + b.size() - 1;
  int n = sz == 1 ? 1 : 1 << (32 - __builtin_clz(sz - 1));
  if (n > fa.size()) fa.resize(n);
  for (int i = 0; i < n; ++i) {
    int x = i < a.size() ? a[i] : 0;
    int y = i < b.size() ? b[i] : 0;
    fa[i] = cpx(x, y);
  }
  fft(fa, n);
  cpx r(0, -0.5 / n);
  for (int i = 0; i <= (n >> 1); ++i) {
    int j = (n - i) & (n - 1);
    cpx x = (fa[i] + fa[j].conj()) / 2;
    cpx y = (fa[i] - fa[j].conj()) * r;
    fa[i] = x * y;
    if (i != j) fa[j] = fa[i].conj();
  }
  fft(fa, n);
  reverse(fa.begin() + 1, fa.begin() + n);
  vector<long long> res(sz);
  for (int i = 0; i < sz; ++i) {
    res[i] = llround(fa[i].r);
  }
  return res;
}
vector<int> multiply(const vector<int>& a, const vector<int>& b, int m) {
  if (m < (1 << 15)) {
    auto res = multiply(a, b);
    vector<int> ret(res.size());
    for (int i = 0; i < res.size(); ++i) ret[i] = res[i] % m;
    return ret;
  }
  if (a.empty() || b.empty()) return {};
  int eq = (a == b);
  int sz = a.size() + b.size() - 1;
  int n = sz == 1 ? 1 : 1 << (32 - __builtin_clz(sz - 1));
  if (n > fa.size()) fa.resize(n);
  for (int i = 0; i < a.size(); ++i) {
    fa[i] = cpx(a[i] & ((1 << 15) - 1), a[i] >> 15);
  }
  fill(fa.begin() + a.size(), fa.begin() + n, cpx(0, 0));
  fft(fa, n);
  if (n > fb.size()) fb.resize(n);
  if (eq) {
    copy(fa.begin(), fa.begin() + n, fb.begin());
  } else {
    for (int i = 0; i < b.size(); ++i) {
      fb[i] = cpx(b[i] & ((1 << 15) - 1), b[i] >> 15);
    }
    fill(fb.begin() + b.size(), fb.begin() + n, cpx(0, 0));
    fft(fb, n);
  }
  double ratio = 0.5 / n;
  cpx r2(0, -0.5);
  cpx r3(ratio, 0);
  cpx r4(0, -ratio);
  cpx r5(0, 1);
  for (int i = 0; i <= (n >> 1); ++i) {
    int j = (n - i) & (n - 1);
    cpx a1 = (fa[i] + fa[j].conj()) / 2;
    cpx a2 = (fa[i] - fa[j].conj()) * r2;
    cpx b1 = (fb[i] + fb[j].conj()) * r3;
    cpx b2 = (fb[i] - fb[j].conj()) * r4;
    cpx x = a1 * b1;
    cpx y = a2 * b2;
    fa[i] = x + y * r5;
    fb[i] = a1 * b2 + a2 * b1;
    if (i != j) {
      fa[j] = x.conj() + y.conj() * r5;
      fb[j] = fb[i].conj();
    }
  }
  fft(fa, n);
  fft(fb, n);
  reverse(fa.begin() + 1, fa.begin() + n);
  reverse(fb.begin() + 1, fb.begin() + n);
  vector<int> res(sz);
  for (int i = 0; i < sz; ++i) {
    long long aa = llround(fa[i].r);
    long long bb = llround(fb[i].r);
    long long cc = llround(fa[i].i);
    res[i] = (aa + ((bb % m) << 15) + ((cc % m) << 30)) % m;
  }
  return res;
}
template <typename T>
vector<T> multiply(const vector<T>& a, const vector<T>& b, int m) {
  vector<int> aa(a.begin(), a.end()), bb(b.begin(), b.end());
  auto c = multiply(aa, bb, m);
  vector<T> ret(c.begin(), c.end());
  return ret;
}
};  // namespace fft
namespace polynomial {
vector<Mint> subtract(vector<Mint> a, const vector<Mint>& b) {
  if (a.size() < b.size()) {
    a.resize(b.size());
  }
  for (int i = 0; i < b.size(); ++i) {
    a[i] -= b[i];
  }
  while (!a.empty() && a.back() == 0) a.pop_back();
  return a;
}
vector<Mint> add(vector<Mint> a, const vector<Mint>& b) {
  if (a.size() < b.size()) {
    a.resize(b.size());
  }
  for (int i = 0; i < b.size(); ++i) {
    a[i] += b[i];
  }
  while (!a.empty() && a.back() == 0) a.pop_back();
  return a;
}
vector<Mint> inverse(const vector<Mint>& a) {
  assert(!a.empty() && a[0] != 0);
  int n = a.size();
  vector<Mint> b = {1 / a[0]};
  for (int m = 2; b.size() < n; m <<= 1) {
    vector<Mint> aCut(a.begin(), a.begin() + min((int)a.size(), m));
    auto x = fft::multiply(aCut, fft::multiply(b, b, MOD), MOD);
    b.resize(m);
    for (int i = 0; i < m; ++i) {
      b[i] += b[i] - x[i];
    }
  }
  b.resize(n);
  return b;
}
vector<Mint> divide(vector<Mint> a, vector<Mint> b) {
  assert(!b.empty() && b.back() != 0);
  int n = a.size();
  int m = b.size();
  if (n < m) return {};
  reverse(a.begin(), a.end());
  reverse(b.begin(), b.end());
  b.resize(n - m + 1);
  a = fft::multiply(a, inverse(b), MOD);
  a.erase(a.begin() + n - m + 1, a.end());
  reverse(a.begin(), a.end());
  return a;
}
vector<Mint> remainder(const vector<Mint>& a, const vector<Mint>& b) {
  return subtract(a, fft::multiply(b, divide(a, b), MOD));
}
vector<Mint> integral(const vector<Mint>& a) {
  vector<Mint> ret(a.size() + 1);
  for (int i = 1; i < ret.size(); ++i) {
    ret[i] = a[i - 1] / i;
  }
  return ret;
}
vector<Mint> derivative(const vector<Mint>& a) {
  if (a.empty()) return a;
  vector<Mint> ret(a.size() - 1);
  for (int i = 0; i + 1 < a.size(); ++i) ret[i] = a[i + 1] * (i + 1);
  return ret;
}
vector<Mint> logarithm(const vector<Mint>& a) {
  assert(!a.empty() && a[0] == 1);
  auto ret = integral(fft::multiply(derivative(a), inverse(a), MOD));
  ret.resize(a.size());
  return ret;
}
vector<Mint> exponent(const vector<Mint>& a) {
  assert(!a.empty() && a[0] == 0);
  int n = a.size();
  vector<Mint> b = {1};
  for (int m = 2; b.size() < n; m <<= 1) {
    vector<Mint> x(a.begin(), a.begin() + min((int)a.size(), m));
    ++x[0];
    auto oldB = b;
    b.resize(m);
    b = fft::multiply(oldB, subtract(x, logarithm(b)), MOD);
    b.resize(m);
  }
  b.resize(n);
  return b;
}
vector<Mint> multipoint(const vector<Mint>& a, vector<Mint> xs) {
  int n = xs.size();
  vector<vector<Mint>> prods(2 * n - 1);
  function<void(int, int, int)> getProds = [&](int sn, int s, int e) {
    if (s == e) {
      prods[sn] = {-xs[s], 1};
      return;
    }
    int m = (s + e) >> 1, lsn = sn + 1, rsn = sn + ((m - s + 1) << 1);
    getProds(lsn, s, m);
    getProds(rsn, m + 1, e);
    prods[sn] = fft::multiply(prods[lsn], prods[rsn], MOD);
  };
  getProds(0, 0, n - 1);
  function<void(int, int, int, vector<Mint>)> calc = [&](int sn, int s, int e,
                                                         vector<Mint> f) {
    if (s == e) {
      xs[s] = f.empty() ? 0 : f[0];
      return;
    }
    int m = (s + e) >> 1, lsn = sn + 1, rsn = sn + ((m - s + 1) << 1);
    calc(lsn, s, m, remainder(f, prods[lsn]));
    calc(rsn, m + 1, e, remainder(f, prods[rsn]));
  };
  calc(0, 0, n - 1, a);
  return xs;
}
vector<Mint> chirpz(vector<Mint> a, Mint g, int n) {
  int d = a.size();
  int phi = MOD - 1;
  vector<Mint> pw(phi + 1);
  pw[0] = 1;
  for (int i = 1; i <= phi; ++i) pw[i] = pw[i - 1] * g;
  auto chirpzEven = [&](const vector<Mint>& b, int m) {
    vector<Mint> u(d), v(m + d - 1);
    for (int i = 0; i < d; ++i) {
      u[i] = b[i] * pw[(long long)i * i % phi];
    }
    for (int i = -(d - 1); i < m; ++i) {
      v[d - 1 + i] = pw[phi - (long long)i * i % phi];
    }
    auto z = fft::multiply(u, v, MOD);
    vector<Mint> ret(m);
    for (int i = 0; i < m; ++i) {
      ret[i] = pw[(long long)i * i % phi] * z[d - 1 + i];
    }
    return ret;
  };
  auto even = chirpzEven(a, (n + 1) >> 1);
  for (int i = 0; i < d; ++i) a[i] *= pw[i % phi];
  auto odd = chirpzEven(a, n >> 1);
  vector<Mint> ret(n);
  for (int i = 0; i < n; ++i) {
    ret[i] = (i & 1) ? odd[i >> 1] : even[i >> 1];
  }
  return ret;
}
vector<Mint> powerMod(const vector<Mint>& a, long long p,
                      const vector<Mint>& b) {
  if (!p) return {1};
  vector<Mint> c;
  if (p & 1) {
    c = fft::multiply(powerMod(a, p - 1, b), a, MOD);
  } else {
    c = powerMod(a, p >> 1, b);
    c = fft::multiply(c, c, MOD);
  }
  return remainder(c, b);
}
vector<Mint> power(vector<Mint> a, long long p, int n) {
  if (!p) return {1};
  assert(a.size() <= n);
  int m = 0;
  while (m < a.size() && a[m] == 0) ++m;
  if (m * p >= n) return {};
  a.erase(a.begin(), a.begin() + m);
  Mint inv = 1 / a[0];
  Mint c = modex(a[0], p);
  for (Mint& x : a) x *= inv;
  a = logarithm(a);
  Mint q = p;
  for (Mint& x : a) x *= q;
  a = exponent(a);
  a.insert(a.begin(), min(n - (long long)a.size(), m * p), 0);
  for (Mint& x : a) x *= c;
  return a;
}
vector<Mint> multiplyAll(int s, int e, const vector<vector<Mint>>& polys) {
  if (s == e) return polys[s];
  int m = (s + e) >> 1;
  auto a = multiplyAll(s, m, polys);
  auto b = multiplyAll(m + 1, e, polys);
  return fft::multiply(a, b, MOD);
}
};  // namespace polynomial
using namespace polynomial;
long long modex(long long a, long long p, int mod) {
  if (!p) return 1;
  if (p & 1) return a * modex(a, p - 1, mod) % mod;
  long long v = modex(a, p >> 1, mod);
  return v * v % mod;
}
int primitiveRoot(int n) {
  vector<int> fact;
  int phi = n - 1, x = phi;
  for (int i = 2; i * i <= x; ++i)
    if (x % i == 0) {
      fact.push_back(i);
      while (x % i == 0) x /= i;
    }
  if (x > 1) fact.push_back(x);
  for (int res = 1; res <= n; ++res) {
    bool ok = true;
    for (int i = 0; i < fact.size() && ok; ++i)
      ok &= modex(res, phi / fact[i], n) != 1;
    if (ok) return res;
  }
  return -1;
}
char str[100005];
int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  vector<int> poly(n);
  scanf("%s", str);
  for (int i = 0; i < n; ++i) {
    poly[i] += str[i] - 'a';
  }
  scanf("%s", str);
  for (int i = 0; i < n; ++i) {
    poly[i] -= str[i] - 'a';
  }
  const int MAXN = 300005;
  bitset<MAXN> notp;
  notp[1] = notp[0] = 1;
  for (int i = 2; i < MAXN; ++i)
    if (!notp[i])
      for (int j = i + i; j < MAXN; j += i) notp[j] = 1;
  mt19937 rng(chrono::high_resolution_clock::now().time_since_epoch().count());
  for (;;) {
    int p = m + n + rng() % 100000;
    if (notp[p]) continue;
    MOD = p;
    int g = primitiveRoot(p);
    vector<Mint> z(poly.begin(), poly.end());
    auto res = chirpz(z, g, p - 1);
    Mint pw = 1;
    for (int i = 0; i < p - 1; ++i) {
      if (1 < pw && pw < p - 1 && res[i] == 0) {
        printf("%d %d\n", MOD, pw.val);
        return 0;
      }
      pw *= g;
    }
  }
}
