#include<iostream>
#include<iomanip>
#include<string>
#include<vector>
#include<algorithm>
#include<utility>
#include<tuple>
#include<map>
#include<queue>
#include<deque>
#include<set>
#include<stack>
#include<numeric>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<cassert>

using namespace std;

struct Edge {
  int to;
  long long weight;
  Edge() : to(0), weight(0) {}
  Edge(int to, long long weight) : to(to), weight(weight) {}
  Edge(const Edge& e) {
    to = e.to;
    weight = e.weight;
  }
  bool operator>(const Edge &e) const { return weight > e.weight; }
  bool operator<(const Edge &e) const { return weight < e.weight; }
  bool operator==(const Edge &e) const { return weight == e.weight; }
  bool operator<=(const Edge &e) const { return weight <= e.weight; }
  bool operator>=(const Edge &e) const { return weight >= e.weight; }
};

using ll = long long;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using Graph = vector<vector<int>>;
using weightedGraph = vector<vector<Edge>>;
using heap = priority_queue<int, vector<int>, greater<int>>;

const ll BIL = 1e9;
const ll MOD = 1e9 + 7;
const ll INF = 1LL << 60;
const int inf = 1 << 29;
const ld PI = 3.141592653589793238462643383;

int main(int argc,char* argv[]){
  cin.tie(0);
  ios::sync_with_stdio(0);
  cout << fixed << setprecision(20);
  int l, r;
  cin >> l >> r;
  vector<int> sp(r+1, -1);
  vector<vector<ll>> p(r+1);
  for(int i=2;i<=r;i++) {
    if(sp[i] < 0) {
      for(int j=1;j*i<=r;j++) sp[i*j] = i;
    }
  }
  for(int i=2;i<=r;i++) {
    int k = i;
    set<int> ck;
    while(sp[k] != k) {
      if(ck.find(sp[k]) == ck.end()) p[i].push_back(sp[k]);
      ck.insert(sp[k]);
      k /= sp[k];
    }
    if(ck.find(k) == ck.end()) p[i].push_back(k);
    sort(p[i].begin(), p[i].end());
  }
  ll ans = 0;
  for(int i=l;i<=r;i++) {
    if(i < 2) continue;
    ll t = 0;
    vector<ll>& q = p[i];
    int sz = q.size();
    for(int b=1;b<(1<<sz);b++) {
      int cnt = 0;
      int k = 1;
      for(int j=0;j<sz;j++) {
        if((1<<j) & b) {
          cnt++;
          k *= q[j];
        }
      }
      if(k == 1) continue;
      ll s = r/k - (i-1)/k;
      if(cnt % 2 == 0) s *= -1;
      t += s;
    }
    t -= r/i;
    ans += t;
  }
  cout << 2*ans << endl;
  return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int Mod=998244353;

namespace modular{
	int add(int a,int b){return a+b>=Mod?a+b-Mod:a+b;}
	int mul(int a,int b){return 1ll*a*b%Mod;}
}using namespace modular;

#define cout cerr
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)

typedef long long ll;
typedef pair<int,int> pii;
#define FR first
#define SE second

inline void rd(int &x){
	x=0;char ch=getchar();int f=1;
	while(ch<'0'||ch>'9'){
		if(ch=='-')f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=x*10+ch-'0';
		ch=getchar();
	}
	x*=f;
}

int n,m;
#define Maxn 5005
pii F[Maxn][2];
pii addt(pii a,pii b){return pii(add(a.FR,b.FR),add(a.SE,b.SE));}
pii mult(pii a,pii b){return pii(mul(a.FR,b.FR),add(mul(a.FR,b.SE),mul(a.SE,b.FR)));}
int DP(int x){
	F[0][0]=pii(1,0);
	rep(i,1,n){
		F[i][0]=F[i][1]=pii(0,0);
		F[i][0]=addt(F[i-1][0],F[i-1][1]);F[i][0]=mult(F[i][0],pii(x,0));
		F[i][1]=mult(F[i-1][0],pii(1,1));
		F[i][1]=addt(F[i][1],mult(F[i-1][1],pii(1,0)));
		F[i][0]=addt(F[i][0],mult(F[i-1][0],pii(m-1-x,0)));
		F[i][1]=addt(F[i][1],mult(F[i-1][1],pii(m-1-x,0)));
	}
	return add(F[n][1].SE,F[n][0].SE);
}

int main(){
	rd(n);rd(m);
	int res=0;
	for(int i=0;i<m;++i)res=add(res,DP(i));
	printf("%d\n",res);
	return 0;
}