#include <iostream>
       
#include <algorithm>
#include <list>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <random>
#include <chrono>
      
#include <cstdio>
#include <cstring>
#include <cmath>
#include <ctime>
#include <cstdlib>
#include <cassert>
 
#define manx maxn
#define whlie while
#define itn int
#define fro for
#define asn ans
#define scnaf scanf
#define sacnf scanf
#define pritnf printf
#define haed head
#define tmep temp
#define udpate update
#define cosnt const
 
#define Fastin freopen("/home/rqdmap/Desktop/codes/in", "r", stdin)
#define Fastout freopen("/home/rqdmap/Desktop/codes/main.out", "w", stdout)
#define lowbit(x) ((x) & (-x))
#define clr(a, x) memset((a), x, sizeof (a))
#define TTT int __; scanf("%d", &__); for(int _ = 1; _ <= __; _++)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
 
/*------------------------------------------------------------------------------------*/
template<typename T>
void prt(T *a, int n, bool withid = 0){
    if(!withid) for(int i = 0; i < n; i++) cout << a[i] << ((i == n - 1)? '\n':' ');
    else for(int i = 0; i < n; i++) cout << i << ": " << a[i] << '\n';
}
 
template<typename T>
T ceil(T a, T b){return (a + b - 1) / b;}
template<typename T>
T gcd(T x, T y){return !x? y: gcd(y % x, x);}
template<typename T>
void exgcd(T a, T b, T &x, T &y){
    if(!b){x = 1; y = 0;return;}
    exgcd(b, a % b, y, x); y -= a / b * x;
}
ll qp(ll a, ll p){
    if(p < 0) return 0;
    ll ans = 1; while(p){if(p & 1) ans = ans * a ; a = a * a; p >>= 1;}
    return ans;
}
ll qp(ll a, ll p, ll M){
    ll ans = 1; while(p){ if(p & 1) ans = ans * a % M; a = a * a % M; p >>= 1;}
    return (ans % M + M) % M;
}
int euler(int *prime, int *vis, int n){
    int top = 0;
    for(int i = 0; i <= n; i++) vis[i] = 0;
    for(int i = 2; i <= n; i++){
        if(!vis[i]) prime[top++] = i;
        for(int j = 0; j < top && i * prime[j] <= n; j++){
            vis[i * prime[j]] = 1;
            if(i % prime[j] == 0) break;
        }
    }
    return top;
}
struct star{int to, next, w;}; 
/*------------------------------------------------------------------------------------*/

const int maxn = 5e3 + 10;
const int M = 998244353;

ll C(int n, int m){
    m = min(m, n - m);
    ll ans = 1;
    for(int i = 1; i <= m; i++){
        ans = ans * qp(i, M - 2, M) % M;
        ans = ans * (n + 1 - i) % M;
    }
    return ans;
}

ll dp[maxn];
ll c[maxn];

int main(){
    // Fastin;
    int n, m; scnaf("%d %d", &n, &m);
    for(int i = 0; i <= n; i++) c[i] = C(n, i);
    dp[0] = 1;
    for(int i = 1; i <= m; i++){
        if(i & 1) dp[i] = 0;
        else{
            for(int j = 0; j + j <= i && j + j <= n; j++){
                dp[i] += c[2 * j] * dp[i / 2 - j] % M;
                dp[i] %= M;
            }
        }
    }
    // prt(dp, m + 1, 1);
    printf("%lld\n", dp[m]);
    return 0;
}
#line 1 "main.cpp"

/**
 * @title Template
 */

#include <iostream>
#include <algorithm>
#include <utility>
#include <numeric>
#include <vector>
#include <array>
#include <cassert>

#line 2 "/Users/kodamankod/Desktop/cpp_programming/Library/other/range.cpp"

#line 4 "/Users/kodamankod/Desktop/cpp_programming/Library/other/range.cpp"

class range {
  struct iter {
    std::size_t itr;
    constexpr iter(std::size_t pos) noexcept: itr(pos) { }
    constexpr void operator ++ () noexcept { ++itr; }
    constexpr bool operator != (iter other) const noexcept { return itr != other.itr; }
    constexpr std::size_t operator * () const noexcept { return itr; }
  };

  struct reviter {
    std::size_t itr;
    constexpr reviter(std::size_t pos) noexcept: itr(pos) { }
    constexpr void operator ++ () noexcept { --itr; }
    constexpr bool operator != (reviter other) const noexcept { return itr != other.itr; }
    constexpr std::size_t operator * () const noexcept { return itr; }
  };

  const iter first, last;

public:
  constexpr range(std::size_t first, std::size_t last) noexcept: first(first), last(std::max(first, last)) { }
  constexpr iter begin() const noexcept { return first; }
  constexpr iter end() const noexcept { return last; }
  constexpr reviter rbegin() const noexcept { return reviter(*last - 1); } 
  constexpr reviter rend() const noexcept { return reviter(*first - 1); } 
};

/**
 * @title Range
 */
#line 2 "/Users/kodamankod/Desktop/cpp_programming/Library/algebraic/fact_prime.cpp"

#include <cstddef>
#line 7 "/Users/kodamankod/Desktop/cpp_programming/Library/algebraic/fact_prime.cpp"
#include <iterator>
#line 9 "/Users/kodamankod/Desktop/cpp_programming/Library/algebraic/fact_prime.cpp"
#include <type_traits>

template <class T, std::enable_if_t<std::is_integral<T>::value>* = nullptr>
std::vector<std::pair<T, size_t>> factorize(T x) {
  assert(x > 0);
  if (x == 1) return { };
  std::vector<std::pair<T, size_t>> res;
  for (T i = 2; i * i <= x; ++i) {
    if (x % i == 0) {
      res.emplace_back(i, 0);
      while (x % i == 0) {
        res.back().second++;
        x /= i;
      }
    }
  }
  if (x > 1) {
    res.emplace_back(x, 1);
  }
  return res;
}

template <class T, std::enable_if_t<std::is_integral<T>::value>* = nullptr>
std::vector<T> divisors(const T x) {
  std::vector<T> small, big;
  for (T i = 1; i * i <= x; ++i) {
    if (x % i == 0) {
      small.push_back(i);
      if (i * i != x) {
        big.push_back(x / i);
      }
    }
  }
  small.reserve(small.size() + big.size());
  std::copy(big.rbegin(), big.rend(), std::back_inserter(small));
  return small;
}

/**
 * @title Factors/Divisors
 */
#line 16 "main.cpp"

using i32 = std::int32_t;
using i64 = std::int64_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;
using isize = std::ptrdiff_t;
using usize = std::size_t;

constexpr i32 inf32 = (u32) ~0 >> 2;
constexpr i64 inf64 = (u64) ~0 >> 2;

template <class T>
using Vec = std::vector<T>;

int main() {
  u64 D;
  std::cin >> D;
  u64 ans = 0;
  for (const auto x: divisors(2 * D)) {
    if (x & 1) {
      ans += 2;
    }
  }
  std::cout << ans << '\n';
  return 0;
}
