#include <iostream>

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <deque>
#include <stack>
#include <queue>
#include <array>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <random>
#include <chrono>
#include <utility>
#include <numeric>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <sstream>
#include <assert.h>
#include <iomanip>
#include <algorithm>
#include <functional>
#include <unordered_map>

using namespace std;
struct _ { ios_base::Init i; _() { ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL); } } _;

#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c> {i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifdef HOME
	~debug() { cerr << endl; }
	eni( != ) cerr << boolalpha << i; ris;
}
eni( == ) ris << range(begin(i), end(i));
}
sim, class b dor(pair < b, c > d) {
	ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
	*this << "[";
	for (auto it = d.b; it != d.e; ++it)
		*this << ", " + 2 * (it == d.b) << *it;
	ris << "]";
}
#else
	sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "


#define ff first
#define ss second
#define REP(i,st,en) for (int i = st; i <= en; i++)
#define REPR(i,st,en) for (int i = st; i >= en; i--)

const int MOD = 998244353;

class Modint {
public:
	long long val;

	Modint (long long _val = 0) {
		if (_val >= MOD) _val %= MOD;
		val = _val;
	}

	Modint operator+ (Modint other) {
		return Modint(val + other.val);
	}

	void operator+= (Modint other) {
		val += other.val;
		if (val >= MOD) val %= MOD;
	}

	Modint operator- () {
		return Modint(MOD - val);
	}

	Modint operator- (Modint other) {
		return Modint(val + MOD - other.val);
	}

	void operator-= (Modint other) {
		val += MOD - other.val;
		if (val >= MOD) val %= MOD;
	}

	Modint operator* (Modint other) {
		return Modint(val * other.val);
	}

	void operator*= (Modint other) {
		val *= other.val;
		if (val >= MOD) val %= MOD;
	}

	bool operator== (Modint other) {
		return val == other.val;
	}

	bool operator!= (Modint other) {
		return val != other.val;
	}
};

Modint exp (Modint a, long long k) {
	Modint res = 1;
	while (k) {
		if (k & 1) res *= a;
		a *= a;
		k >>= 1;
	}
	return res;
}

Modint inv (Modint a) {
	return exp(a, MOD - 2);
}

ostream& operator<< (ostream& out, Modint p) {
	out << p.val;
	return out;
}

const int maxn = 2e5;

vector<Modint> fact(maxn + 1, 1);
vector<Modint> inv_fact(maxn + 1, 1);

void preC() {
	for (int i = 2; i <= maxn; i++) {
		fact[i] = fact[i - 1] * i;
	}
	inv_fact[maxn] = inv(fact[maxn]);
	for (int i = maxn - 1; i >= 0; i--) inv_fact[i] = inv_fact[i + 1] * (i + 1);
}

Modint C(int n, int r) { // nCr % MOD
	if (n < r) return 0;
	return fact[n] * inv_fact[r] * inv_fact[n - r];
}


class MainClass {
public:

	void solve() {

		int n, m; cin >> n >> m;

		if (m == 1) {
			cout << 1;
			return;
		}

		int lgm = log2(m) + 1;

		Modint ans = 0;
		vector<Modint> dp(m + 1, 1), new_dp(m + 1);


		for (int i = 1; i <= lgm; i++) {
			fill(new_dp.begin(), new_dp.end(), 0);
			Modint curr = 0;

			for (int j = 1; j <= m; j++) {
				for (int k = 2 * j; k <= m; k += j) new_dp[k] += dp[j];
				curr += dp[j];
			}

			ans += C(n - 1, i - 1) * curr;
			dp.swap(new_dp);
		}

		cout << ans;


		return;
	}
};

int main() {
	preC();

	int test = 1; //cin >> test;
	for (int tst = 1; tst <= test; ++tst) {
		MainClass Ausmosian;

		Ausmosian.solve();
		cout << "\n";
	}

	return 0;
}
#include <bits/stdc++.h>
#define MAX_N (200000 + 5)
#define LL long long
using namespace std;
const int mod = 998244353;
int n, m;
int inv[MAX_N];
int p[MAX_N], tot;
bool is[MAX_N];
int pw[MAX_N], f[MAX_N];
int main() {
	scanf("%d%d", &n, &m);
	inv[1] = 1;
	for (int i = 2; i <= m; ++i) inv[i] = (LL)(mod - mod / i) * inv[mod % i] % mod;
	for (int i = 2; i <= m; ++i) {
		if (!is[i]) p[++tot] = i, pw[i] = 1, f[i] = n;
		for (int j = 1; i * p[j] <= m; ++j) {
			is[i * p[j]] = 1;
			if (i % p[j]) {
				pw[i * p[j]] = 1;
				f[i * p[j]] = (LL)f[i] * n % mod;
			}
			else {
				pw[i * p[j]] = pw[i] + 1;
				f[i * p[j]] = (LL)f[i] * (n + pw[i]) % mod * inv[pw[i] + 1] % mod;
				break;
			}
		}
	}
	int ans = 1;
	for (int i = 2; i <= m; ++i) ans = (ans + f[i]) % mod;
	printf("%d", ans);
	return 0;
}