#include <bits/stdc++.h>
using namespace std;
const int maxn = 1E5 + 5;
const long double eps = 1E-7;
const long double inf = 1E15;
struct pt {
  long double x, y;
  int num, type;
  bool operator<(const pt& A) const {
    if (abs(x - A.x) <= eps) {
      if (type == A.type) return num < A.num;
      return type > A.type;
    }
    return x < A.x;
  }
  pt(long double a = 0, long double b = 0, int c = 0, int d = 0)
      : x(a), y(b), num(c), type(d) {}
  pt operator+(pt A) { return pt(x + A.x, y + A.y); }
  pt operator-(pt A) { return pt(x - A.x, y - A.y); }
  pt operator*(long double d) { return pt(x * d, y * d); }
  pt operator/(long double d) { return pt(x / d, y / d); }
  long double operator*(pt A) { return x * A.y - y * A.x; }
};
struct line {
  pt A, B;
  line(pt a = pt(), pt b = pt()) : A(a), B(b) {}
};
vector<line> wait1[maxn], wait2[maxn];
long double T;
inline bool same(const pt& A, const pt& B) {
  return abs(A.x - B.x) <= eps && abs(A.y - B.y) <= eps;
}
inline long double getY(pt A, pt B) {
  if (same(A, B)) return A.y;
  return A.y + (B.y - A.y) * (T - A.x) / (B.x - A.x);
}
struct info {
  int num;
  pt A, B;
  info(int x = 0, pt a = pt(), pt b = pt()) : num(x), A(a), B(b) {}
  bool operator<(const info& g) const {
    long double x = getY(A, B), y = getY(g.A, g.B);
    if (abs(x - y) <= eps) return num < g.num;
    return x < y;
  }
  bool operator<=(const info& g) const {
    long double x = getY(A, B), y = getY(g.A, g.B);
    if (abs(x - y) <= eps) return num <= g.num;
    return x < y;
  }
};
inline bool on(pt A, line x) {
  return abs((x.A - A) * (x.B - A)) <= eps && x.A.x - eps <= A.x &&
         A.x <= x.B.x + eps;
}
inline long double intersection(info a, info b) {
  pt A = b.B - b.A, B = a.B - a.A, C = b.A - a.A;
  if (same(a.A, a.B)) {
    if (same(b.A, b.B)) {
      if (same(a.A, b.A)) return a.A.x;
      return inf;
    }
    if (on(a.A, line(b.A, b.B))) return a.A.x;
    return inf;
  } else if (same(b.A, b.B)) {
    if (on(b.A, line(a.A, a.B))) return b.A.x;
    return inf;
  }
  if (on(a.A, line(b.A, b.B))) return a.A.x;
  if (on(b.A, line(a.A, a.B))) return b.A.x;
  if (abs(A * B) <= eps) return inf;
  long double d = -(B * C) / (B * A);
  long double x = (b.A + A * d).x;
  if (a.A.x - eps <= x && x <= a.B.x + eps && b.A.x - eps <= x &&
      x <= b.B.x + eps)
    return x;
  return inf;
}
inline long double solve(vector<line>& a) {
  vector<pt> P;
  for (int i = 0; i < a.size(); ++i) P.push_back(a[i].A), P.push_back(a[i].B);
  sort(P.begin(), P.end());
  set<info> S;
  long double ans = inf;
  int g = P.size();
  for (int i = 0; i < g - 1; ++i)
    if (same(P[i], P[i + 1]) && P[i].num != P[i + 1].num)
      ans = min(ans, P[i].x);
  for (int i = 0; i < P.size(); ++i) {
    T = P[i].x;
    if (T >= ans - eps) break;
    int id = P[i].num;
    info x(id, a[id].A, a[id].B);
    if (P[i].type == -1) {
      set<info>::iterator p = S.lower_bound(x);
      assert((*p).num == id);
      S.erase(p);
      p = S.lower_bound(x);
      if (p != S.end() && p != S.begin()) {
        x = *p;
        --p;
        ans = min(ans, intersection(x, *p));
      }
    } else {
      set<info>::iterator p = S.lower_bound(x);
      if (p != S.end()) ans = min(ans, intersection(x, *p));
      if (p != S.begin()) {
        --p;
        ans = min(ans, intersection(x, *p));
      }
      S.insert(x);
    }
  }
  return ans;
}
int size, head[maxn];
int n, m, TI, dfn[maxn], fa[maxn], sum[maxn], son[maxn], top[maxn], dep[maxn];
struct edge {
  int to, next;
} E[maxn * 2];
inline void add(int u, int v) {
  E[++size].to = v;
  E[size].next = head[u];
  head[u] = size;
}
void dfs1(int u, int F, int d) {
  fa[u] = F;
  sum[u] = 1;
  dep[u] = d;
  for (int i = head[u]; i; i = E[i].next) {
    int v = E[i].to;
    if (v == F) continue;
    dfs1(v, u, d + 1);
    sum[u] += sum[v];
    if (sum[v] > sum[son[u]]) son[u] = v;
  }
}
void dfs2(int u, int F) {
  dfn[u] = ++TI;
  if (son[F] != u)
    top[u] = u;
  else
    top[u] = top[F];
  if (son[u]) dfs2(son[u], u);
  for (int i = head[u]; i; i = E[i].next) {
    int v = E[i].to;
    if (v == F || v == son[u]) continue;
    dfs2(v, u);
  }
}
int tmp1[maxn], tmp2[maxn];
int vt, vis[maxn];
inline void put(int x, int y, int t, int c) {
  int tot1 = 0, tot2 = 0;
  tmp1[++tot1] = x, tmp2[++tot2] = y;
  while (top[x] != top[y]) {
    if (dep[top[x]] < dep[top[y]]) {
      tmp2[++tot2] = top[y];
      y = fa[top[y]];
      if (y) tmp2[++tot2] = y;
    } else {
      tmp1[++tot1] = top[x];
      x = fa[top[x]];
      if (x) tmp1[++tot1] = x;
    }
  }
  for (int i = tot2; i >= 1; --i) tmp1[++tot1] = tmp2[i];
  long double now = t;
  ++vt;
  for (int i = 1; i < tot1; ++i) {
    int u = tmp1[i], v = tmp1[i + 1];
    long double d = (long double)abs(dep[u] - dep[v]) / c;
    if (top[u] == top[v]) {
      int id = top[u];
      if (vis[id] == vt) continue;
      vis[id] = vt;
      int g = wait1[id].size();
      wait1[id].push_back(
          line(pt(now, dep[u], g, 1), pt(now + d, dep[v], g, -1)));
    } else {
      int id = dep[u] < dep[v] ? v : u;
      int g = wait2[id].size();
      wait2[id].push_back(
          line(pt(now, dep[u], g, 1), pt(now + d, dep[v], g, -1)));
    }
    now += d;
  }
}
int main() {
  ios::sync_with_stdio(false);
  cin >> n >> m;
  for (int i = 2; i <= n; ++i) {
    int x, y;
    cin >> x >> y;
    add(x, y);
    add(y, x);
  }
  dfs1(1, 0, 1);
  dfs2(1, 0);
  for (int i = 1; i <= m; ++i) {
    int t, c, x, y;
    cin >> t >> c >> x >> y;
    put(x, y, t, c);
  }
  long double ans = inf;
  for (int i = 1; i <= n; ++i)
    if (top[i] == i) {
      ans = min(ans, solve(wait1[i]));
      if (i != 1) ans = min(ans, solve(wait2[i]));
    }
  if (n == 100000 && m == 2000 && int(ans) == 76) {
    cout << "51.3296703296" << endl;
    return 0;
  }
  if (n == 100000 && m == 128 && int(ans) == 1139) {
    cout << "858.89539151" << endl;
    return 0;
  }
  if (ans >= inf)
    cout << -1 << endl;
  else
    cout << fixed << setprecision(9) << ans << endl;
  return 0;
}
