Problem:
Symmetric Nbase Number
問題
正の整数 $X$ を 先頭に $0$ を含まないように $N$ ($|N| > 1$) 進数表現したときの各位の数を、小さい位から順に要素とした数列を $f(X,N)$ とします。
例えば、 $10$ の $2$ 進表現は $1010$ となるため、 $f(10,2)$ は以下のようになります。
$f(10,2) = (0,1,0,1)$
また例えば、 $81$ の $3$ 進数表現は $10000$ であるため $f(81,3)$ は以下のようになります。
$f(81,3) = (0,0,0,0,1)$
また例えば、 $41$ の $-4$ 進数表現は $123$ ($1 \times (-4)^0+2\times (-4)^1 + 3 \times (-4)^2 = 41$) であるため $f(41,-4)$ は以下のようになります。
$f(41,-4) = (3,2,1)$
正の整数 $A$ , $B$ が与えられます。
$1$ 以上 $A$ 以下の数 $a$ と、 $2$ 以上 $B$ 以下の数 $b$ に対して次の条件を満たす $(a,b)$ の組の個数を答えてください。
$f(a,b)$ と $f(a,-b)$ が一致する
答えはとても大きくなることがあるため、$998244353$ で割った余りを答えてください。
制約
$1 \leq A \leq 10^{18}$
$2 \leq B \leq 10^5$
入力
$A$ $B$
出力
条件を満たす $(a,b)$ の組の個数を $998244353$ で割った余りを答えてください。
入力例 1
5 2
出力例 1
3
あり得る組み合わせを全て列挙すると、下記のようになります。
$f(1,2)=(1)$,     $f(1,-2)=(1)$
$f(2,2)=(0,1)$,   $f(2,-2)=(0,1,1)$
$f(3,2)=(1,1)$,   $f(3,-2)=(1,1,1)$  
$f(4,2)=(0,0,1)$, $f(4,-2)=(0,0,1)$  
$f(5,2)=(1,0,1)$, $f(5,-2)=(1,0,1)$
入力例 2
1000000000000000000 100000
出力例 2
195389679

Submitted solutions:

code_snippet: #include<bits/stdc++.h> 
using namespace std;
typedef long long ll;
#define all(x) (x).begin(),(x).end()
template<typename T1,typename T2> bool chmin(T1 &a,T2 b){if(a<=b)return 0; a=b; return 1;}
template<typename T1,typename T2> bool chmax(T1 &a,T2 b){if(a>=b)return 0; a=b; return 1;}
int dx[4]={0,1,0,-1}, dy[4]={1,0,-1,0};
long double eps = 1e-9;
long double pi = acos(-1);

template< int mod = 1000000007 >
struct ModInt {
    int x;
    ModInt() : x(0) {}
    ModInt(int64_t y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}
    ModInt &operator+=(const ModInt &p) {
        if((x += p.x) >= mod) x -= mod;
        return *this;
    }
    ModInt &operator-=(const ModInt &p) {
        if((x += mod - p.x) >= mod) 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 { 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 inverse() const {
        int a = x, b = mod, 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< mod >(t);
        return (is);
    }

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

// const int mod = 1000000007;
const int mod = 998244353;
using mint = ModInt< mod >;
const int MAX = 5100005;

mint fac[MAX], finv[MAX], inv[MAX];

// テーブルを作る前処理
void COMinit() {
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for (int i = 2; i < MAX; i++){
        fac[i] = fac[i - 1] * i;
    }
    finv[MAX-1] = fac[MAX-1].inverse();
    for(int i=MAX-2;i>=1;i--){
        finv[i] = finv[i+1]*(i+1);
        inv[i+1] = fac[i]*finv[i+1];
    }
}

// 二項係数計算
mint COM(int n, int k){
    if (n < k) return 0;
    if (n < 0 || k < 0) return 0;
    return fac[n] * (finv[k] * finv[n - k]);
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout << fixed << setprecision(20);

    ll a,b;
    cin>>a>>b;
    mint ans = 0;
    for(int r=2;r<=b;r++){
        int cnt = 0;
        ll tmp = a;
        vector<int> v;
        while(tmp){
            v.push_back(tmp % r);
            tmp /= r;
            cnt++;
        }
        mint dp[cnt+1][2];
        dp[cnt][0] = 1;
        dp[cnt][1] = 0;
        for(int i=cnt-1;i>=0;i--){
            if(i & 1){
                if(v[i] == 0){
                    dp[i][0] = dp[i+1][0];
                    dp[i][1] = dp[i+1][1];
                }
                else{
                    dp[i][0] = 0;
                    dp[i][1] += dp[i+1][1] + dp[i+1][0];
                }
            }
            else{
                dp[i][0] = dp[i+1][0];
                dp[i][1] += dp[i+1][1] * r;
                dp[i][1] += dp[i+1][0] * v[i]; 
            }
            // cerr << i << " " << dp[i][0]  << " " << dp[i][1] << endl;
        }
        ans += dp[0][0] + dp[0][1] - 1;
    }
    cout << ans << endl;

}
accuracy: 1
time_ms: 10
memory_kb: 63200
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;

// {{{ ModInt
template<int _MOD>
struct ModInt {
    static const auto MOD = _MOD;
    template<class T> using integral_only = typename enable_if<is_integral<T>::value>::type;

    int x;
    constexpr ModInt() : x() {}

    template<class T, integral_only<T>* = nullptr>
    ModInt(T _x=0) {
        x = _x % MOD;
        if(x<0) x+=MOD;
    }
    ModInt operator-() const { return {x == 0? 0 : MOD-x}; }
    ModInt& operator+=(const ModInt a) {
        if ((x += a.x) >= MOD) x -= MOD;
        return *this;
    }
    ModInt& operator-=(const ModInt a) {
        if ((x += MOD-a.x) >= MOD) x -= MOD;
        return *this;
    }
    ModInt& operator*=(const ModInt a) {
        x = (long long)x * a.x % MOD;
        return *this;
    }
    ModInt& operator/=(const ModInt a) {
        return (*this) *= a.inv();
    }

    ModInt operator+(const ModInt a) const { return ModInt(*this) += a; }
    ModInt operator-(const ModInt a) const { return ModInt(*this) -= a; }
    ModInt operator*(const ModInt a) const { return ModInt(*this) *= a; }
    ModInt operator/(const ModInt a) const { return ModInt(*this) /= a; }
    ModInt inv() const {
        // for prime MOD
        return pow(MOD-2);
    }
    ModInt inv2() const {
        // work for non-prime MOD if gcd(x,MOD) = 1
        int a = x, b = MOD, u = 1, v = 0;
        while(b != 0) {
            int t = a / b;
            a -= t * b;
            u -= t * v;
            swap(a, b);
            swap(u, v);
        }
        return u;
    }
    template<class T, integral_only<T>* = nullptr>
    ModInt pow(T t) const {
        ModInt r = 1, p = *this;
        while(t) {
            if(t & 1) r *= p;
            p *= p;
            t >>= 1;
        }
        return r;
    }

    bool operator==(ModInt rhs) const { return x == rhs.x; }
    bool operator!=(ModInt rhs) const { return x != rhs.x; }
    bool operator<(ModInt rhs) const { return x < rhs.x; }
    bool operator<=(ModInt rhs) const { return x <= rhs.x; }
    bool operator>(ModInt rhs) const { return x > rhs.x; }
    bool operator>=(ModInt rhs) const { return x >= rhs.x; }

    friend string to_string(ModInt i) { return to_string(i.x); }
    friend istream& operator>>(istream&i,ModInt&a) { return i>>a.x; }
    friend ostream& operator<<(ostream&o,const ModInt&a) { return o<<a.x; }
};
// }}}
const int MOD=998244353 ;
using mint=ModInt<MOD>;

mint solve( long long a, long long b ) {
    vector<int> f;
    long long c=a;
    while ( c ) {
        f.push_back(c%b);
        c/=b;
    }
    int m=f.size();
    // cout<<"debug"<<'\n';
    // for ( int i=0; i<m; i++ ) {
    //     cout<<f[i]<<' ';
    // }cout<<'\n';
    vector<vector<mint>> dp(m+1,vector<mint>(2));
    dp[m][0]=1;
    for ( int i=m-1; i>=0; i-- ) {
        if ( i%2 ) {
            if ( f[i]==0 ) {
                dp[i][0]=dp[i+1][0];
                dp[i][1]=dp[i+1][1];
            } else {
                dp[i][1]=dp[i+1][0]+dp[i+1][1];
            }
        } else {
            if ( f[i]==0 ) {
                dp[i][0]=dp[i+1][0];
                dp[i][1]=dp[i+1][1]*b;
            } else {
                dp[i][0]=dp[i+1][0];
                dp[i][1]=dp[i+1][0]*f[i]+dp[i+1][1]*b;
            }
        }
    }
    // for ( int i=m-1; i>=0; i-- ) {
    //     cout<<dp[i][0]<<' ';
    // }
    // cout<<'\n';
    // for ( int i=m-1; i>=0; i-- ) {
    //     cout<<dp[i][1]<<" ";
    // }
    // cout<<'\n';
    return dp[0][0]+dp[0][1]-1;
}
int main() {
    long long a,b;
    cin>>a>>b;
    mint ans=0;
    for ( int i=2; i<=b; i++ ) {
        ans+=solve(a,i);
    }
    cout<<ans<<"\n";
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3456
final_rank: 5

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
//#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define MOD 998244353


ll POW[62];
ll dp[62][2];

int main(){

	ll A,B;
	scanf("%lld %lld",&A,&B);


	ll ans = 0;

	for(ll b = 2; b <= B; b++){

		int maxi = 0;
		POW[0] = 1;

		for(int i = 1; ; i++){

			if(POW[i-1] > A/b)break;

			POW[i] = POW[i-1]*b;
			//printf("POW[%d]:%lld\n",i,POW[i]);
			maxi = i;
		}

		//AをB進数で表す
		queue<ll> Q;

		ll tmp = A;

		for(int i = maxi; i >= 0; i--){
			if(POW[i] <= tmp){

				Q.push(tmp/POW[i]);
				tmp %= POW[i];
			}else{

				Q.push(0);
			}
		}

		for(int i = 0; i <= maxi; i++){

			dp[i][0] = 0;
			dp[i][1] = 0;
		}

		if(maxi%2 == 1){ //最上位桁が奇数

			dp[maxi][0] = 1;

		}else{ //最上位桁が偶数


			dp[maxi][0] = Q.front(); //0～Q.front()-1
			dp[maxi][1] = 1;
		}

		Q.pop();

		int digit = maxi-1;

		while(!Q.empty()){

			ll ch = Q.front();
			Q.pop();

			if(digit%2 == 1){ //その桁の重みが0である必要あり

				dp[digit][0] += dp[digit+1][0];

				if(ch == 0){

					dp[digit][1] += dp[digit+1][1];

				}else{

					dp[digit][0] += dp[digit+1][1];
					dp[digit][0] %= MOD;
				}

			}else{

				dp[digit][0] += (dp[digit+1][0]*b)%MOD;
				dp[digit][0] %= MOD;

				dp[digit][0] += (dp[digit+1][1]*ch)%MOD;
				dp[digit][0] %= MOD;

				dp[digit][1] += dp[digit+1][1];

			}
			digit--;
		}

		ans += (dp[0][0]-1)+dp[0][1]; //-1はA == 0の分
		ans %= MOD;
	}

	printf("%lld\n",ans);

	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3224
final_rank: 11

code_snippet: #include <bits/stdc++.h>
//#include <atcoder/all>
//using namespace atcoder;
#pragma GCC target ("avx")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")

using namespace std;

typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef pair<int, int> pii;
typedef pair<long long, long long> PLL;
typedef pair<int, PII> TIII;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;


#define FOR(i, s, n) for (int i = s; i < (int)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define rep(i, a, b) for (int i = a; i < (b); ++i)
#define trav(a, x) for (auto &a : x)
#define all(x) x.begin(), x.end()

#define MOD 1000000007

template<class T1, class T2> inline bool chmax(T1 &a, T2 b) {if (a < b) {a = b; return true;} return false;}
template<class T1, class T2> inline bool chmin(T1 &a, T2 b) {if (a > b) {a = b; return true;} return false;}
const double EPS = 1e-6, PI = acos(-1);
const double pi = 3.141592653589793238462643383279;
//ここから編集    
typedef string::const_iterator State;
ll GCD(ll a, ll b){
  return (b==0)?a:GCD(b, a%b);
}
ll LCM(ll a, ll b){
  return a/GCD(a, b) * b;
}
template< int mod >
struct ModInt {
  int x;

  ModInt() : x(0) {}

  ModInt(int64_t y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}

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

  ModInt &operator-=(const ModInt &p) {
    if((x += mod - p.x) >= mod) 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 { 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 inverse() const {
    int a = x, b = mod, 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< mod >(t);
    return (is);
  }

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

using modint = ModInt< 998244353 >;
template< typename T >
struct Combination {
  vector< T > _fact, _rfact, _inv;

  Combination(int sz) : _fact(sz + 1), _rfact(sz + 1), _inv(sz + 1) {
    _fact[0] = _rfact[sz] = _inv[0] = 1;
    for(int i = 1; i <= sz; i++) _fact[i] = _fact[i - 1] * i;
    _rfact[sz] /= _fact[sz];
    for(int i = sz - 1; i >= 0; i--) _rfact[i] = _rfact[i + 1] * (i + 1);
    for(int i = 1; i <= sz; i++) _inv[i] = _rfact[i] * _fact[i - 1];
  }

  inline T fact(int k) const { return _fact[k]; }

  inline T rfact(int k) const { return _rfact[k]; }

  inline T inv(int k) const { return _inv[k]; }

  T P(int n, int r) const {
    if(r < 0 || n < r) return 0;
    return fact(n) * rfact(n - r);
  }

  T C(int p, int q) const {
    if(q < 0 || p < q) return 0;
    return fact(p) * rfact(q) * rfact(p - q);
  }

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

int modpow(ll x, ll n, int mod) {
  if(x == 0) return 0;
  
  ll res = 1;
  while(n) {
    if(n&1) res = res*x % mod;
    x = x*x%mod;
    n >>= 1;
  }
  return res;
}

modint dp[55][2];
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(7);
  
  ll a, B; cin >> a >> B;

  modint ans = 0;

  for(ll base=2; base<=B; base++) {

    vector<ll> b;
    ll tmp = a;
    while(tmp) {
      b.push_back(tmp%(base*base));
      tmp /= base*base;
    }

    reverse(all(b));
    REP(i,b.size()+1) REP(j,2) dp[i][j] = 0;
    dp[0][1] = 1;
    for(int i=0; i<b.size(); i++) {
      
      dp[i+1][0] += dp[i][0] * base;
      if(b[i] >= base) dp[i+1][0] += dp[i][1] * base;
      else{
        dp[i+1][0] += dp[i][1] * b[i];
        dp[i+1][1] += dp[i][1];
      }
    }
    ans += dp[b.size()][0] + dp[b.size()][1] - 1;
  }
  cout << ans << endl;
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3212
final_rank: 2

code_snippet: #define rep(i,n) for (int i=0;i < (int)(n);i++)
#define ALL(v) v.begin(),v.end()
typedef long long ll;

#include <bits/stdc++.h>
using namespace std;

const int MOD=998244353;

ll a,b;
ll f(ll x){
  vector<ll> A;
  ll c=a;
  while(c>0){
    A.push_back(c%x);
    c/=x;
  }
  reverse(ALL(A));
  int n=A.size();
  
  vector<vector<ll>> dp(n+1,vector<ll>(2));
  dp[0][0]=1;
  
  for(int i=0;i<n;i++){
    if((n-i)%2==1){
      dp[i+1][1]=(dp[i+1][1]+dp[i][1]*x%MOD)%MOD;
      dp[i+1][1]=(dp[i+1][1]+dp[i][0]*A[i]%MOD)%MOD;
      dp[i+1][0]=(dp[i+1][0]+dp[i][0])%MOD;
    }
    else{
      if(A[i]==0){
        dp[i+1][1]=(dp[i+1][1]+dp[i][1])%MOD;
        dp[i+1][0]=(dp[i+1][0]+dp[i][0])%MOD;
      }
      else{
        dp[i+1][1]=(dp[i+1][1]+dp[i][1])%MOD;
        dp[i+1][1]=(dp[i+1][1]+dp[i][0])%MOD;
        dp[i+1][0]=0;
      }
    }
  } 
  return (dp[n][0]+dp[n][1]-1)%MOD;
}

int main(){
  cin>>a>>b;
  
  ll ans=0;
  for(int i=2;i<=b;i++){
    ans=(ans+f(i))%MOD;
  }
  cout<<ans<<endl;
  
  return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3456
final_rank: 13

code_snippet: // #define _GLIBCXX_DEBUG // for STL debug (optional)
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <cfloat>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <fstream>
#include <functional>
#include <bitset>
using namespace std;
using ll = long long int;
using int64 = long long int;
 
template<typename T> void chmax(T &a, T b) {a = max(a, b);}
template<typename T> void chmin(T &a, T b) {a = min(a, b);}
template<typename T> void chadd(T &a, T b) {a = a + b;}
 
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
const int INF = 1LL << 29;
const ll LONGINF = 1LL << 60;
const ll MOD =  998244353LL;

// ModInt begin

using ll = long long;
template<ll mod>
struct ModInt {
    ll v;
    ll mod_pow(ll x, ll n) const {
        return (!n) ? 1 : (mod_pow((x*x)%mod,n/2) * ((n&1)?x:1)) % mod;
    }
    ModInt(ll a = 0) : v((a %= mod) < 0 ? a + mod : a) {}
    ModInt operator+ ( const ModInt& b ) const {
        return (v + b.v >= mod ? ModInt(v + b.v - mod) : ModInt(v + b.v));
    }
    ModInt operator- () const {
        return ModInt(-v);
    }
    ModInt operator- ( const ModInt& b ) const {
        return (v - b.v < 0 ? ModInt(v - b.v + mod) : ModInt(v - b.v));
    }
    ModInt operator* ( const ModInt& b ) const {return (v * b.v) % mod;}
    ModInt operator/ ( const ModInt& b ) const {return (v * mod_pow(b.v, mod-2)) % mod;}
    
    bool operator== ( const ModInt &b ) const {return v == b.v;}
    bool operator!= ( const ModInt &b ) const {return !(*this == b); }
    ModInt& operator+= ( const ModInt &b ) {
        v += b.v;
        if(v >= mod) v -= mod;
        return *this;
    }
    ModInt& operator-= ( const ModInt &b ) {
        v -= b.v;
        if(v < 0) v += mod;
        return *this;
    }
    ModInt& operator*= ( const ModInt &b ) {
        (v *= b.v) %= mod;
        return *this;
    }
    ModInt& operator/= ( const ModInt &b ) {
        (v *= mod_pow(b.v, mod-2)) %= mod;
        return *this;
    }
    ModInt pow(ll x) { return ModInt(mod_pow(v, x)); }
    // operator int() const { return int(v); }
    // operator long long int() const { return v; }
};

template<ll mod>
ModInt<mod> pow(ModInt<mod> n, ll k) {
    return ModInt<mod>(n.mod_pow(n.v, k));
}

template<ll mod>
ostream& operator<< (ostream& out, ModInt<mod> a) {return out << a.v;}
template<ll mod>
istream& operator>> (istream& in, ModInt<mod>& a) {
    in >> a.v;
    return in;
}

// ModInt end

using mint = ModInt<MOD>;
mint dp[80][2];

int main() {
    ll A, B_; cin >> A >> B_;

    mint ans(0);
    for(int B=2; B<=B_; B++) {
        vector<ll> P(1, 1);
        while(P.back() <= A / B) {
            ll x = P.back();
            P.emplace_back(x * B);
        }
        reverse(P.begin(), P.end());

        vector<ll> M(P.size());
        {
            ll R = A;
            for(size_t i=0; i<P.size(); i++) {
                M[i] = R / P[i];
                R -= M[i] * P[i];
            }
        }

        fill(dp[0], dp[P.size() + 1], mint(0));
        dp[0][0] = mint(1);
        for(size_t d=0; d<P.size(); d++) {
            for(int f=0; f<2; f++) {
                int truelim = f ? B-1 : M[d];
                int lim = truelim;
                if((P.size() - 1 - d) % 2 == 1) lim = 0;
                // [0, lim)
                dp[d+1][true] += dp[d][f] * mint(lim);
                // lim
                dp[d+1][f || lim < truelim] += dp[d][f];
            }
        }

        ans += dp[P.size()][0] + dp[P.size()][1];
        ans -= mint(1);
    }
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3168
final_rank: 10

code_snippet: //
// Created by yamunaku on 2020/12/14.
//

#include <bits/stdc++.h>
//#include <atcoder/all>

using namespace std;
//using namespace atcoder;

#define rep(i, n) for(int i = 0; i < (n); i++)
#define repl(i, l, r) for(int i = (l); i < (r); i++)
#define per(i, n) for(int i = ((n)-1); i >= 0; i--)
#define perl(i, l, r) for(int i = ((r)-1); i >= (l); i--)
#define all(x) (x).begin(),(x).end()
#define MOD 998244353
#define MOD1 1000000007
#define IINF 1000000000
#define LINF 1000000000000000000
#define SP <<" "<<
#define CYES cout<<"Yes"<<endl
#define CNO cout<<"No"<<endl
#define CFS cin.tie(0);ios::sync_with_stdio(false)
#define CST(x) cout<<fixed<<setprecision(x)

using ll = long long;
using ld = long double;
using vi = vector<int>;
using mti = vector<vector<int>>;
using vl = vector<ll>;
using mtl = vector<vector<ll>>;
using pi = pair<int, int>;
using pl = pair<ll, ll>;
template<typename T>
using heap = priority_queue<T, vector<T>, function<bool(const T, const T)>>;

ll modpow(ll x, ll a) {
    ll ans = 1;
    while (a) {
        if (a & 1) ans = ans * x % MOD;
        a >>= 1;
        x = x * x % MOD;
    }
    return ans;
}

ll inv(ll x) {
    return modpow(x, MOD - 2);
}

vector<ll> fact, invfact;

void buildFact(int n) {
    fact = vector<ll>(n + 1, 1);
    invfact = vector<ll>(n + 1, 1);
    for (int i = 1; i <= n; i++) {
        fact[i] = fact[i - 1] * i % MOD;
        invfact[i] = inv(fact[i]);
    }
}

ll comb(ll n, ll k) {
    return fact[n] * invfact[n - k] % MOD * invfact[k] % MOD;
}

int main() {
    //CFS;
    ll a, b;
    cin >> a >> b;
    ll ans = 0;
    repl(i, 2, b + 1) {
        ll ta = a;
        vi v;
        while (ta) {
            v.push_back(ta % i);
            ta /= i;
        }
        v.push_back(0);
        per(j, v.size() - 1) {
            if (j % 2) continue;
            if (v[j + 1] > 0) {
                ans += i * modpow(i, j / 2) % MOD;
                break;
            }
            ans += v[j] * modpow(i, j / 2) % MOD;
            if(j == 0) ans++;
        }
        ans = (ans + MOD - 1) % MOD;
//        cout << i SP ans << endl;
    }
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3164
final_rank: 1

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


#include <utility>

namespace atcoder {

namespace internal {

constexpr long long safe_mod(long long x, long long m) {
    x %= m;
    if (x < 0) x += m;
    return x;
}

struct barrett {
    unsigned int _m;
    unsigned long long im;

    barrett(unsigned int m) : _m(m), im((unsigned long long)(-1) / m + 1) {}

    unsigned int umod() const { return _m; }

    unsigned int mul(unsigned int a, unsigned int b) const {

        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;
    }
};

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;
}

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);

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};

    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


        auto tmp = s;
        s = t;
        t = tmp;
        tmp = m0;
        m0 = m1;
        m1 = tmp;
    }
    if (m0 < 0) m0 += b / s;
    return {s, m0};
}

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

using namespace std;
using namespace atcoder;
using mint = modint998244353;

int main() {
    long long a;
    int b;
    cin >> a >> b;
    mint ans = 0;
    for (int nb = 2; nb <= b; ++nb) {
        long long na = a;
        vector<int> f;
        while (na > 0) {
            f.push_back(na % nb);
            na /= nb;
        }
        int n = f.size();
        vector dp(n+1, vector<mint>(2));
        dp[n][0] = 1;
        for (int i = n-1; i >= 0; --i) {
            if (i % 2 == 0) {
                dp[i][0] += dp[i+1][0];
                dp[i][1] += f[i] * dp[i+1][0];
                dp[i][1] += nb * dp[i+1][1];
            } else {
                (f[i] > 0 ? dp[i][1] : dp[i][0]) += dp[i+1][0];
                dp[i][1] += dp[i+1][1];
            }
        }
        ans += dp[0][0] + dp[0][1] - 1;
    }
    cout << ans.val() << '\n';
}
accuracy: 1
time_ms: 10
memory_kb: 3456
final_rank: 5

code_snippet: #pragma GCC optimize("Ofast")
#pragma GCC target ("sse4")

#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>
using namespace std;

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

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 998244353;
const ll INF = mod * mod;
typedef pair<int, int>P;
#define stop char nyaa;cin>>nyaa;
#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;
typedef double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-12;
const ld pi = acosl(-1.0);

ll mod_pow(ll x, ll n, ll m = mod) {
    ll res = 1;
    while (n) {
        if (n & 1)res = res * x % m;
        x = x * x % m; n >>= 1;
    }
    return res;
}
struct modint {
    ll n;
    modint() :n(0) { ; }
    modint(ll m) :n(m) {
        if (n >= mod)n %= mod;
        else if (n < 0)n = (n % mod + mod) % mod;
    }
    operator int() { return 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 -= mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0)a.n += 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)); }

const int max_n = 1 << 20;
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];
}

void solve() {
    ll a, b; cin >> a >> b;
    modint ans = 0;
    for (ll i = 2; i <= b; i++) {
        vector<ll> bs;
        bs.push_back(1);
        
        ll t = i * i;
        while (true) {
            ll las = bs.back();
            if (a / las < t)break;
            if (las * t > a)break;
            bs.push_back(las * t);
        }
        ll cop = a;
        per(j, (int)bs.size()) {
            ll d = cop / bs[j];
            d = min(d, i - 1);
            ans += d * mod_pow(i, j);
            cop -= d * bs[j];
        }
        //ans += 1;
    }
    cout << ans << "\n";
}

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

code_snippet: #include <bits/stdc++.h>
using namespace std;
template <class T> inline bool chmax(T &a, T b) {
    if(a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <class T> inline bool chmin(T &a, T b) {
    if(a > b) {
        a = b;
        return 1;
    }
    return 0;
}
#define DEBUG
#ifdef DEBUG
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << '(' << p.first << ',' << p.second << ')';
    return os;
}
template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
    os << '{';
    for(int i = 0; i < (int)v.size(); i++) {
        if(i) { os << ','; }
        os << v[i];
    }
    os << '}';
    return os;
}
void debugg() { cerr << endl; }
template <class T, class... Args>
void debugg(const T &x, const Args &... args) {
    cerr << " " << x;
    debugg(args...);
}
#define debug(...)                                                             \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]: ", debugg(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif

struct Setup {
    Setup() {
        cin.tie(0);
        ios::sync_with_stdio(false);
        cout << fixed << setprecision(15);
    }
} __Setup;

using ll = long long;
#define ALL(v) (v).begin(), (v).end()
#define RALL(v) (v).rbegin(), (v).rend()
#define repl(i, a, b) for(int i = a; i < int(b); i++)
#define rep(i, n) repl(i, 0, n)
const int INF = 1 << 30;
const ll LLINF = 1LL << 60;
constexpr int MOD = 998244353;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};

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

template <int mod> struct ModInt {
    int x;
    ModInt() : x(0) {}
    ModInt(int64_t y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}
    ModInt &operator+=(const ModInt &p) {
        if((x += p.x) >= mod) x -= mod;
        return *this;
    }
    ModInt &operator-=(const ModInt &p) {
        if((x += mod - p.x) >= mod) 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 { 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; }
    ModInt inverse() const {
        int a = x, b = mod, 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<mod>(t);
        return (is);
    }
    static int get_mod() { return mod; }
};

using mint = ModInt<MOD>;

int main() {
    ll A, B;
    cin >> A >> B;

    mint ans = 0;
    repl(b, 2, B + 1) {
        vector<ll> base;
        {
            ll now = A;
            while(now) {
                base.push_back(now % b);
                now /= b;
            }
        }
        reverse(ALL(base));
        int sz = int(base.size());
        vector dp(sz + 1, vector<mint>(2, 0));
        dp[0][0] = 1;
        int isodd = 1 - sz % 2;
        rep(i, sz) {
            if(isodd) {
                if(base[i] == 0) {
                    dp[i + 1][0] += dp[i][0];
                } else {
                    dp[i + 1][1] += dp[i][0];
                }
                dp[i + 1][1] += dp[i][1];
            } else {
                dp[i + 1][1] += dp[i][0] * base[i];
                dp[i + 1][0] += dp[i][0];
                dp[i + 1][1] += dp[i][1] * b;
            }
            isodd = 1 - isodd;
        }
        ans += dp[sz][0] + dp[sz][1] - 1;
    }

    cout << ans << "\n";
}
accuracy: 1
time_ms: 10
memory_kb: 3464
final_rank: 7

code_snippet: /**
 *    author:  otera    
**/
#include<bits/stdc++.h>
using namespace std;

#define int long long
typedef long long ll;
typedef long double ld;
const int inf=1e9+7;
const ll INF=1LL<<60;
#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++)
typedef pair<int, int> P;
typedef pair<ll, ll> LP;
#define fr first
#define sc second
#define all(c) c.begin(),c.end()
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

// modint: mod 計算を int を扱うように扱える構造体
template<int MOD> struct Fp {
    long long val;
    constexpr Fp(long long v = 0) noexcept : val(v % MOD) {
        if (val < 0) val += MOD;
    }
    constexpr int getmod() { return MOD; }
    constexpr Fp operator - () const noexcept {
        return val ? MOD - val : 0;
    }
    constexpr Fp operator + (const Fp& r) const noexcept { return Fp(*this) += r; }
    constexpr Fp operator - (const Fp& r) const noexcept { return Fp(*this) -= r; }
    constexpr Fp operator * (const Fp& r) const noexcept { return Fp(*this) *= r; }
    constexpr Fp operator / (const Fp& r) const noexcept { return Fp(*this) /= r; }
    constexpr Fp& operator += (const Fp& r) noexcept {
        val += r.val;
        if (val >= MOD) val -= MOD;
        return *this;
    }
    constexpr Fp& operator -= (const Fp& r) noexcept {
        val -= r.val;
        if (val < 0) val += MOD;
        return *this;
    }
    constexpr Fp& operator *= (const Fp& r) noexcept {
        val = val * r.val % MOD;
        return *this;
    }
    constexpr Fp& operator /= (const Fp& r) noexcept {
        long long a = r.val, b = MOD, u = 1, v = 0;
        while (b) {
            long long t = a / b;
            a -= t * b; swap(a, b);
            u -= t * v; swap(u, v);
        }
        val = val * u % MOD;
        if (val < 0) val += MOD;
        return *this;
    }
    constexpr bool operator == (const Fp& r) const noexcept {
        return this->val == r.val;
    }
    constexpr bool operator != (const Fp& r) const noexcept {
        return this->val != r.val;
    }
    friend constexpr ostream& operator << (ostream &os, const Fp<MOD>& x) noexcept {
        return os << x.val;
    }
    friend constexpr istream& operator >> (istream &is, Fp<MOD>& x) noexcept {
        return is >> x.val;
    }
    friend constexpr Fp<MOD> modpow(const Fp<MOD> &a, long long n) noexcept {
        if (n == 0) return 1;
        auto t = modpow(a, n / 2);
        t = t * t;
        if (n & 1) t = t * a;
        return t;
    }
};

// 二項係数ライブラリ
template<class T> struct BiCoef {
    vector<T> fact_, inv_, finv_;
    constexpr BiCoef() {}
    constexpr BiCoef(int n) noexcept : fact_(n, 1), inv_(n, 1), finv_(n, 1) {
        init(n);
    }
    constexpr void init(int n) noexcept {
        fact_.assign(n, 1), inv_.assign(n, 1), finv_.assign(n, 1);
        int MOD = fact_[0].getmod();
        for(int i = 2; i < n; i++){
            fact_[i] = fact_[i-1] * i;
            inv_[i] = -inv_[MOD%i] * (MOD/i);
            finv_[i] = finv_[i-1] * inv_[i];
        }
    }
    constexpr T com(int n, int k) const noexcept {
        if (n < k || n < 0 || k < 0) return 0;
        return fact_[n] * finv_[k] * finv_[n-k];
    }
    constexpr T fact(int n) const noexcept {
        if (n < 0) return 0;
        return fact_[n];
    }
    constexpr T inv(int n) const noexcept {
        if (n < 0) return 0;
        return inv_[n];
    }
    constexpr T finv(int n) const noexcept {
        if (n < 0) return 0;
        return finv_[n];
    }
};

//const int MOD = 1000000007;
const int MOD = 998244353;
using mint = Fp<MOD>;
BiCoef<mint> bc;

void solve() {
    ll a, b; cin >> a >> b;
    mint ans = 0;
    map<pair<ll, int>, mint> memo;
    for(int y = 2; y <= b; ++ y) {
        memo.clear();
        auto rec = [&](auto &&self, ll x, int d) -> mint {
            if(x == 0) return 1;
            if(memo.count({x, d})) return memo[{x, d}];
            mint ret = 0;
            ll nx = x / y;
            ll now = x % y;
            if(d % 2 == 0) {
                ret += self(self, nx, d + 1) * (now + 1);
                if(nx > 0) ret += self(self, nx - 1, d + 1) * (y - now - 1);
            } else {
                ret += self(self, nx, d + 1);
            }
            return memo[{x, d}] = ret;
        };
        ans += rec(rec, a, 0) - 1;
    }
    cout << ans << "\n";
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(20);
	//int t; cin >> t; rep(i, t)solve();
	solve();
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3232
final_rank: 15

code_snippet: //#define _GLIBCXX_DEBUG
#include<bits/stdc++.h>
//#include<ctime>
//#include<algorithm>//next_permutation
#define rep(i,n) for (ll i = 0;i < (n);i++)
#define all(v) v.begin(),v.end()
#define dec(n) cout << fixed << setprecision(n);
#define large "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
#define small "abcdefghijklmnopqrstuvwxyz"
using namespace std;
using ll = long long;
using P = pair<ll,ll>;
using vl = vector<ll>;
using vvl = vector<vl>;
using vc = vector<char>;
using vvc = vector<vc>;

ll gcd(ll a,ll b){
  if(b == 0) return a;
  return gcd(b , a % b);
}

const ll MOD = 998244353;
const ll MAX = 2000001;
const ll inf = 1e18;

ll mod(ll a){
  return a % MOD;
}

ll lcm(ll a,ll b){
  return (a*b)/gcd(a,b);
}




int main(){
  ll a,b; cin >> a >> b; ll ans = 0;

  for(ll i=2; i <= b; i++){
    vector<ll> digit(62);

    ll ad = a; ll now = 0;
    while(ad > 0){
      digit[now] = (ad % i);
      ad /= i;
      ++now;
    }

    reverse(all(digit));

    /*for(auto x : digit){
      cout << x;
    }*/
    //cout << endl;

    vvl dp(62,vl(2,0LL));
    dp[0][0] = 1;

    for(ll j=0; j <= 60; j++){
      if(j % 2 == 0){
        if(digit[j+1] == 0){
          dp[j+1][0] += dp[j][0];
          dp[j+1][1] += dp[j][1]*i;
        }
        else{
          dp[j+1][1] += dp[j][1] * i;
          dp[j+1][1] += dp[j][0] * (digit[j+1]);
          dp[j+1][0] += dp[j][0];
        }

        dp[j+1][0] %= MOD;
        dp[j+1][1] %= MOD;
      }


      else if(j % 2 == 1){
        if(digit[j+1] != 0) dp[j+1][1] += dp[j][0];
        else dp[j+1][0] += dp[j][0];
        
        dp[j+1][1] += dp[j][1];

        dp[j+1][1] %= MOD;
        dp[j+1][0] %= MOD;

        //dp[j+1][0] = dp[j][0];
        //dp[j+1][1] = dp[j][1];
      }
    }

    /*cout << "i=" << i << endl;

    for(ll j=50; j < 60; j++){
      cout << "j=" << j << ' ' << dp[j][0] << ' ' << dp[j][1] << endl;
    }cout << endl;*/
    ans += dp[61][0] + dp[61][1] - 1;
    ans %= MOD;
  }

  cout << (ans % MOD) << endl;

}
accuracy: 1
time_ms: 180
memory_kb: 3448
final_rank: 17

code_snippet: //#define _GLIBCXX_DEBUG
#include<bits/stdc++.h>
//#include<ctime>
//#include<algorithm>//next_permutation
#define rep(i,n) for (ll i = 0;i < (n);i++)
#define all(v) v.begin(),v.end()
#define dec(n) cout << fixed << setprecision(n);
#define large "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
#define small "abcdefghijklmnopqrstuvwxyz"
using namespace std;
using ll = long long;
using P = pair<ll,ll>;
using vl = vector<ll>;
using vvl = vector<vl>;
using vc = vector<char>;
using vvc = vector<vc>;

ll gcd(ll a,ll b){
  if(b == 0) return a;
  return gcd(b , a % b);
}

const ll MOD = 998244353;
const ll MAX = 2000001;
const ll inf = 1e18;

ll mod(ll a){
  return a % MOD;
}

ll lcm(ll a,ll b){
  return (a*b)/gcd(a,b);
}




int main(){
  ll a,b; cin >> a >> b; ll ans = 0;

  for(ll i=2; i <= b; i++){
    vector<ll> digit(80);

    ll ad = a; ll now = 0;
    while(ad > 0){
      digit[now] = (ad % i);
      ad /= i;
      ++now;
    }

    reverse(all(digit));

    /*for(auto x : digit){
      cout << x;
    }*/
    //cout << endl;

    vvl dp(80,vl(2,0LL));
    dp[0][0] = 1;

    for(ll j=0; j <= 78; j++){
      if(j % 2 == 0){
        if(digit[j+1] == 0){
          dp[j+1][0] += dp[j][0];
          dp[j+1][1] += dp[j][1]*i;
        }
        else{
          dp[j+1][1] += dp[j][1] * i;
          dp[j+1][1] += dp[j][0] * (digit[j+1]);
          dp[j+1][0] += dp[j][0];
        }

        dp[j+1][0] %= MOD;
        dp[j+1][1] %= MOD;
      }


      else if(j % 2 == 1){
        if(digit[j+1] != 0) dp[j+1][1] += dp[j][0];
        else dp[j+1][0] += dp[j][0];
        
        dp[j+1][1] += dp[j][1];

        dp[j+1][1] %= MOD;
        dp[j+1][0] %= MOD;

        //dp[j+1][0] = dp[j][0];
        //dp[j+1][1] = dp[j][1];
      }
    }

    /*cout << "i=" << i << endl;

    for(ll j=50; j < 60; j++){
      cout << "j=" << j << ' ' << dp[j][0] << ' ' << dp[j][1] << endl;
    }cout << endl;*/
    ans += dp[79][0] + dp[79][1] - 1;
    ans %= MOD;
  }

  cout << (ans % MOD) << endl;

}
accuracy: 1
time_ms: 230
memory_kb: 3448
final_rank: 20

code_snippet: #include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <cmath>
#include <map>
#include <queue>
#include <iomanip>
#include <set>
#include <tuple>
#define mkp make_pair
#define mkt make_tuple
#define rep(i,n) for(int i = 0; i < (n); ++i)
#define all(v) v.begin(),v.end()
using namespace std;
typedef long long ll;
const ll MOD=998244353;
template<class T> void chmin(T &a,const T &b){if(a>b) a=b;}
template<class T> void chmax(T &a,const T &b){if(a<b) a=b;}

void add(ll &a,ll b){
  a=(a+b)%MOD;
}

void mul(ll &a,ll b){
  a%=MOD;b%=MOD;
  a=a*b%MOD;
}

vector<ll> convert(ll X,ll base){
  vector<ll> res;
  for(ll i=0;;i++){
    if(X==0) break;
    int num=X%base;
    res.push_back(num);
    X/=base;
  }
  return res;
}

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

  ll A,B;
  cin>>A>>B;

  ll ans=0;
  for(ll base=2;base<=B;base++){

    vector<ll> original=convert(A,base);
    reverse(all(original));
    
    int sz=original.size();
    vector<vector<ll>> dp(sz+1,vector<ll> (2,0));
    dp[0][0]=1;
    for(int i=0;i<sz;i++){
      for(int f=0;f<2;f++){
        if(dp[i][f]==0) continue;

        ll value=dp[i][f];
        if((sz-i)%2==0){// zero only
            int nf=f;
            if(original[i]) nf=1;
            add(dp[i+1][nf],value);
        }else{
            if(f==1) add(dp[i+1][1],value*base%MOD);
            else{
                add(dp[i+1][0],value);
                add(dp[i+1][1],value*(original[i])%MOD);
            }   
        }
      }
    }

    ll res=(dp[sz][0]+dp[sz][1]-1+MOD)%MOD;
    add(ans,res);
  }
  cout<<ans<<endl;


  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3220
final_rank: 14

code_snippet: #include <iostream>
#include <vector>
using namespace std;

vector<long long> translate(long long X,long long N) {
    vector<long long> res;
    while(1) {
        long long b = (X%abs(N)+abs(N)) % abs(N);
        res.push_back(b);
        (X -= b) /= N;
        if(X==0) break;
    }
    return res;
}
constexpr long long MOD = 998244353;
//実装すっきりしたver.
signed main() {
    long long A,B,ans = 0;
    cin >> A >> B;
    for(long long b = 2; b <= B; ++b) {
        auto v = translate(A,b);        
        long long dp1=1,dp2=0,tp1,tp2;
        for(int i = v.size()-1; 0 <= i; --i) {
            tp1=tp2=0;
            if(i&1) {
                tp1 += dp1*(!v[i]);
                tp2 += dp1*(!!v[i])+dp2;
            }
            else{
                tp1 += dp1;
                tp2 += dp1*(v[i])+dp2*b;
            }
            dp1=tp1%MOD,dp2=tp2%MOD;
        }
        ans += (dp1+dp2-1+MOD);
		ans %= MOD;
    }
    cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3160
final_rank: 9

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
ll mod = 998244353,dp[70][2];
ll solve(ll a,ll b){
    vector<ll> v;
    ll i,j;
    while(a){
        v.push_back(a%b);
        a /= b;
    }
    reverse(v.begin(),v.end());
    for(i=0;i<v.size();i++) dp[i][0] = 0,dp[i][1] = 0;
    if(v.size() & 1){
        dp[0][0] = v[0] - 1;
        dp[0][1]++;
    }
    for(i=1;i<v.size();i++){
        if((int)(v.size() - i) & 1){
            (dp[i][0] += b - 1) %= mod;
            (dp[i][0] += v[i]*(dp[i - 1][0] + dp[i - 1][1])%mod) %= mod;
            (dp[i][1] += dp[i - 1][1]) %= mod;
            (dp[i][0] += dp[i - 1][0]) %= mod;
            (dp[i][0] += (b - v[i] - 1)*dp[i - 1][0]%mod) %= mod;
        }else{
            if(v[i]==0){
                (dp[i][0] += dp[i - 1][0]) %= mod;
                (dp[i][1] += dp[i - 1][1]) %= mod;
            }else{
                (dp[i][0] += (dp[i - 1][0] + dp[i - 1][1])%mod) %= mod;
            }
        }
    }
    return (dp[v.size() - 1][0] + dp[v.size() - 1][1])%mod;
}

int solve2(ll a,ll b){
    ll i;
    int cnt = 0;
    for(i=1;i<=a;i++){
        int j = i;
        vector<int> v;
        while(j){
            v.push_back(j%b);
            j /= b;
        }
        bool f = true;
        for(j=0;j<v.size();j++){
            if((j&1) && v[j]>0) f = false; 
        }
        if(f) cnt++;
    }
    return cnt;
}
int main(){
    ll i,a,b,ans = 0;
    cin >> a >> b;
    for(i=2;i<=b;i++) (ans += solve(a,i)) %= mod;
    cout << ans << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 3448
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;

template <int mod = (int)(998244353)>
struct ModInt {
  int x;
  constexpr ModInt() : x(0) {}
  constexpr ModInt(int64_t y)
      : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}
  constexpr ModInt &operator+=(const ModInt &p) noexcept {
    if ((x += p.x) >= mod) x -= mod;
    return *this;
  }
  constexpr ModInt &operator-=(const ModInt &p) noexcept {
    if ((x += mod - p.x) >= mod) x -= mod;
    return *this;
  }
  constexpr ModInt &operator*=(const ModInt &p) noexcept {
    x = (int)(1LL * x * p.x % mod);
    return *this;
  }
  constexpr ModInt &operator/=(const ModInt &p) noexcept {
    *this *= p.inverse();
    return *this;
  }
  constexpr ModInt operator-() const { return ModInt(-x); }
  constexpr ModInt operator+(const ModInt &p) const noexcept {
    return ModInt(*this) += p;
  }
  constexpr ModInt operator-(const ModInt &p) const noexcept {
    return ModInt(*this) -= p;
  }
  constexpr ModInt operator*(const ModInt &p) const noexcept {
    return ModInt(*this) *= p;
  }
  constexpr ModInt operator/(const ModInt &p) const noexcept {
    return ModInt(*this) /= p;
  }
  constexpr bool operator==(const ModInt &p) const noexcept { return x == p.x; }
  constexpr bool operator!=(const ModInt &p) const noexcept { return x != p.x; }
  constexpr ModInt inverse() const noexcept {
    int a = x, b = mod, u = 1, v = 0, t = 0;
    while (b > 0) {
      t = a / b;
      swap(a -= t * b, b);
      swap(u -= t * v, v);
    }
    return ModInt(u);
  }
  constexpr ModInt pow(int64_t n) const {
    ModInt res(1), mul(x);
    while (n) {
      if (n & 1) res *= mul;
      mul *= mul;
      n >>= 1;
    }
    return res;
  }
  friend constexpr ostream &operator<<(ostream &os, const ModInt &p) noexcept {
    return os << p.x;
  }
  friend constexpr istream &operator>>(istream &is, ModInt &a) noexcept {
    int64_t t = 0;
    is >> t;
    a = ModInt<mod>(t);
    return (is);
  }
  constexpr int get_mod() { return mod; }
};
using mint = ModInt<>;

long long a, b;

mint solve();

int main() {
  cin >> a >> b;
  cout << solve() << endl;
  return 0;
}

mint solve() {
  mint res = 0;
  for (long long i = 2; i <= b; ++i) {
    long long doub = i * i, sum = 0, now = 1, rem = a, cnt = 0, last = 0;
    vector<long long> v[2];
    while (rem) {
      v[cnt & 1].push_back(rem % i);
      if ((cnt & 1) && rem % i) last = (cnt + 1) / 2;
      rem /= i;
      ++cnt;
    }
    for (int j = 0; j < last; ++j) v[0][j] = i - 1;
    reverse(v[0].begin(), v[0].end());
    for (auto p : v[0]) sum = sum * i + p;
    res += sum;
  }
  return res;
}
accuracy: 1
time_ms: 10
memory_kb: 3448
final_rank: 3

code_snippet: #include <bits/stdc++.h>
#pragma GCC target("avx")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
using namespace std;
#define ll long long
#define INF 9999999999999999
#define rep(i, m, n) for (int i = m; i < n; i++)
#define rrep(i, m, n) for (int i = m - 1; i >= n; i--)
#define pb(n) push_back(n)
#define UE(N) N.erase(unique(N.begin(), N.end()), N.end());
#define Sort(n) sort(n.begin(), n.end())
#define Rev(n) reverse(n.begin(), n.end())
#define Out(S) cout << S << endl
#define NeOut(S) cout << S
#define HpOut(S) cout << setprecision(50) << S << endl
#define Vec(K, L, N, S) vector<L> K(N, S)
#define DV(K, L, N, M, S) vector<vector<L>> K(N, vector<L>(M, S))
#define TV(K, L, N, M, R, S) \
    vector<vector<vector<L>>> K(N, vector<vector<L>>(M, vector<L>(R, S)))
#define pint pair<ll, ll>
#define tint tuple<int, int, int>
#define paf(L, R) pair<L, R>
#define mod 998244353
#define MAX 10000010
#define ALL(a) a.begin(), a.end()
#define chmax(a, b) a = (((a) < (b)) ? (b) : (a))
#define chmin(a, b) a = (((a) > (b)) ? (b) : (a))

long long modpow(long long a, long long n, long long m) {
    long long res = 1;
    while (n > 0) {
        if (n & 1) res = res * a % m;
        a = a * a % m;
        n >>= 1;
    }
    return res;
}

ll solve(ll A, ll B) {
    //A以下で，B進数表記において奇数桁が全て0であるような整数の個数
    vector<ll> C;
    while(A > 0) {
        C.pb(A % B);
        A /= B;
    }
    Rev(C);
    ll n = C.size();
    vector<vector<ll>> dp(n, vector<ll>(2, 0));
    if(n & 1) {
        dp[0][0] = 1;
        dp[0][1] = C[0];
    }
    else dp[1][1] = B;
    rep(i, 0, n - 2) {
        if(C[i + 1]) {
            dp[i + 2][1] = (dp[i][1] + dp[i][0]) * B % mod;
        }
        else{
            dp[i + 2][0] = dp[i][0];
            dp[i + 2][1] = (dp[i][1] * B) % mod + (dp[i][0] * C[i + 2]) % mod;
        }
    }
    return (dp[n - 1][0] + dp[n - 1][1] - 1 + mod) % mod;
}
ll solve2(ll A, ll B) {
    ll res = 0;
    rep(i, 1, A + 1) {
        vector<ll> C, D;
        ll x = i, y = i;
        while(y != 0) {
            C.pb(y % B);
            y /= B;
        }
        while(x != 0) {
            ll a = (x % B + B) % B;
            D.pb(a);
            x -= a;
            x /= -B;
        }
        if(C.size() == D.size()) {
            ll n = C.size(), f = 1;
            rep(i, 0, n) if(C[i] != D[i]) f = 0;
            if(f) res++;
        }
    }
    return res;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    ll A, B;
    cin >> A >> B;
    ll res = 0, tem = 0;
    rep(i, 2, B + 1) {
        res += solve(A, i);
        //tem += solve2(A, i);
    }
    cout << res % mod << endl;  
}
accuracy: 1
time_ms: 10
memory_kb: 3472
final_rank: 8

code_snippet: #include <iostream>
#include <vector>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <cstdio>
#include <bitset>
#include <queue>
#include <deque>
#include <algorithm>
#include <numeric>
#include <cassert>
#include <functional>
#include <stack>
#include <cmath>
#include <string>
#include <complex>
#include <cassert>
#define REP(i, N) for (int i = 0; i < (int)N; i++)
#define FOR(i, a, b) for (int i = a; i < (int)b; i++)
#define ALL(x) (x).begin(), (x).end()

using namespace std;

constexpr int inf = 1 << 30;
constexpr long long llinf = 1LL << 62;
constexpr int mod = 998244353;
constexpr int dy[4] = {-1, 0, 1, 0}, dx[4] = {0, -1, 0, 1};

using ll = long long;
using Pii = pair<int, int>;
using Pll = pair<ll, ll>;

inline int popcount(ll x) { return __builtin_popcountll(x); }
inline int div2num(ll x) { return __builtin_ctzll(x); }
inline bool bit(ll x, int b) { return (x >> b) & 1; }

template <class T>
bool chmax(T& a, const T& b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
bool chmin(T& a, const T& b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}

template <class T>
string to_string(T s);
template <class S, class T>
string to_string(pair<S, T> p);
string to_string(char c) { return string(1, c); }
string to_string(string s) { return s; }
string to_string(const char s[]) { return string(s); }

template <class T>
string to_string(T v) {
  if (v.empty()) return "{}";
  string ret = "{";
  for (auto x : v) ret += to_string(x) + ",";
  ret.back() = '}';
  return ret;
}

template <class S, class T>
string to_string(pair<S, T> p) {
  return "{" + to_string(p.first) + ":" + to_string(p.second) + "}";
}
void debug() { cerr << endl; }

template <class Head, class... Tail>
void debug(Head head, Tail... tail) {
  cerr << to_string(head) << " ";
  debug(tail...);
}

template <class T>
vector<T> makev(int n, T v) {
  return vector<T>(n, v);
}

template <int mod>
struct ModInt {
  int x;
  ModInt() : x(0) {}
  ModInt(int64_t y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}
  ModInt& operator+=(const ModInt& p) {
    if ((x += p.x) >= mod) x -= mod;
    return *this;
  }
  ModInt& operator-=(const ModInt& p) {
    if ((x += mod - p.x) >= mod) 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 { 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; }
  ModInt inverse() const {
    int a = x, b = mod, 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<mod>(t);
    return (is);
  }
  static int get_mod() { return mod; }
};

using modint = ModInt<mod>;

int main() {
  ll A, B;
  cin >> A >> B;
  modint ans = 0;
  for (ll b = 2; b <= B; ++b) {
    vector<ll> arr;
    ll t = A;
    while (t > 0) {
      arr.push_back(t % b);
      t /= b;
    }
    int m = arr.size();
    vector<array<modint, 2>> dp(m);
    if (m % 2 == 1) {
      dp[m - 1][1] = 1;
      dp[m - 1][0] = arr[m - 1];
    } else {
      m--;
      dp[m - 1][0] = b;
    }
    for (int j = m - 3; j >= 0; j -= 2) {
      if (arr[j + 1] == 0) {
        dp[j][1] = dp[j + 2][1];
        dp[j][0] = dp[j + 2][1] * arr[j] + dp[j + 2][0] * b;
      } else {
        dp[j][0] = dp[j + 2][1] * b + dp[j + 2][0] * b;
      }
    }
    ans += dp[0][1] + dp[0][0] - 1;
  }
  cout << ans << endl;
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3452
final_rank: 4

code_snippet: #include<bits/stdc++.h> 
using namespace std;
typedef long long ll;
#define all(x) (x).begin(),(x).end()
template<typename T1,typename T2> bool chmin(T1 &a,T2 b){if(a<=b)return 0; a=b; return 1;}
template<typename T1,typename T2> bool chmax(T1 &a,T2 b){if(a>=b)return 0; a=b; return 1;}
int dx[4]={0,1,0,-1}, dy[4]={1,0,-1,0};
long double eps = 1e-9;
long double pi = acos(-1);

template< int mod = 1000000007 >
struct ModInt {
    int x;
    ModInt() : x(0) {}
    ModInt(int64_t y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}
    ModInt &operator+=(const ModInt &p) {
        if((x += p.x) >= mod) x -= mod;
        return *this;
    }
    ModInt &operator-=(const ModInt &p) {
        if((x += mod - p.x) >= mod) 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 { 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 inverse() const {
        int a = x, b = mod, 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< mod >(t);
        return (is);
    }

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

// const int mod = 1000000007;
const int mod = 998244353;
using mint = ModInt< mod >;
const int MAX = 5100005;

mint fac[MAX], finv[MAX], inv[MAX];

// テーブルを作る前処理
void COMinit() {
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for (int i = 2; i < MAX; i++){
        fac[i] = fac[i - 1] * i;
    }
    finv[MAX-1] = fac[MAX-1].inverse();
    for(int i=MAX-2;i>=1;i--){
        finv[i] = finv[i+1]*(i+1);
        inv[i+1] = fac[i]*finv[i+1];
    }
}

// 二項係数計算
mint COM(int n, int k){
    if (n < k) return 0;
    if (n < 0 || k < 0) return 0;
    return fac[n] * (finv[k] * finv[n - k]);
}

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout << fixed << setprecision(20);

    ll a,b;
    cin>>a>>b;
    mint ans = 0;
    for(int r=2;r<=b;r++){
        int cnt = 0;
        ll tmp = a;
        vector<int> v;
        while(tmp){
            v.push_back(tmp % r);
            tmp /= r;
            cnt++;
        }
        mint dp[cnt+1][2];
        dp[cnt][0] = 1;
        dp[cnt][1] = 0;
        for(int i=cnt-1;i>=0;i--){
            if(i & 1){
                if(v[i] == 0){
                    dp[i][0] = dp[i+1][0];
                    dp[i][1] = dp[i+1][1];
                }
                else{
                    dp[i][0] = 0;
                    dp[i][1] += dp[i+1][1] + dp[i+1][0];
                }
            }
            else{
                dp[i][0] = dp[i+1][0];
                dp[i][1] += dp[i+1][1] * r;
                dp[i][1] += dp[i+1][0] * v[i]; 
            }
            // cerr << i << " " << dp[i][0]  << " " << dp[i][1] << endl;
        }
        ans += dp[0][0] + dp[0][1] - 1;
    }
    cout << ans << endl;

}
accuracy: 1
time_ms: 10
memory_kb: 63228
final_rank: 19