#include <bits/stdc++.h>
using namespace std;
inline int read() {
  register int x = 0, f = 1;
  register char ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-') f = 0;
    ch = getchar();
  }
  while (isdigit(ch)) {
    x = x * 10 + (ch ^ '0');
    ch = getchar();
  }
  return f ? x : -x;
}
const int N = 1e5 + 5, inf = 1e9;
int n, m;
vector<int> E[N];
int fa[N], siz[N], tp[N], son[N], dep[N];
void dfs(int u, int pa) {
  fa[u] = pa;
  dep[u] = dep[pa] + 1;
  siz[u] = 1;
  for (int v : E[u]) {
    if (v == pa) continue;
    dfs(v, u);
    siz[u] += siz[v];
    if (siz[v] > siz[son[u]]) son[u] = v;
  }
}
void dfs(int u) {
  if (!tp[u]) tp[u] = u;
  if (son[u]) {
    tp[son[u]] = tp[u];
    dfs(son[u]);
  }
  for (int v : E[u]) {
    if (v == fa[u] || v == son[u]) continue;
    dfs(v);
  }
}
int lca(int x, int y) {
  while (tp[x] ^ tp[y])
    if (dep[tp[x]] >= dep[tp[y]])
      x = fa[tp[x]];
    else
      y = fa[tp[y]];
  return dep[x] < dep[y] ? x : y;
}
int dis(int x, int y) { return dep[x] + dep[y] - 2 * dep[lca(x, y)]; }
inline long long gcd(long long a, long long b) { return b ? gcd(b, a % b) : a; }
struct frac {
  long long x, y;
  inline frac() {}
  inline frac(long long _x, long long _y = 1) {
    x = _x, y = _y;
    long long d = (y < 0 ? -1ll : 1ll) * gcd(abs(x), abs(y));
    x /= d, y /= d;
  }
  inline frac operator-() { return frac(-x, y); }
  inline frac operator+(const frac& o) {
    return frac(x * o.y + y * o.x, y * o.y);
  }
  inline frac operator-(const frac& o) {
    return frac(x * o.y - y * o.x, y * o.y);
  }
  inline frac operator*(const frac& o) { return frac(x * o.x, y * o.y); }
  inline frac operator/(const frac& o) { return frac(x * o.y, y * o.x); }
  inline bool operator==(const frac& o) { return x == o.x && y == o.y; }
  inline bool operator<(const frac& o) { return x * o.y < y * o.x; }
  inline bool operator>(const frac& o) { return x * o.y > y * o.x; }
  inline bool operator<=(const frac& o) { return x * o.y <= y * o.x; }
  inline void print() { fprintf(stderr, "{%lld}{%lld},", x, y); }
} T, ans;
struct line {
  frac k, b, s, t;
  inline line(frac _k, frac _b, frac _s, frac _t)
      : k(_k), b(_b), s(_s), t(_t) {}
  inline frac y() { return k * T + b; }
};
inline bool operator<(line a, line b) {
  return a.y() == b.y()
             ? (a.s == b.s ? (a.t == b.t ? a.k < b.k : a.t < b.t) : a.s < b.s)
             : a.y() < b.y();
}
inline frac cross(line a, line b) {
  if (a.k == b.k) return a.b == b.b ? (a.s > b.s ? a.s : b.s) : frac(inf);
  frac c = (b.b - a.b) / (a.k - b.k);
  return (c < a.s || c < b.s || c > a.t || c > b.t) ? frac(inf) : c;
}
vector<line> se[N], fe[N];
void partition(frac s, frac c, int x, int y) {
  frac t = s + frac(dis(x, y)) / c;
  while (tp[x] ^ tp[y])
    if (dep[tp[x]] > dep[tp[y]]) {
      se[tp[x]].push_back(
          line(-c, frac(dep[x]) + c * s, s, s + frac(dis(x, tp[x])) / c));
      s = s + frac(dis(x, tp[x])) / c;
      x = tp[x];
      fe[x].push_back(
          line(-c, frac(dep[x]) + c * s, s, s + frac(dis(x, fa[x])) / c));
      s = s + frac(dis(x, fa[x])) / c;
      x = fa[x];
    } else {
      se[tp[y]].push_back(
          line(c, frac(dep[y]) - c * t, t - frac(dis(y, tp[y])) / c, t));
      t = t - frac(dis(y, tp[y])) / c;
      y = tp[y];
      fe[y].push_back(
          line(c, frac(dep[y]) - c * t, t - frac(dis(y, fa[y])) / c, t));
      t = t - frac(dis(y, fa[y])) / c;
      y = fa[y];
    }
  if (dep[x] > dep[y])
    se[tp[x]].push_back(line(-c, frac(dep[x]) + c * s, s, t));
  else
    se[tp[y]].push_back(line(c, frac(dep[y]) - c * t, s, t));
}
inline bool operator<(const pair<line, int>& a, const pair<line, int>& b) {
  frac x = ~a.second ? a.first.s : a.first.t,
       y = ~b.second ? b.first.s : b.first.t;
  return x == y ? a.second > b.second : x < y;
}
typedef multiset<line>::iterator slt;
inline slt pre(slt it) { return --it; }
inline slt nxt(slt it) { return ++it; }
void work(const vector<line> l) {
  static multiset<line> s;
  static vector<pair<line, int> > v;
  s.clear(), v.clear();
  for (line nw : l)
    v.push_back(make_pair(nw, 1)), v.push_back(make_pair(nw, -1));
  sort(v.begin(), v.end());
  for (pair<line, int> nw : v) {
    frac _ = ~nw.second ? nw.first.s : nw.first.t;
    if (ans <= _) break;
    T = _;
    frac res = frac(inf);
    if (~nw.second) {
      slt it = s.insert(nw.first);
      if (it != s.begin()) res = cross(*pre(it), *it);
      if (res < ans) ans = res;
      if (nxt(it) != s.end()) res = cross(*it, *nxt(it));
      if (res < ans) ans = res;
    } else {
      slt it = s.find(nw.first);
      if (it != s.begin() && nxt(it) != s.end())
        res = cross(*pre(it), *nxt(it));
      if (res < ans) ans = res;
      s.erase(it);
    }
  }
}
int main() {
  n = read(), m = read();
  for (int i = (1), _ed = (n - 1); i <= _ed; ++i) {
    int u = read(), v = read();
    E[u].push_back(v), E[v].push_back(u);
  }
  dfs(1, 0), dfs(1);
  for (int i = (1), _ed = (m); i <= _ed; ++i) {
    int t = read(), c = read(), u = read(), v = read();
    partition(frac(t), frac(c), u, v);
  }
  ans = frac(inf);
  for (int i = (1), _ed = (n); i <= _ed; ++i) work(se[i]), work(fe[i]);
  if (ans == frac(inf))
    return puts("-1"), 0;
  else
    return printf("%.9f\n", (double)ans.x / ans.y), 0;
}
