#include <bits/stdc++.h>
using namespace std;
template <class T>
inline void read(T &x) {
  x = 0;
  char c = getchar();
  int f = 1;
  while (!isdigit(c)) {
    if (c == '-') f = -1;
    c = getchar();
  }
  while (isdigit(c)) {
    x = x * 10 + c - '0';
    c = getchar();
  }
  x *= f;
}
template <class T>
inline void umin(T &x, T y) {
  x = x < y ? x : y;
}
template <class T>
inline void umax(T &x, T y) {
  x = x > y ? x : y;
}
inline unsigned int R() {
  static unsigned int seed = 416;
  return seed ^= seed >> 5, seed ^= seed << 17, seed ^= seed >> 13;
}
const int N = 266666;
const double inf = 1e9, eps = 1e-6;
int n, m, fa[N], top[N], dep[N], sz[N], son[N], dfn[N], idfn[N], num;
vector<int> e[N];
double ans = inf, cur;
struct dot {
  double x, y;
  dot(double X = 0, double Y = 0) {
    x = X;
    y = Y;
  }
};
vector<pair<dot, dot> > mrk[N];
dot a[N], b[N];
int len;
pair<double, int> ev[N];
bool cmp1(pair<double, int> a, pair<double, int> b) {
  return a.first != b.first ? a.first < b.first : a.second > b.second;
}
inline double gety(int i) {
  return a[i].x == b[i].x
             ? a[i].y
             : a[i].y + (cur - a[i].x) / (b[i].x - a[i].x) * (b[i].y - a[i].y);
}
struct node {
  int u;
  bool operator<(const node &a) const {
    return gety(u) != gety(a.u) ? gety(u) < gety(a.u) : u < a.u;
  }
};
set<node> Set;
dot operator-(dot a, dot b) { return dot(a.x - b.x, a.y - b.y); }
double Cross(dot a, dot b) { return a.x * b.y - a.y * b.x; }
bool isin(dot p, dot a, dot b) {
  return p.x >= min(a.x, b.x) - eps && p.x <= max(a.x, b.x) + eps &&
         p.y >= min(a.y, b.y) - eps && p.y <= max(a.y, b.y) + eps;
}
double Abs(double x) { return x > 0 ? x : -x; }
bool on_line(dot p, dot a, dot b) { return Abs(Cross(p - a, b - a)) <= eps; }
double getlen(dot a) { return sqrt(a.x * a.x + a.y * a.y); }
void print(int i) {
  printf("%lf %lf %lf %lf\n", a[i].x, a[i].y, b[i].x, b[i].y);
}
double getans(int i, int j) {
  if (i == j) return inf;
  if (getlen(b[i] - a[i]) > getlen(b[j] - a[j])) swap(i, j);
  if (getlen(b[i] - a[i]) <= eps) {
    if (isin(a[i], a[j], b[j]) && on_line(a[i], a[j], b[j])) return a[i].x;
    return inf;
  }
  dot A = a[i], B = b[i], C = a[j], D = b[j], u = B - A, v = D - C;
  if (Abs(Cross(u, v)) <= eps) {
    if (Abs(gety(i) - gety(j)) <= eps && cur >= A.x - eps && cur <= B.x + eps &&
        cur >= C.x - eps && cur <= D.x + eps) {
      return cur;
    }
    return inf;
  }
  double k = (Cross(D, v) - Cross(A, v)) / Cross(u, v);
  dot p(A.x + k * u.x, A.y + k * u.y);
  if (isin(p, A, B) && isin(p, C, D) && on_line(p, A, B) && on_line(p, C, D))
    return A.x + k * u.x;
  return inf;
}
void upd(int i) {
  set<node>::iterator it = Set.lower_bound((node){i});
  if (it != Set.end()) umin(ans, getans(i, (*it).u));
  if (it != Set.begin()) it--, umin(ans, getans(i, (*it).u));
}
void dfs1(int u, int Fa, int Dep) {
  fa[u] = Fa;
  dep[u] = Dep;
  sz[u] = 1;
  for (register int i = (0); i <= (((int)e[u].size()) - 1); i++)
    if (e[u][i] != Fa) {
      dfs1(e[u][i], u, Dep + 1), sz[u] += sz[e[u][i]];
      if (sz[e[u][i]] > sz[son[u]]) son[u] = e[u][i];
    }
}
void dfs2(int u, int Top) {
  top[u] = Top;
  dfn[u] = ++num;
  idfn[num] = u;
  if (son[u]) dfs2(son[u], Top);
  for (register int i = (0); i <= (((int)e[u].size()) - 1); i++)
    if (e[u][i] != fa[u] && e[u][i] != son[u]) dfs2(e[u][i], e[u][i]);
}
int getlca(int u, int v) {
  while (top[u] != top[v]) {
    if (dep[top[u]] < dep[top[v]]) swap(u, v);
    u = fa[top[u]];
  }
  return dep[u] < dep[v] ? u : v;
}
int getpath(int u, int v, double t, int xs, double c) {
  while (top[u] != top[v]) {
    int x = fa[top[u]];
    mrk[top[u]].push_back(make_pair(
        dot(t, dfn[u]),
        dot(t + xs * (dep[u] - dep[x]) / c, dfn[u] - (dep[u] - dep[x]))));
    t += xs * (dep[u] - dep[x]) / c;
    u = fa[top[u]];
  }
  return u;
}
int main() {
  read(n);
  read(m);
  for (register int i = (1); i <= (n - 1); i++) {
    int u, v;
    read(u);
    read(v);
    e[u].push_back(v);
    e[v].push_back(u);
  }
  dfs1(1, 0, 0);
  dfs2(1, 1);
  for (register int i = (1); i <= (m); i++) {
    int T, C, u, v;
    read(T);
    read(C);
    read(u);
    read(v);
    double t = T, c = C;
    int lca = getlca(u, v);
    int ori = u;
    v = getpath(v, lca, t + (dep[u] + dep[v] - 2 * dep[lca]) * 1.0 / c, -1, c);
    u = getpath(u, lca, t, 1, c);
    t += (dep[ori] - dep[u]) * 1.0 / c;
    if (dep[u] >= dep[v])
      mrk[top[u]].push_back(make_pair(
          dot(t, dfn[u]), dot(t + (dep[u] - dep[v]) * 1.0 / c, dfn[v])));
    else
      mrk[top[u]].push_back(make_pair(
          dot(t, dfn[u]), dot(t + (dep[v] - dep[u]) * 1.0 / c, dfn[v])));
  }
  for (register int t = (1); t <= (n); t++)
    if (((int)mrk[t].size())) {
      Set.clear();
      len = 0;
      for (register int i = (0); i <= (((int)mrk[t].size()) - 1); i++)
        len++, a[len] = mrk[t][i].first, b[len] = mrk[t][i].second;
      for (register int i = (1); i <= (len); i++)
        if (a[i].x > b[i].x) swap(a[i], b[i]);
      for (register int i = (1); i <= (len); i++)
        ev[2 * i - 1] = make_pair(a[i].x, i), ev[2 * i] = make_pair(b[i].x, -i);
      sort(ev + 1, ev + len * 2 + 1, cmp1);
      for (register int i = (1); i <= (len * 2); i++) {
        if ((cur = ev[i].first) >= ans) break;
        if (ev[i].second > 0) {
          set<node>::iterator it = Set.insert((node){ev[i].second}).first, pre,
                              nxt;
          pre = it;
          nxt = it;
          nxt++;
          if (it != Set.begin()) {
            pre--;
            umin(ans, getans((*pre).u, (*it).u));
          }
          if (nxt != Set.end()) {
            umin(ans, getans((*nxt).u, (*it).u));
          }
        } else {
          set<node>::iterator it = Set.find((node){-ev[i].second}), it1, it2;
          it1 = it, it2 = it;
          it2++;
          if (it != Set.begin() && it2 != Set.end()) {
            it1--;
            umin(ans, getans((*it1).u, (*it2).u));
          }
          Set.erase(it);
        }
      }
    }
  if (ans < 1e8)
    printf("%.9lf\n", ans);
  else
    puts("-1");
  return 0;
}
