#include <bits/stdc++.h>
 
using namespace std;
 
const int max_n = 100000;
const long long inf = 2e18;
 
#define ll long long
#define PLI pair<ll, int>
 
int n, m;
ll dis[max_n + 15];
struct E {
  int v;
  ll c, d;
  E () {}
  E (int v, ll c, ll d) : v(v), c(c), d(d) {}
};
vector<E> edges[max_n + 15];
priority_queue<PLI, vector<PLI>, greater<PLI> > que;
inline ll f(ll x, ll d) { return x + d / (x + 1); }
ll cal(ll start_t, ll d) {
  ll s = start_t, e = 1e9, ans;
  while (s <= e - 1000) {
    ll ml = (2 * s + e) / 3;
    ll mr = (s + 2 * e) / 3;
       ll fl = f(ml, d), fr = f(mr, d);
    if (fl < fr) e = mr;
    else s = ml;
    //cout << s << ' ' << e << endl;
  }
  ans = f(s, d);
  for (ll i = s + 1; i <= e; ++i) {
    ll res = f(i, d);
    if (res < ans) ans = res;
  }
  return ans - start_t;
}
ll Dij() {
  for (int i = 2; i <= n; ++i) dis[i] = inf;
  que.push(PLI(dis[1] = 0, 1));
  while (que.size()) {
    PLI pp = que.top(); que.pop();
    ll t = pp.first; int u = pp.second;
    if (dis[u] < t) continue;
    for (auto e : edges[u]) {
      int v = e.v; ll c = e.c, d = e.d;
      ll delta = c + cal(t, d);
      if (dis[u] + delta < dis[v]) {
        que.push(PLI(dis[v] = dis[u] + delta, v));
      }
    }
  }
  return inf == dis[n] ? -1 : dis[n];
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= m; ++i) {
    int u, v, c, d;
    scanf("%d%d%d%d", &u, &v, &c, &d);
    edges[u].push_back(E(v, c, d));
    edges[v].push_back(E(u, c, d));
  }
  printf("%lld\n", Dij());
  return 0;
 }
#define _USE_MATH_DEFINES
#include <bits/stdc++.h>
using namespace std;
#define FOR(i,m,n) for(int i=(m);i<(n);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()
using ll = long long;
constexpr int INF = 0x3f3f3f3f;
constexpr long long LINF = 0x3f3f3f3f3f3f3f3fLL;
constexpr double EPS = 1e-8;
constexpr int MOD = 1000000007;
// constexpr int MOD = 998244353;
constexpr int dy[] = {1, 0, -1, 0}, dx[] = {0, -1, 0, 1};
constexpr int dy8[] = {1, 1, 0, -1, -1, -1, 0, 1}, dx8[] = {0, -1, -1, -1, 0, 1, 1, 1};
template <typename T, typename U> inline bool chmax(T &a, U b) { return a < b ? (a = b, true) : false; }
template <typename T, typename U> inline bool chmin(T &a, U b) { return a > b ? (a = b, true) : false; }
struct IOSetup {
  IOSetup() {
    std::cin.tie(nullptr);
    std::ios_base::sync_with_stdio(false);
    std::cout << fixed << setprecision(20);
  }
} iosetup;

int main() {
  ll x, y; cin >> x >> y;
  if (x >= y) {
    cout << x - y << '\n';
    return 0;
  }
  map<ll, int> dp{{y, 0}};
  using P = pair<int, ll>;
  priority_queue<P, vector<P>, greater<P>> que;
  que.emplace(0, y);
  ll ans = y - x;
  while (!que.empty()) {
    auto [cost, z] = que.top(); que.pop();
    if (cost > dp[z] || cost >= ans) continue;
    if (z % 2 == 0) {
      if (dp.count(z / 2) == 0 || dp[z / 2] > dp[z] + 1) {
        dp[z / 2] = dp[z] + 1;
        chmin(ans, dp[z / 2] + abs(z / 2 - x));
        if (z / 2 > x) que.emplace(dp[z / 2], z / 2);
      }
    } else {
      if (dp.count((z + 1) / 2) == 0 || dp[(z + 1) / 2] > dp[z] + 2) {
        dp[(z + 1) / 2] = dp[z] + 2;
        chmin(ans, dp[(z + 1) / 2] + abs((z + 1) / 2 - x));
        if ((z + 1) / 2 > x) que.emplace(dp[(z + 1) / 2], (z + 1) / 2);
      }
      if (dp.count((z - 1) / 2) == 0 || dp[(z - 1) / 2] > dp[z] + 2) {
        dp[(z - 1) / 2] = dp[z] + 2;
        chmin(ans, dp[(z - 1) / 2] + abs((z - 1) / 2 - x));
        if ((z - 1) / 2 > x) que.emplace(dp[(z - 1) / 2], (z - 1) / 2);
      }
    }
  }
  cout << ans << '\n';
  return 0;
}
