#include <bits/stdc++.h>
#define ll long long
#define vec vector
#define pii pair<int, int> 
using namespace std;
 
const long long MAXVAL = (long long) 1e18 + 1;
//const long long MOD = 1000000007ll;
const long long MOD = 998244353ll;
const int INF = 1000000001;
 
long long poww(int x, long long pow) {
  if (pow == 0ll ) return 1;
  if (pow == 1ll) return x % MOD;
  long long ans = poww(x, pow >> 1) % MOD;
  ans = (ans * ans) % MOD;
  if ((pow & 1) == 1) {
    ans = (ans * x ) % MOD;
  }
  return ans % MOD;
}
 
ll gcd(ll x, ll y) {
  if (x == 0) return y;
  while (y) {
    x %= y;
    swap(x, y);
  }
  return x;
}

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  int q = 1;
  //cin >> q;
  while (q-- >0) {
    int n;
    cin >> n;
    int m;
    cin >> m;
    vec<int> primes;
    vec<int> minp(m + 1, -1);
    for (int i = 2; i <= m; ++i) {
      if (minp[i] < 0) {
        primes.push_back(i);
      }
      for (int j = 0; j < primes.size() && primes[j] <= i; ++j) {
        if (primes[j] * 1ll * i > m) break;
        minp[primes[j] * i] = j;
      }
    }
    vec<int> combs;
    combs.push_back(1);
    for (int i = 1; i <= 20; ++i) {
      int old = combs[i - 1];
      int new_ = (old * 1ll * (i + n - 1)) % MOD;
      new_ = (new_ * 1ll * poww(i, MOD - 2)) % MOD;
      combs.push_back(new_);
    }
    int res = 0;
    for (int x = m; x > 0; --x) {
      int curres = 1;
      int y = x;
      while (minp[y] >= 0) {
        int p = primes[minp[y]];
        assert (y % p == 0);
        int deg = 0;
        while (y % p == 0) {
          y /= p;
          ++deg;
        }
        curres = (curres * 1ll * combs[deg]) % MOD;
      }
      if (y > 1) {
        curres = (curres * 1ll * combs[1]) % MOD;
      }
      res = (res + curres) % MOD;
    }
    cout << res  << "\n";

  }
}

 

#include <bits/stdc++.h>
#pragma GCC optimize ("O2,unroll-loops")
//#pragma GCC optimize("no-stack-protector,fast-math")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<pii, int> piii;
typedef pair<ll, ll> pll;
#define debug(x) cerr<<#x<<'='<<(x)<<endl;
#define debugp(x) cerr<<#x<<"= {"<<(x.first)<<", "<<(x.second)<<"}"<<endl;
#define debug2(x, y) cerr<<"{"<<#x<<", "<<#y<<"} = {"<<(x)<<", "<<(y)<<"}"<<endl;
#define debugv(v) {cerr<<#v<<" : ";for (auto x:v) cerr<<x<<' ';cerr<<endl;}
#define all(x) x.begin(), x.end()
#define pb push_back
#define kill(x) return cout<<x<<'\n', 0;

const int inf=1000000010;
const ll INF=1000000000000001000LL;
const int mod=998244353;
const int MAXN=300010, LOG=20;

ll n, m, k, u, v, x, y, t, a, b, ans;
ll F[MAXN], I[MAXN];
ll dp[MAXN][LOG];

ll powmod(ll a, ll b){
	ll res=1;
	for (; b; b>>=1, a=a*a%mod) if (b&1) res=res*a%mod;
	return res;
}
ll nCr(ll n, ll r){
	if (r<0 || r>n) return 0;
	return F[n]*I[r]%mod*I[n-r]%mod;
}

int main(){
	ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	F[0]=1;
	for (int i=1; i<MAXN; i++) F[i]=F[i-1]*i%mod;
	I[MAXN-1]=powmod(F[MAXN-1], mod-2);
	for (int i=MAXN-1; i; i--) I[i-1]=I[i]*i%mod;
	cin>>n>>m;
	for (int i=1; i<=m; i++){
		dp[i][1]++;
		for (int j=1; j<LOG; j++) if (dp[i][j]){
			ans=(ans + dp[i][j]*nCr(n-1, j-1))%mod;
			for (int k=2*i; k<=m; k+=i) dp[k][j+1]=(dp[k][j+1] + dp[i][j])%mod;
		}
	}
	cout<<ans<<"\n";
	
	return 0;
}
