#include <bits/stdc++.h>   using namespace std;   long long modex(long long a, long long p, long long m) {     if (!p) return 1;     if (p & 1) return a * modex(a, p - 1, m) % m;     long long v = modex(a, p >> 1, m);     return v * v % m;   }   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(vector<int> a, 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.end());     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 (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.end());     reverse(fb.begin() + 1, fb.end());     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);       assert(llround(fb[i].i) == 0);       res[i] = (aa + ((bb % m) << 15) + ((cc % m) << 30)) % m;     }     return res;   }   };  // namespace fft   namespace polynomial {   int MOD = 998244353;   template <typename T>   vector<T> subtract(vector<T> a, const vector<T>& b) {     if (a.size() < b.size()) {       a.resize(b.size());     }     for (int i = 0; i < b.size(); ++i) {       a[i] -= b[i];       if (a[i] < 0) a[i] += MOD;     }     return a;   }   template <typename T>   vector<T> inverse(const vector<T>& a) {     assert(!a.empty() && a[0] != 0);     int n = a.size();     vector<T> b = {modex(a[0], MOD - 2, MOD)};     for (int m = 2; b.size() < n; m <<= 1) {       vector<T> aCut(a.begin(), a.begin() + min(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];         if (b[i] >= MOD) b[i] -= MOD;         if (b[i] < 0) b[i] += MOD;       }     }     b.resize(n);     return b;   }   template <typename T>   vector<T> divide(vector<T> a, vector<T> 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 = multiply(a, inverse(b), MOD);     a.erase(a.begin() + n - m + 1, a.end());     reverse(a.begin(), a.end());     return a;   }   template <typename T>   vector<T> remainder(const vector<T>& a, const vector<T>& b) {     return subtract(a, fft::multiply(b, divide(a, b), MOD));   }   template <typename T>   vector<T> integral(const vector<T>& a) {     vector<T> ret(a.size() + 1);     for (int i = 1; i < ret.size(); ++i) {       ret[i] = a[i] * modex(i, MOD - 2, MOD) % MOD;     }     return ret;   }   template <typename T>   vector<T> derivative(const vector<T>& a) {     if (a.empty()) return a;     vector<T> ret(a.size() - 1);     for (int i = 0; i + 1 < a.size(); ++i)       ret[i] = (long long)a[i + 1] * (i + 1) % MOD;     return ret;   }   template <typename T>   vector<T> logarithm(const vector<T>& a) {     assert(!a.empty() && a[0] == 1);     auto ret = integral(fft::multiply(derivative(a), inverse(a), MOD));     ret.resize(a.size());     return ret;   }   template <typename T>   vector<T> exponent(const vector<T>& a) {     assert(!a.empty() && a[0] == 0);     int n = a.size();     vector<T> b = {1};     for (int m = 2; b.size() < n; m <<= 1) {       vector<T> x(a.begin(), a.begin() + min(a.size(), m));       ++x[0];       if (x[0] >= MOD) x[0] -= MOD;       auto oldB = b;       b.resize(m);       b = fft::multiply(oldB, subtract(x, logarithm(b)), MOD);       b.resize(m);     }     b.resize(n);     return b;   }   template <typename T>   vector<T> multipoint(const vector<T>& a, vector<T> xs) {     int n = xs.size();     vector<vector<T>> prods(2 * n - 1);     function<void(int, int, int)> getProds = [&](int sn, int s, int e) {       if (s == e) {         prods[sn] = {(MOD - xs[s]) % MOD, 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]);     };     getProds(0, 0, n - 1);     function<void(int, int, int, vector<T>)> calc = [&](int sn, int s, int e,                                                         vector<T> f) {       if (s == e) {         xs[s] = 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;   }   template <typename T>   vector<T> chirpz(vector<T> a, T g, int n) {     int d = a.size();     int phi = MOD - 1;     vector<long long> pw(phi + 1, 1);     for (int i = 1; i <= phi; ++i) pw[i] = pw[i - 1] * g % MOD;     auto chirpzEven = [&](const vector<T>& b, int m) {       vector<T> u(d), v(m + d - 1);       for (int i = 0; i < d; ++i) {         u[i] = b[i] * pw[(long long)i * i % phi] % MOD;       }       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<T> ret(m);       for (int i = 0; i < m; ++i) {         ret[i] = pw[(long long)i * i % phi] * z[d - 1 + i] % MOD;       }       return ret;     };     auto even = chirpzEven(a, (n + 1) >> 1);     for (int i = 0; i < d; ++i) a[i] = a[i] * pw[i] % MOD;     auto odd = chirpzEven(a, n >> 1);     vector<T> ret(n);     for (int i = 0; i < n; ++i) {       ret[i] = (i & 1) ? odd[i >> 1] : even[i >> 1];     }     return ret;   }   };  // namespace polynomial   using namespace polynomial;   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(42);     for (;;) {       int p = m + n + rng() % 100000;       if (notp[p]) continue;       MOD = p;       int g = primitiveRoot(p);       auto z = poly;       for (int i = 0; i < z.size(); ++i) z[i] = (z[i] % MOD + MOD) % MOD;       auto res = chirpz(z, g, p - 1);       long long pw = 1;       for (int i = 0; i < p - 1; ++i) {         if (1 < pw && pw < p - 1 && res[i] == 0) {           long long z = 0;           long long r = pw;           for (int i = n - 1; i >= 0; --i) {             z = (z * r + poly[i]) % MOD;           }           cerr <<  z                 <<  =  << z << endl;           printf( %d %lld n , MOD, r);           return 0;         }         pw = pw * g % MOD;       }     }   }