Problem:
Ferris Wheel
The big Ferris wheel,
Cosmo Clock 21
, is a landmark of Yokohama and adds beauty to the city's night view. The ICPC city also wants something similar.
The ICPC city plans to build an illuminated Ferris wheel with an even number of gondolas. All
the gondolas are to be colored with one of the given set of candidate colors. The illumination is
planned as follows.
All the gondolas are paired up; every gondola belongs to a single pair.
Only two gondolas of the same color can form a pair.
Paired gondolas are connected with a straight LED line to illuminate the wheel.
No two LED lines cross when looked from the front side.
A coloring of gondolas is
suitable
if it allows at least one way of pairing for the illumination plan.
Figure C.1. Ferris wheels with suitable (left) and not suitable (right) colorings
Given the numbers of gondolas and candidate colors, count the number of suitable colorings of gondolas. Since the Ferris wheel rotates, two colorings are considered the same if they coincide under a certain rotation. Two colorings that coincide only when looked from the opposite sides are considered different.
Input
The input consists of a single test case in the following format.
$n$ $k$
$n$ and $k$ are integers between $1$ and $3 \times 10^6$, inclusive. The numbers of gondolas and candidate colors are $2n$ and $k$, respectively.
Output
Output the number of suitable colorings of gondolas in modulo $998 244 353 = 2^{23} \times 7 \times 17 + 1$, which is a prime number.
Sample Input 1
3 2
Sample Output 1
6
Sample Input 2
5 3
Sample Output 2
372
Sample Input 3
2023 1126
Sample Output 3
900119621
For Sample Input 1, there are six suitable colorings as listed in the figure below.
Figure C.2. Suitable colorings in case of $n = 3$ and $k = 2$

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for (int i = 0; i < n; i++)
#define all(v) begin(v), end(v)
template <int modulo>
struct modint {
    int x;
    modint() : x(0) {}
    modint(int64_t y) : x(y >= 0 ? y % modulo : (modulo - (-y) % modulo) % modulo) {}
    modint &operator+=(const modint &p) {
        if ((x += p.x) >= modulo) x -= modulo;
        return *this;
    }
    modint &operator-=(const modint &p) {
        if ((x += modulo - p.x) >= modulo) x -= modulo;
        return *this;
    }
    modint &operator*=(const modint &p) {
        x = (int)(1LL * x * p.x % modulo);
        return *this;
    }
    modint &operator/=(const modint &p) {
        *this *= p.inv();
        return *this;
    }
    modint operator-() const { return modint(-x); }
    modint operator+(const modint &p) const { return modint(*this) += p; }
    modint operator-(const modint &p) const { return modint(*this) -= p; }
    modint operator*(const modint &p) const { return modint(*this) *= p; }
    modint operator/(const modint &p) const { return modint(*this) /= p; }
    bool operator==(const modint &p) const { return x == p.x; }
    bool operator!=(const modint &p) const { return x != p.x; }
    modint inv() const {
        int a = x, b = modulo, u = 1, v = 0, t;
        while (b > 0) {
            t = a / b;
            swap(a -= t * b, b);
            swap(u -= t * v, v);
        }
        return modint(u);
    }
    modint pow(int64_t n) const {
        modint ret(1), mul(x);
        while (n > 0) {
            if (n & 1) ret *= mul;
            mul *= mul;
            n >>= 1;
        }
        return ret;
    }
    friend ostream &operator<<(ostream &os, const modint &p) { return os << p.x; }
    friend istream &operator>>(istream &is, modint &a) {
        int64_t t;
        is >> t;
        a = modint<modulo>(t);
        return (is);
    }
    int val() const { return x; }
    static constexpr int mod() { return modulo; }
    static constexpr int half() { return (modulo + 1) >> 1; }
};
template <typename T>
struct Binomial {
    vector<T> inv, fact, factinv;
    Binomial(int n) {
        inv.resize(n + 1);
        fact.resize(n + 1);
        factinv.resize(n + 1);
        inv[0] = fact[0] = factinv[0] = 1;
        for (int i = 1; i <= n; i++) fact[i] = fact[i - 1] * i;
        factinv[n] = fact[n].inv();
        inv[n] = fact[n - 1] * factinv[n];
        for (int i = n - 1; i >= 1; i--) {
            factinv[i] = factinv[i + 1] * (i + 1);
            inv[i] = fact[i - 1] * factinv[i];
        }
    }
    T C(int n, int r) {
        if (n < 0 || n < r || r < 0) return 0;
        return fact[n] * factinv[n - r] * factinv[r];
    }
    T P(int n, int r) {
        if (n < 0 || n < r || r < 0) return 0;
        return fact[n] * factinv[n - r];
    }
    T H(int n, int r) {
        if (n == 0 && r == 0) return 1;
        if (n < 0 || r < 0) return 0;
        return r == 0 ? 1 : C(n + r - 1, r);
    }
};
using mint = modint<998244353>;
int main() {
    int n, k;
    cin >> n >> k;
    Binomial<mint> bin(2 * n);
    vector<int> cnt(n * 2 + 1);
    for (int i = 1; i <= 2 * n; i++) cnt[gcd(2 * n, i)]++;
    mint ans = 0;
    for (int p = 1; p <= 2 * n; p++) {
        if (cnt[p] == 0) continue;
        if (p % 2 == 0) {
            vector<mint> x(p / 2 + 1);
            for (int i = 1; i <= p / 2; i++) x[i] = bin.C(p - i, p / 2) * i / (p - i);
            for (int i = 1; i <= p / 2; i++) ans += x[i] * mint(k).pow(i) * mint(k - 1).pow(p / 2 - i) * cnt[p];
        } else {
            vector<mint> x((p + 1) / 2 + 1);
            x[(p + 1) / 2] = 1;
            for (int i = (p - 1) / 2; i >= 1; i--) {
                x[i] = bin.C(p - i, (p - 1) / 2);
            }
            for (int i = 1; i <= (p + 1) / 2; i++) ans += x[i] * mint(k).pow(i) * mint(k - 1).pow((p + 1) / 2 - i) * cnt[p];
        }
    }
    cout << ans / (n * 2) << endl;
}
accuracy: 1
time_ms: 2370
memory_kb: 108960
final_rank: 5

code_snippet: #include <iostream>
#include <vector>
using namespace std;
#define rep(i,n) for(int i=0; i<int(n); i++)

const int MOD = 998244353;

struct Modint{
    Modint() : x(0) {}
    Modint(long long y) : x(y%MOD){ if(x<0){ x+=MOD; } }
    Modint& operator+=(const Modint& r){
        x += r.x; if(x >= MOD){ x -= MOD; } return *this; }
    Modint& operator-=(const Modint& r){
        x -= r.x; if(x < 0){ x += MOD; } return *this; }
    Modint& operator*=(const Modint& r){
        x = (long long)x * r.x % MOD; return *this; }
    Modint operator+(const Modint& r) const {
        auto v = *this; v += r; return v; }
    Modint operator-(const Modint& r){
        auto v = *this; v -= r; return v; }
    Modint operator*(const Modint& r){
        auto v = *this; v *= r; return v; }
    Modint operator-() const { return Modint(-x); }
    Modint pow(long long i) const{
        Modint a = 1;
        Modint r = *this;
        while(i){
            if(i%2) a *= r;
            r *= r;
            i /= 2;
        }
        return a;
    }
    Modint inv() const { return pow(MOD-2); }
    int x;
};

Modint solve(long long n, long long k){
    long long N = n;
    if(k == 1){ return Modint(1); }
    auto q = Modint(k-1).inv() * Modint(k);
    vector<Modint> I(N+10);
    I[1] = 1; for(int i=2; i<int(I.size()); i++) I[i] = -I[MOD%i] * (MOD/i);
    vector<Modint> C(N+1);
    C[0] = 1; for(int i=1; i<=N; i++) C[i] = C[i-1] * I[i+1] * Modint(i*4-2);
    vector<Modint> F(N+1); {
        int Z = F.size() - 1;
        Modint a = (Modint(2) - q * Modint(2)).inv();
        F[0] = Modint(2) - Modint(2) * q;
        for(int i=1; i<=Z; i++) F[i] += C[i-1] * Modint(2) * q;
        Modint b = Modint(-2) * q * q * a;
        for(int i=1; i<=Z; i++) F[i] += F[i-1] * b;
        for(auto& f : F) f *= a;
    }
    vector<Modint> D(N*2+1); {
        D[0] = 1;
        D[1] = 1;
        for(int i=2; i<=N*2; i++){
            D[i] = D[i-1] + D[i-1];
            if(i%2 == 0) D[i] -= C[i/2-1];
        }
    }
    
    //for(auto a : C){ cout << a.x << " "; } cout << endl;
    //for(auto a : F){ cout << a.x << " "; } cout << endl;
    //for(auto a : D){ cout << a.x << " "; } cout << endl;
    //rep(i,N+1){ cout << (F[i] * Modint(k-1).pow(i)).x << " "; } cout << endl;

    vector<pair<int,int>> pfN; {
        int m = N*2;
        for(int p=2; p<=m; p++) if(m%p==0){
            pfN.push_back({ p, 0 });
            while(m%p == 0){ pfN.back().second++; m/=p; }
        }
    }
    vector<int> divs, dims; {
        divs.push_back(1);
        dims.push_back(1);
        for(auto [p,e] : pfN){
            int k=divs.size();
            rep(i,k*e) divs.push_back(divs[i] * p);
            dims.push_back(divs.size());
        }
    }
    int M = divs.size();
    vector<Modint> cnt(divs.size()); {
        rep(i,M) cnt[i] = N*2/divs[i];
        rep(i,dims.size()-1){
            for(int d=dims[i]; d<M; d++) if(divs[d] % divs[dims[i]] == 0){
                cnt[d-dims[i]] -= cnt[d];
            }
        }
    }

    vector<Modint> powK(N+1); powK[0] = 1;
    rep(i,N) powK[i+1] = powK[i] * Modint(k-1);
    //for(auto a : powK){ cout << a.x << " "; } cout << endl;

    Modint ans = 0;
    //for(auto a : divs){ cout << a << " "; } cout << endl;
    //for(auto a : cnt){ cout << a.x << " "; } cout << endl;

    rep(i,M){
        int c = divs[i];
        Modint t = 0;
        if(c % 2 == 0){
            t += F[c/2] * powK[c/2];
        } else {
            for(int q=1; q<=c; q+=2){
                t += F[(c-q)/2] * D[q] * powK[c/2] * Modint(k);
            }
        }
        ans += t * cnt[i];
        //cout << ans.x << endl;
    }

    //cout << ans.x << endl;

    //ans += Modint(k).pow(n) * Modint(n);

    //if(n%2 == 1){
    //    ans += F[n/2] * powK[n/2] * Modint(k) * Modint(n);
    //} else {
    //    ans += F[n/2-1] * powK[n/2-1] * Modint(k) * Modint(n);
    //}

    //cout << ans.x << endl;

    ans *= Modint(n*2).inv();

    return ans;
}

#include <algorithm>

void testcase(){
    long long n, k; cin >> n >> k;
    auto ans = solve(n,k);
    cout << ans.x << "\n";
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    testcase();
    return 0;
}
accuracy: 1
time_ms: 100
memory_kb: 73372
final_rank: 1

code_snippet: #include <iostream>
#include <vector>
using namespace std;
#define rep(i,n) for(int i=0; i<int(n); i++)

const int MOD = 998244353;

struct Modint{
    Modint() : x(0) {}
    Modint(long long y) : x(y%MOD){ if(x<0){ x+=MOD; } }
    Modint& operator+=(const Modint& r){
        x += r.x; if(x >= MOD){ x -= MOD; } return *this; }
    Modint& operator-=(const Modint& r){
        x -= r.x; if(x < 0){ x += MOD; } return *this; }
    Modint& operator*=(const Modint& r){
        x = (long long)x * r.x % MOD; return *this; }
    Modint operator+(const Modint& r) const {
        auto v = *this; v += r; return v; }
    Modint operator-(const Modint& r){
        auto v = *this; v -= r; return v; }
    Modint operator*(const Modint& r){
        auto v = *this; v *= r; return v; }
    Modint operator-() const { return Modint(-x); }
    Modint pow(long long i) const{
        Modint a = 1;
        Modint r = *this;
        while(i){
            if(i%2) a *= r;
            r *= r;
            i /= 2;
        }
        return a;
    }
    Modint inv() const { return pow(MOD-2); }
    int x;
};

Modint solve(long long n, long long k){
    long long N = n;
    //if(k == 1){ return Modint(1); }
    auto q = Modint(k-1).inv() * Modint(k);
    vector<Modint> I(N+10);
    I[1] = 1; for(int i=2; i<int(I.size()); i++) I[i] = -I[MOD%i] * (MOD/i);
    vector<Modint> C(N+1);
    C[0] = 1; for(int i=1; i<=N; i++) C[i] = C[i-1] * I[i+1] * Modint(i*4-2);
    vector<Modint> F(N+1); {
        int Z = F.size() - 1;
        Modint a = (Modint(2) - q * Modint(2)).inv();
        F[0] = Modint(2) - Modint(2) * q;
        for(int i=1; i<=Z; i++) F[i] += C[i-1] * Modint(2) * q;
        Modint b = Modint(-2) * q * q * a;
        for(int i=1; i<=Z; i++) F[i] += F[i-1] * b;
        for(auto& f : F) f *= a;
    }
    vector<Modint> D(N*2+1); {
        D[0] = 1;
        D[1] = 1;
        for(int i=2; i<=N*2; i++){
            D[i] = D[i-1] + D[i-1];
            if(i%2 == 0) D[i] -= C[i/2-1];
        }
    }
    
    //for(auto a : C){ cout << a.x << " "; } cout << endl;
    //for(auto a : F){ cout << a.x << " "; } cout << endl;
    //for(auto a : D){ cout << a.x << " "; } cout << endl;
    //rep(i,N+1){ cout << (F[i] * Modint(k-1).pow(i)).x << " "; } cout << endl;

    vector<pair<int,int>> pfN; {
        int m = N*2;
        for(int p=2; p<=m; p++) if(m%p==0){
            pfN.push_back({ p, 0 });
            while(m%p == 0){ pfN.back().second++; m/=p; }
        }
    }
    vector<int> divs, dims; {
        divs.push_back(1);
        dims.push_back(1);
        for(auto [p,e] : pfN){
            int k=divs.size();
            rep(i,k*e) divs.push_back(divs[i] * p);
            dims.push_back(divs.size());
        }
    }
    int M = divs.size();
    vector<Modint> cnt(divs.size()); {
        rep(i,M) cnt[i] = N*2/divs[i];
        rep(i,dims.size()-1){
            for(int d=dims[i]; d<M; d++) if(divs[d] % divs[dims[i]] == 0){
                cnt[d-dims[i]] -= cnt[d];
            }
        }
    }

    vector<Modint> powK(N+1); powK[0] = 1;
    rep(i,N) powK[i+1] = powK[i] * Modint(k-1);
    //for(auto a : powK){ cout << a.x << " "; } cout << endl;

    Modint ans = 0;
    //for(auto a : divs){ cout << a << " "; } cout << endl;
    //for(auto a : cnt){ cout << a.x << " "; } cout << endl;

    rep(i,M){
        int c = divs[i];
        Modint t = 0;
        if(c % 2 == 0){
            t += F[c/2] * powK[c/2];
        } else {
            for(int q=1; q<=c; q+=2){
                t += F[(c-q)/2] * D[q] * powK[c/2] * Modint(k);
            }
        }
        ans += t * cnt[i];
        //cout << ans.x << endl;
    }

    //cout << ans.x << endl;

    //ans += Modint(k).pow(n) * Modint(n);

    //if(n%2 == 1){
    //    ans += F[n/2] * powK[n/2] * Modint(k) * Modint(n);
    //} else {
    //    ans += F[n/2-1] * powK[n/2-1] * Modint(k) * Modint(n);
    //}

    //cout << ans.x << endl;

    ans *= Modint(n*2).inv();

    return ans;
}

#include <algorithm>

void testcase(){
    long long n, k; cin >> n >> k;
    auto ans = solve(n,k);
    cout << ans.x << "\n";
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    testcase();
    return 0;
}
accuracy: 0.9534883720930233
time_ms: 100
memory_kb: 73356
final_rank: 14

code_snippet: #include <iostream>
#include <vector>
using namespace std;
#define rep(i,n) for(int i=0; i<int(n); i++)

const int MOD = 998244353;

struct Modint{
    Modint() : x(0) {}
    Modint(int y) : x(y){ if(x<0){ x+=MOD; } }
    Modint& operator+=(const Modint& r){
        x += r.x; if(x >= MOD){ x -= MOD; } return *this; }
    Modint& operator-=(const Modint& r){
        x -= r.x; if(x < 0){ x += MOD; } return *this; }
    Modint& operator*=(const Modint& r){
        x = (long long)x * r.x % MOD; return *this; }
    Modint operator+(const Modint& r) const {
        auto v = *this; v += r; return v; }
    Modint operator-(const Modint& r){
        auto v = *this; v -= r; return v; }
    Modint operator*(const Modint& r){
        auto v = *this; v *= r; return v; }
    Modint operator-() const { return Modint(-x); }
    Modint pow(long long i) const{
        Modint a = 1;
        Modint r = *this;
        while(i){
            if(i%2) a *= r;
            r *= r;
            i /= 2;
        }
        return a;
    }
    Modint inv() const { return pow(MOD-2); }
    int x;
};

Modint solve(long long n, long long k){
    long long N = n;
    auto q = Modint(k-1).inv() * Modint(k);
    vector<Modint> I(N+10);
    I[1] = 1; for(int i=2; i<int(I.size()); i++) I[i] = -I[MOD%i] * (MOD/i);
    vector<Modint> C(N+1);
    C[0] = 1; for(int i=1; i<=N; i++) C[i] = C[i-1] * I[i+1] * Modint(i*4-2);
    vector<Modint> F(N+1); {
        int Z = F.size() - 1;
        Modint a = (Modint(2) - q * Modint(2)).inv();
        F[0] = Modint(2) - Modint(2) * q;
        for(int i=1; i<=Z; i++) F[i] += C[i-1] * Modint(2) * q;
        Modint b = Modint(-2) * q * q * a;
        for(int i=1; i<=Z; i++) F[i] += F[i-1] * b;
        for(auto& f : F) f *= a;
    }
    vector<Modint> D(N*2+1); {
        D[0] = 1;
        D[1] = 1;
        for(int i=2; i<=N*2; i++){
            D[i] = D[i-1] + D[i-1];
            if(i%2 == 0) D[i] -= C[i/2-1];
        }
    }
    
    //for(auto a : C){ cout << a.x << " "; } cout << endl;
    //for(auto a : F){ cout << a.x << " "; } cout << endl;
    //for(auto a : D){ cout << a.x << " "; } cout << endl;
    //rep(i,N+1){ cout << (F[i] * Modint(k-1).pow(i)).x << " "; } cout << endl;

    vector<pair<int,int>> pfN; {
        int m = N*2;
        for(int p=2; p<=m; p++) if(m%p==0){
            pfN.push_back({ p, 0 });
            while(m%p == 0){ pfN.back().second++; m/=p; }
        }
    }
    vector<int> divs, dims; {
        divs.push_back(1);
        dims.push_back(1);
        for(auto [p,e] : pfN){
            int k=divs.size();
            rep(i,k*e) divs.push_back(divs[i] * p);
            dims.push_back(divs.size());
        }
    }
    int M = divs.size();
    vector<Modint> cnt(divs.size()); {
        rep(i,M) cnt[i] = N*2/divs[i];
        rep(i,dims.size()-1){
            for(int d=dims[i]; d<M; d++) if(divs[d] % divs[dims[i]] == 0){
                cnt[d-dims[i]] -= cnt[d];
            }
        }
    }

    vector<Modint> powK(N+1); powK[0] = 1;
    rep(i,N) powK[i+1] = powK[i] * Modint(k-1);
    //for(auto a : powK){ cout << a.x << " "; } cout << endl;

    Modint ans = 0;
    //for(auto a : divs){ cout << a << " "; } cout << endl;
    //for(auto a : cnt){ cout << a.x << " "; } cout << endl;

    rep(i,M){
        int c = divs[i];
        Modint t = 0;
        if(c % 2 == 0){
            t += F[c/2] * powK[c/2];
        } else {
            for(int q=1; q<=c; q+=2){
                t += F[(c-q)/2] * D[q] * powK[c/2] * Modint(k);
            }
        }
        ans += t * cnt[i];
        //cout << ans.x << endl;
    }

    //cout << ans.x << endl;

    //ans += Modint(k).pow(n) * Modint(n);

    //if(n%2 == 1){
    //    ans += F[n/2] * powK[n/2] * Modint(k) * Modint(n);
    //} else {
    //    ans += F[n/2-1] * powK[n/2-1] * Modint(k) * Modint(n);
    //}

    //cout << ans.x << endl;

    ans *= Modint(n*2).inv();

    return ans;
}

#include <algorithm>

void testcase(){
    long long n, k; cin >> n >> k;
    auto ans = solve(n,k);
    cout << ans.x << "\n";
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    testcase();
    return 0;
}
accuracy: 0.9534883720930233
time_ms: 90
memory_kb: 73340
final_rank: 13

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<ll> vi;
#define FOR(i,l,r) for(ll i=l;i<r;i++)
#define REP(i,n) FOR(i,0,n)
const ll mod=998244353;
ll pow_mod(ll a,ll n){
    ll res=1;
    a%=mod;if(a<0)a+=mod;
    while(n){
        if(n%2)res=res*a%mod;
        a=a*a%mod;n/=2;
    }
    return res;
}
ll inv_mod(ll a){return pow_mod(a,mod-2);}
int main(){
    ll N,K;cin>>N>>K;
    vi ex(1e7,1),re(1e7);
    FOR(i,1,1e7)ex[i]=ex[i-1]*i%mod;
    REP(i,1e7)re[i]=inv_mod(ex[i]);
    vector<bool>prime(1e7,1);
    vi phi(1e7);
    iota(phi.begin(),phi.end(),0);
    FOR(i,2,1e7)if(prime[i]){
        for(ll j=i;j<1e7;j+=i)phi[j]-=phi[j]/i,prime[j]=0;
    }
    vi f(N+10,1),pk(N+10,1);
    FOR(i,1,N+10)pk[i]=pk[i-1]*(K-1)%mod;
    FOR(i,1,N+10)f[i]=-ex[2*i-2]*re[i-1]%mod*re[i]%mod*K%mod*pk[i]%mod;
    FOR(i,1,N+10)f[i]=(f[i]+K*K%mod*f[i-1])%mod;
    f[0]=K;
    ll ans=0;
    FOR(d,1,2*N+1)if(2*N%d==0){
        ll s=0;
        if(d%2==0)s=f[d/2];
        else{
            REP(k,(d+1)/2)s+=(2*k+1)%mod*pk[k]%mod*f[(d-1)/2-k]%mod*ex[2*k]%mod*re[k]%mod*re[k+1]%mod,s%=mod;
        }
        ans+=s*phi[2*N/d]%mod;
        ans%=mod;
    }
    ans*=inv_mod(2*N);
    ans%=mod;
    if(ans<0)ans+=mod;
    cout<<ans<<endl;
    return 0;
}
accuracy: 1
time_ms: 1150
memory_kb: 285864
final_rank: 6

code_snippet: #line 1 "library/Template/template.hpp"
#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}
#line 2 "library/Utility/fastio.hpp"
#include <unistd.h>
namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf

uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio

using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */
#line 3 "sol.cpp"

#line 2 "library/Math/modint.hpp"

template <unsigned mod = 1000000007> struct fp {
    unsigned v;
    static constexpr int get_mod() {
        return mod;
    }
    constexpr unsigned inv() const {
        assert(v != 0);
        int x = v, y = mod, p = 1, q = 0, t = 0, tmp = 0;
        while (y > 0) {
            t = x / y;
            x -= t * y, p -= t * q;
            tmp = x, x = y, y = tmp;
            tmp = p, p = q, q = tmp;
        }
        if (p < 0)
            p += mod;
        return p;
    }
    constexpr fp(ll x = 0) : v(x >= 0 ? x % mod : (mod - (-x) % mod) % mod) {}
    fp operator-() const {
        return fp() - *this;
    }
    fp pow(ull t) {
        fp res = 1, b = *this;
        while (t) {
            if (t & 1)
                res *= b;
            b *= b;
            t >>= 1;
        }
        return res;
    }
    fp &operator+=(const fp &x) {
        if ((v += x.v) >= mod)
            v -= mod;
        return *this;
    }
    fp &operator-=(const fp &x) {
        if ((v += mod - x.v) >= mod)
            v -= mod;
        return *this;
    }
    fp &operator*=(const fp &x) {
        v = ull(v) * x.v % mod;
        return *this;
    }
    fp &operator/=(const fp &x) {
        v = ull(v) * x.inv() % mod;
        return *this;
    }
    fp operator+(const fp &x) const {
        return fp(*this) += x;
    }
    fp operator-(const fp &x) const {
        return fp(*this) -= x;
    }
    fp operator*(const fp &x) const {
        return fp(*this) *= x;
    }
    fp operator/(const fp &x) const {
        return fp(*this) /= x;
    }
    bool operator==(const fp &x) const {
        return v == x.v;
    }
    bool operator!=(const fp &x) const {
        return v != x.v;
    }
    friend istream &operator>>(istream &is, fp &x) {
        return is >> x.v;
    }
    friend ostream &operator<<(ostream &os, const fp &x) {
        return os << x.v;
    }
};

template <unsigned mod> void rd(fp<mod> &x) {
    fastio::rd(x.v);
}
template <unsigned mod> void wt(fp<mod> x) {
    fastio::wt(x.v);
}

/**
 * @brief Modint
 */
#line 5 "sol.cpp"
using Fp = fp<998244353>;
#line 2 "library/Math/comb.hpp"

template <typename T> T Inv(ll n) {
    static int md;
    static vector<T> buf({0, 1});
    if (md != T::get_mod()) {
        md = T::get_mod();
        buf = vector<T>({0, 1});
    }
    assert(n > 0);
    n %= md;
    while (SZ(buf) <= n) {
        int k = SZ(buf), q = (md + k - 1) / k;
        buf.push_back(buf[k * q - md] * q);
    }
    return buf[n];
}

template <typename T> T Fact(ll n, bool inv = 0) {
    static int md;
    static vector<T> buf({1, 1}), ibuf({1, 1});
    if (md != T::get_mod()) {
        md = T::get_mod();
        buf = ibuf = vector<T>({1, 1});
    }
    assert(n >= 0 and n < md);
    while (SZ(buf) <= n) {
        buf.push_back(buf.back() * SZ(buf));
        ibuf.push_back(ibuf.back() * Inv<T>(SZ(ibuf)));
    }
    return inv ? ibuf[n] : buf[n];
}

template <typename T> T nPr(int n, int r, bool inv = 0) {
    if (n < 0 || n < r || r < 0)
        return 0;
    return Fact<T>(n, inv) * Fact<T>(n - r, inv ^ 1);
}
template <typename T> T nCr(int n, int r, bool inv = 0) {
    if (n < 0 || n < r || r < 0)
        return 0;
    return Fact<T>(n, inv) * Fact<T>(r, inv ^ 1) * Fact<T>(n - r, inv ^ 1);
}
// sum = n, r tuples
template <typename T> T nHr(int n, int r, bool inv = 0) {
    return nCr<T>(n + r - 1, r - 1, inv);
}
// sum = n, a nonzero tuples and b tuples
template <typename T> T choose(int n, int a, int b) {
    if (n == 0)
        return !a;
    return nCr<T>(n + b - 1, a + b - 1);
}

/**
 * @brief Combination
 */
#line 7 "sol.cpp"

#line 2 "library/Convolution/ntt.hpp"

template <typename T> struct NTT {
    static constexpr int rank2 = __builtin_ctzll(T::get_mod() - 1);
    std::array<T, rank2 + 1> root;  // root[i]^(2^i) == 1
    std::array<T, rank2 + 1> iroot; // root[i] * iroot[i] == 1

    std::array<T, std::max(0, rank2 - 2 + 1)> rate2;
    std::array<T, std::max(0, rank2 - 2 + 1)> irate2;

    std::array<T, std::max(0, rank2 - 3 + 1)> rate3;
    std::array<T, std::max(0, rank2 - 3 + 1)> irate3;

    NTT() {
        T g = 2;
        while (g.pow((T::get_mod() - 1) >> 1) == 1) {
            g += 1;
        }
        root[rank2] = g.pow((T::get_mod() - 1) >> rank2);
        iroot[rank2] = root[rank2].inv();
        for (int i = rank2 - 1; i >= 0; i--) {
            root[i] = root[i + 1] * root[i + 1];
            iroot[i] = iroot[i + 1] * iroot[i + 1];
        }

        {
            T prod = 1, iprod = 1;
            for (int i = 0; i <= rank2 - 2; i++) {
                rate2[i] = root[i + 2] * prod;
                irate2[i] = iroot[i + 2] * iprod;
                prod *= iroot[i + 2];
                iprod *= root[i + 2];
            }
        }
        {
            T prod = 1, iprod = 1;
            for (int i = 0; i <= rank2 - 3; i++) {
                rate3[i] = root[i + 3] * prod;
                irate3[i] = iroot[i + 3] * iprod;
                prod *= iroot[i + 3];
                iprod *= root[i + 3];
            }
        }
    }

    void ntt(std::vector<T> &a, bool type = 0) {
        int n = int(a.size());
        int h = __builtin_ctzll((unsigned int)n);
        a.resize(1 << h);

        if (type) {
            int len = h; // a[i, i+(n>>len), i+2*(n>>len), ..] is transformed
            while (len) {
                if (len == 1) {
                    int p = 1 << (h - len);
                    T irot = 1;
                    for (int s = 0; s < (1 << (len - 1)); s++) {
                        int offset = s << (h - len + 1);
                        for (int i = 0; i < p; i++) {
                            auto l = a[i + offset];
                            auto r = a[i + offset + p];
                            a[i + offset] = l + r;
                            a[i + offset + p] =
                                (unsigned long long)(T::get_mod() + l.v - r.v) *
                                irot.v;
                            ;
                        }
                        if (s + 1 != (1 << (len - 1)))
                            irot *= irate2[__builtin_ctzll(~(unsigned int)(s))];
                    }
                    len--;
                } else {
                    // 4-base
                    int p = 1 << (h - len);
                    T irot = 1, iimag = iroot[2];
                    for (int s = 0; s < (1 << (len - 2)); s++) {
                        T irot2 = irot * irot;
                        T irot3 = irot2 * irot;
                        int offset = s << (h - len + 2);
                        for (int i = 0; i < p; i++) {
                            auto a0 = 1ULL * a[i + offset + 0 * p].v;
                            auto a1 = 1ULL * a[i + offset + 1 * p].v;
                            auto a2 = 1ULL * a[i + offset + 2 * p].v;
                            auto a3 = 1ULL * a[i + offset + 3 * p].v;

                            auto a2na3iimag =
                                1ULL * T((T::get_mod() + a2 - a3) * iimag.v).v;

                            a[i + offset] = a0 + a1 + a2 + a3;
                            a[i + offset + 1 * p] =
                                (a0 + (T::get_mod() - a1) + a2na3iimag) *
                                irot.v;
                            a[i + offset + 2 * p] =
                                (a0 + a1 + (T::get_mod() - a2) +
                                 (T::get_mod() - a3)) *
                                irot2.v;
                            a[i + offset + 3 * p] =
                                (a0 + (T::get_mod() - a1) +
                                 (T::get_mod() - a2na3iimag)) *
                                irot3.v;
                        }
                        if (s + 1 != (1 << (len - 2)))
                            irot *= irate3[__builtin_ctzll(~(unsigned int)(s))];
                    }
                    len -= 2;
                }
            }
            T e = T(n).inv();
            for (auto &x : a)
                x *= e;
        } else {
            int len = 0; // a[i, i+(n>>len), i+2*(n>>len), ..] is transformed
            while (len < h) {
                if (h - len == 1) {
                    int p = 1 << (h - len - 1);
                    T rot = 1;
                    for (int s = 0; s < (1 << len); s++) {
                        int offset = s << (h - len);
                        for (int i = 0; i < p; i++) {
                            auto l = a[i + offset];
                            auto r = a[i + offset + p] * rot;
                            a[i + offset] = l + r;
                            a[i + offset + p] = l - r;
                        }
                        if (s + 1 != (1 << len))
                            rot *= rate2[__builtin_ctzll(~(unsigned int)(s))];
                    }
                    len++;
                } else {
                    // 4-base
                    int p = 1 << (h - len - 2);
                    T rot = 1, imag = root[2];
                    for (int s = 0; s < (1 << len); s++) {
                        T rot2 = rot * rot;
                        T rot3 = rot2 * rot;
                        int offset = s << (h - len);
                        for (int i = 0; i < p; i++) {
                            auto mod2 = 1ULL * T::get_mod() * T::get_mod();
                            auto a0 = 1ULL * a[i + offset].v;
                            auto a1 = 1ULL * a[i + offset + p].v * rot.v;
                            auto a2 = 1ULL * a[i + offset + 2 * p].v * rot2.v;
                            auto a3 = 1ULL * a[i + offset + 3 * p].v * rot3.v;
                            auto a1na3imag =
                                1ULL * T(a1 + mod2 - a3).v * imag.v;
                            auto na2 = mod2 - a2;
                            a[i + offset] = a0 + a2 + a1 + a3;
                            a[i + offset + 1 * p] =
                                a0 + a2 + (2 * mod2 - (a1 + a3));
                            a[i + offset + 2 * p] = a0 + na2 + a1na3imag;
                            a[i + offset + 3 * p] =
                                a0 + na2 + (mod2 - a1na3imag);
                        }
                        if (s + 1 != (1 << len))
                            rot *= rate3[__builtin_ctzll(~(unsigned int)(s))];
                    }
                    len += 2;
                }
            }
        }
    }
    vector<T> mult(const vector<T> &a, const vector<T> &b) {
        if (a.empty() or b.empty())
            return vector<T>();
        int as = a.size(), bs = b.size();
        int n = as + bs - 1;
        if (as <= 30 or bs <= 30) {
            if (as > 30)
                return mult(b, a);
            vector<T> res(n);
            rep(i, 0, as) rep(j, 0, bs) res[i + j] += a[i] * b[j];
            return res;
        }
        int m = 1;
        while (m < n)
            m <<= 1;
        vector<T> res(m);
        rep(i, 0, as) res[i] = a[i];
        ntt(res);
        if (a == b)
            rep(i, 0, m) res[i] *= res[i];
        else {
            vector<T> c(m);
            rep(i, 0, bs) c[i] = b[i];
            ntt(c);
            rep(i, 0, m) res[i] *= c[i];
        }
        ntt(res, 1);
        res.resize(n);
        return res;
    }
};

/**
 * @brief Number Theoretic Transform
 */
#line 9 "sol.cpp"
using Fp = fp<998244353>;
NTT<Fp> ntt;

template <typename T> T CatalanPow(int n, int k) { // [x^n] C(x)^k
    if (n == 0)
        return 1;
    return nCr<T>(n * 2 + k, n) * k * Inv<T>(n * 2 + k);
}

int main() {
    int n, k;
    read(n, k);

    int N = n * 2;
    vector<Fp> pwk(N), pwk1(N);
    pwk[0] = pwk1[0] = 1;
    rep(i, 0, N - 1) {
        pwk[i + 1] = pwk[i] * k;
        pwk1[i + 1] = pwk1[i] * (k - 1);
    }

    vector<Fp> pre(N + 1);
    rep(d, 1, N + 1) if (N % d == 0) {
        // period d
        if (d & 1) {
            rep(e, 1, (d + 1) / 2 + 1) {
                pre[d] += nCr<Fp>(d - e, (d - 1) / 2) * pwk[e] *
                          pwk1[(d + 1) / 2 - e];
            }
        } else {
            rep(e, 1, d / 2 + 1) {
                pre[d] +=
                    CatalanPow<Fp>(d / 2 - e, e) * pwk[e] * pwk1[d / 2 - e];
            }
        }
    }
    Fp ret;
    rep(x, 1, N + 1) {
        int g = gcd(x, N);
        ret += pre[g];
    }
    ret /= N;
    print(ret);
    return 0;
}
accuracy: 1
time_ms: 1040
memory_kb: 149492
final_rank: 4

code_snippet: #include <bits/stdc++.h>

template <int MOD>
struct Modint {
    int x;
    Modint() : x(0) {}
    Modint(int64_t y) {
        if (y >= 0)
            x = y % MOD;
        else
            x = (y % MOD + MOD) % MOD;
    }

    Modint &operator+=(const Modint &p) {
        x += p.x;
        if (x >= MOD) x -= MOD;
        return *this;
    }

    Modint &operator-=(const Modint &p) {
        x -= p.x;
        if (x < 0) x += MOD;
        return *this;
    }

    Modint &operator*=(const Modint &p) {
        x = int(1LL * x * p.x % MOD);
        return *this;
    }

    Modint &operator/=(const Modint &p) {
        *this *= p.inverse();
        return *this;
    }

    Modint &operator%=(const Modint &p) {
        assert(p.x == 0);
        return *this;
    }

    Modint operator-() const {
        return Modint(-x);
    }

    Modint &operator++() {
        x++;
        if (x == MOD) x = 0;
        return *this;
    }

    Modint &operator--() {
        if (x == 0) x = MOD;
        x--;
        return *this;
    }

    Modint operator++(int) {
        Modint result = *this;
        ++*this;
        return result;
    }

    Modint operator--(int) {
        Modint result = *this;
        --*this;
        return result;
    }

    friend Modint operator+(const Modint &lhs, const Modint &rhs) {
        return Modint(lhs) += rhs;
    }

    friend Modint operator-(const Modint &lhs, const Modint &rhs) {
        return Modint(lhs) -= rhs;
    }

    friend Modint operator*(const Modint &lhs, const Modint &rhs) {
        return Modint(lhs) *= rhs;
    }

    friend Modint operator/(const Modint &lhs, const Modint &rhs) {
        return Modint(lhs) /= rhs;
    }

    friend Modint operator%(const Modint &lhs, const Modint &rhs) {
        assert(rhs.x == 0);
        return Modint(lhs);
    }

    bool operator==(const Modint &p) const {
        return x == p.x;
    }

    bool operator!=(const Modint &p) const {
        return x != p.x;
    }

    bool operator<(const Modint &rhs) const {
        return x < rhs.x;
    }

    bool operator<=(const Modint &rhs) const {
        return x <= rhs.x;
    }

    bool operator>(const Modint &rhs) const {
        return x > rhs.x;
    }

    bool operator>=(const Modint &rhs) const {
        return x >= rhs.x;
    }

    Modint inverse() const {
        int a = x, b = MOD, u = 1, v = 0, t;
        while (b > 0) {
            t = a / b;
            a -= t * b;
            u -= t * v;
            std::swap(a, b);
            std::swap(u, v);
        }
        return Modint(u);
    }

    Modint pow(int64_t k) const {
        Modint ret(1);
        Modint y(x);
        while (k > 0) {
            if (k & 1) ret *= y;
            y *= y;
            k >>= 1;
        }
        return ret;
    }

    std::pair<int, int> to_frac(int max_n = 1000) const {
        int y = x;
        for (int i = 1; i <= max_n; i++) {
            if (y <= max_n) {
                return {y, i};
            } else if (MOD - y <= max_n) {
                return {-(MOD - y), i};
            }
            y = (y + x) % MOD;
        }
        return {-1, -1};
    }

    friend std::ostream &operator<<(std::ostream &os, const Modint &p) {
        return os << p.x;
    }

    friend std::istream &operator>>(std::istream &is, Modint &p) {
        int64_t y;
        is >> y;
        p = Modint<MOD>(y);
        return (is);
    }

    static int get_mod() {
        return MOD;
    }
};

struct Arbitrary_Modint {
    int x;
    static int MOD;

    static void set_mod(int mod) {
        MOD = mod;
    }

    Arbitrary_Modint() : x(0) {}
    Arbitrary_Modint(int64_t y) {
        if (y >= 0)
            x = y % MOD;
        else
            x = (y % MOD + MOD) % MOD;
    }

    Arbitrary_Modint &operator+=(const Arbitrary_Modint &p) {
        x += p.x;
        if (x >= MOD) x -= MOD;
        return *this;
    }

    Arbitrary_Modint &operator-=(const Arbitrary_Modint &p) {
        x -= p.x;
        if (x < 0) x += MOD;
        return *this;
    }

    Arbitrary_Modint &operator*=(const Arbitrary_Modint &p) {
        x = int(1LL * x * p.x % MOD);
        return *this;
    }

    Arbitrary_Modint &operator/=(const Arbitrary_Modint &p) {
        *this *= p.inverse();
        return *this;
    }

    Arbitrary_Modint &operator%=(const Arbitrary_Modint &p) {
        assert(p.x == 0);
        return *this;
    }

    Arbitrary_Modint operator-() const {
        return Arbitrary_Modint(-x);
    }

    Arbitrary_Modint &operator++() {
        x++;
        if (x == MOD) x = 0;
        return *this;
    }

    Arbitrary_Modint &operator--() {
        if (x == 0) x = MOD;
        x--;
        return *this;
    }

    Arbitrary_Modint operator++(int) {
        Arbitrary_Modint result = *this;
        ++*this;
        return result;
    }

    Arbitrary_Modint operator--(int) {
        Arbitrary_Modint result = *this;
        --*this;
        return result;
    }

    friend Arbitrary_Modint operator+(const Arbitrary_Modint &lhs, const Arbitrary_Modint &rhs) {
        return Arbitrary_Modint(lhs) += rhs;
    }

    friend Arbitrary_Modint operator-(const Arbitrary_Modint &lhs, const Arbitrary_Modint &rhs) {
        return Arbitrary_Modint(lhs) -= rhs;
    }

    friend Arbitrary_Modint operator*(const Arbitrary_Modint &lhs, const Arbitrary_Modint &rhs) {
        return Arbitrary_Modint(lhs) *= rhs;
    }

    friend Arbitrary_Modint operator/(const Arbitrary_Modint &lhs, const Arbitrary_Modint &rhs) {
        return Arbitrary_Modint(lhs) /= rhs;
    }

    friend Arbitrary_Modint operator%(const Arbitrary_Modint &lhs, const Arbitrary_Modint &rhs) {
        assert(rhs.x == 0);
        return Arbitrary_Modint(lhs);
    }

    bool operator==(const Arbitrary_Modint &p) const {
        return x == p.x;
    }

    bool operator!=(const Arbitrary_Modint &p) const {
        return x != p.x;
    }

    bool operator<(const Arbitrary_Modint &rhs) {
        return x < rhs.x;
    }

    bool operator<=(const Arbitrary_Modint &rhs) {
        return x <= rhs.x;
    }

    bool operator>(const Arbitrary_Modint &rhs) {
        return x > rhs.x;
    }

    bool operator>=(const Arbitrary_Modint &rhs) {
        return x >= rhs.x;
    }

    Arbitrary_Modint inverse() const {
        int a = x, b = MOD, u = 1, v = 0, t;
        while (b > 0) {
            t = a / b;
            a -= t * b;
            u -= t * v;
            std::swap(a, b);
            std::swap(u, v);
        }
        return Arbitrary_Modint(u);
    }

    Arbitrary_Modint pow(int64_t k) const {
        Arbitrary_Modint ret(1);
        Arbitrary_Modint y(x);
        while (k > 0) {
            if (k & 1) ret *= y;
            y *= y;
            k >>= 1;
        }
        return ret;
    }

    friend std::ostream &operator<<(std::ostream &os, const Arbitrary_Modint &p) {
        return os << p.x;
    }

    friend std::istream &operator>>(std::istream &is, Arbitrary_Modint &p) {
        int64_t y;
        is >> y;
        p = Arbitrary_Modint(y);
        return (is);
    }

    static int get_mod() {
        return MOD;
    }
};
int Arbitrary_Modint::MOD = 998244353;

using modint9 = Modint<998244353>;
using modint1 = Modint<1000000007>;
using modint  = Arbitrary_Modint;
using mint    = modint9;

template <typename T>
struct Combination {
    int N;
    std::vector<T> fact, invfact;
    Combination(int N) : N(N) {
        fact.resize(N + 1);
        invfact.resize(N + 1);
        fact[0] = 1;
        for (int i = 1; i <= N; i++) {
            fact[i] = fact[i - 1] * i;
        }
        invfact[N] = T(1) / fact[N];
        for (int i = N - 1; i >= 0; i--) {
            invfact[i] = invfact[i + 1] * (i + 1);
        }
    }

    void extend(int n) {
        int le = fact.size();
        fact.resize(n + 1);
        invfact.resize(n + 1);
        for (int i = le; i <= n; i++) {
            fact[i] = fact[i - 1] * i;
        }
        invfact[n] = T(1) / fact[n];
        for (int i = n - 1; i >= le; i--) {
            invfact[i] = invfact[i + 1] * (i + 1);
        }
    }

    T nCk(int n, int k) {
        if (k > n || k < 0) return T(0);
        if (n >= int(fact.size())) extend(n);
        return fact[n] * invfact[k] * invfact[n - k];
    }

    T nPk(int n, int k) {
        if (k > n || k < 0) return T(0);
        if (n >= int(fact.size())) extend(n);
        return fact[n] * invfact[n - k];
    }

    T nHk(int n, int k) {
        if (n == 0 && k == 0) return T(1);
        return nCk(n + k - 1, k);
    }

    T catalan(int n) {
        return nCk(2 * n, n) - nCk(2 * n, n + 1);
    }

    // n 個の +1, m 個の -1, 累積和が常にk以下
    T catalan(int n, int m, int k) {
        if (n > m + k || k < 0)
            return T(0);
        else
            return nCk(n + m, n) - nCk(n + m, m + k + 1);
    }

    // return [x^n] C^k(x)
    // 先頭に ( が k - 1 個連続するような長さ n + k - 1 の括弧列と一対一対応
    T catalan_convolution(int n, int k) {
        return catalan(k + n - 1, n, k - 1);
    }

    T narayana(int n, int k) {
        return nCk(n, k) * nCk(n, k - 1) / n;
    }

    T inv(int n) {
        assert(n >= 1);
        if (n >= int(fact.size())) extend(n);
        return invfact[n] * fact[n - 1];
    }
};

void solve() {
    int n, k;
    std::cin >> n >> k;
    Combination<mint> Comb(2 * n + 10);
    std::vector<int> count(2 * n + 1);
    std::vector<int> divs;
    for (int d = 1; d <= 2 * n; d++) {
        int g = std::gcd(d, 2 * n);
        if (2 * n % d == 0) {
            divs.push_back(d);
        }
        count[g]++;
    }

    std::vector<mint> powk(n + 1);
    std::vector<mint> powk_1(n + 1);
    powk[0]   = 1;
    powk_1[0] = 1;
    for (int i = 1; i <= n; i++) {
        powk[i]   = powk[i - 1] * k;
        powk_1[i] = powk_1[i - 1] * (k - 1);
    }

    mint ans = 0;
    for (auto d : divs) {
        mint tot = 0;
        if (d % 2 == 0) {
            int x = d / 2;
            for (int i = 1; i <= x; i++) {
                tot += Comb.catalan_convolution(x - i, i) * powk[i] * powk_1[x - i];
            }
        } else {
            int x = d / 2;
            for (int i = 0; i <= x; i++) {
                tot += Comb.nCk(2 * x - i, x) * powk[i + 1] * powk_1[x - i];
            }
        }
        ans += tot * count[d];
    }
    ans /= 2 * n;
    std::cout << ans << std::endl;
}

int main() {
#ifndef INTERACTIVE
    std::cin.tie(0)->sync_with_stdio(0);
#endif
    // std::cout << std::fixed << std::setprecision(12);
    int t;
    t = 1;
    // std::cin >> t;
    while (t--) solve();
    return 0;
}

// #include <bits/stdc++.h>
//
// #include "misc/Modint.hpp"
// using mint = modint9;
// #include "math/Combination.hpp"
//
// void solve() {
//     int n, k;
//     std::cin >> n >> k;
//     Combination<mint> Comb(2 * n + 10);
//     std::vector<int> count(2 * n + 1);
//     std::vector<int> divs;
//     for (int d = 1; d <= 2 * n; d++) {
//         int g = std::gcd(d, 2 * n);
//         if (2 * n % d == 0) {
//             divs.push_back(d);
//         }
//         count[g]++;
//     }
//
//     std::vector<mint> powk(n + 1);
//     std::vector<mint> powk_1(n + 1);
//     powk[0]   = 1;
//     powk_1[0] = 1;
//     for (int i = 1; i <= n; i++) {
//         powk[i]   = powk[i - 1] * k;
//         powk_1[i] = powk_1[i - 1] * (k - 1);
//     }
//
//     mint ans = 0;
//     for (auto d : divs) {
//         mint tot = 0;
//         if (d % 2 == 0) {
//             int x = d / 2;
//             for (int i = 1; i <= x; i++) {
//                 tot += Comb.catalan_convolution(x - i, i) * powk[i] * powk_1[x - i];
//             }
//         } else {
//             int x = d / 2;
//             for (int i = 0; i <= x; i++) {
//                 tot += Comb.nCk(2 * x - i, x) * powk[i + 1] * powk_1[x - i];
//             }
//         }
//         ans += tot * count[d];
//     }
//     ans /= 2 * n;
//     std::cout << ans << std::endl;
// }
//
// int main() {
// #ifndef INTERACTIVE
//     std::cin.tie(0)->sync_with_stdio(0);
// #endif
//     // std::cout << std::fixed << std::setprecision(12);
//     int t;
//     t = 1;
//     // std::cin >> t;
//     while (t--) solve();
//     return 0;
// }
accuracy: 1
time_ms: 670
memory_kb: 96892
final_rank: 2

code_snippet: #include <bits/stdc++.h>

template <int MOD>
struct Modint {
    int x;
    Modint() : x(0) {}
    Modint(int64_t y) {
        if (y >= 0)
            x = y % MOD;
        else
            x = (y % MOD + MOD) % MOD;
    }

    Modint &operator+=(const Modint &p) {
        x += p.x;
        if (x >= MOD) x -= MOD;
        return *this;
    }

    Modint &operator-=(const Modint &p) {
        x -= p.x;
        if (x < 0) x += MOD;
        return *this;
    }

    Modint &operator*=(const Modint &p) {
        x = int(1LL * x * p.x % MOD);
        return *this;
    }

    Modint &operator/=(const Modint &p) {
        *this *= p.inverse();
        return *this;
    }

    Modint &operator%=(const Modint &p) {
        assert(p.x == 0);
        return *this;
    }

    Modint operator-() const {
        return Modint(-x);
    }

    Modint &operator++() {
        x++;
        if (x == MOD) x = 0;
        return *this;
    }

    Modint &operator--() {
        if (x == 0) x = MOD;
        x--;
        return *this;
    }

    Modint operator++(int) {
        Modint result = *this;
        ++*this;
        return result;
    }

    Modint operator--(int) {
        Modint result = *this;
        --*this;
        return result;
    }

    friend Modint operator+(const Modint &lhs, const Modint &rhs) {
        return Modint(lhs) += rhs;
    }

    friend Modint operator-(const Modint &lhs, const Modint &rhs) {
        return Modint(lhs) -= rhs;
    }

    friend Modint operator*(const Modint &lhs, const Modint &rhs) {
        return Modint(lhs) *= rhs;
    }

    friend Modint operator/(const Modint &lhs, const Modint &rhs) {
        return Modint(lhs) /= rhs;
    }

    friend Modint operator%(const Modint &lhs, const Modint &rhs) {
        assert(rhs.x == 0);
        return Modint(lhs);
    }

    bool operator==(const Modint &p) const {
        return x == p.x;
    }

    bool operator!=(const Modint &p) const {
        return x != p.x;
    }

    bool operator<(const Modint &rhs) const {
        return x < rhs.x;
    }

    bool operator<=(const Modint &rhs) const {
        return x <= rhs.x;
    }

    bool operator>(const Modint &rhs) const {
        return x > rhs.x;
    }

    bool operator>=(const Modint &rhs) const {
        return x >= rhs.x;
    }

    Modint inverse() const {
        int a = x, b = MOD, u = 1, v = 0, t;
        while (b > 0) {
            t = a / b;
            a -= t * b;
            u -= t * v;
            std::swap(a, b);
            std::swap(u, v);
        }
        return Modint(u);
    }

    Modint pow(int64_t k) const {
        Modint ret(1);
        Modint y(x);
        while (k > 0) {
            if (k & 1) ret *= y;
            y *= y;
            k >>= 1;
        }
        return ret;
    }

    std::pair<int, int> to_frac(int max_n = 1000) const {
        int y = x;
        for (int i = 1; i <= max_n; i++) {
            if (y <= max_n) {
                return {y, i};
            } else if (MOD - y <= max_n) {
                return {-(MOD - y), i};
            }
            y = (y + x) % MOD;
        }
        return {-1, -1};
    }

    friend std::ostream &operator<<(std::ostream &os, const Modint &p) {
        return os << p.x;
    }

    friend std::istream &operator>>(std::istream &is, Modint &p) {
        int64_t y;
        is >> y;
        p = Modint<MOD>(y);
        return (is);
    }

    static int get_mod() {
        return MOD;
    }
};

struct Arbitrary_Modint {
    int x;
    static int MOD;

    static void set_mod(int mod) {
        MOD = mod;
    }

    Arbitrary_Modint() : x(0) {}
    Arbitrary_Modint(int64_t y) {
        if (y >= 0)
            x = y % MOD;
        else
            x = (y % MOD + MOD) % MOD;
    }

    Arbitrary_Modint &operator+=(const Arbitrary_Modint &p) {
        x += p.x;
        if (x >= MOD) x -= MOD;
        return *this;
    }

    Arbitrary_Modint &operator-=(const Arbitrary_Modint &p) {
        x -= p.x;
        if (x < 0) x += MOD;
        return *this;
    }

    Arbitrary_Modint &operator*=(const Arbitrary_Modint &p) {
        x = int(1LL * x * p.x % MOD);
        return *this;
    }

    Arbitrary_Modint &operator/=(const Arbitrary_Modint &p) {
        *this *= p.inverse();
        return *this;
    }

    Arbitrary_Modint &operator%=(const Arbitrary_Modint &p) {
        assert(p.x == 0);
        return *this;
    }

    Arbitrary_Modint operator-() const {
        return Arbitrary_Modint(-x);
    }

    Arbitrary_Modint &operator++() {
        x++;
        if (x == MOD) x = 0;
        return *this;
    }

    Arbitrary_Modint &operator--() {
        if (x == 0) x = MOD;
        x--;
        return *this;
    }

    Arbitrary_Modint operator++(int) {
        Arbitrary_Modint result = *this;
        ++*this;
        return result;
    }

    Arbitrary_Modint operator--(int) {
        Arbitrary_Modint result = *this;
        --*this;
        return result;
    }

    friend Arbitrary_Modint operator+(const Arbitrary_Modint &lhs, const Arbitrary_Modint &rhs) {
        return Arbitrary_Modint(lhs) += rhs;
    }

    friend Arbitrary_Modint operator-(const Arbitrary_Modint &lhs, const Arbitrary_Modint &rhs) {
        return Arbitrary_Modint(lhs) -= rhs;
    }

    friend Arbitrary_Modint operator*(const Arbitrary_Modint &lhs, const Arbitrary_Modint &rhs) {
        return Arbitrary_Modint(lhs) *= rhs;
    }

    friend Arbitrary_Modint operator/(const Arbitrary_Modint &lhs, const Arbitrary_Modint &rhs) {
        return Arbitrary_Modint(lhs) /= rhs;
    }

    friend Arbitrary_Modint operator%(const Arbitrary_Modint &lhs, const Arbitrary_Modint &rhs) {
        assert(rhs.x == 0);
        return Arbitrary_Modint(lhs);
    }

    bool operator==(const Arbitrary_Modint &p) const {
        return x == p.x;
    }

    bool operator!=(const Arbitrary_Modint &p) const {
        return x != p.x;
    }

    bool operator<(const Arbitrary_Modint &rhs) {
        return x < rhs.x;
    }

    bool operator<=(const Arbitrary_Modint &rhs) {
        return x <= rhs.x;
    }

    bool operator>(const Arbitrary_Modint &rhs) {
        return x > rhs.x;
    }

    bool operator>=(const Arbitrary_Modint &rhs) {
        return x >= rhs.x;
    }

    Arbitrary_Modint inverse() const {
        int a = x, b = MOD, u = 1, v = 0, t;
        while (b > 0) {
            t = a / b;
            a -= t * b;
            u -= t * v;
            std::swap(a, b);
            std::swap(u, v);
        }
        return Arbitrary_Modint(u);
    }

    Arbitrary_Modint pow(int64_t k) const {
        Arbitrary_Modint ret(1);
        Arbitrary_Modint y(x);
        while (k > 0) {
            if (k & 1) ret *= y;
            y *= y;
            k >>= 1;
        }
        return ret;
    }

    friend std::ostream &operator<<(std::ostream &os, const Arbitrary_Modint &p) {
        return os << p.x;
    }

    friend std::istream &operator>>(std::istream &is, Arbitrary_Modint &p) {
        int64_t y;
        is >> y;
        p = Arbitrary_Modint(y);
        return (is);
    }

    static int get_mod() {
        return MOD;
    }
};
int Arbitrary_Modint::MOD = 998244353;

using modint9 = Modint<998244353>;
using modint1 = Modint<1000000007>;
using modint  = Arbitrary_Modint;
using mint    = modint9;

template <typename T>
struct Combination {
    int N;
    std::vector<T> fact, invfact;
    Combination(int N) : N(N) {
        fact.resize(N + 1);
        invfact.resize(N + 1);
        fact[0] = 1;
        for (int i = 1; i <= N; i++) {
            fact[i] = fact[i - 1] * i;
        }
        invfact[N] = T(1) / fact[N];
        for (int i = N - 1; i >= 0; i--) {
            invfact[i] = invfact[i + 1] * (i + 1);
        }
    }

    void extend(int n) {
        int le = fact.size();
        fact.resize(n + 1);
        invfact.resize(n + 1);
        for (int i = le; i <= n; i++) {
            fact[i] = fact[i - 1] * i;
        }
        invfact[n] = T(1) / fact[n];
        for (int i = n - 1; i >= le; i--) {
            invfact[i] = invfact[i + 1] * (i + 1);
        }
    }

    T nCk(int n, int k) {
        if (k > n || k < 0) return T(0);
        if (n >= int(fact.size())) extend(n);
        return fact[n] * invfact[k] * invfact[n - k];
    }

    T nPk(int n, int k) {
        if (k > n || k < 0) return T(0);
        if (n >= int(fact.size())) extend(n);
        return fact[n] * invfact[n - k];
    }

    T nHk(int n, int k) {
        if (n == 0 && k == 0) return T(1);
        return nCk(n + k - 1, k);
    }

    T catalan(int n) {
        return nCk(2 * n, n) - nCk(2 * n, n + 1);
    }

    // n 個の +1, m 個の -1, 累積和が常にk以下
    T catalan(int n, int m, int k) {
        if (n > m + k || k < 0)
            return T(0);
        else
            return nCk(n + m, n) - nCk(n + m, m + k + 1);
    }

    // return [x^n] C^k(x)
    // 先頭に ( が k - 1 個連続するような長さ n + k - 1 の括弧列と一対一対応
    T catalan_convolution(int n, int k) {
        return catalan(k + n - 1, n, k - 1);
    }

    T narayana(int n, int k) {
        return nCk(n, k) * nCk(n, k - 1) / n;
    }

    T inv(int n) {
        assert(n >= 1);
        if (n >= int(fact.size())) extend(n);
        return invfact[n] * fact[n - 1];
    }
};

void solve() {
    int n, k;
    std::cin >> n >> k;
    Combination<mint> Comb(2 * n + 10);
    std::vector<int> count(2 * n + 1);
    std::vector<int> divs;
    for (int d = 1; d <= 2 * n; d++) {
        int g = std::gcd(d, 2 * n);
        if (2 * n % d == 0) {
            divs.push_back(d);
        }
        count[g]++;
    }

    std::vector<mint> powk(n + 1);
    std::vector<mint> powk_1(n + 1);
    powk[0]   = 1;
    powk_1[0] = 1;
    for (int i = 1; i <= n; i++) {
        powk[i]   = powk[i - 1] * k;
        powk_1[i] = powk_1[i - 1] * (k - 1);
    }

    mint ans = 0;
    for (auto d : divs) {
        mint tot = 0;
        if (d % 2 == 0) {
            int x = d / 2;
            for (int i = 1; i <= x; i++) {
                tot += Comb.catalan_convolution(x - i, i) * powk[i] * powk_1[x - i];
            }
        } else {
            int x = d / 2;
            // for (int i = 0; i <= x; i++) {
            //     mint tot2 = 0;
            //     for (int j = 1; j <= d; j += 2) {
            //         int u = (d + j) / 2;
            //         u--;
            //         int v = (d - j) / 2;
            //         if (i > v) break;
            //         u -= i;
            //         mint tmp = Comb.catalan(v, u, i);
            //         tmp -= Comb.catalan(v, u, i - 1);
            //         tot2 += tmp;
            //     }
            //     tot += tot2 * powk[i + 1] * powk_1[x - i];
            // }

            for (int i = 0; i <= x; i++) {
                int t = d - i - 1;
                int s = (d + 1) / 2 - 1;
                // mint tot2 = 0;
                // for (int u = s; u <= s + x; u++) {
                //     tot2 += Comb.nCk(t, u);
                //     tot2 -= Comb.nCk(t, u + 1);
                // }
                tot += (Comb.nCk(t, s) - Comb.nCk(t, s + x + 1)) * powk[i + 1] * powk_1[x - i];
            }
        }
        ans += tot * count[d];
    }
    ans /= 2 * n;
    std::cout << ans << std::endl;
}

int main() {
#ifndef INTERACTIVE
    std::cin.tie(0)->sync_with_stdio(0);
#endif
    // std::cout << std::fixed << std::setprecision(12);
    int t;
    t = 1;
    // std::cin >> t;
    while (t--) solve();
    return 0;
}

// #include <bits/stdc++.h>
//
// #include "misc/Modint.hpp"
// using mint = modint9;
// #include "math/Combination.hpp"
//
// void solve() {
//     int n, k;
//     std::cin >> n >> k;
//     Combination<mint> Comb(2 * n + 10);
//     std::vector<int> count(2 * n + 1);
//     std::vector<int> divs;
//     for (int d = 1; d <= 2 * n; d++) {
//         int g = std::gcd(d, 2 * n);
//         if (2 * n % d == 0) {
//             divs.push_back(d);
//         }
//         count[g]++;
//     }
//
//     std::vector<mint> powk(n + 1);
//     std::vector<mint> powk_1(n + 1);
//     powk[0]   = 1;
//     powk_1[0] = 1;
//     for (int i = 1; i <= n; i++) {
//         powk[i]   = powk[i - 1] * k;
//         powk_1[i] = powk_1[i - 1] * (k - 1);
//     }
//
//     mint ans = 0;
//     for (auto d : divs) {
//         mint tot = 0;
//         if (d % 2 == 0) {
//             int x = d / 2;
//             for (int i = 1; i <= x; i++) {
//                 tot += Comb.catalan_convolution(x - i, i) * powk[i] * powk_1[x - i];
//             }
//         } else {
//             int x = d / 2;
//             // for (int i = 0; i <= x; i++) {
//             //     mint tot2 = 0;
//             //     for (int j = 1; j <= d; j += 2) {
//             //         int u = (d + j) / 2;
//             //         u--;
//             //         int v = (d - j) / 2;
//             //         if (i > v) break;
//             //         u -= i;
//             //         mint tmp = Comb.catalan(v, u, i);
//             //         tmp -= Comb.catalan(v, u, i - 1);
//             //         tot2 += tmp;
//             //     }
//             //     tot += tot2 * powk[i + 1] * powk_1[x - i];
//             // }
//
//             for (int i = 0; i <= x; i++) {
//                 int t = d - i - 1;
//                 int s = (d + 1) / 2 - 1;
//                 // mint tot2 = 0;
//                 // for (int u = s; u <= s + x; u++) {
//                 //     tot2 += Comb.nCk(t, u);
//                 //     tot2 -= Comb.nCk(t, u + 1);
//                 // }
//                 tot += (Comb.nCk(t, s) - Comb.nCk(t, s + x + 1)) * powk[i + 1] * powk_1[x - i];
//             }
//         }
//         ans += tot * count[d];
//     }
//     ans /= 2 * n;
//     std::cout << ans << std::endl;
// }
//
// int main() {
// #ifndef INTERACTIVE
//     std::cin.tie(0)->sync_with_stdio(0);
// #endif
//     // std::cout << std::fixed << std::setprecision(12);
//     int t;
//     t = 1;
//     // std::cin >> t;
//     while (t--) solve();
//     return 0;
// }
accuracy: 1
time_ms: 670
memory_kb: 96936
final_rank: 3

code_snippet: #pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include <iostream>
#include <string>
#include <cstdio>
#include <vector>
#include <cmath>
#include <algorithm>
#include <functional>
#include <iomanip>
#include <queue>
#include <ciso646>
#include <random>
#include <map>
#include <set>
#include <bitset>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <cassert>
#include <complex>
#include <numeric>
#include <array>
#include <chrono>
using namespace std;

// データ型と定数の定義
typedef long long ll;
typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 998244353; // モジュラス
const int mod17 = 1000000007;
const ll INF = (ll)mod17 * mod17;
typedef pair<int, int> P;

#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;

using ld = double;
typedef pair<ld, ld> LDP;
const ld eps = 1e-10;
const ld pi = acosl(-1.0);

// 最小値と最大値を更新する関数
template<typename T>
void chmin(T& a, T b) {
    a = min(a, b);
}

template<typename T>
void chmax(T& a, T b) {
    a = max(a, b);
}

// ベクトルのマージ
template<typename T>
vector<T> vmerge(vector<T>& a, vector<T>& b) {
    vector<T> res;
    int ida = 0, idb = 0;
    while (ida < a.size() || idb < b.size()) {
        if (idb == b.size()) {
            res.push_back(a[ida]); ida++;
        } else if (ida == a.size()) {
            res.push_back(b[idb]); idb++;
        } else {
            if (a[ida] < b[idb]) {
                res.push_back(a[ida]); ida++;
            } else {
                res.push_back(b[idb]); idb++;
            }
        }
    }
    return res;
}

// ベクトルの入力と出力
template<typename T>
void cinarray(vector<T>& v) {
    rep(i, v.size()) cin >> v[i];
}

template<typename T>
void coutarray(vector<T>& v) {
    rep(i, v.size()) {
        if (i > 0) cout << " "; 
        cout << v[i];
    }
    cout << "\n";
}

// モジュラスのべき乗
ll mod_pow(ll x, ll n, ll m = mod) {
    if (n < 0) {
        ll res = mod_pow(x, -n, m);
        return mod_pow(res, m - 2, m);
    }
    if (abs(x) >= m) x %= m;
    if (x < 0) x += m;
    ll res = 1;
    while (n) {
        if (n & 1) res = res * x % m;
        x = x * x % m; 
        n >>= 1;
    }
    return res;
}

// modint構造体
struct modint {
    int n;
    modint() : n(0) { ; }
    modint(ll m) {
        if (m < 0 || mod <= m) {
            m %= mod; 
            if (m < 0) m += mod;
        }
        n = m;
    }
    operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
bool operator<(modint a, modint b) { return a.n < b.n; }
modint operator+=(modint& a, modint b) { a.n += b.n; if (a.n >= mod) a.n -= (int)mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0) a.n += (int)mod; return a; }
modint operator*=(modint& a, modint b) { a.n = ((ll)a.n * b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, ll n) {
    if (n == 0) return modint(1);
    modint res = (a * a) ^ (n / 2);
    if (n % 2) res = res * a;
    return res;
}

// 逆元の計算
ll inv(ll a, ll p) {
    return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }
modint operator/=(modint& a, modint b) { a = a / b; return a; }

const int max_n = 1 << 24;
modint fact[max_n], factinv[max_n];

// 階乗の初期化
void init_f() {
    fact[0] = modint(1);
    for (int i = 0; i < max_n - 1; i++) {
        fact[i + 1] = fact[i] * modint(i + 1);
    }
    factinv[max_n - 1] = modint(1) / fact[max_n - 1];
    for (int i = max_n - 2; i >= 0; i--) {
        factinv[i] = factinv[i + 1] * modint(i + 1);
    }
}

// 組み合わせ計算
modint comb(int a, int b) {
    if (a < 0 || b < 0 || a < b) return 0;
    return fact[a] * factinv[b] * factinv[a - b];
}

modint combP(int a, int b) {
    if (a < 0 || b < 0 || a < b) return 0;
    return fact[a] * factinv[a - b];
}

// 最大公約数
ll gcd(ll a, ll b) {
    a = abs(a); b = abs(b);
    if (a < b) swap(a, b);
    while (b) {
        ll r = a % b; 
        a = b; 
        b = r;
    }
    return a;
}

template<typename T>
void addv(vector<T>& v, int loc, T val) {
    if (loc >= v.size()) v.resize(loc + 1, 0);
    v[loc] += val;
}

// 前のイテレータを取得
template<typename T>
auto prev_itr(set<T>& st, T val) -> typename set<T>::iterator {
    auto res = st.lower_bound(val);
    if (res == st.begin()) return st.end();
    res--; 
    return res;
}

// 次のイテレータを取得
template<typename T>
auto next_itr(set<T>& st, T val) -> typename set<T>::iterator {
    auto res = st.lower_bound(val);
    return res;
}

using mP = pair<modint, modint>;

// 演算子オーバーロード
mP operator+(mP a, mP b) {
    return { a.first + b.first, a.second + b.second };
}

mP operator+=(mP& a, mP b) {
    a = a + b; return a;
}

mP operator-(mP a, mP b) {
    return { a.first - b.first, a.second - b.second };
}

mP operator-=(mP& a, mP b) {
    a = a - b; return a;
}

LP operator+(LP a, LP b) {
    return { a.first + b.first, a.second + b.second };
}

LP operator+=(LP& a, LP b) {
    a = a + b; return a;
}

LP operator-(LP a, LP b) {
    return { a.first - b.first, a.second - b.second };
}

LP operator-=(LP& a, LP b) {
    a = a - b; return a;
}

// 乱数生成
mt19937 mt(time(0));

// プリミティブルートの取得
int get_premitive_root() {
    int primitive_root = 0;
    if (!primitive_root) {
        primitive_root = [&]() {
            set<int> fac;
            int v = mod - 1;
            for (ll i = 2; i * i <= v; i++) while (v % i == 0) fac.insert(i), v /= i;
            if (v > 1) fac.insert(v);
            for (int g = 1; g < mod; g++) {
                bool ok = true;
                for (auto i : fac) if (mod_pow(g, (mod - 1) / i) == 1) { ok = false; break; }
                if (ok) return g;
            }
            return -1;
        }();
    }
    return primitive_root;
}

const int proot = get_premitive_root();

// 多項式の定義
typedef vector <modint> poly;

// 離散フーリエ変換
void dft(poly& f, bool inverse = false) {
    int n = f.size(); if (n == 1) return;

    static poly w{ 1 }, iw{ 1 };
    for (int m = w.size(); m < n / 2; m *= 2) {
        modint dw = mod_pow(proot, (mod - 1) / (4 * m)), dwinv = (modint)1 / dw;
        w.resize(m * 2); iw.resize(m * 2);
        for (int i = 0; i < m; i++) w[m + i] = w[i] * dw, iw[m + i] = iw[i] * dwinv;
    }

    if (!inverse) {
        for (int m = n; m >>= 1;) {
            for (int s = 0, k = 0; s < n; s += 2 * m, k++) {
                for (int i = s; i < s + m; i++) {
                    modint x = f[i], y = f[i + m] * w[k];
                    f[i] = x + y, f[i + m] = x - y;
                }
            }
        }
    } else {
        for (int m = 1; m < n; m *= 2) {
            for (int s = 0, k = 0; s < n; s += 2 * m, k++) {
                for (int i = s; i < s + m; i++) {
                    modint x = f[i], y = f[i + m];
                    f[i] = x + y, f[i + m] = (x - y) * iw[k];
                }
            }
        }
        modint n_inv = (modint)1 / (modint)n;
        for (modint& v : f) v *= n_inv;
    }
}

// 多項式の積
poly multiply(poly g, poly h) {
    int n = 1;
    int pi = 0, qi = 0;
    rep(i, g.size()) if (g[i]) pi = i;
    rep(i, h.size()) if (h[i]) qi = i;
    int sz = pi + qi + 2;
    while (n < sz) n *= 2;
    g.resize(n); h.resize(n);
    dft(g); dft(h);
    rep(i, n) {
        g[i] *= h[i];
    }
    dft(g, true);
    return g;
}

// 順序付けされた多項式の積
poly ordered_multiply(poly p, poly q, bool eq) {
    poly res;
    function<void(int, int)> dfs = [&](int l, int r) {
        if (l + 1 == r) return;
        int m = (l + r) / 2;
        dfs(l, m);
        dfs(m, r);
        poly pl, pr;
        Rep(j, l, m) if (j < p.size()) pl.push_back(p[j]);
        Rep(j, m, r) if (j < q.size()) pr.push_back(q[j]);
        poly pp = multiply(pl, pr);
        rep(j, pp.size()) addv(res, l + m + j, pp[j]);
    };
    dfs(0, q.size());
    if (eq) {
        rep(j, q.size()) if (j < p.size()) addv(res, 2 * j, p[j] * q[j]);
    }
    return res;
}

// 計算関数
modint calc(int j, int i) {
    if (i == 0) {
        if (j == 0) return 1;
        else return 0;
    }
    return comb(i - 1 + j + j, j) - comb(i - 1 + j + j, j - 1);
}

void solve() {
    int n, k; 
    cin >> n >> k;
    vector<int> cnt(2 * n + 1);
    rep(d, 2 * n) {
        int g = gcd(d, 2 * n);
        cnt[g]++;
    }
    modint ans = 0;
    rep1(i, 2 * n) {
        modint csum = 0;
        if (2 * n % i == 0) {
            modint al = mod_pow(k, i);
            if (i % 2 == 0) {
                int num = i / 2;
                for (int c = 0; c <= num; c++) {
                    modint val = calc(num - c, c);
                    val *= mod_pow(k - 1, num - c);
                    val *= mod_pow(k, c);
                    csum += val;
                }
            } else {
                modint preval = 0;
                rep(x, (i - 1) / 2 + 1) preval += comb(i - 1, x);
                rep(y, i / 2 + 1) {
                    modint coef = mod_pow(k, y + 1);
                    coef *= mod_pow(k - 1, (i - 1) / 2 - y);
                    csum += preval * coef;

                    int a = i - 1 - y;
                    int b = (i - 1) / 2 - y;
                    modint nval = preval + comb(a - 1, b); nval *= (1 + mod) / 2;
                    nval -= comb(a - 1, b);
                    preval = nval;
                }
                rep(x, (i - 1) / 2) preval += comb(i - 1, x);
                rep(y, i / 2) {
                    modint coef = mod_pow(k, y + 1);
                    coef *= mod_pow(k - 1, (i - 1) / 2 - y);
                    csum -= preval * coef;

                    int a = i - 1 - y;
                    int b = (i - 1) / 2 - y - 1;
                    modint nval = preval + comb(a - 1, b); nval *= (1 + mod) / 2;
                    nval -= comb(a - 1, b);
                    preval = nval;
                }
                preval = 0;
            }
            al -= csum;
        }
        ans += csum * (modint)cnt[i];
    }
    ans /= 2 * n;
    cout << ans << "\n";
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    init_f(); // 初期化
    solve();  // 問題解決
    return 0;
}
accuracy: 1
time_ms: 2660
memory_kb: 157564
final_rank: 8

code_snippet: /**
 * date   : 2023-11-27 02:30:10
 * author : Nyaan
 */

#define NDEBUG

using namespace std;

// intrinstic
#include <immintrin.h>

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cfenv>
#include <cfloat>
#include <chrono>
#include <cinttypes>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdarg>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <fstream>
#include <functional>
#include <initializer_list>
#include <iomanip>
#include <ios>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <streambuf>
#include <string>
#include <tuple>
#include <type_traits>
#include <typeinfo>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

// utility

namespace Nyaan {
using ll = long long;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;

template <typename T>
using V = vector<T>;
template <typename T>
using VV = vector<vector<T>>;
using vi = vector<int>;
using vl = vector<long long>;
using vd = V<double>;
using vs = V<string>;
using vvi = vector<vector<int>>;
using vvl = vector<vector<long long>>;
template <typename T>
using minpq = priority_queue<T, vector<T>, greater<T>>;

constexpr int inf = 1001001001;
constexpr long long infLL = 4004004004004004004LL;

template <typename T>
int sz(const T &t) {
  return t.size();
}

}  // namespace Nyaan


// bit operation

namespace Nyaan {
__attribute__((target("popcnt"))) inline int popcnt(const u64 &a) {
  return _mm_popcnt_u64(a);
}
inline int lsb(const u64 &a) { return a ? __builtin_ctzll(a) : 64; }
inline int ctz(const u64 &a) { return a ? __builtin_ctzll(a) : 64; }
inline int msb(const u64 &a) { return a ? 63 - __builtin_clzll(a) : -1; }
template <typename T>
inline int gbit(const T &a, int i) {
  return (a >> i) & 1;
}
template <typename T>
inline void sbit(T &a, int i, bool b) {
  if (gbit(a, i) != b) a ^= T(1) << i;
}
constexpr long long PW(int n) { return 1LL << n; }
constexpr long long MSK(int n) { return (1LL << n) - 1; }
}  // namespace Nyaan


// inout

namespace Nyaan {

template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << p.first << " " << p.second;
  return os;
}
template <typename T, typename U>
istream &operator>>(istream &is, pair<T, U> &p) {
  is >> p.first >> p.second;
  return is;
}

template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  int s = (int)v.size();
  for (int i = 0; i < s; i++) os << (i ? " " : "") << v[i];
  return os;
}
template <typename T>
istream &operator>>(istream &is, vector<T> &v) {
  for (auto &x : v) is >> x;
  return is;
}

void in() {}
template <typename T, class... U>
void in(T &t, U &...u) {
  cin >> t;
  in(u...);
}

void out() { cout << "\n"; }
template <typename T, class... U, char sep = ' '>
void out(const T &t, const U &...u) {
  cout << t;
  if (sizeof...(u)) cout << sep;
  out(u...);
}

struct IoSetupNya {
  IoSetupNya() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(15);
    cerr << fixed << setprecision(7);
  }
} iosetupnya;

}  // namespace Nyaan


// debug


#ifdef NyaanDebug
#define trc(...) (void(0))
#else
#define trc(...) (void(0))
#endif

#ifdef NyaanLocal
#define trc2(...) (void(0))
#else
#define trc2(...) (void(0))
#endif


// macro

#define each(x, v) for (auto&& x : v)
#define each2(x, y, v) for (auto&& [x, y] : v)
#define all(v) (v).begin(), (v).end()
#define rep(i, N) for (long long i = 0; i < (long long)(N); i++)
#define repr(i, N) for (long long i = (long long)(N)-1; i >= 0; i--)
#define rep1(i, N) for (long long i = 1; i <= (long long)(N); i++)
#define repr1(i, N) for (long long i = (N); (long long)(i) > 0; i--)
#define reg(i, a, b) for (long long i = (a); i < (b); i++)
#define regr(i, a, b) for (long long i = (b)-1; i >= (a); i--)
#define fi first
#define se second
#define ini(...)   \
  int __VA_ARGS__; \
  in(__VA_ARGS__)
#define inl(...)         \
  long long __VA_ARGS__; \
  in(__VA_ARGS__)
#define ins(...)      \
  string __VA_ARGS__; \
  in(__VA_ARGS__)
#define in2(s, t)                           \
  for (int i = 0; i < (int)s.size(); i++) { \
    in(s[i], t[i]);                         \
  }
#define in3(s, t, u)                        \
  for (int i = 0; i < (int)s.size(); i++) { \
    in(s[i], t[i], u[i]);                   \
  }
#define in4(s, t, u, v)                     \
  for (int i = 0; i < (int)s.size(); i++) { \
    in(s[i], t[i], u[i], v[i]);             \
  }
#define die(...)             \
  do {                       \
    Nyaan::out(__VA_ARGS__); \
    return;                  \
  } while (0)


namespace Nyaan {
void solve();
}
int main() { Nyaan::solve(); }


//




template <typename mint>
struct NTT {
  static constexpr uint32_t get_pr() {
    uint32_t _mod = mint::get_mod();
    using u64 = uint64_t;
    u64 ds[32] = {};
    int idx = 0;
    u64 m = _mod - 1;
    for (u64 i = 2; i * i <= m; ++i) {
      if (m % i == 0) {
        ds[idx++] = i;
        while (m % i == 0) m /= i;
      }
    }
    if (m != 1) ds[idx++] = m;

    uint32_t _pr = 2;
    while (1) {
      int flg = 1;
      for (int i = 0; i < idx; ++i) {
        u64 a = _pr, b = (_mod - 1) / ds[i], r = 1;
        while (b) {
          if (b & 1) r = r * a % _mod;
          a = a * a % _mod;
          b >>= 1;
        }
        if (r == 1) {
          flg = 0;
          break;
        }
      }
      if (flg == 1) break;
      ++_pr;
    }
    return _pr;
  };

  static constexpr uint32_t mod = mint::get_mod();
  static constexpr uint32_t pr = get_pr();
  static constexpr int level = __builtin_ctzll(mod - 1);
  mint dw[level], dy[level];

  void setwy(int k) {
    mint w[level], y[level];
    w[k - 1] = mint(pr).pow((mod - 1) / (1 << k));
    y[k - 1] = w[k - 1].inverse();
    for (int i = k - 2; i > 0; --i)
      w[i] = w[i + 1] * w[i + 1], y[i] = y[i + 1] * y[i + 1];
    dw[1] = w[1], dy[1] = y[1], dw[2] = w[2], dy[2] = y[2];
    for (int i = 3; i < k; ++i) {
      dw[i] = dw[i - 1] * y[i - 2] * w[i];
      dy[i] = dy[i - 1] * w[i - 2] * y[i];
    }
  }

  NTT() { setwy(level); }

  void fft4(vector<mint> &a, int k) {
    if ((int)a.size() <= 1) return;
    if (k == 1) {
      mint a1 = a[1];
      a[1] = a[0] - a[1];
      a[0] = a[0] + a1;
      return;
    }
    if (k & 1) {
      int v = 1 << (k - 1);
      for (int j = 0; j < v; ++j) {
        mint ajv = a[j + v];
        a[j + v] = a[j] - ajv;
        a[j] += ajv;
      }
    }
    int u = 1 << (2 + (k & 1));
    int v = 1 << (k - 2 - (k & 1));
    mint one = mint(1);
    mint imag = dw[1];
    while (v) {
      // jh = 0
      {
        int j0 = 0;
        int j1 = v;
        int j2 = j1 + v;
        int j3 = j2 + v;
        for (; j0 < v; ++j0, ++j1, ++j2, ++j3) {
          mint t0 = a[j0], t1 = a[j1], t2 = a[j2], t3 = a[j3];
          mint t0p2 = t0 + t2, t1p3 = t1 + t3;
          mint t0m2 = t0 - t2, t1m3 = (t1 - t3) * imag;
          a[j0] = t0p2 + t1p3, a[j1] = t0p2 - t1p3;
          a[j2] = t0m2 + t1m3, a[j3] = t0m2 - t1m3;
        }
      }
      // jh >= 1
      mint ww = one, xx = one * dw[2], wx = one;
      for (int jh = 4; jh < u;) {
        ww = xx * xx, wx = ww * xx;
        int j0 = jh * v;
        int je = j0 + v;
        int j2 = je + v;
        for (; j0 < je; ++j0, ++j2) {
          mint t0 = a[j0], t1 = a[j0 + v] * xx, t2 = a[j2] * ww,
               t3 = a[j2 + v] * wx;
          mint t0p2 = t0 + t2, t1p3 = t1 + t3;
          mint t0m2 = t0 - t2, t1m3 = (t1 - t3) * imag;
          a[j0] = t0p2 + t1p3, a[j0 + v] = t0p2 - t1p3;
          a[j2] = t0m2 + t1m3, a[j2 + v] = t0m2 - t1m3;
        }
        xx *= dw[__builtin_ctzll((jh += 4))];
      }
      u <<= 2;
      v >>= 2;
    }
  }

  void ifft4(vector<mint> &a, int k) {
    if ((int)a.size() <= 1) return;
    if (k == 1) {
      mint a1 = a[1];
      a[1] = a[0] - a[1];
      a[0] = a[0] + a1;
      return;
    }
    int u = 1 << (k - 2);
    int v = 1;
    mint one = mint(1);
    mint imag = dy[1];
    while (u) {
      // jh = 0
      {
        int j0 = 0;
        int j1 = v;
        int j2 = v + v;
        int j3 = j2 + v;
        for (; j0 < v; ++j0, ++j1, ++j2, ++j3) {
          mint t0 = a[j0], t1 = a[j1], t2 = a[j2], t3 = a[j3];
          mint t0p1 = t0 + t1, t2p3 = t2 + t3;
          mint t0m1 = t0 - t1, t2m3 = (t2 - t3) * imag;
          a[j0] = t0p1 + t2p3, a[j2] = t0p1 - t2p3;
          a[j1] = t0m1 + t2m3, a[j3] = t0m1 - t2m3;
        }
      }
      // jh >= 1
      mint ww = one, xx = one * dy[2], yy = one;
      u <<= 2;
      for (int jh = 4; jh < u;) {
        ww = xx * xx, yy = xx * imag;
        int j0 = jh * v;
        int je = j0 + v;
        int j2 = je + v;
        for (; j0 < je; ++j0, ++j2) {
          mint t0 = a[j0], t1 = a[j0 + v], t2 = a[j2], t3 = a[j2 + v];
          mint t0p1 = t0 + t1, t2p3 = t2 + t3;
          mint t0m1 = (t0 - t1) * xx, t2m3 = (t2 - t3) * yy;
          a[j0] = t0p1 + t2p3, a[j2] = (t0p1 - t2p3) * ww;
          a[j0 + v] = t0m1 + t2m3, a[j2 + v] = (t0m1 - t2m3) * ww;
        }
        xx *= dy[__builtin_ctzll(jh += 4)];
      }
      u >>= 4;
      v <<= 2;
    }
    if (k & 1) {
      u = 1 << (k - 1);
      for (int j = 0; j < u; ++j) {
        mint ajv = a[j] - a[j + u];
        a[j] += a[j + u];
        a[j + u] = ajv;
      }
    }
  }

  void ntt(vector<mint> &a) {
    if ((int)a.size() <= 1) return;
    fft4(a, __builtin_ctz(a.size()));
  }

  void intt(vector<mint> &a) {
    if ((int)a.size() <= 1) return;
    ifft4(a, __builtin_ctz(a.size()));
    mint iv = mint(a.size()).inverse();
    for (auto &x : a) x *= iv;
  }

  vector<mint> multiply(const vector<mint> &a, const vector<mint> &b) {
    int l = a.size() + b.size() - 1;
    if (min<int>(a.size(), b.size()) <= 40) {
      vector<mint> s(l);
      for (int i = 0; i < (int)a.size(); ++i)
        for (int j = 0; j < (int)b.size(); ++j) s[i + j] += a[i] * b[j];
      return s;
    }
    int k = 2, M = 4;
    while (M < l) M <<= 1, ++k;
    setwy(k);
    vector<mint> s(M);
    for (int i = 0; i < (int)a.size(); ++i) s[i] = a[i];
    fft4(s, k);
    if (a.size() == b.size() && a == b) {
      for (int i = 0; i < M; ++i) s[i] *= s[i];
    } else {
      vector<mint> t(M);
      for (int i = 0; i < (int)b.size(); ++i) t[i] = b[i];
      fft4(t, k);
      for (int i = 0; i < M; ++i) s[i] *= t[i];
    }
    ifft4(s, k);
    s.resize(l);
    mint invm = mint(M).inverse();
    for (int i = 0; i < l; ++i) s[i] *= invm;
    return s;
  }

  void ntt_doubling(vector<mint> &a) {
    int M = (int)a.size();
    auto b = a;
    intt(b);
    mint r = 1, zeta = mint(pr).pow((mint::get_mod() - 1) / (M << 1));
    for (int i = 0; i < M; i++) b[i] *= r, r *= zeta;
    ntt(b);
    copy(begin(b), end(b), back_inserter(a));
  }
};


template <typename mint>
struct FormalPowerSeries : vector<mint> {
  using vector<mint>::vector;
  using FPS = FormalPowerSeries;

  FPS &operator+=(const FPS &r) {
    if (r.size() > this->size()) this->resize(r.size());
    for (int i = 0; i < (int)r.size(); i++) (*this)[i] += r[i];
    return *this;
  }

  FPS &operator+=(const mint &r) {
    if (this->empty()) this->resize(1);
    (*this)[0] += r;
    return *this;
  }

  FPS &operator-=(const FPS &r) {
    if (r.size() > this->size()) this->resize(r.size());
    for (int i = 0; i < (int)r.size(); i++) (*this)[i] -= r[i];
    return *this;
  }

  FPS &operator-=(const mint &r) {
    if (this->empty()) this->resize(1);
    (*this)[0] -= r;
    return *this;
  }

  FPS &operator*=(const mint &v) {
    for (int k = 0; k < (int)this->size(); k++) (*this)[k] *= v;
    return *this;
  }

  FPS &operator/=(const FPS &r) {
    if (this->size() < r.size()) {
      this->clear();
      return *this;
    }
    int n = this->size() - r.size() + 1;
    if ((int)r.size() <= 64) {
      FPS f(*this), g(r);
      g.shrink();
      mint coeff = g.back().inverse();
      for (auto &x : g) x *= coeff;
      int deg = (int)f.size() - (int)g.size() + 1;
      int gs = g.size();
      FPS quo(deg);
      for (int i = deg - 1; i >= 0; i--) {
        quo[i] = f[i + gs - 1];
        for (int j = 0; j < gs; j++) f[i + j] -= quo[i] * g[j];
      }
      *this = quo * coeff;
      this->resize(n, mint(0));
      return *this;
    }
    return *this = ((*this).rev().pre(n) * r.rev().inv(n)).pre(n).rev();
  }

  FPS &operator%=(const FPS &r) {
    *this -= *this / r * r;
    shrink();
    return *this;
  }

  FPS operator+(const FPS &r) const { return FPS(*this) += r; }
  FPS operator+(const mint &v) const { return FPS(*this) += v; }
  FPS operator-(const FPS &r) const { return FPS(*this) -= r; }
  FPS operator-(const mint &v) const { return FPS(*this) -= v; }
  FPS operator*(const FPS &r) const { return FPS(*this) *= r; }
  FPS operator*(const mint &v) const { return FPS(*this) *= v; }
  FPS operator/(const FPS &r) const { return FPS(*this) /= r; }
  FPS operator%(const FPS &r) const { return FPS(*this) %= r; }
  FPS operator-() const {
    FPS ret(this->size());
    for (int i = 0; i < (int)this->size(); i++) ret[i] = -(*this)[i];
    return ret;
  }

  void shrink() {
    while (this->size() && this->back() == mint(0)) this->pop_back();
  }

  FPS rev() const {
    FPS ret(*this);
    reverse(begin(ret), end(ret));
    return ret;
  }

  FPS dot(FPS r) const {
    FPS ret(min(this->size(), r.size()));
    for (int i = 0; i < (int)ret.size(); i++) ret[i] = (*this)[i] * r[i];
    return ret;
  }

  // 前 sz 項を取ってくる。sz に足りない項は 0 埋めする
  FPS pre(int sz) const {
    FPS ret(begin(*this), begin(*this) + min((int)this->size(), sz));
    if ((int)ret.size() < sz) ret.resize(sz);
    return ret;
  }

  FPS operator>>(int sz) const {
    if ((int)this->size() <= sz) return {};
    FPS ret(*this);
    ret.erase(ret.begin(), ret.begin() + sz);
    return ret;
  }

  FPS operator<<(int sz) const {
    FPS ret(*this);
    ret.insert(ret.begin(), sz, mint(0));
    return ret;
  }

  FPS diff() const {
    const int n = (int)this->size();
    FPS ret(max(0, n - 1));
    mint one(1), coeff(1);
    for (int i = 1; i < n; i++) {
      ret[i - 1] = (*this)[i] * coeff;
      coeff += one;
    }
    return ret;
  }

  FPS integral() const {
    const int n = (int)this->size();
    FPS ret(n + 1);
    ret[0] = mint(0);
    if (n > 0) ret[1] = mint(1);
    auto mod = mint::get_mod();
    for (int i = 2; i <= n; i++) ret[i] = (-ret[mod % i]) * (mod / i);
    for (int i = 0; i < n; i++) ret[i + 1] *= (*this)[i];
    return ret;
  }

  mint eval(mint x) const {
    mint r = 0, w = 1;
    for (auto &v : *this) r += w * v, w *= x;
    return r;
  }

  FPS log(int deg = -1) const {
    assert(!(*this).empty() && (*this)[0] == mint(1));
    if (deg == -1) deg = (int)this->size();
    return (this->diff() * this->inv(deg)).pre(deg - 1).integral();
  }

  FPS pow(int64_t k, int deg = -1) const {
    const int n = (int)this->size();
    if (deg == -1) deg = n;
    if (k == 0) {
      FPS ret(deg);
      if (deg) ret[0] = 1;
      return ret;
    }
    for (int i = 0; i < n; i++) {
      if ((*this)[i] != mint(0)) {
        mint rev = mint(1) / (*this)[i];
        FPS ret = (((*this * rev) >> i).log(deg) * k).exp(deg);
        ret *= (*this)[i].pow(k);
        ret = (ret << (i * k)).pre(deg);
        if ((int)ret.size() < deg) ret.resize(deg, mint(0));
        return ret;
      }
      if (__int128_t(i + 1) * k >= deg) return FPS(deg, mint(0));
    }
    return FPS(deg, mint(0));
  }

  static void *ntt_ptr;
  static void set_fft();
  FPS &operator*=(const FPS &r);
  void ntt();
  void intt();
  void ntt_doubling();
  static int ntt_pr();
  FPS inv(int deg = -1) const;
  FPS exp(int deg = -1) const;
};
template <typename mint>
void *FormalPowerSeries<mint>::ntt_ptr = nullptr;

/**
 * @brief 多項式/形式的冪級数ライブラリ
 * @docs docs/fps/formal-power-series.md
 */


template <typename mint>
void FormalPowerSeries<mint>::set_fft() {
  if (!ntt_ptr) ntt_ptr = new NTT<mint>;
}

template <typename mint>
FormalPowerSeries<mint>& FormalPowerSeries<mint>::operator*=(
    const FormalPowerSeries<mint>& r) {
  if (this->empty() || r.empty()) {
    this->clear();
    return *this;
  }
  set_fft();
  auto ret = static_cast<NTT<mint>*>(ntt_ptr)->multiply(*this, r);
  return *this = FormalPowerSeries<mint>(ret.begin(), ret.end());
}

template <typename mint>
void FormalPowerSeries<mint>::ntt() {
  set_fft();
  static_cast<NTT<mint>*>(ntt_ptr)->ntt(*this);
}

template <typename mint>
void FormalPowerSeries<mint>::intt() {
  set_fft();
  static_cast<NTT<mint>*>(ntt_ptr)->intt(*this);
}

template <typename mint>
void FormalPowerSeries<mint>::ntt_doubling() {
  set_fft();
  static_cast<NTT<mint>*>(ntt_ptr)->ntt_doubling(*this);
}

template <typename mint>
int FormalPowerSeries<mint>::ntt_pr() {
  set_fft();
  return static_cast<NTT<mint>*>(ntt_ptr)->pr;
}

template <typename mint>
FormalPowerSeries<mint> FormalPowerSeries<mint>::inv(int deg) const {
  assert((*this)[0] != mint(0));
  if (deg == -1) deg = (int)this->size();
  FormalPowerSeries<mint> res(deg);
  res[0] = {mint(1) / (*this)[0]};
  for (int d = 1; d < deg; d <<= 1) {
    FormalPowerSeries<mint> f(2 * d), g(2 * d);
    for (int j = 0; j < min((int)this->size(), 2 * d); j++) f[j] = (*this)[j];
    for (int j = 0; j < d; j++) g[j] = res[j];
    f.ntt();
    g.ntt();
    for (int j = 0; j < 2 * d; j++) f[j] *= g[j];
    f.intt();
    for (int j = 0; j < d; j++) f[j] = 0;
    f.ntt();
    for (int j = 0; j < 2 * d; j++) f[j] *= g[j];
    f.intt();
    for (int j = d; j < min(2 * d, deg); j++) res[j] = -f[j];
  }
  return res.pre(deg);
}

template <typename mint>
FormalPowerSeries<mint> FormalPowerSeries<mint>::exp(int deg) const {
  using fps = FormalPowerSeries<mint>;
  assert((*this).size() == 0 || (*this)[0] == mint(0));
  if (deg == -1) deg = this->size();

  fps inv;
  inv.reserve(deg + 1);
  inv.push_back(mint(0));
  inv.push_back(mint(1));

  auto inplace_integral = [&](fps& F) -> void {
    const int n = (int)F.size();
    auto mod = mint::get_mod();
    while ((int)inv.size() <= n) {
      int i = inv.size();
      inv.push_back((-inv[mod % i]) * (mod / i));
    }
    F.insert(begin(F), mint(0));
    for (int i = 1; i <= n; i++) F[i] *= inv[i];
  };

  auto inplace_diff = [](fps& F) -> void {
    if (F.empty()) return;
    F.erase(begin(F));
    mint coeff = 1, one = 1;
    for (int i = 0; i < (int)F.size(); i++) {
      F[i] *= coeff;
      coeff += one;
    }
  };

  fps b{1, 1 < (int)this->size() ? (*this)[1] : 0}, c{1}, z1, z2{1, 1};
  for (int m = 2; m < deg; m *= 2) {
    auto y = b;
    y.resize(2 * m);
    y.ntt();
    z1 = z2;
    fps z(m);
    for (int i = 0; i < m; ++i) z[i] = y[i] * z1[i];
    z.intt();
    fill(begin(z), begin(z) + m / 2, mint(0));
    z.ntt();
    for (int i = 0; i < m; ++i) z[i] *= -z1[i];
    z.intt();
    c.insert(end(c), begin(z) + m / 2, end(z));
    z2 = c;
    z2.resize(2 * m);
    z2.ntt();
    fps x(begin(*this), begin(*this) + min<int>(this->size(), m));
    x.resize(m);
    inplace_diff(x);
    x.push_back(mint(0));
    x.ntt();
    for (int i = 0; i < m; ++i) x[i] *= y[i];
    x.intt();
    x -= b.diff();
    x.resize(2 * m);
    for (int i = 0; i < m - 1; ++i) x[m + i] = x[i], x[i] = mint(0);
    x.ntt();
    for (int i = 0; i < 2 * m; ++i) x[i] *= z2[i];
    x.intt();
    x.pop_back();
    inplace_integral(x);
    for (int i = m; i < min<int>(this->size(), 2 * m); ++i) x[i] += (*this)[i];
    fill(begin(x), begin(x) + m, mint(0));
    x.ntt();
    for (int i = 0; i < 2 * m; ++i) x[i] *= y[i];
    x.intt();
    b.insert(end(b), begin(x) + m, end(x));
  }
  return fps{begin(b), begin(b) + deg};
}

/**
 * @brief NTT mod用FPSライブラリ
 * @docs docs/fps/ntt-friendly-fps.md
 */




template <uint32_t mod>
struct LazyMontgomeryModInt {
  using mint = LazyMontgomeryModInt;
  using i32 = int32_t;
  using u32 = uint32_t;
  using u64 = uint64_t;

  static constexpr u32 get_r() {
    u32 ret = mod;
    for (i32 i = 0; i < 4; ++i) ret *= 2 - mod * ret;
    return ret;
  }

  static constexpr u32 r = get_r();
  static constexpr u32 n2 = -u64(mod) % mod;
  static_assert(mod < (1 << 30), "invalid, mod >= 2 ^ 30");
  static_assert((mod & 1) == 1, "invalid, mod % 2 == 0");
  static_assert(r * mod == 1, "this code has bugs.");

  u32 a;

  constexpr LazyMontgomeryModInt() : a(0) {}
  constexpr LazyMontgomeryModInt(const int64_t &b)
      : a(reduce(u64(b % mod + mod) * n2)){};

  static constexpr u32 reduce(const u64 &b) {
    return (b + u64(u32(b) * u32(-r)) * mod) >> 32;
  }

  constexpr mint &operator+=(const mint &b) {
    if (i32(a += b.a - 2 * mod) < 0) a += 2 * mod;
    return *this;
  }

  constexpr mint &operator-=(const mint &b) {
    if (i32(a -= b.a) < 0) a += 2 * mod;
    return *this;
  }

  constexpr mint &operator*=(const mint &b) {
    a = reduce(u64(a) * b.a);
    return *this;
  }

  constexpr mint &operator/=(const mint &b) {
    *this *= b.inverse();
    return *this;
  }

  constexpr mint operator+(const mint &b) const { return mint(*this) += b; }
  constexpr mint operator-(const mint &b) const { return mint(*this) -= b; }
  constexpr mint operator*(const mint &b) const { return mint(*this) *= b; }
  constexpr mint operator/(const mint &b) const { return mint(*this) /= b; }
  constexpr bool operator==(const mint &b) const {
    return (a >= mod ? a - mod : a) == (b.a >= mod ? b.a - mod : b.a);
  }
  constexpr bool operator!=(const mint &b) const {
    return (a >= mod ? a - mod : a) != (b.a >= mod ? b.a - mod : b.a);
  }
  constexpr mint operator-() const { return mint() - mint(*this); }
  constexpr mint operator+() const { return mint(*this); }

  constexpr mint pow(u64 n) const {
    mint ret(1), mul(*this);
    while (n > 0) {
      if (n & 1) ret *= mul;
      mul *= mul;
      n >>= 1;
    }
    return ret;
  }

  constexpr mint inverse() const {
    int x = get(), y = mod, u = 1, v = 0, t = 0, tmp = 0;
    while (y > 0) {
      t = x / y;
      x -= t * y, u -= t * v;
      tmp = x, x = y, y = tmp;
      tmp = u, u = v, v = tmp;
    }
    return mint{u};
  }

  friend ostream &operator<<(ostream &os, const mint &b) {
    return os << b.get();
  }

  friend istream &operator>>(istream &is, mint &b) {
    int64_t t;
    is >> t;
    b = LazyMontgomeryModInt<mod>(t);
    return (is);
  }

  constexpr u32 get() const {
    u32 ret = reduce(a);
    return ret >= mod ? ret - mod : ret;
  }

  static constexpr u32 get_mod() { return mod; }
};





using namespace std;

// コンストラクタの MAX に 「C(n, r) や fac(n) でクエリを投げる最大の n 」
// を入れると倍速くらいになる
// mod を超えて前計算して 0 割りを踏むバグは対策済み
template <typename T>
struct Binomial {
  vector<T> f, g, h;
  Binomial(int MAX = 0) {
    assert(T::get_mod() != 0 && "Binomial<mint>()");
    f.resize(1, T{1});
    g.resize(1, T{1});
    h.resize(1, T{1});
    if (MAX > 0) extend(MAX + 1);
  }

  void extend(int m = -1) {
    int n = f.size();
    if (m == -1) m = n * 2;
    m = min<int>(m, T::get_mod());
    if (n >= m) return;
    f.resize(m);
    g.resize(m);
    h.resize(m);
    for (int i = n; i < m; i++) f[i] = f[i - 1] * T(i);
    g[m - 1] = f[m - 1].inverse();
    h[m - 1] = g[m - 1] * f[m - 2];
    for (int i = m - 2; i >= n; i--) {
      g[i] = g[i + 1] * T(i + 1);
      h[i] = g[i] * f[i - 1];
    }
  }

  T fac(int i) {
    if (i < 0) return T(0);
    while (i >= (int)f.size()) extend();
    return f[i];
  }

  T finv(int i) {
    if (i < 0) return T(0);
    while (i >= (int)g.size()) extend();
    return g[i];
  }

  T inv(int i) {
    if (i < 0) return -inv(-i);
    while (i >= (int)h.size()) extend();
    return h[i];
  }

  T C(int n, int r) {
    if (n < 0 || n < r || r < 0) return T(0);
    return fac(n) * finv(n - r) * finv(r);
  }

  inline T operator()(int n, int r) { return C(n, r); }

  template <typename I>
  T multinomial(const vector<I>& r) {
    static_assert(is_integral<I>::value == true);
    int n = 0;
    for (auto& x : r) {
      if (x < 0) return T(0);
      n += x;
    }
    T res = fac(n);
    for (auto& x : r) res *= finv(x);
    return res;
  }

  template <typename I>
  T operator()(const vector<I>& r) {
    return multinomial(r);
  }

  T C_naive(int n, int r) {
    if (n < 0 || n < r || r < 0) return T(0);
    T ret = T(1);
    r = min(r, n - r);
    for (int i = 1; i <= r; ++i) ret *= inv(i) * (n--);
    return ret;
  }

  T P(int n, int r) {
    if (n < 0 || n < r || r < 0) return T(0);
    return fac(n) * finv(n - r);
  }

  // [x^r] 1 / (1-x)^n
  T H(int n, int r) {
    if (n < 0 || r < 0) return T(0);
    return r == 0 ? 1 : C(n + r - 1, r);
  }
};


// #include "fps/arbitrary-fps.hpp"
//
using namespace Nyaan;
using mint = LazyMontgomeryModInt<998244353>;
// using mint = LazyMontgomeryModInt<1000000007>;
using vm = vector<mint>;
using vvm = vector<vm>;
Binomial<mint> C;
using fps = FormalPowerSeries<mint>;
using namespace Nyaan;

void q() {
  ini(N, M);
  auto Cat = [&](int n) {
    assert(n >= 0);
    return C(2 * n, n) * C.inv(n + 1);
  };

  fps pre(2 * N + 1);

  {
    fps c(N + 1);
    rep1(i, N) { c[i] = Cat(i - 1) * M * mint{M - 1}.pow(i - 1); }
    fps f = (fps{1} - c).inv(N + 1);
    rep(i, N + 1) pre[i * 2] = f[i];
  }
  {
    int E = N / 2 * 2 + 10;
    fps d(E + 1);
    rep(i, E / 2 + 1) d[i * 2] = Cat(i) * mint{M - 1}.pow(i);
    d = d << 2;

    fps f1 = fps{1} - d * M;
    fps f2 = fps{1} - d * (M - 1);

    fps denom = (((f2 * f2).pre(E) - fps{0, 0, M - 1}) * f1).pre(E);
    fps numer = (f2 << 1) * M;
    fps g = numer * denom.inv();
    trc(g);
    for (int i = 1; i <= N; i += 2) pre[i] = g[i];
  }
  mint ans = 0;
  rep1(i, 2 * N) {
    int g = gcd(i, 2 * N);
    ans += pre[g];
  }
  out(ans / (2 * N));
}

void Nyaan::solve() {
  int t = 1;
  // in(t);
  while (t--) q();
}
accuracy: 1
time_ms: 3420
memory_kb: 314280
final_rank: 11

code_snippet: #define NDEBUG

using namespace std;


#include <immintrin.h>

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cfenv>
#include <cfloat>
#include <chrono>
#include <cinttypes>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdarg>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <fstream>
#include <functional>
#include <initializer_list>
#include <iomanip>
#include <ios>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <streambuf>
#include <string>
#include <tuple>
#include <type_traits>
#include <typeinfo>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>



namespace Nyaan {
using ll = long long;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;

template <typename T>
using V = vector<T>;
template <typename T>
using VV = vector<vector<T>>;
using vi = vector<int>;
using vl = vector<long long>;
using vd = V<double>;
using vs = V<string>;
using vvi = vector<vector<int>>;
using vvl = vector<vector<long long>>;
template <typename T>
using minpq = priority_queue<T, vector<T>, greater<T>>;

template <typename T, typename U>
struct P : pair<T, U> {
 template <typename... Args>
 P(Args... args) : pair<T, U>(args...) {}

 using pair<T, U>::first;
 using pair<T, U>::second;

 P &operator+=(const P &r) {
 first += r.first;
 second += r.second;
 return *this;
 }
 P &operator-=(const P &r) {
 first -= r.first;
 second -= r.second;
 return *this;
 }
 P &operator*=(const P &r) {
 first *= r.first;
 second *= r.second;
 return *this;
 }
 template <typename S>
 P &operator*=(const S &r) {
 first *= r, second *= r;
 return *this;
 }
 P operator+(const P &r) const { return P(*this) += r; }
 P operator-(const P &r) const { return P(*this) -= r; }
 P operator*(const P &r) const { return P(*this) *= r; }
 template <typename S>
 P operator*(const S &r) const {
 return P(*this) *= r;
 }
 P operator-() const { return P{-first, -second}; }
};

using pl = P<ll, ll>;
using pi = P<int, int>;
using vp = V<pl>;

constexpr int inf = 1001001001;
constexpr long long infLL = 4004004004004004004LL;

template <typename T>
int sz(const T &t) {
 return t.size();
}

template <typename T, typename U>
inline bool amin(T &x, U y) {
 return (y < x) ? (x = y, true) : false;
}
template <typename T, typename U>
inline bool amax(T &x, U y) {
 return (x < y) ? (x = y, true) : false;
}

template <typename T>
inline T Max(const vector<T> &v) {
 return *max_element(begin(v), end(v));
}
template <typename T>
inline T Min(const vector<T> &v) {
 return *min_element(begin(v), end(v));
}
template <typename T>
inline long long Sum(const vector<T> &v) {
 return accumulate(begin(v), end(v), 0LL);
}

template <typename T>
int lb(const vector<T> &v, const T &a) {
 return lower_bound(begin(v), end(v), a) - begin(v);
}
template <typename T>
int ub(const vector<T> &v, const T &a) {
 return upper_bound(begin(v), end(v), a) - begin(v);
}

constexpr long long TEN(int n) {
 long long ret = 1, x = 10;
 for (; n; x *= x, n >>= 1) ret *= (n & 1 ? x : 1);
 return ret;
}

template <typename T, typename U>
pair<T, U> mkp(const T &t, const U &u) {
 return make_pair(t, u);
}

template <typename T>
vector<T> mkrui(const vector<T> &v, bool rev = false) {
 vector<T> ret(v.size() + 1);
 if (rev) {
 for (int i = int(v.size()) - 1; i >= 0; i--) ret[i] = v[i] + ret[i + 1];
 } else {
 for (int i = 0; i < int(v.size()); i++) ret[i + 1] = ret[i] + v[i];
 }
 return ret;
};

template <typename T>
vector<T> mkuni(const vector<T> &v) {
 vector<T> ret(v);
 sort(ret.begin(), ret.end());
 ret.erase(unique(ret.begin(), ret.end()), ret.end());
 return ret;
}

template <typename F>
vector<int> mkord(int N, F f) {
 vector<int> ord(N);
 iota(begin(ord), end(ord), 0);
 sort(begin(ord), end(ord), f);
 return ord;
}

template <typename T>
vector<int> mkinv(vector<T> &v) {
 int max_val = *max_element(begin(v), end(v));
 vector<int> inv(max_val + 1, -1);
 for (int i = 0; i < (int)v.size(); i++) inv[v[i]] = i;
 return inv;
}

vector<int> mkiota(int n) {
 vector<int> ret(n);
 iota(begin(ret), end(ret), 0);
 return ret;
}

template <typename T>
T mkrev(const T &v) {
 T w{v};
 reverse(begin(w), end(w));
 return w;
}

template <typename T>
bool nxp(vector<T> &v) {
 return next_permutation(begin(v), end(v));
}



template <typename T>
vector<vector<T>> product(const vector<T> &a) {
 vector<vector<T>> ret;
 vector<T> v;
 auto dfs = [&](auto rc, int i) -> void {
 if (i == (int)a.size()) {
 ret.push_back(v);
 return;
 }
 for (int j = 0; j < a[i]; j++) v.push_back(j), rc(rc, i + 1), v.pop_back();
 };
 dfs(dfs, 0);
 return ret;
}



template <typename T>
T Power(T a, long long n, const T &I, const function<void(T &)> &f) {
 T res = I;
 for (; n; f(a = a * a), n >>= 1) {
 if (n & 1) f(res = res * a);
 }
 return res;
}

template <typename T>
T Power(T a, long long n, const T &I = T{1}) {
 return Power(a, n, I, function<void(T &)>{[](T &) -> void {}});
}

template <typename T>
T Rev(const T &v) {
 T res = v;
 reverse(begin(res), end(res));
 return res;
}

template <typename T>
vector<T> Transpose(const vector<T> &v) {
 using U = typename T::value_type;
 int H = v.size(), W = v[0].size();
 vector res(W, T(H, U{}));
 for (int i = 0; i < H; i++) {
 for (int j = 0; j < W; j++) {
 res[j][i] = v[i][j];
 }
 }
 return res;
}

template <typename T>
vector<T> Rotate(const vector<T> &v, int clockwise = true) {
 using U = typename T::value_type;
 int H = v.size(), W = v[0].size();
 vector res(W, T(H, U{}));
 for (int i = 0; i < H; i++) {
 for (int j = 0; j < W; j++) {
 if (clockwise) {
 res[W - 1 - j][i] = v[i][j];
 } else {
 res[j][H - 1 - i] = v[i][j];
 }
 }
 }
 return res;
}

} 




namespace Nyaan {
__attribute__((target("popcnt"))) inline int popcnt(const u64 &a) {
 return _mm_popcnt_u64(a);
}
inline int lsb(const u64 &a) { return a ? __builtin_ctzll(a) : 64; }
inline int ctz(const u64 &a) { return a ? __builtin_ctzll(a) : 64; }
inline int msb(const u64 &a) { return a ? 63 - __builtin_clzll(a) : -1; }
template <typename T>
inline int gbit(const T &a, int i) {
 return (a >> i) & 1;
}
template <typename T>
inline void sbit(T &a, int i, bool b) {
 if (gbit(a, i) != b) a ^= T(1) << i;
}
constexpr long long PW(int n) { return 1LL << n; }
constexpr long long MSK(int n) { return (1LL << n) - 1; }
} 




namespace Nyaan {

template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
 os << p.first << " " << p.second;
 return os;
}
template <typename T, typename U>
istream &operator>>(istream &is, pair<T, U> &p) {
 is >> p.first >> p.second;
 return is;
}

template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v) {
 int s = (int)v.size();
 for (int i = 0; i < s; i++) os << (i ? " " : "") << v[i];
 return os;
}
template <typename T>
istream &operator>>(istream &is, vector<T> &v) {
 for (auto &x : v) is >> x;
 return is;
}

istream &operator>>(istream &is, __int128_t &x) {
 string S;
 is >> S;
 x = 0;
 int flag = 0;
 for (auto &c : S) {
 if (c == '-') {
 flag = true;
 continue;
 }
 x *= 10;
 x += c - '0';
 }
 if (flag) x = -x;
 return is;
}

istream &operator>>(istream &is, __uint128_t &x) {
 string S;
 is >> S;
 x = 0;
 for (auto &c : S) {
 x *= 10;
 x += c - '0';
 }
 return is;
}

ostream &operator<<(ostream &os, __int128_t x) {
 if (x == 0) return os << 0;
 if (x < 0) os << '-', x = -x;
 string S;
 while (x) S.push_back('0' + x % 10), x /= 10;
 reverse(begin(S), end(S));
 return os << S;
}
ostream &operator<<(ostream &os, __uint128_t x) {
 if (x == 0) return os << 0;
 string S;
 while (x) S.push_back('0' + x % 10), x /= 10;
 reverse(begin(S), end(S));
 return os << S;
}

void in() {}
template <typename T, class... U>
void in(T &t, U &...u) {
 cin >> t;
 in(u...);
}

void out() { cout << "\n"; }
template <typename T, class... U, char sep = ' '>
void out(const T &t, const U &...u) {
 cout << t;
 if (sizeof...(u)) cout << sep;
 out(u...);
}

struct IoSetupNya {
 IoSetupNya() {
 cin.tie(nullptr);
 ios::sync_with_stdio(false);
 cout << fixed << setprecision(15);
 cerr << fixed << setprecision(7);
 }
} iosetupnya;

} 





#ifdef NyaanDebug
#define trc(...) (void(0))
#else
#define trc(...) (void(0))
#endif

#ifdef NyaanLocal
#define trc2(...) (void(0))
#else
#define trc2(...) (void(0))
#endif




#define each(x, v) for (auto&& x : v)
#define each2(x, y, v) for (auto&& [x, y] : v)
#define all(v) (v).begin(), (v).end()
#define rep(i, N) for (long long i = 0; i < (long long)(N); i++)
#define repr(i, N) for (long long i = (long long)(N)-1; i >= 0; i--)
#define rep1(i, N) for (long long i = 1; i <= (long long)(N); i++)
#define repr1(i, N) for (long long i = (N); (long long)(i) > 0; i--)
#define reg(i, a, b) for (long long i = (a); i < (b); i++)
#define regr(i, a, b) for (long long i = (b)-1; i >= (a); i--)
#define fi first
#define se second
#define ini(...) \
 int __VA_ARGS__; \
 in(__VA_ARGS__)
#define inl(...) \
 long long __VA_ARGS__; \
 in(__VA_ARGS__)
#define ins(...) \
 string __VA_ARGS__; \
 in(__VA_ARGS__)
#define in2(s, t) \
 for (int i = 0; i < (int)s.size(); i++) { \
 in(s[i], t[i]); \
 }
#define in3(s, t, u) \
 for (int i = 0; i < (int)s.size(); i++) { \
 in(s[i], t[i], u[i]); \
 }
#define in4(s, t, u, v) \
 for (int i = 0; i < (int)s.size(); i++) { \
 in(s[i], t[i], u[i], v[i]); \
 }
#define die(...) \
 do { \
 Nyaan::out(__VA_ARGS__); \
 return; \
 } while (0)


namespace Nyaan {
void solve();
}
int main() { Nyaan::solve(); }







template <typename mint>
struct NTT {
 static constexpr uint32_t get_pr() {
 uint32_t _mod = mint::get_mod();
 using u64 = uint64_t;
 u64 ds[32] = {};
 int idx = 0;
 u64 m = _mod - 1;
 for (u64 i = 2; i * i <= m; ++i) {
 if (m % i == 0) {
 ds[idx++] = i;
 while (m % i == 0) m /= i;
 }
 }
 if (m != 1) ds[idx++] = m;

 uint32_t _pr = 2;
 while (1) {
 int flg = 1;
 for (int i = 0; i < idx; ++i) {
 u64 a = _pr, b = (_mod - 1) / ds[i], r = 1;
 while (b) {
 if (b & 1) r = r * a % _mod;
 a = a * a % _mod;
 b >>= 1;
 }
 if (r == 1) {
 flg = 0;
 break;
 }
 }
 if (flg == 1) break;
 ++_pr;
 }
 return _pr;
 };

 static constexpr uint32_t mod = mint::get_mod();
 static constexpr uint32_t pr = get_pr();
 static constexpr int level = __builtin_ctzll(mod - 1);
 mint dw[level], dy[level];

 void setwy(int k) {
 mint w[level], y[level];
 w[k - 1] = mint(pr).pow((mod - 1) / (1 << k));
 y[k - 1] = w[k - 1].inverse();
 for (int i = k - 2; i > 0; --i)
 w[i] = w[i + 1] * w[i + 1], y[i] = y[i + 1] * y[i + 1];
 dw[1] = w[1], dy[1] = y[1], dw[2] = w[2], dy[2] = y[2];
 for (int i = 3; i < k; ++i) {
 dw[i] = dw[i - 1] * y[i - 2] * w[i];
 dy[i] = dy[i - 1] * w[i - 2] * y[i];
 }
 }

 NTT() { setwy(level); }

 void fft4(vector<mint> &a, int k) {
 if ((int)a.size() <= 1) return;
 if (k == 1) {
 mint a1 = a[1];
 a[1] = a[0] - a[1];
 a[0] = a[0] + a1;
 return;
 }
 if (k & 1) {
 int v = 1 << (k - 1);
 for (int j = 0; j < v; ++j) {
 mint ajv = a[j + v];
 a[j + v] = a[j] - ajv;
 a[j] += ajv;
 }
 }
 int u = 1 << (2 + (k & 1));
 int v = 1 << (k - 2 - (k & 1));
 mint one = mint(1);
 mint imag = dw[1];
 while (v) {
 
 {
 int j0 = 0;
 int j1 = v;
 int j2 = j1 + v;
 int j3 = j2 + v;
 for (; j0 < v; ++j0, ++j1, ++j2, ++j3) {
 mint t0 = a[j0], t1 = a[j1], t2 = a[j2], t3 = a[j3];
 mint t0p2 = t0 + t2, t1p3 = t1 + t3;
 mint t0m2 = t0 - t2, t1m3 = (t1 - t3) * imag;
 a[j0] = t0p2 + t1p3, a[j1] = t0p2 - t1p3;
 a[j2] = t0m2 + t1m3, a[j3] = t0m2 - t1m3;
 }
 }
 
 mint ww = one, xx = one * dw[2], wx = one;
 for (int jh = 4; jh < u;) {
 ww = xx * xx, wx = ww * xx;
 int j0 = jh * v;
 int je = j0 + v;
 int j2 = je + v;
 for (; j0 < je; ++j0, ++j2) {
 mint t0 = a[j0], t1 = a[j0 + v] * xx, t2 = a[j2] * ww,
 t3 = a[j2 + v] * wx;
 mint t0p2 = t0 + t2, t1p3 = t1 + t3;
 mint t0m2 = t0 - t2, t1m3 = (t1 - t3) * imag;
 a[j0] = t0p2 + t1p3, a[j0 + v] = t0p2 - t1p3;
 a[j2] = t0m2 + t1m3, a[j2 + v] = t0m2 - t1m3;
 }
 xx *= dw[__builtin_ctzll((jh += 4))];
 }
 u <<= 2;
 v >>= 2;
 }
 }

 void ifft4(vector<mint> &a, int k) {
 if ((int)a.size() <= 1) return;
 if (k == 1) {
 mint a1 = a[1];
 a[1] = a[0] - a[1];
 a[0] = a[0] + a1;
 return;
 }
 int u = 1 << (k - 2);
 int v = 1;
 mint one = mint(1);
 mint imag = dy[1];
 while (u) {
 
 {
 int j0 = 0;
 int j1 = v;
 int j2 = v + v;
 int j3 = j2 + v;
 for (; j0 < v; ++j0, ++j1, ++j2, ++j3) {
 mint t0 = a[j0], t1 = a[j1], t2 = a[j2], t3 = a[j3];
 mint t0p1 = t0 + t1, t2p3 = t2 + t3;
 mint t0m1 = t0 - t1, t2m3 = (t2 - t3) * imag;
 a[j0] = t0p1 + t2p3, a[j2] = t0p1 - t2p3;
 a[j1] = t0m1 + t2m3, a[j3] = t0m1 - t2m3;
 }
 }
 
 mint ww = one, xx = one * dy[2], yy = one;
 u <<= 2;
 for (int jh = 4; jh < u;) {
 ww = xx * xx, yy = xx * imag;
 int j0 = jh * v;
 int je = j0 + v;
 int j2 = je + v;
 for (; j0 < je; ++j0, ++j2) {
 mint t0 = a[j0], t1 = a[j0 + v], t2 = a[j2], t3 = a[j2 + v];
 mint t0p1 = t0 + t1, t2p3 = t2 + t3;
 mint t0m1 = (t0 - t1) * xx, t2m3 = (t2 - t3) * yy;
 a[j0] = t0p1 + t2p3, a[j2] = (t0p1 - t2p3) * ww;
 a[j0 + v] = t0m1 + t2m3, a[j2 + v] = (t0m1 - t2m3) * ww;
 }
 xx *= dy[__builtin_ctzll(jh += 4)];
 }
 u >>= 4;
 v <<= 2;
 }
 if (k & 1) {
 u = 1 << (k - 1);
 for (int j = 0; j < u; ++j) {
 mint ajv = a[j] - a[j + u];
 a[j] += a[j + u];
 a[j + u] = ajv;
 }
 }
 }

 void ntt(vector<mint> &a) {
 if ((int)a.size() <= 1) return;
 fft4(a, __builtin_ctz(a.size()));
 }

 void intt(vector<mint> &a) {
 if ((int)a.size() <= 1) return;
 ifft4(a, __builtin_ctz(a.size()));
 mint iv = mint(a.size()).inverse();
 for (auto &x : a) x *= iv;
 }

 vector<mint> multiply(const vector<mint> &a, const vector<mint> &b) {
 int l = a.size() + b.size() - 1;
 if (min<int>(a.size(), b.size()) <= 40) {
 vector<mint> s(l);
 for (int i = 0; i < (int)a.size(); ++i)
 for (int j = 0; j < (int)b.size(); ++j) s[i + j] += a[i] * b[j];
 return s;
 }
 int k = 2, M = 4;
 while (M < l) M <<= 1, ++k;
 setwy(k);
 vector<mint> s(M);
 for (int i = 0; i < (int)a.size(); ++i) s[i] = a[i];
 fft4(s, k);
 if (a.size() == b.size() && a == b) {
 for (int i = 0; i < M; ++i) s[i] *= s[i];
 } else {
 vector<mint> t(M);
 for (int i = 0; i < (int)b.size(); ++i) t[i] = b[i];
 fft4(t, k);
 for (int i = 0; i < M; ++i) s[i] *= t[i];
 }
 ifft4(s, k);
 s.resize(l);
 mint invm = mint(M).inverse();
 for (int i = 0; i < l; ++i) s[i] *= invm;
 return s;
 }

 void ntt_doubling(vector<mint> &a) {
 int M = (int)a.size();
 auto b = a;
 intt(b);
 mint r = 1, zeta = mint(pr).pow((mint::get_mod() - 1) / (M << 1));
 for (int i = 0; i < M; i++) b[i] *= r, r *= zeta;
 ntt(b);
 copy(begin(b), end(b), back_inserter(a));
 }
};


template <typename mint>
struct FormalPowerSeries : vector<mint> {
 using vector<mint>::vector;
 using FPS = FormalPowerSeries;

 FPS &operator+=(const FPS &r) {
 if (r.size() > this->size()) this->resize(r.size());
 for (int i = 0; i < (int)r.size(); i++) (*this)[i] += r[i];
 return *this;
 }

 FPS &operator+=(const mint &r) {
 if (this->empty()) this->resize(1);
 (*this)[0] += r;
 return *this;
 }

 FPS &operator-=(const FPS &r) {
 if (r.size() > this->size()) this->resize(r.size());
 for (int i = 0; i < (int)r.size(); i++) (*this)[i] -= r[i];
 return *this;
 }

 FPS &operator-=(const mint &r) {
 if (this->empty()) this->resize(1);
 (*this)[0] -= r;
 return *this;
 }

 FPS &operator*=(const mint &v) {
 for (int k = 0; k < (int)this->size(); k++) (*this)[k] *= v;
 return *this;
 }

 FPS &operator/=(const FPS &r) {
 if (this->size() < r.size()) {
 this->clear();
 return *this;
 }
 int n = this->size() - r.size() + 1;
 if ((int)r.size() <= 64) {
 FPS f(*this), g(r);
 g.shrink();
 mint coeff = g.back().inverse();
 for (auto &x : g) x *= coeff;
 int deg = (int)f.size() - (int)g.size() + 1;
 int gs = g.size();
 FPS quo(deg);
 for (int i = deg - 1; i >= 0; i--) {
 quo[i] = f[i + gs - 1];
 for (int j = 0; j < gs; j++) f[i + j] -= quo[i] * g[j];
 }
 *this = quo * coeff;
 this->resize(n, mint(0));
 return *this;
 }
 return *this = ((*this).rev().pre(n) * r.rev().inv(n)).pre(n).rev();
 }

 FPS &operator%=(const FPS &r) {
 *this -= *this / r * r;
 shrink();
 return *this;
 }

 FPS operator+(const FPS &r) const { return FPS(*this) += r; }
 FPS operator+(const mint &v) const { return FPS(*this) += v; }
 FPS operator-(const FPS &r) const { return FPS(*this) -= r; }
 FPS operator-(const mint &v) const { return FPS(*this) -= v; }
 FPS operator*(const FPS &r) const { return FPS(*this) *= r; }
 FPS operator*(const mint &v) const { return FPS(*this) *= v; }
 FPS operator/(const FPS &r) const { return FPS(*this) /= r; }
 FPS operator%(const FPS &r) const { return FPS(*this) %= r; }
 FPS operator-() const {
 FPS ret(this->size());
 for (int i = 0; i < (int)this->size(); i++) ret[i] = -(*this)[i];
 return ret;
 }

 void shrink() {
 while (this->size() && this->back() == mint(0)) this->pop_back();
 }

 FPS rev() const {
 FPS ret(*this);
 reverse(begin(ret), end(ret));
 return ret;
 }

 FPS dot(FPS r) const {
 FPS ret(min(this->size(), r.size()));
 for (int i = 0; i < (int)ret.size(); i++) ret[i] = (*this)[i] * r[i];
 return ret;
 }

 
 FPS pre(int sz) const {
 FPS ret(begin(*this), begin(*this) + min((int)this->size(), sz));
 if ((int)ret.size() < sz) ret.resize(sz);
 return ret;
 }

 FPS operator>>(int sz) const {
 if ((int)this->size() <= sz) return {};
 FPS ret(*this);
 ret.erase(ret.begin(), ret.begin() + sz);
 return ret;
 }

 FPS operator<<(int sz) const {
 FPS ret(*this);
 ret.insert(ret.begin(), sz, mint(0));
 return ret;
 }

 FPS diff() const {
 const int n = (int)this->size();
 FPS ret(max(0, n - 1));
 mint one(1), coeff(1);
 for (int i = 1; i < n; i++) {
 ret[i - 1] = (*this)[i] * coeff;
 coeff += one;
 }
 return ret;
 }

 FPS integral() const {
 const int n = (int)this->size();
 FPS ret(n + 1);
 ret[0] = mint(0);
 if (n > 0) ret[1] = mint(1);
 auto mod = mint::get_mod();
 for (int i = 2; i <= n; i++) ret[i] = (-ret[mod % i]) * (mod / i);
 for (int i = 0; i < n; i++) ret[i + 1] *= (*this)[i];
 return ret;
 }

 mint eval(mint x) const {
 mint r = 0, w = 1;
 for (auto &v : *this) r += w * v, w *= x;
 return r;
 }

 FPS log(int deg = -1) const {
 assert(!(*this).empty() && (*this)[0] == mint(1));
 if (deg == -1) deg = (int)this->size();
 return (this->diff() * this->inv(deg)).pre(deg - 1).integral();
 }

 FPS pow(int64_t k, int deg = -1) const {
 const int n = (int)this->size();
 if (deg == -1) deg = n;
 if (k == 0) {
 FPS ret(deg);
 if (deg) ret[0] = 1;
 return ret;
 }
 for (int i = 0; i < n; i++) {
 if ((*this)[i] != mint(0)) {
 mint rev = mint(1) / (*this)[i];
 FPS ret = (((*this * rev) >> i).log(deg) * k).exp(deg);
 ret *= (*this)[i].pow(k);
 ret = (ret << (i * k)).pre(deg);
 if ((int)ret.size() < deg) ret.resize(deg, mint(0));
 return ret;
 }
 if (__int128_t(i + 1) * k >= deg) return FPS(deg, mint(0));
 }
 return FPS(deg, mint(0));
 }

 static void *ntt_ptr;
 static void set_fft();
 FPS &operator*=(const FPS &r);
 void ntt();
 void intt();
 void ntt_doubling();
 static int ntt_pr();
 FPS inv(int deg = -1) const;
 FPS exp(int deg = -1) const;
};
template <typename mint>
void *FormalPowerSeries<mint>::ntt_ptr = nullptr;







template <typename mint>
void FormalPowerSeries<mint>::set_fft() {
 if (!ntt_ptr) ntt_ptr = new NTT<mint>;
}

template <typename mint>
FormalPowerSeries<mint>& FormalPowerSeries<mint>::operator*=(
 const FormalPowerSeries<mint>& r) {
 if (this->empty() || r.empty()) {
 this->clear();
 return *this;
 }
 set_fft();
 auto ret = static_cast<NTT<mint>*>(ntt_ptr)->multiply(*this, r);
 return *this = FormalPowerSeries<mint>(ret.begin(), ret.end());
}

template <typename mint>
void FormalPowerSeries<mint>::ntt() {
 set_fft();
 static_cast<NTT<mint>*>(ntt_ptr)->ntt(*this);
}

template <typename mint>
void FormalPowerSeries<mint>::intt() {
 set_fft();
 static_cast<NTT<mint>*>(ntt_ptr)->intt(*this);
}

template <typename mint>
void FormalPowerSeries<mint>::ntt_doubling() {
 set_fft();
 static_cast<NTT<mint>*>(ntt_ptr)->ntt_doubling(*this);
}

template <typename mint>
int FormalPowerSeries<mint>::ntt_pr() {
 set_fft();
 return static_cast<NTT<mint>*>(ntt_ptr)->pr;
}

template <typename mint>
FormalPowerSeries<mint> FormalPowerSeries<mint>::inv(int deg) const {
 assert((*this)[0] != mint(0));
 if (deg == -1) deg = (int)this->size();
 FormalPowerSeries<mint> res(deg);
 res[0] = {mint(1) / (*this)[0]};
 for (int d = 1; d < deg; d <<= 1) {
 FormalPowerSeries<mint> f(2 * d), g(2 * d);
 for (int j = 0; j < min((int)this->size(), 2 * d); j++) f[j] = (*this)[j];
 for (int j = 0; j < d; j++) g[j] = res[j];
 f.ntt();
 g.ntt();
 for (int j = 0; j < 2 * d; j++) f[j] *= g[j];
 f.intt();
 for (int j = 0; j < d; j++) f[j] = 0;
 f.ntt();
 for (int j = 0; j < 2 * d; j++) f[j] *= g[j];
 f.intt();
 for (int j = d; j < min(2 * d, deg); j++) res[j] = -f[j];
 }
 return res.pre(deg);
}

template <typename mint>
FormalPowerSeries<mint> FormalPowerSeries<mint>::exp(int deg) const {
 using fps = FormalPowerSeries<mint>;
 assert((*this).size() == 0 || (*this)[0] == mint(0));
 if (deg == -1) deg = this->size();

 fps inv;
 inv.reserve(deg + 1);
 inv.push_back(mint(0));
 inv.push_back(mint(1));

 auto inplace_integral = [&](fps& F) -> void {
 const int n = (int)F.size();
 auto mod = mint::get_mod();
 while ((int)inv.size() <= n) {
 int i = inv.size();
 inv.push_back((-inv[mod % i]) * (mod / i));
 }
 F.insert(begin(F), mint(0));
 for (int i = 1; i <= n; i++) F[i] *= inv[i];
 };

 auto inplace_diff = [](fps& F) -> void {
 if (F.empty()) return;
 F.erase(begin(F));
 mint coeff = 1, one = 1;
 for (int i = 0; i < (int)F.size(); i++) {
 F[i] *= coeff;
 coeff += one;
 }
 };

 fps b{1, 1 < (int)this->size() ? (*this)[1] : 0}, c{1}, z1, z2{1, 1};
 for (int m = 2; m < deg; m *= 2) {
 auto y = b;
 y.resize(2 * m);
 y.ntt();
 z1 = z2;
 fps z(m);
 for (int i = 0; i < m; ++i) z[i] = y[i] * z1[i];
 z.intt();
 fill(begin(z), begin(z) + m / 2, mint(0));
 z.ntt();
 for (int i = 0; i < m; ++i) z[i] *= -z1[i];
 z.intt();
 c.insert(end(c), begin(z) + m / 2, end(z));
 z2 = c;
 z2.resize(2 * m);
 z2.ntt();
 fps x(begin(*this), begin(*this) + min<int>(this->size(), m));
 x.resize(m);
 inplace_diff(x);
 x.push_back(mint(0));
 x.ntt();
 for (int i = 0; i < m; ++i) x[i] *= y[i];
 x.intt();
 x -= b.diff();
 x.resize(2 * m);
 for (int i = 0; i < m - 1; ++i) x[m + i] = x[i], x[i] = mint(0);
 x.ntt();
 for (int i = 0; i < 2 * m; ++i) x[i] *= z2[i];
 x.intt();
 x.pop_back();
 inplace_integral(x);
 for (int i = m; i < min<int>(this->size(), 2 * m); ++i) x[i] += (*this)[i];
 fill(begin(x), begin(x) + m, mint(0));
 x.ntt();
 for (int i = 0; i < 2 * m; ++i) x[i] *= y[i];
 x.intt();
 b.insert(end(b), begin(x) + m, end(x));
 }
 return fps{begin(b), begin(b) + deg};
}









template <uint32_t mod>
struct LazyMontgomeryModInt {
 using mint = LazyMontgomeryModInt;
 using i32 = int32_t;
 using u32 = uint32_t;
 using u64 = uint64_t;

 static constexpr u32 get_r() {
 u32 ret = mod;
 for (i32 i = 0; i < 4; ++i) ret *= 2 - mod * ret;
 return ret;
 }

 static constexpr u32 r = get_r();
 static constexpr u32 n2 = -u64(mod) % mod;
 static_assert(mod < (1 << 30), "invalid, mod >= 2 ^ 30");
 static_assert((mod & 1) == 1, "invalid, mod % 2 == 0");
 static_assert(r * mod == 1, "this code has bugs.");

 u32 a;

 constexpr LazyMontgomeryModInt() : a(0) {}
 constexpr LazyMontgomeryModInt(const int64_t &b)
 : a(reduce(u64(b % mod + mod) * n2)){};

 static constexpr u32 reduce(const u64 &b) {
 return (b + u64(u32(b) * u32(-r)) * mod) >> 32;
 }

 constexpr mint &operator+=(const mint &b) {
 if (i32(a += b.a - 2 * mod) < 0) a += 2 * mod;
 return *this;
 }

 constexpr mint &operator-=(const mint &b) {
 if (i32(a -= b.a) < 0) a += 2 * mod;
 return *this;
 }

 constexpr mint &operator*=(const mint &b) {
 a = reduce(u64(a) * b.a);
 return *this;
 }

 constexpr mint &operator/=(const mint &b) {
 *this *= b.inverse();
 return *this;
 }

 constexpr mint operator+(const mint &b) const { return mint(*this) += b; }
 constexpr mint operator-(const mint &b) const { return mint(*this) -= b; }
 constexpr mint operator*(const mint &b) const { return mint(*this) *= b; }
 constexpr mint operator/(const mint &b) const { return mint(*this) /= b; }
 constexpr bool operator==(const mint &b) const {
 return (a >= mod ? a - mod : a) == (b.a >= mod ? b.a - mod : b.a);
 }
 constexpr bool operator!=(const mint &b) const {
 return (a >= mod ? a - mod : a) != (b.a >= mod ? b.a - mod : b.a);
 }
 constexpr mint operator-() const { return mint() - mint(*this); }
 constexpr mint operator+() const { return mint(*this); }

 constexpr mint pow(u64 n) const {
 mint ret(1), mul(*this);
 while (n > 0) {
 if (n & 1) ret *= mul;
 mul *= mul;
 n >>= 1;
 }
 return ret;
 }

 constexpr mint inverse() const {
 int x = get(), y = mod, u = 1, v = 0, t = 0, tmp = 0;
 while (y > 0) {
 t = x / y;
 x -= t * y, u -= t * v;
 tmp = x, x = y, y = tmp;
 tmp = u, u = v, v = tmp;
 }
 return mint{u};
 }

 friend ostream &operator<<(ostream &os, const mint &b) {
 return os << b.get();
 }

 friend istream &operator>>(istream &is, mint &b) {
 int64_t t;
 is >> t;
 b = LazyMontgomeryModInt<mod>(t);
 return (is);
 }

 constexpr u32 get() const {
 u32 ret = reduce(a);
 return ret >= mod ? ret - mod : ret;
 }

 static constexpr u32 get_mod() { return mod; }
};





using namespace std;




template <typename T>
struct Binomial {
 vector<T> f, g, h;
 Binomial(int MAX = 0) {
 assert(T::get_mod() != 0 && "Binomial<mint>()");
 f.resize(1, T{1});
 g.resize(1, T{1});
 h.resize(1, T{1});
 if (MAX > 0) extend(MAX + 1);
 }

 void extend(int m = -1) {
 int n = f.size();
 if (m == -1) m = n * 2;
 m = min<int>(m, T::get_mod());
 if (n >= m) return;
 f.resize(m);
 g.resize(m);
 h.resize(m);
 for (int i = n; i < m; i++) f[i] = f[i - 1] * T(i);
 g[m - 1] = f[m - 1].inverse();
 h[m - 1] = g[m - 1] * f[m - 2];
 for (int i = m - 2; i >= n; i--) {
 g[i] = g[i + 1] * T(i + 1);
 h[i] = g[i] * f[i - 1];
 }
 }

 T fac(int i) {
 if (i < 0) return T(0);
 while (i >= (int)f.size()) extend();
 return f[i];
 }

 T finv(int i) {
 if (i < 0) return T(0);
 while (i >= (int)g.size()) extend();
 return g[i];
 }

 T inv(int i) {
 if (i < 0) return -inv(-i);
 while (i >= (int)h.size()) extend();
 return h[i];
 }

 T C(int n, int r) {
 if (n < 0 || n < r || r < 0) return T(0);
 return fac(n) * finv(n - r) * finv(r);
 }

 inline T operator()(int n, int r) { return C(n, r); }

 template <typename I>
 T multinomial(const vector<I>& r) {
 static_assert(is_integral<I>::value == true);
 int n = 0;
 for (auto& x : r) {
 if (x < 0) return T(0);
 n += x;
 }
 T res = fac(n);
 for (auto& x : r) res *= finv(x);
 return res;
 }

 template <typename I>
 T operator()(const vector<I>& r) {
 return multinomial(r);
 }

 T C_naive(int n, int r) {
 if (n < 0 || n < r || r < 0) return T(0);
 T ret = T(1);
 r = min(r, n - r);
 for (int i = 1; i <= r; ++i) ret *= inv(i) * (n--);
 return ret;
 }

 T P(int n, int r) {
 if (n < 0 || n < r || r < 0) return T(0);
 return fac(n) * finv(n - r);
 }

 
 T H(int n, int r) {
 if (n < 0 || r < 0) return T(0);
 return r == 0 ? 1 : C(n + r - 1, r);
 }
};




using namespace Nyaan;
using mint = LazyMontgomeryModInt<998244353>;

using vm = vector<mint>;
using vvm = vector<vm>;
Binomial<mint> C;
using fps = FormalPowerSeries<mint>;
using namespace Nyaan;

int naive(int n, int M) {
 int res = 0;
 each(v, product(vi(n, M))) {
 vi w;
 each(x, v) {
 w.push_back(x);
 if (sz(w) >= 2 and w[sz(w) - 2] == w[sz(w) - 1])
 w.pop_back(), w.pop_back();
 }
 if (n % 2 == 0) {
 res += !!w.empty();
 } else {
 vi x = w;
 reverse(all(x));
 res += w == x;
 }
 }
 return res;
}

void q() {
 ini(N, M);
 auto Cat = [&](int n) {
 assert(n >= 0);
 return C(2 * n, n) * C.inv(n + 1);
 };

 fps pre(2 * N + 1);

 {
 fps c(N + 1);
 rep1(i, N) { c[i] = Cat(i - 1) * M * mint{M - 1}.pow(i - 1); }
 fps f = (fps{1} - c).inv(N + 1);
 rep(i, N + 1) pre[i * 2] = f[i];
 }
 {
 int E = N / 2 * 2 + 10;
 fps d(E + 1);
 rep(i, E / 2 + 1) d[i * 2] = Cat(i) * mint{M - 1}.pow(i);
 d = d << 2;

 fps f1 = fps{1} - d * M;
 fps f2 = fps{1} - d * (M - 1);

 fps denom = (((f2 * f2).pre(E) - fps{0, 0, M - 1}) * f1).pre(E);
 fps numer = (f2 << 1) * M;
 fps g = numer * denom.inv();
 trc(g);
 for (int i = 1; i <= N; i += 2) pre[i] = g[i];
 }
 trc(pre);

 








 mint ans = 0;
 rep1(i, 2 * N) {
 int g = gcd(i, 2 * N);
 ans += pre[g];
 }
 out(ans / (2 * N));
}

void Nyaan::solve() {
 int t = 1;
 
 while (t--) q();
}
accuracy: 1
time_ms: 3410
memory_kb: 313848
final_rank: 10

code_snippet: // -fsanitize=undefined,
//#define _GLIBCXX_DEBUG


#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <random>
#include <stdio.h>
#include <fstream>
#include <functional>
#include <cassert>
#include <unordered_map>
#include <bitset>
//#include <atcoder/all>
//#include <atcoder/modint>

using namespace std;
//using namespace atcoder;


#define rep(i,n) for (int i=0;i<n;i+=1)
#define rrep(i,n) for (int i=n-1;i>-1;i--)
#define pb push_back
#define all(x) (x).begin(), (x).end()

template<class T>
using vec = vector<T>;
template<class T>
using vvec = vec<vec<T>>;
template<class T>
using vvvec = vec<vvec<T>>;
using ll = long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;


template<class T>
bool chmin(T &a, T b){
  if (a>b){
    a = b;
    return true;
  }
  return false;
}

template<class T>
bool chmax(T &a, T b){
  if (a<b){
    a = b;
    return true;
  }
  return false;
}

template<class T>
T sum(vec<T> x){
  T res=0;
  for (auto e:x){
    res += e;
  }
  return res;
}

template<class T>
void printv(vec<T> x){
  for (auto e:x){
    cout<<e<<" ";
  }
  cout<<endl;
}

template<class T>
ostream& operator<<(ostream& os, const vec<T>& A){
  os << "[";
  rep(i,A.size()){
    os << A[i];
    if (i!=A.size()-1){
      os << ", ";
    }
  }
  os << "]" ;
  return os;
}

template<class T,class U>
ostream& operator<<(ostream& os, const pair<T,U>& A){
  os << "(" << A.first <<", " << A.second << ")";
  return os;
}

template<class T>
ostream& operator<<(ostream& os, const set<T>& S){
  os << "set{";
  for (auto a:S){
    os << a;
    auto it = S.find(a);
    it++;
    if (it!=S.end()){
      os << ", ";
    }
  }
  os << "}";
  return os;
}

const long long mod = 998244353;
const long long root = 3;

struct mint {
    long long x;

    mint(long long xx = 0) : x((xx % mod + mod) % mod) {}

    mint& operator+=(mint r) {
        x += r.x;
        if (x >= mod) x -= mod;
        return *this;
    }
    mint& operator-=(mint r) {
        if (x < r.x) x += mod;
        x -= r.x;
        return *this;
    }
    mint& operator*=(mint r) {
        x *= r.x;
        x %= mod;
        return *this;
    }
    mint& operator/=(mint r) {
        x *= r.inv().x;
        x %= mod;
        return *this;
    }

    mint pow(long long n) {
        assert(0 <= n);
        mint a = *this, r = 1;
        while (n) {
            if (n & 1) r *= a;
            a *= a;
            n >>= 1;
        }
        return r;
    }

    mint inv() { return pow(mod - 2); }

    friend mint operator+(mint l, mint r) { return mint(l) += r; }
    friend mint operator-(mint l, mint r) { return mint(l) -= r; }
    friend mint operator*(mint l, mint r) { return mint(l) *= r; }
    friend mint operator/(mint l, mint r) { return mint(l) /= r; }
};



void ntt(vector<mint>& a) {
    int n = (int)a.size();
    int l = 31 - __builtin_clz(n);
    static vector<mint> rt(2, 1);
    for (static int k = 2, s = 2; k < n; k *= 2, s++) {
        rt.resize(n);
        mint z[] = {1, mint(root).pow(mod >> s)};
        for (int i = k; i < 2 * k; i++) {
            rt[i] = rt[i / 2] * z[i & 1];
        }
    }
    vector<int> rev(n);
    for (int i = 0; i < n; i++) {
        rev[i] = (rev[i / 2] | (i & 1) << l) / 2;
    }
    for (int i = 0; i < n; i++) {
        if (i < rev[i]) {
            swap(a[i], a[rev[i]]);
        }
    }
    for (int k = 1; k < n; k *= 2) {
        for (int i = 0; i < n; i += 2 * k) {
            for (int j = 0; j < k; j++) {
                mint z = rt[j + k] * a[i + j + k];
                a[i + j + k] = a[i + j] - z;
                a[i + j] += z;
            }
        }
    }
}

vector<mint> multiply(vector<mint> a, vector<mint> b) {
    if (a.empty() || b.empty()) {
        return {};
    }
    int s = (int)(a.size() + b.size() - 1);
    int l = 32 - __builtin_clz(s);
    int n = 1 << l;
    mint inv = mint(n).inv();
    a.resize(n);
    b.resize(n);
    ntt(a);
    ntt(b);
    vector<mint> res(n);
    for (int i = 0; i < n; i++) {
        res[-i & (n - 1)] = a[i] * b[i] * inv;
    }
    ntt(res);
    res.resize(s);
    return res;
}

ostream& operator<<(ostream& os, const mint& a){
  os << a.x;
  return os;
}

const int M = 6000000+100;
mint g1[M],g2[M],inverse[M];

void init_mint(){
  g1[0] = 1, g1[1] = 1;
  g2[0] = 1, g2[1] = 1;
  inverse[0] = 0, inverse[1] = 1;
  for (int n=2;n<M;n++){
    g1[n] = g1[n-1] * n;
    inverse[n] = (inverse[998244353%n]) * (998244353/n) * (-1);
    g2[n] = g2[n-1] * inverse[n];
  }
}

mint comb(int n,int r){
  if (r < 0 || n < r) return 0;
  return g1[n] * g2[r] * g2[n-r];
}


#define debug(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << " )\n";

int main(){
  ios::sync_with_stdio(false);
  std::cin.tie(nullptr);

  init_mint();

  int n,k;
  cin>>n>>k;

  if (k==1){
    cout << 1 << endl;
    return 0;
  }

  vector<mint> g(n+1,0);
  for (int i=0;i<=n;i++) g[i] = comb(2*i,i) * inverse[i+1] * mint(k-1).pow(i);

  //debug(g);
  mint C = mint(k) * inverse[2] * inverse[k-1];

  vector<mint> G(n+1,0);
  for (int i=1;i<=n;i++) G[i] = 2 * C * (k-1) * g[i-1];
  G[0] = 1 - 2 * C;

  {
    mint zero = mint(1) - mint(2) * C, two = mint(4*(k-1)) * C * C;
    mint inv_zero = zero.inv();
    for (int i = 0; i <= n; i+=1) G[i] = (G[i] - two * (i-1 >= 0 ? G[i-1] : 0)) * inv_zero;
  }

  //debug(G);

  vector<mint> H(n+1,0);
  for (int i=1;i<=n;i++) H[i] = mint(2*(k-1)) * g[i-1];
  H[1] += mint(4) * mint(k-1);
  H[0] -= mint(2);
  vector<mint> res;
  vector<mint> I(n+1);
  {
    mint two = mint(8)*mint(k-1)*mint(-1);
    for (int i=0;i<=n;i++){
      I[i] = (H[i] * (-1) - two * (i-1 >= 0 ? I[i-1] : 0)) * inverse[2];
    }
    //debug(I);
    //assert (G.size()+g.size() <= (1<<23));
    auto a = multiply(G,g);
    while (int(a.size()) > n+1) a.pop_back();
    //assert (a.size()+I.size() <= (1<<23));
    res = multiply(a,I);
  }

  assert (int(res.size()) >= n+1);

  //debug(res);

  mint ans = 0;
  for (int i=1;i<=2*n;i++){
    int GCD = gcd(i,2*n);
    if (~GCD & 1) ans += G[GCD>>1];
    else ans += res[(GCD-1)>>1] * mint(k);
  }
  ans *= inverse[2*n];
  cout << ans.x << endl;



  
}
accuracy: 1
time_ms: 3750
memory_kb: 598012
final_rank: 12

code_snippet: // -fsanitize=undefined,
#define _GLIBCXX_DEBUG


#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <random>
#include <stdio.h>
#include <fstream>
#include <functional>
#include <cassert>
#include <unordered_map>
#include <bitset>
//#include <atcoder/all>


#include <utility>

namespace atcoder {

namespace internal {

// @param m `1 <= m`
// @return x mod m
constexpr long long safe_mod(long long x, long long m) {
    x %= m;
    if (x < 0) x += m;
    return x;
}

// Fast modular multiplication by barrett reduction
// Reference: https://en.wikipedia.org/wiki/Barrett_reduction
// NOTE: reconsider after Ice Lake
struct barrett {
    unsigned int _m;
    unsigned long long im;

    // @param m `1 <= m < 2^31`
    barrett(unsigned int m) : _m(m), im((unsigned long long)(-1) / m + 1) {}

    // @return m
    unsigned int umod() const { return _m; }

    // @param a `0 <= a < m`
    // @param b `0 <= b < m`
    // @return `a * b % m`
    unsigned int mul(unsigned int a, unsigned int b) const {
        // [1] m = 1
        // a = b = im = 0, so okay

        // [2] m >= 2
        // im = ceil(2^64 / m)
        // -> im * m = 2^64 + r (0 <= r < m)
        // let z = a*b = c*m + d (0 <= c, d < m)
        // a*b * im = (c*m + d) * im = c*(im*m) + d*im = c*2^64 + c*r + d*im
        // c*r + d*im < m * m + m * im < m * m + 2^64 + m <= 2^64 + m * (m + 1) < 2^64 * 2
        // ((ab * im) >> 64) == c or c + 1
        unsigned long long z = a;
        z *= b;
#ifdef _MSC_VER
        unsigned long long x;
        _umul128(z, im, &x);
#else
        unsigned long long x =
            (unsigned long long)(((unsigned __int128)(z)*im) >> 64);
#endif
        unsigned int v = (unsigned int)(z - x * _m);
        if (_m <= v) v += _m;
        return v;
    }
};

// @param n `0 <= n`
// @param m `1 <= m`
// @return `(x ** n) % m`
constexpr long long pow_mod_constexpr(long long x, long long n, int m) {
    if (m == 1) return 0;
    unsigned int _m = (unsigned int)(m);
    unsigned long long r = 1;
    unsigned long long y = safe_mod(x, m);
    while (n) {
        if (n & 1) r = (r * y) % _m;
        y = (y * y) % _m;
        n >>= 1;
    }
    return r;
}

// Reference:
// M. Forisek and J. Jancina,
// Fast Primality Testing for Integers That Fit into a Machine Word
// @param n `0 <= n`
constexpr bool is_prime_constexpr(int n) {
    if (n <= 1) return false;
    if (n == 2 || n == 7 || n == 61) return true;
    if (n % 2 == 0) return false;
    long long d = n - 1;
    while (d % 2 == 0) d /= 2;
    constexpr long long bases[3] = {2, 7, 61};
    for (long long a : bases) {
        long long t = d;
        long long y = pow_mod_constexpr(a, t, n);
        while (t != n - 1 && y != 1 && y != n - 1) {
            y = y * y % n;
            t <<= 1;
        }
        if (y != n - 1 && t % 2 == 0) {
            return false;
        }
    }
    return true;
}
template <int n> constexpr bool is_prime = is_prime_constexpr(n);

// @param b `1 <= b`
// @return pair(g, x) s.t. g = gcd(a, b), xa = g (mod b), 0 <= x < b/g
constexpr std::pair<long long, long long> inv_gcd(long long a, long long b) {
    a = safe_mod(a, b);
    if (a == 0) return {b, 0};

    // Contracts:
    // [1] s - m0 * a = 0 (mod b)
    // [2] t - m1 * a = 0 (mod b)
    // [3] s * |m1| + t * |m0| <= b
    long long s = b, t = a;
    long long m0 = 0, m1 = 1;

    while (t) {
        long long u = s / t;
        s -= t * u;
        m0 -= m1 * u;  // |m1 * u| <= |m1| * s <= b

        // [3]:
        // (s - t * u) * |m1| + t * |m0 - m1 * u|
        // <= s * |m1| - t * u * |m1| + t * (|m0| + |m1| * u)
        // = s * |m1| + t * |m0| <= b

        auto tmp = s;
        s = t;
        t = tmp;
        tmp = m0;
        m0 = m1;
        m1 = tmp;
    }
    // by [3]: |m0| <= b/g
    // by g != b: |m0| < b/g
    if (m0 < 0) m0 += b / s;
    return {s, m0};
}

// Compile time primitive root
// @param m must be prime
// @return primitive root (and minimum in now)
constexpr int primitive_root_constexpr(int m) {
    if (m == 2) return 1;
    if (m == 167772161) return 3;
    if (m == 469762049) return 3;
    if (m == 754974721) return 11;
    if (m == 998244353) return 3;
    int divs[20] = {};
    divs[0] = 2;
    int cnt = 1;
    int x = (m - 1) / 2;
    while (x % 2 == 0) x /= 2;
    for (int i = 3; (long long)(i)*i <= x; i += 2) {
        if (x % i == 0) {
            divs[cnt++] = i;
            while (x % i == 0) {
                x /= i;
            }
        }
    }
    if (x > 1) {
        divs[cnt++] = x;
    }
    for (int g = 2;; g++) {
        bool ok = true;
        for (int i = 0; i < cnt; i++) {
            if (pow_mod_constexpr(g, (m - 1) / divs[i], m) == 1) {
                ok = false;
                break;
            }
        }
        if (ok) return g;
    }
}
template <int m> constexpr int primitive_root = primitive_root_constexpr(m);

}  // namespace internal

}  // namespace atcoder


#include <cassert>
#include <numeric>
#include <type_traits>

namespace atcoder {

namespace internal {

#ifndef _MSC_VER
template <class T>
using is_signed_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value ||
                                  std::is_same<T, __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int128 =
    typename std::conditional<std::is_same<T, __uint128_t>::value ||
                                  std::is_same<T, unsigned __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using make_unsigned_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value,
                              __uint128_t,
                              unsigned __int128>;

template <class T>
using is_integral = typename std::conditional<std::is_integral<T>::value ||
                                                  is_signed_int128<T>::value ||
                                                  is_unsigned_int128<T>::value,
                                              std::true_type,
                                              std::false_type>::type;

template <class T>
using is_signed_int = typename std::conditional<(is_integral<T>::value &&
                                                 std::is_signed<T>::value) ||
                                                    is_signed_int128<T>::value,
                                                std::true_type,
                                                std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<(is_integral<T>::value &&
                               std::is_unsigned<T>::value) ||
                                  is_unsigned_int128<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<
    is_signed_int128<T>::value,
    make_unsigned_int128<T>,
    typename std::conditional<std::is_signed<T>::value,
                              std::make_unsigned<T>,
                              std::common_type<T>>::type>::type;

#else

template <class T> using is_integral = typename std::is_integral<T>;

template <class T>
using is_signed_int =
    typename std::conditional<is_integral<T>::value && std::is_signed<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<is_integral<T>::value &&
                                  std::is_unsigned<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<is_signed_int<T>::value,
                                              std::make_unsigned<T>,
                                              std::common_type<T>>::type;

#endif

template <class T>
using is_signed_int_t = std::enable_if_t<is_signed_int<T>::value>;

template <class T>
using is_unsigned_int_t = std::enable_if_t<is_unsigned_int<T>::value>;

template <class T> using to_unsigned_t = typename to_unsigned<T>::type;

}  // namespace internal

}  // namespace atcoder

#include <cassert>
#include <numeric>
#include <type_traits>

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

struct modint_base {};
struct static_modint_base : modint_base {};

template <class T> using is_modint = std::is_base_of<modint_base, T>;
template <class T> using is_modint_t = std::enable_if_t<is_modint<T>::value>;

}  // namespace internal

template <int m, std::enable_if_t<(1 <= m)>* = nullptr>
struct static_modint : internal::static_modint_base {
    using mint = static_modint;

  public:
    static constexpr int mod() { return m; }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }

    static_modint() : _v(0) {}
    template <class T, internal::is_signed_int_t<T>* = nullptr>
    static_modint(T v) {
        long long x = (long long)(v % (long long)(umod()));
        if (x < 0) x += umod();
        _v = (unsigned int)(x);
    }
    template <class T, internal::is_unsigned_int_t<T>* = nullptr>
    static_modint(T v) {
        _v = (unsigned int)(v % umod());
    }
    static_modint(bool v) { _v = ((unsigned int)(v) % umod()); }

    unsigned int val() const { return _v; }

    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }

    mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        _v -= rhs._v;
        if (_v >= umod()) _v += umod();
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        unsigned long long z = _v;
        z *= rhs._v;
        _v = (unsigned int)(z % umod());
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }

    mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const {
        if (prime) {
            assert(_v);
            return pow(umod() - 2);
        } else {
            auto eg = internal::inv_gcd(_v, m);
            assert(eg.first == 1);
            return eg.second;
        }
    }

    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }

  private:
    unsigned int _v;
    static constexpr unsigned int umod() { return m; }
    static constexpr bool prime = internal::is_prime<m>;
};

template <int id> struct dynamic_modint : internal::modint_base {
    using mint = dynamic_modint;

  public:
    static int mod() { return (int)(bt.umod()); }
    static void set_mod(int m) {
        assert(1 <= m);
        bt = internal::barrett(m);
    }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }

    dynamic_modint() : _v(0) {}
    template <class T, internal::is_signed_int_t<T>* = nullptr>
    dynamic_modint(T v) {
        long long x = (long long)(v % (long long)(mod()));
        if (x < 0) x += mod();
        _v = (unsigned int)(x);
    }
    template <class T, internal::is_unsigned_int_t<T>* = nullptr>
    dynamic_modint(T v) {
        _v = (unsigned int)(v % mod());
    }
    dynamic_modint(bool v) { _v = ((unsigned int)(v) % mod()); }

    unsigned int val() const { return _v; }

    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }

    mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        _v += mod() - rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        _v = bt.mul(_v, rhs._v);
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }

    mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const {
        auto eg = internal::inv_gcd(_v, mod());
        assert(eg.first == 1);
        return eg.second;
    }

    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }

  private:
    unsigned int _v;
    static internal::barrett bt;
    static unsigned int umod() { return bt.umod(); }
};
template <int id> internal::barrett dynamic_modint<id>::bt = 998244353;

using modint998244353 = static_modint<998244353>;
using modint1000000007 = static_modint<1000000007>;
using modint = dynamic_modint<-1>;

namespace internal {

template <class T>
using is_static_modint = std::is_base_of<internal::static_modint_base, T>;

template <class T>
using is_static_modint_t = std::enable_if_t<is_static_modint<T>::value>;

template <class> struct is_dynamic_modint : public std::false_type {};
template <int id>
struct is_dynamic_modint<dynamic_modint<id>> : public std::true_type {};

template <class T>
using is_dynamic_modint_t = std::enable_if_t<is_dynamic_modint<T>::value>;

}  // namespace internal

}  // namespace atcoder


#include <algorithm>
#include <array>

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

// @param n `0 <= n`
// @return minimum non-negative `x` s.t. `n <= 2**x`
int ceil_pow2(int n) {
    int x = 0;
    while ((1U << x) < (unsigned int)(n)) x++;
    return x;
}

// @param n `1 <= n`
// @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`
int bsf(unsigned int n) {
#ifdef _MSC_VER
    unsigned long index;
    _BitScanForward(&index, n);
    return index;
#else
    return __builtin_ctz(n);
#endif
}

}  // namespace internal

}  // namespace atcoder

#include <cassert>
#include <type_traits>
#include <vector>

namespace atcoder {

namespace internal {

template <class mint, internal::is_static_modint_t<mint>* = nullptr>
void butterfly(std::vector<mint>& a) {
    static constexpr int g = internal::primitive_root<mint::mod()>;
    int n = int(a.size());
    int h = internal::ceil_pow2(n);

    static bool first = true;
    static mint sum_e[30];  // sum_e[i] = ies[0] * ... * ies[i - 1] * es[i]
    if (first) {
        first = false;
        mint es[30], ies[30];  // es[i]^(2^(2+i)) == 1
        int cnt2 = bsf(mint::mod() - 1);
        mint e = mint(g).pow((mint::mod() - 1) >> cnt2), ie = e.inv();
        for (int i = cnt2; i >= 2; i--) {
            // e^(2^i) == 1
            es[i - 2] = e;
            ies[i - 2] = ie;
            e *= e;
            ie *= ie;
        }
        mint now = 1;
        for (int i = 0; i <= cnt2 - 2; i++) {
            sum_e[i] = es[i] * now;
            now *= ies[i];
        }
    }
    for (int ph = 1; ph <= h; ph++) {
        int w = 1 << (ph - 1), p = 1 << (h - ph);
        mint now = 1;
        for (int s = 0; s < w; s++) {
            int offset = s << (h - ph + 1);
            for (int i = 0; i < p; i++) {
                auto l = a[i + offset];
                auto r = a[i + offset + p] * now;
                a[i + offset] = l + r;
                a[i + offset + p] = l - r;
            }
            now *= sum_e[bsf(~(unsigned int)(s))];
        }
    }
}

template <class mint, internal::is_static_modint_t<mint>* = nullptr>
void butterfly_inv(std::vector<mint>& a) {
    static constexpr int g = internal::primitive_root<mint::mod()>;
    int n = int(a.size());
    int h = internal::ceil_pow2(n);

    static bool first = true;
    static mint sum_ie[30];  // sum_ie[i] = es[0] * ... * es[i - 1] * ies[i]
    if (first) {
        first = false;
        mint es[30], ies[30];  // es[i]^(2^(2+i)) == 1
        int cnt2 = bsf(mint::mod() - 1);
        mint e = mint(g).pow((mint::mod() - 1) >> cnt2), ie = e.inv();
        for (int i = cnt2; i >= 2; i--) {
            // e^(2^i) == 1
            es[i - 2] = e;
            ies[i - 2] = ie;
            e *= e;
            ie *= ie;
        }
        mint now = 1;
        for (int i = 0; i <= cnt2 - 2; i++) {
            sum_ie[i] = ies[i] * now;
            now *= es[i];
        }
    }

    for (int ph = h; ph >= 1; ph--) {
        int w = 1 << (ph - 1), p = 1 << (h - ph);
        mint inow = 1;
        for (int s = 0; s < w; s++) {
            int offset = s << (h - ph + 1);
            for (int i = 0; i < p; i++) {
                auto l = a[i + offset];
                auto r = a[i + offset + p];
                a[i + offset] = l + r;
                a[i + offset + p] =
                    (unsigned long long)(mint::mod() + l.val() - r.val()) *
                    inow.val();
            }
            inow *= sum_ie[bsf(~(unsigned int)(s))];
        }
    }
}

}  // namespace internal

template <class mint, internal::is_static_modint_t<mint>* = nullptr>
std::vector<mint> convolution(std::vector<mint> a, std::vector<mint> b) {
    int n = int(a.size()), m = int(b.size());
    if (!n || !m) return {};
    if (std::min(n, m) <= 60) {
        if (n < m) {
            std::swap(n, m);
            std::swap(a, b);
        }
        std::vector<mint> ans(n + m - 1);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                ans[i + j] += a[i] * b[j];
            }
        }
        return ans;
    }
    int z = 1 << internal::ceil_pow2(n + m - 1);
    a.resize(z);
    internal::butterfly(a);
    b.resize(z);
    internal::butterfly(b);
    for (int i = 0; i < z; i++) {
        a[i] *= b[i];
    }
    internal::butterfly_inv(a);
    a.resize(n + m - 1);
    mint iz = mint(z).inv();
    for (int i = 0; i < n + m - 1; i++) a[i] *= iz;
    return a;
}

template <unsigned int mod = 998244353,
          class T,
          std::enable_if_t<internal::is_integral<T>::value>* = nullptr>
std::vector<T> convolution(const std::vector<T>& a, const std::vector<T>& b) {
    int n = int(a.size()), m = int(b.size());
    if (!n || !m) return {};

    using mint = static_modint<mod>;
    std::vector<mint> a2(n), b2(m);
    for (int i = 0; i < n; i++) {
        a2[i] = mint(a[i]);
    }
    for (int i = 0; i < m; i++) {
        b2[i] = mint(b[i]);
    }
    auto c2 = convolution(move(a2), move(b2));
    std::vector<T> c(n + m - 1);
    for (int i = 0; i < n + m - 1; i++) {
        c[i] = c2[i].val();
    }
    return c;
}

std::vector<long long> convolution_ll(const std::vector<long long>& a,
                                      const std::vector<long long>& b) {
    int n = int(a.size()), m = int(b.size());
    if (!n || !m) return {};

    static constexpr unsigned long long MOD1 = 754974721;  // 2^24
    static constexpr unsigned long long MOD2 = 167772161;  // 2^25
    static constexpr unsigned long long MOD3 = 469762049;  // 2^26
    static constexpr unsigned long long M2M3 = MOD2 * MOD3;
    static constexpr unsigned long long M1M3 = MOD1 * MOD3;
    static constexpr unsigned long long M1M2 = MOD1 * MOD2;
    static constexpr unsigned long long M1M2M3 = MOD1 * MOD2 * MOD3;

    static constexpr unsigned long long i1 =
        internal::inv_gcd(MOD2 * MOD3, MOD1).second;
    static constexpr unsigned long long i2 =
        internal::inv_gcd(MOD1 * MOD3, MOD2).second;
    static constexpr unsigned long long i3 =
        internal::inv_gcd(MOD1 * MOD2, MOD3).second;

    auto c1 = convolution<MOD1>(a, b);
    auto c2 = convolution<MOD2>(a, b);
    auto c3 = convolution<MOD3>(a, b);

    std::vector<long long> c(n + m - 1);
    for (int i = 0; i < n + m - 1; i++) {
        unsigned long long x = 0;
        x += (c1[i] * i1) % MOD1 * M2M3;
        x += (c2[i] * i2) % MOD2 * M1M3;
        x += (c3[i] * i3) % MOD3 * M1M2;
        // B = 2^63, -B <= x, r(real value) < B
        // (x, x - M, x - 2M, or x - 3M) = r (mod 2B)
        // r = c1[i] (mod MOD1)
        // focus on MOD1
        // r = x, x - M', x - 2M', x - 3M' (M' = M % 2^64) (mod 2B)
        // r = x,
        //     x - M' + (0 or 2B),
        //     x - 2M' + (0, 2B or 4B),
        //     x - 3M' + (0, 2B, 4B or 6B) (without mod!)
        // (r - x) = 0, (0)
        //           - M' + (0 or 2B), (1)
        //           -2M' + (0 or 2B or 4B), (2)
        //           -3M' + (0 or 2B or 4B or 6B) (3) (mod MOD1)
        // we checked that
        //   ((1) mod MOD1) mod 5 = 2
        //   ((2) mod MOD1) mod 5 = 3
        //   ((3) mod MOD1) mod 5 = 4
        long long diff =
            c1[i] - internal::safe_mod((long long)(x), (long long)(MOD1));
        if (diff < 0) diff += MOD1;
        static constexpr unsigned long long offset[5] = {
            0, 0, M1M2M3, 2 * M1M2M3, 3 * M1M2M3};
        x -= offset[diff % 5];
        c[i] = x;
    }

    return c;
}

}  // namespace atcoder


using namespace std;
using namespace atcoder;


#define rep(i,n) for (int i=0;i<n;i+=1)
#define rrep(i,n) for (int i=n-1;i>-1;i--)
#define pb push_back
#define all(x) (x).begin(), (x).end()

template<class T>
using vec = vector<T>;
template<class T>
using vvec = vec<vec<T>>;
template<class T>
using vvvec = vec<vvec<T>>;
using ll = long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;


template<class T>
bool chmin(T &a, T b){
  if (a>b){
    a = b;
    return true;
  }
  return false;
}

template<class T>
bool chmax(T &a, T b){
  if (a<b){
    a = b;
    return true;
  }
  return false;
}

template<class T>
T sum(vec<T> x){
  T res=0;
  for (auto e:x){
    res += e;
  }
  return res;
}

template<class T>
void printv(vec<T> x){
  for (auto e:x){
    cout<<e<<" ";
  }
  cout<<endl;
}

template<class T>
ostream& operator<<(ostream& os, const vec<T>& A){
  os << "[";
  rep(i,A.size()){
    os << A[i];
    if (i!=A.size()-1){
      os << ", ";
    }
  }
  os << "]" ;
  return os;
}

template<class T,class U>
ostream& operator<<(ostream& os, const pair<T,U>& A){
  os << "(" << A.first <<", " << A.second << ")";
  return os;
}

template<class T>
ostream& operator<<(ostream& os, const set<T>& S){
  os << "set{";
  for (auto a:S){
    os << a;
    auto it = S.find(a);
    it++;
    if (it!=S.end()){
      os << ", ";
    }
  }
  os << "}";
  return os;
}

using mint = modint998244353;

ostream& operator<<(ostream& os, const mint& a){
  os << a.val();
  return os;
}

const int M = 6000000+100;
mint g1[M],g2[M],inverse[M];

void init_mint(){
  g1[0] = 1, g1[1] = 1;
  g2[0] = 1, g2[1] = 1;
  inverse[0] = 0, inverse[1] = 1;
  for (int n=2;n<M;n++){
    g1[n] = g1[n-1] * n;
    inverse[n] = (-inverse[998244353%n]) * (998244353/n);
    g2[n] = g2[n-1] * inverse[n];
  }
}

mint comb(int n,int r){
  if (r < 0 || n < r) return 0;
  return g1[n] * g2[r] * g2[n-r];
}


#define debug(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << " )\n";

int main(){
  ios::sync_with_stdio(false);
  std::cin.tie(nullptr);

  init_mint();

  int n,k;
  cin>>n>>k;

  if (k==1){
    cout << 1 << endl;
    return 0;
  }

  vector<mint> g(n+1,0);
  for (int i=0;i<=n;i++) g[i] = comb(2*i,i) * inverse[i+1] * mint(k-1).pow(i);

  //debug(g);
  mint C = mint(k) * inverse[2] * inverse[k-1];

  vector<mint> G(n+1,0);
  for (int i=1;i<=n;i++) G[i] = 2 * C * (k-1) * g[i-1];
  G[0] = 1 - 2 * C;

  {
    mint zero = mint(1) - mint(2) * C, two = mint(4*(k-1)) * C * C;
    mint inv_zero = zero.inv();
    for (int i = 0; i <= n; i+=1) G[i] = (G[i] - two * (i-1 >= 0 ? G[i-1] : 0)) * inv_zero;
  }

  //debug(G);

  vector<mint> H(n+1,0);
  for (int i=1;i<=n;i++) H[i] = mint(2*(k-1)) * g[i-1];
  H[1] += mint(4) * mint(k-1);
  H[0] -= mint(2);
  vector<mint> res;
  vector<mint> I(n+1);
  {
    mint two = -mint(8)*mint(k-1);
    for (int i=0;i<=n;i++){
      I[i] = (H[i] * (-1) - two * (i-1 >= 0 ? I[i-1] : 0)) * inverse[2];
    }
    //debug(I);
    //assert (G.size()+g.size() <= (1<<23));
    auto a = convolution(G,g);
    while (int(a.size()) > n+1) a.pop_back();
    //assert (a.size()+I.size() <= (1<<23));
    res = convolution(a,I);
  }

  assert (int(res.size()) >= n+1);

  //debug(res);

  mint ans = 0;
  for (int i=1;i<=2*n;i++){
    int GCD = gcd(i,2*n);
    if (~GCD & 1) ans += G[GCD>>1];
    else ans += res[(GCD-1)>>1] * mint(k);
  }
  ans *= inverse[2*n];
  cout << ans.val() << endl;



  
}
accuracy: 1
time_ms: 2440
memory_kb: 242268
final_rank: 9

code_snippet: #pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
#include<chrono>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
//ll mod = 1;
constexpr ll mod = 998244353;
//constexpr ll mod = 1000000007;
const int mod17 = 1000000007;
const ll INF = (ll)mod17 * mod17;
typedef pair<int, int>P;

#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;

using ld = double;
typedef pair<ld, ld> LDP;
const ld eps = 1e-10;
const ld pi = acosl(-1.0);

template<typename T>
void chmin(T& a, T b) {
    a = min(a, b);
}
template<typename T>
void chmax(T& a, T b) {
    a = max(a, b);
}
template<typename T>
vector<T> vmerge(vector<T>& a, vector<T>& b) {
    vector<T> res;
    int ida = 0, idb = 0;
    while (ida < a.size() || idb < b.size()) {
        if (idb == b.size()) {
            res.push_back(a[ida]); ida++;
        }
        else if (ida == a.size()) {
            res.push_back(b[idb]); idb++;
        }
        else {
            if (a[ida] < b[idb]) {
                res.push_back(a[ida]); ida++;
            }
            else {
                res.push_back(b[idb]); idb++;
            }
        }
    }
    return res;
}
template<typename T>
void cinarray(vector<T>& v) {
    rep(i, v.size())cin >> v[i];
}
template<typename T>
void coutarray(vector<T>& v) {
    rep(i, v.size()) {
        if (i > 0)cout << " "; cout << v[i];
    }
    cout << "\n";
}
ll mod_pow(ll x, ll n, ll m = mod) {
    if (n < 0) {
        ll res = mod_pow(x, -n, m);
        return mod_pow(res, m - 2, m);
    }
    if (abs(x) >= m)x %= m;
    if (x < 0)x += m;
    //if (x == 0)return 0;
    ll res = 1;
    while (n) {
        if (n & 1)res = res * x % m;
        x = x * x % m; n >>= 1;
    }
    return res;
}
//mod should be <2^31
struct modint {
    int n;
    modint() :n(0) { ; }
    modint(ll m) {
        if (m < 0 || mod <= m) {
            m %= mod; if (m < 0)m += mod;
        }
        n = m;
    }
    operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
bool operator<(modint a, modint b) { return a.n < b.n; }
modint operator+=(modint& a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= (int)mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0)a.n += (int)mod; return a; }
modint operator*=(modint& a, modint b) { a.n = ((ll)a.n * b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, ll n) {
    if (n == 0)return modint(1);
    modint res = (a * a) ^ (n / 2);
    if (n % 2)res = res * a;
    return res;
}

ll inv(ll a, ll p) {
    return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }
modint operator/=(modint& a, modint b) { a = a / b; return a; }
const int max_n = 1 << 24;
modint fact[max_n], factinv[max_n];
void init_f() {
    fact[0] = modint(1);
    for (int i = 0; i < max_n - 1; i++) {
        fact[i + 1] = fact[i] * modint(i + 1);
    }
    factinv[max_n - 1] = modint(1) / fact[max_n - 1];
    for (int i = max_n - 2; i >= 0; i--) {
        factinv[i] = factinv[i + 1] * modint(i + 1);
    }
}
modint comb(int a, int b) {
    if (a < 0 || b < 0 || a < b)return 0;
    return fact[a] * factinv[b] * factinv[a - b];
}
modint combP(int a, int b) {
    if (a < 0 || b < 0 || a < b)return 0;
    return fact[a] * factinv[a - b];
}

ll gcd(ll a, ll b) {
    a = abs(a); b = abs(b);
    if (a < b)swap(a, b);
    while (b) {
        ll r = a % b; a = b; b = r;
    }
    return a;
}
template<typename T>
void addv(vector<T>& v, int loc, T val) {
    if (loc >= v.size())v.resize(loc + 1, 0);
    v[loc] += val;
}
/*const int mn = 2000005;
bool isp[mn];
vector<int> ps;
void init() {
    fill(isp + 2, isp + mn, true);
    for (int i = 2; i < mn; i++) {
        if (!isp[i])continue;
        ps.push_back(i);
        for (int j = 2 * i; j < mn; j += i) {
            isp[j] = false;
        }
    }
}*/

//[,val)
template<typename T>
auto prev_itr(set<T>& st, T val) {
    auto res = st.lower_bound(val);
    if (res == st.begin())return st.end();
    res--; return res;
}

//[val,)
template<typename T>
auto next_itr(set<T>& st, T val) {
    auto res = st.lower_bound(val);
    return res;
}
using mP = pair<modint, modint>;
mP operator+(mP a, mP b) {
    return { a.first + b.first,a.second + b.second };
}
mP operator+=(mP& a, mP b) {
    a = a + b; return a;
}
mP operator-(mP a, mP b) {
    return { a.first - b.first,a.second - b.second };
}
mP operator-=(mP& a, mP b) {
    a = a - b; return a;
}
LP operator+(LP a, LP b) {
    return { a.first + b.first,a.second + b.second };
}
LP operator+=(LP& a, LP b) {
    a = a + b; return a;
}
LP operator-(LP a, LP b) {
    return { a.first - b.first,a.second - b.second };
}
LP operator-=(LP& a, LP b) {
    a = a - b; return a;
}

mt19937 mt(time(0));

const string drul = "DRUL";
string senw = "SENW";
//DRUL,or SENW
//int dx[4] = { 1,0,-1,0 };
//int dy[4] = { 0,1,0,-1 };

//------------------------------------


int get_premitive_root() {
    int primitive_root = 0;
    if (!primitive_root) {
        primitive_root = [&]() {
            set<int> fac;
            int v = mod - 1;
            for (ll i = 2; i * i <= v; i++) while (v % i == 0) fac.insert(i), v /= i;
            if (v > 1) fac.insert(v);
            for (int g = 1; g < mod; g++) {
                bool ok = true;
                for (auto i : fac) if (mod_pow(g, (mod - 1) / i) == 1) { ok = false; break; }
                if (ok) return g;
            }
            return -1;
        }();
    }
    return primitive_root;
}
const int proot = get_premitive_root();

typedef vector <modint> poly;
void dft(poly& f, bool inverse = false) {
    int n = f.size(); if (n == 1)return;

    static poly w{ 1 }, iw{ 1 };
    for (int m = w.size(); m < n / 2; m *= 2) {
        modint dw = mod_pow(proot, (mod - 1) / (4 * m)), dwinv = (modint)1 / dw;
        w.resize(m * 2); iw.resize(m * 2);
        for (int i = 0; i < m; i++)w[m + i] = w[i] * dw, iw[m + i] = iw[i] * dwinv;
    }
    if (!inverse) {
        for (int m = n; m >>= 1;) {
            for (int s = 0, k = 0; s < n; s += 2 * m, k++) {
                for (int i = s; i < s + m; i++) {
                    modint x = f[i], y = f[i + m] * w[k];
                    f[i] = x + y, f[i + m] = x - y;
                }
            }
        }
    }
    else {
        for (int m = 1; m < n; m *= 2) {
            for (int s = 0, k = 0; s < n; s += 2 * m, k++) {
                for (int i = s; i < s + m; i++) {
                    modint x = f[i], y = f[i + m];
                    f[i] = x + y, f[i + m] = (x - y) * iw[k];
                }
            }
        }
        modint n_inv = (modint)1 / (modint)n;
        for (modint& v : f)v *= n_inv;
    }
}
poly multiply(poly g, poly h) {
    int n = 1;
    int pi = 0, qi = 0;
    rep(i, g.size())if (g[i])pi = i;
    rep(i, h.size())if (h[i])qi = i;
    int sz = pi + qi + 2;
    while (n < sz)n *= 2;
    g.resize(n); h.resize(n);
    dft(g); dft(h);
    rep(i, n) {
        g[i] *= h[i];
    }
    dft(g, true);
    return g;
}

//i<=j
poly ordered_multiply(poly p, poly q, bool eq) {
    poly res;
    function<void(int, int)> dfs = [&](int l, int r) {
        if (l + 1 == r)return;
        int m = (l + r) / 2;
        dfs(l, m);
        dfs(m, r);
        poly pl, pr;
        Rep(j, l, m)if (j < p.size())pl.push_back(p[j]);
        Rep(j, m, r)pr.push_back(q[j]);
        poly pp = multiply(pl, pr);
        rep(j, pp.size())addv(res, l + m + j, pp[j]);
    };
    dfs(0, q.size());
    if (eq) {
        rep(j, q.size())if (j < p.size())addv(res, 2 * j, p[j] * q[j]);
    }
    return res;
}


modint calc(int j, int i) {
    if (i == 0) {
        if (j == 0)return 1;
        else return 0;
    }
    return comb(i - 1 + j + j, j) - comb(i - 1 + j + j, j - 1);
}
void solve() {
    int n, k; cin >> n >> k;
    vector<int> cnt(2*n + 1);
    rep(d, 2*n) {
        int g = gcd(d, 2*n);
        cnt[g]++;
        //cnt[2*n/g]++;
    }
    modint ans = 0;
    rep1(i, 2*n) {
        modint csum = 0;
        if (2*n % i == 0) {
            modint al = mod_pow(k, i);
            if (i % 2 == 0) {
                int num = i / 2;
                for (int c = 0; c <= num; c++) {
                    modint val = calc(num - c, c);
                    //cout << i << " " << c << " " << val << "\n";
                    val *= mod_pow(k - 1, num - c);
                    val *= mod_pow(k, c);
                    csum += val;
                }
            }
            else {
                modint preval = 0;
                rep(x, (i - 1) / 2 + 1)preval += comb(i - 1, x);
                rep(y, i / 2 + 1) {
                    /*modint zz = 0;
                    rep(x, (i - 1) / 2 - y + 1) {
                        zz += comb((i - 1 - y), x);
                    }
                    assert(zz == preval);*/
                    modint coef = mod_pow(k, y + 1);
                    coef *= mod_pow(k - 1, (i - 1) / 2 - y);
                    csum += preval * coef;

                    int a = i - 1 - y;
                    int b = (i - 1) / 2 - y;
                    modint nval = preval + comb(a - 1, b); nval *= (1 + mod) / 2;
                    nval -= comb(a - 1, b);
                    preval = nval;
                }
                rep(x, (i - 1) / 2)preval += comb(i - 1, x);
                rep(y, i / 2) {
                    modint coef = mod_pow(k, y + 1);
                    coef *= mod_pow(k - 1, (i - 1) / 2 - y);
                    csum -= preval * coef;

                    int a = i - 1 - y;
                    int b = (i - 1) / 2 - y - 1;
                    modint nval = preval + comb(a - 1, b); nval *= (1 + mod) / 2;
                    nval -= comb(a - 1, b);
                    preval = nval;
                }

                preval = 0;


                //rep(y, i / 2 + 1) {
                //    modint coef = mod_pow(k, y + 1);
                //    coef *= mod_pow(k - 1, (i - 1) / 2 - y);

                //}
                //
           
                //for (int x = 0; x <= i / 2; x++) {
                //    for (int y = 0; y <= (i - 2 * x - 1)/2; y++) {
                //        //modint val = comb(i - 1 - y, (i - 1) / 2 - (x + y));
                //        modint val = 0;

                //        val -= comb(i - 1 - y, (i - 1) / 2 - (x + y) - 1);
                //        val *= mod_pow(k - 1, (i-1)/2-y);
                //        val *= mod_pow(k, y + 1);
                //        csum += val;
                //    }
                //}
                /*for (int las = 1; las <= i; las += 2) {
                    for (int cl = 0; cl <= (i - las) / 2; cl++) {
                        int num = i - las - 2 * cl;
                        num /= 2;
                        int b = las + cl;
                        modint val = calc(num, b);
                        val *= mod_pow(k - 1, num+las/2);
                        val *= mod_pow(k, cl+1);
                        csum += val;
                    }
                }*/
                //int num = i / 2;
                //for (int c = 0; c <= num; c++) {
                //    modint val = calc(num - c, c + 1);
                //    val *= mod_pow(k, c + 1);
                //    val *= mod_pow(k - 1, num - c);
                //    //cout << i << " " << c << " " << val << "\n";
                //    csum += val;
                //}
                /*for (int c = 0; c <= num; c++) {
                    modint val = calc(num - c, c);
                    val *= mod_pow(k, c+1);
                    val *= mod_pow(k-1, num - c);
                    csum += val;
                }*/
                
            }
            al -= csum;
            /*if (2 * n % (2 * i) == 0) {
                ans += al * (modint)cnt[i];
            }*/
            //ans+=al*(modint)cnt[]
            /*al -= csum;
            if (2 * n % (2 * i) == 0) {
                ans += al * (modint)cnt[2 * i];
            }*/
        }
        //cout << i << " " << csum << " "<<cnt[i]<<"\n";
        ans += csum * (modint)cnt[i];
    }
    /*for (int i = 1; i <= 2 * n; i++) {


        if (i % 2 == 0 && cnt[i]) {
            modint val = mem[i] - mem[i / 2];
            ans += val * (modint)(cnt[i / 2]);
        }
    }*/
    ans /= 2*n;
    cout << ans << "\n";
}



signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    //cout << fixed<<setprecision(10);
    init_f();
    //init();
    //while(true)
    //expr();
    //int t; cin >> t; rep(i, t)
    solve();
    return 0;
}
accuracy: 1
time_ms: 2310
memory_kb: 157576
final_rank: 7