// Artur Kraska, II UWr

#include <bits/stdc++.h>

#define forr(i, n)                  for(int i=0; i<n; i++)
#define FOREACH(iter, coll)         for(auto iter = coll.begin(); iter != coll.end(); ++iter)
#define FOREACHR(iter, coll)        for(auto iter = coll.rbegin(); iter != coll.rend(); ++iter)
#define lbound(P,R,PRED)            ({typeof(P) X=P,RRR=(R), PPP = P; while(PPP<RRR) {X = (PPP+(RRR-PPP)/2); if(PRED) RRR = X; else PPP = X+1;} PPP;})
#define testy()                     int _tests; scanf("%d", &_tests); FOR(_test, 1, _tests)
#define CLEAR(tab)                  memset(tab, 0, sizeof(tab))
#define CONTAIN(el, coll)           (coll.find(el) != coll.end())
#define FOR(i, a, b)                for(int i=a; i<=b; i++)
#define FORD(i, a, b)               for(int i=a; i>=b; i--)
#define MP                          make_pair
#define PB                          push_back
#define ff                          first
#define ss                          second
#define deb(X)                      X;

#define M 998244353
#define INF 1000000007LL

using namespace std;

int n, m, a;
long long tr[200057][22];
long long sito[200057];

int solve()
{
    scanf("%d %d", &n, &m);

    tr[0][0] = 1;
    FOR(i, 1, n+30)
    {
        tr[i][0] = 1;
        FOR(j, 1, 20)
        {
            tr[i][j] = (tr[i-1][j-1] + tr[i-1][j]) % M;
        }
    }

    FOR(i, 2, m)
    {
        if(sito[i] == 0)
        {
            sito[i] = i;
            for(long long j = i*(long long)i; j <= m; j+=i)
                if(sito[j] == 0)
                    sito[j] = i;
        }
    }

    long long res = 1;
    FOR(i, 2, m)
    {
        long long r = 1;
        int x = i;
        map <int, int> mapa;
        while(x != 1)
        {
            mapa[sito[x]]++;
            x  = x/sito[x];
        }
        for(auto p : mapa)
        {
            r = (r*tr[n+p.ss-1][p.ss])%M;
        }
        //cout << i << " daje " << r << endl;
        res = (res + r)%M;
    }
    printf("%lld\n", res);

    return 0;
}

int main()
{
    solve();

    return 0;
}

#include<bits/stdc++.h>
#define ll long long int
#define pll pair<ll,ll>
#define vpll vector< pll >
#define mpll map<ll,ll>
#define MOD 998244353
#define all(v) v.begin(),v.end()
#define s(v) v.size()
#define test ll t;cin>>t;while(t--)
#define vec vector<ll>
#define read0(v,n) for(int i=0;i<n;i++)cin>>v[i];
#define read1(v,n) for(int i=1;i<=n;i++)cin>>v[i];
#define trav(a,x) for (auto& a: x)
#define fast ios_base::sync_with_stdio(false);cin.tie(NULL);
#define cut(x) {cout<<x;return 0;}
#define print(x) {cout<<x<<nl;continue;}
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define FORB(i,a,b) for(int i=a;i>=b;i--)
#define err1(a) {cout<<#a<<' '<<a<<nl;}
#define err2(a,b) {cout<<#a<<' '<<a<<' '<<#b<<' '<<b<<nl;}

#define mp make_pair
#define pb push_back
#define eb emplace_back
#define f first
#define sc second
#define lb lower_bound
#define ub upper_bound
#define nl '\n'
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace __gnu_pbds;
using namespace std;
#define oset tree<int, null_type,less_equal<int>, rb_tree_tag,tree_order_statistics_node_update>
ll gcd(ll a, ll b)
{
	if (b==0)return a;
	return gcd(b, a % b);
}
ll lcm(ll a,ll b)
{
    return (a*b)/gcd(a,b);
}
ll bpow(ll a, ll b)
{
	ll ans=1;
	while(b)
	{
		if(b&1)
			ans=(ans*a)%MOD;
		b/=2;
		a=(a*a)%MOD;
	}
	return ans;
}
mpll factorise(ll n)
{
    mpll fact;
    while (n % 2 == 0)
    {
        fact[2]++;
        n = n/2;
    }

    // n must be odd at this point. So we can skip
    // one element (Note i = i +2)
    for (int i = 3; i <= sqrt(n); i = i + 2)
    {
        // While i divides n, print i and divide n
        while (n % i == 0)
        {
           fact[i]++;
            n = n/i;
        }
    }

    // This condition is to handle the case when n
    // is a prime number greater than 2
    if (n > 2)
        fact[n]++;
    return fact;
}
const int N=1e6;
ll fac[N];
void precompute()
{
    fac[0]=1;
    FOR(i,1,(ll)5e5)fac[i]=(i*fac[i-1])%MOD;
}
ll ncr(ll n,ll r)
{
    return (((fac[n]*bpow(fac[r],MOD-2))%MOD)*(bpow(fac[n-r],MOD-2)))%MOD;
}

int main()
{
	#ifndef ONLINE_JUDGE
    	freopen("input.txt", "r", stdin);
    	freopen("output.txt", "w", stdout);
    	#endif

	fast
	ll n,m;
	cin>>n>>m;
	precompute();
	ll sum=0;
	FOR(i,1,m)
	{
	    mpll temp=factorise(i);
	    ll x=1;
	    trav(it,temp)
	    {
	        x=(x*ncr(n+it.sc-1,n-1))%MOD;
	    }
	    sum=(sum+x)%MOD;
	}
	cut(sum)




}
