// #include <bits/stdc++.h>
// #define f first
// #define s second
// using namespace std;
// typedef long long ll;
// typedef pair<ll, ll> pii;
// const ll mod = 998244353;
// // cope counter = 2254
// signed main() {
// ios::sync_with_stdio(0);
// cin.tie(0);
// }
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <cstring>
#include <algorithm>
#include <chrono>
#include <iomanip>
#include <iostream>
#include <queue>
#include <set>
#include <unordered_set>
#include <sstream>
#include <string>
#include <map>
#include <unordered_map>
#include <vector>
#include <functional>
#include <numeric>
#define int long long
#define FOR(a,b) for(int a = 0; a < b; a++)
#define All(vec) vec.begin(),vec.end()
using std::string;
using std::vector;
using std::pair;
using std::cin;
using std::cout;
const int oo = 3074457345618258602LL;
std::stringstream out;
template<class T> bool ckmax(T& a, const T& b) {
return a < b ? a = b, 1 : 0;
}
template<class T> bool ckmin(T& a, const T& b) {
return a > b ? a = b, 1 : 0;
}
template<int D, typename T>
struct Vec : public vector<Vec<D - 1, T>> {
static_assert(D >= 1, "Vector dimension must be greater than zero!");
template<typename U, typename... Args>
Vec(U n = U(), Args... args) : vector<Vec<D - 1, T>>(n, Vec<D - 1, T>(args...)) {
}
template<typename... Args>
Vec(int n = 0, Args... args) : vector<Vec<D - 1, T>>(n, Vec<D - 1, T>(args...)) {
}
};
template<typename T>
struct Vec<1, T> : public vector<T> {
template<typename... Args>
Vec(Args... args) : vector<T>(args...) {
}
Vec(int n = 0, const T& val = T()) : vector<T>(n, val) {
}
};
const bool kReadTestCases = 0;
const bool kLocalRun = 0;
const bool kBruteSolve = 0;
struct Fraction {
int num, denom;
};
struct Solution {
void ReadInput() {
}
void Solve(std::stringstream& out) {
int N, M;
cin >> N >> M;
int bound = std::max(N, M) + 1;
int ans = 0;
std::function<void(int, int, bool)> DFS = [&](int n, int d) {
if(std::max(n, d) > bound) return;
if(n <= N && d <= M) ans++;
if(n <= M && d <= N) ans++;
DFS(n + 2 * d, d);
DFS(n, d + 2 * n);
//DFS(n - 2 * d, d, 0);
};
DFS(1, 2);
out << ans << "\n";
//int x = 1000;
//for (int i = 1; i <= x; i++) {
// int gcd = std::gcd(i, x);
// int N, M;
// cin >> N >> M;
// if (gcd == 1) {
// cout << i << "\n";
// }
//}
//int bound = std::max(N, M) + 1;
//Vec<2, int> dp(bound, bound, -1);
//std::function<int(int, int)> Solve = [&](int n, int d) {
// int& ans = dp[n][d];
// if (n == 0) {
// ans = 1;
// } else if (n * 2 > d && n < 2 * d) {
// ans = 0;
// } else if (ans == -1) {
// if (n > d) {
// ans = Solve(n - 2 * d, d);
// } else {
// ans = Solve(d, n);
// }
// }
// return ans;
// };
//int ans = 0;
//for (int i = 1; i <= N; i++) {
// for (int j = 1; j <= M; j++) {
// if (std::gcd(i, j) == 1) {
// ans += Solve(i, j);
// }
// }
//}
//out << ans << "\n";
}
void SolveBrute(std::stringstream& out) {
}
void GenInput() {
}
void PrintInput() {
}
inline vector<int> ReadVec(int N) {
vector<int> vec(N);
FOR(i, N) {
cin >> vec[i];
}
return vec;
}
inline string Stringify(vector<int>& arr) {
std::stringstream ss;
FOR(i, arr.size()) {
ss << arr[i] << " \n"[i == arr.size() - 1];
}
return ss.str();
}
};
void RunLocal() {
srand(time(NULL));
int iter = 0;
while (true) {
if (++iter % 1000 == 0) {
std::cout << iter << "\n";
}
Solution solution;
solution.GenInput();
std::stringstream ss1;
std::stringstream ss2;
solution.Solve(ss1);
solution.SolveBrute(ss2);
string ans = ss1.str();
string ans_correct = ss2.str();
if (ans != ans_correct) {
solution.PrintInput();
cout << "\n\n";
cout << "Wrong answer:\n";
cout << "---------------------------------------------------------\n";
cout << ans << "\n";
cout << "Correct answer:\n";
cout << "---------------------------------------------------------\n";
cout << ans_correct << "\n";
break;
}
}
}
int32_t main() {
std::ios_base::sync_with_stdio(0);
std::cin.tie(0);
std::cout.tie(0);
if (kLocalRun) {
RunLocal();
return 0;
}
int tc = 1;
if (kReadTestCases)std::cin >> tc;
for (int _ = 1; _ <= tc; _++) {
Solution solution;
solution.ReadInput();
if (kBruteSolve) {
solution.SolveBrute(out);
} else {
solution.Solve(out);
}
}
std::cout << out.str();
std::cout.flush();
return 0;
}