#include <bits/stdc++.h>
#define MP make_pair
#define PB push_back
#define int long long
#define st first
#define nd second
#define rd third
#define FOR(i, a, b) for(int i =(a); i <=(b); ++i)
#define RE(i, n) FOR(i, 1, n)
#define FORD(i, a, b) for(int i = (a); i >= (b); --i)
#define REP(i, n) for(int i = 0;i <(n); ++i)
#define VAR(v, i) __typeof(i) v=(i)
#define FORE(i, c) for(VAR(i, (c).begin()); i != (c).end(); ++i)
#define ALL(x) (x).begin(), (x).end()
#define SZ(x) ((int)(x).size())
#define __builtin_ctz __builtin_ctzll
#define __builtin_clz __builtin_clzll
#define __builtin_popcount __builtin_popcountll
using namespace std;
template<typename TH> void _dbg(const char* sdbg, TH h) { cerr<<sdbg<<"="<<h<<"\n"; }
template<typename TH, typename... TA> void _dbg(const char* sdbg, TH h, TA... t) {
  while(*sdbg != ',') { cerr<<*sdbg++; } cerr<<"="<<h<<","; _dbg(sdbg+1, t...);
}
#ifdef LOCAL
#define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#define debugv(x) {{cerr <<#x <<" = "; FORE(itt, (x)) cerr <<*itt <<", "; cerr <<"\n"; }}
#else
#define debug(...) (__VA_ARGS__)
#define debugv(x)
#define cerr if(0)cout
#endif
#define next ____next
#define prev ____prev
#define left ____left
#define hash ____hash
typedef long long ll;
typedef long double LD;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<ll> VLL;
typedef vector<pair<int, int> > VPII;
typedef vector<pair<ll, ll> > VPLL;

template<class C> void mini(C&a4, C b4){a4=min(a4, b4); }
template<class C> void maxi(C&a4, C b4){a4=max(a4, b4); }
template<class T1, class T2>
ostream& operator<< (ostream &out, pair<T1, T2> pair) { return out << "(" << pair.first << ", " << pair.second << ")";}
template<class A, class B, class C> struct Triple { A first; B second; C third;
  bool operator<(const Triple& t) const { if (st != t.st) return st < t.st; if (nd != t.nd) return nd < t.nd; return rd < t.rd; } };
template<class T> void ResizeVec(T&, vector<int>) {}
template<class T> void ResizeVec(vector<T>& vec, vector<int> sz) {
  vec.resize(sz[0]); sz.erase(sz.begin()); if (sz.empty()) { return; }
  for (T& v : vec) { ResizeVec(v, sz); }
}
typedef Triple<int, int, int> TIII;
template<class A, class B, class C>
ostream& operator<< (ostream &out, Triple<A, B, C> t) { return out << "(" << t.st << ", " << t.nd << ", " << t.rd << ")"; }
template<class T> ostream& operator<<(ostream& out, vector<T> vec) { out<<"("; for (auto& v: vec) out<<v<<", "; return out<<")"; }
template<class T> ostream& operator<<(ostream& out, set<T> vec) { out<<"("; for (auto& v: vec) out<<v<<", "; return out<<")"; }
template<class L, class R> ostream& operator<<(ostream& out, map<L, R> vec) { out<<"("; for (auto& v: vec) out<<v<<", "; return out<<")"; }

const int PP = 1e9 + 33;
typedef __int128_t T;
int32_t main() {

  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(10);
  cerr << fixed << setprecision(10);
  cin.tie(0);
  //double beg_clock = 1.0 * clock() / CLOCKS_PER_SEC;
  
  int r, b;
  cin>>r>>b;
  int Kl = 1, Kr = 1e9, Kfaj = 1;
  while (Kl <= Kr) {
    int Kakt = (Kl + Kr) / 2;
    int Pl = 1, Pr = PP - 1;
    int Kok = 0, Kfail = 0;
    int smX = -1, smY = -1, bigX = -1, bigY = -1;
    while (Pl <= Pr) {
      T Pakt = (Pl + Pr) / 2;
      T Qakt = PP - Pakt; //pX + qY minimalne
      T Zl = 0, Zr = 1e18;
      int Xfaj, Yfaj;
      while (Zl <= Zr) {
        T Zakt = (Zl + Zr) / 2;
        int cnt_taken = 0;
        T Xhere = 0, Yhere = 0;
        int sw = 0;
        if (Pakt < Qakt) {
          sw = 1;
          swap(Pakt, Qakt);
        }
        REP (x, 2000) {
          T rem = Zakt - x * Pakt;
          if (rem < 0) { break; }
          T maxY = rem / Qakt;
          cnt_taken += maxY + 1;
          Xhere += x * (maxY + 1);
          Yhere += maxY * (maxY + 1) / 2;
        }
        if (sw) {
          swap(Xhere, Yhere);
          swap(Pakt, Qakt);
        }
        if (cnt_taken == Kakt) {
          Xfaj = Xhere;
          Yfaj = Yhere;
          break;
        }
        if (cnt_taken < Kakt) {
          Zl = Zakt + 1;
        } else {
          Zr = Zakt - 1;
        }
      }
      if (r >= Xfaj && b >= Yfaj) {
        debug((int)Pakt, (int)Qakt, (int)Xfaj, (int)Yfaj);
        Kok = 1;
        break;
      }
      if (r <= Xfaj && b <= Yfaj) {
        Kfail = 1;
        break;
      }
      if (r >= Xfaj) { // trzeba bardziej brac x, tzn zmniejszyc p
        Pr = Pakt - 1;
        smX = Xfaj;
        smY = Yfaj;
      } else {
        Pl = Pakt + 1;
        bigX = Xfaj;
        bigY = Yfaj;
      }
    }
    if (!Kfail && !Kok) {
      debug(smX, smY, bigX, bigY, Pl, Pr, Kakt);
      assert(smX != -1 && smY != -1 && bigX != -1 && bigY != -1);
      //smX < bigX
      //smY > bigY
      int atR = bigY + (T(smY - bigY) * (bigX - r) + bigX - smX - 1) / (bigX - smX);
      Kok = (b >= atR);
    }
    if (Kok) {
      Kl = Kakt + 1;
      Kfaj = Kakt;
    } else {
      Kr = Kakt - 1;
    }
  }
  cout<<Kfaj - 1<<endl;
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  return 0;
}


Measured memory_bytes: 384