#include <bits/stdc++.h>
using namespace std;
const double Inf = 1e18;
const int N = 3e5 + 9;
double ans = Inf;
double x;
const double eps = 1e-10;
struct line {
  double lx, rx, ly, ry, k;
  line(double lx = 0, double ly = 0, double rx = 0, double ry = 0, double k = 0)
      : lx(lx), ly(ly), rx(rx), ry(ry), k(k) {}
  double cal(double x) { return ly + (x - lx) * k; }
} q[N];
struct cmp {
  bool operator()(const int &a, const int &b) {
    return q[a].cal(x) < q[b].cal(x);
  }
};
struct query {
  double x;
  int id;
  query(double x = 0, int id = 0) : x(x), id(id) {}
  bool operator<(const query &o) const {
    if (fabs(x - o.x) < eps) return id > o.id;
    return x < o.x;
  }
} que[N];
void upd(int idx, int idy) {
  if (q[idx].lx > q[idy].lx) swap(idx, idy);
  if (q[idx].rx + eps < q[idy].lx) return;
  double y = q[idx].cal(q[idy].lx);
  if (fabs(q[idx].k - q[idy].k) < eps) {
    if (fabs(y - q[idy].ly) < eps) ans = min(ans, q[idy].lx);
    return;
  }
  double px = (q[idy].ly - y) / (q[idx].k - q[idy].k);
  if (px < -eps || px + q[idy].lx > min(q[idx].rx, q[idy].rx) + eps) return;
  ans = min(ans, px + q[idy].lx);
}
set<int, cmp> S;
void erase(int id) {
  S.erase(id);
  set<int, cmp>::iterator pre, nxt;
  pre = nxt = S.lower_bound(id);
  if (pre != S.begin() && nxt != S.end()) upd(*(--pre), *nxt);
}
void insert(int id) {
  set<int, cmp>::iterator pre, nxt;
  pre = nxt = S.lower_bound(id);
  if (pre != S.begin()) upd(*(--pre), id);
  if (nxt != S.end()) upd(*(nxt), id);
  S.insert(id);
}
void solve(const vector<line> &vec) {
  int top = 0;
  for (int i = (0); i < (vec.size()); ++i) {
    q[i + 1] = vec[i];
    que[++top] = query(q[i + 1].lx, i + 1);
    que[++top] = query(q[i + 1].rx, -i - 1);
  }
  S.clear();
  sort(que + 1, que + top + 1);
  for (int i = (1); i < (top + 1); ++i) {
    x = que[i].x;
    if (x + eps >= ans) break;
    if (que[i].id < 0)
      erase(-que[i].id);
    else
      insert(que[i].id);
  }
}
vector<line> G[N];
vector<int> g[N];
int sz[N], top[N], fa[N], dep[N];
void dfs(int u, int f) {
  fa[u] = f;
  dep[u] = dep[f] + 1;
  sz[u] = 1;
  for (auto v : g[u]) {
    if (v == f) continue;
    dfs(v, u);
    sz[u] += sz[v];
  }
}
void dfs2(int u, int tp) {
  int p = 0;
  top[u] = tp;
  for (auto v : g[u]) {
    if (v == fa[u]) continue;
    if (sz[v] > sz[p]) p = v;
  }
  if (p) dfs2(p, tp);
  for (auto v : g[u]) {
    if (v == fa[u] || v == p) continue;
    dfs2(v, v);
  }
}
int LCA(int u, int v) {
  for (; top[u] != top[v]; u = fa[top[u]]) {
    if (dep[top[u]] < dep[top[v]]) swap(u, v);
  }
  if (dep[u] < dep[v]) return u;
  return v;
}
int dis(int x, int y) { return dep[x] + dep[y] - 2 * dep[LCA(x, y)]; }
void add(int u, int v, double S, double T, double k) {
  int L = LCA(u, v);
  for (; top[u] != top[L]; u = fa[top[u]]) {
    int len = dep[u] - dep[top[u]] + 1;
    G[top[u]].push_back(line(S, len, S + 1.0 * len / k, 0, -k));
    S += 1.0 * len / k;
  }
  for (; top[v] != top[L]; v = fa[top[v]]) {
    int len = dep[v] - dep[top[v]] + 1;
    G[top[v]].push_back(line(T - 1.0 * len / k, 0, T, len, k));
    T -= 1.0 * len / k;
  }
  int px = dep[u] - dep[top[u]] + 1;
  int py = dep[v] - dep[top[v]] + 1;
  if (dep[u] > dep[v])
    G[top[u]].push_back(line(S, px, T, py, -k));
  else
    G[top[u]].push_back(line(S, px, T, py, k));
}
int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  for (int i = (1); i < (n); ++i) {
    int u, v;
    scanf("%d%d", &u, &v);
    g[u].push_back(v), g[v].push_back(u);
  }
  dfs(1, 0);
  dfs2(1, 1);
  for (int i = (0); i < (m); ++i) {
    int u, v, k, t;
    scanf("%d%d%d%d", &t, &k, &u, &v);
    add(u, v, t, t + 1.0 * dis(u, v) / k, k);
  }
  for (int i = (1); i < (n + 1); ++i)
    if (top[i] == i) solve(G[i]);
  if (ans > 1e6) return printf("-1"), 0;
  printf("%.10lf\n", ans);
}
