#include <bits/stdc++.h>
using namespace std;
int read() {
  int x = 0;
  char ch = getchar();
  for (; !isdigit(ch); ch = getchar())
    ;
  for (; isdigit(ch); ch = getchar()) x = (x << 3) + (x << 1) + (ch ^ 48);
  return x;
}
const double eps = 1e-9;
int n, m;
struct Edge {
  int to, nxt;
} edge[200010];
int cnt = 1, last[100010];
inline void addedge(int x, int y) {
  edge[++cnt] = (Edge){y, last[x]}, last[x] = cnt;
  edge[++cnt] = (Edge){x, last[y]}, last[y] = cnt;
}
int fat[100010], dep[100010], son[100010], siz[100010];
int top[100010], id[100010], od[100010];
void dfs1(int cur, int fat, int dep) {
  ::fat[cur] = fat;
  ::dep[cur] = dep;
  siz[cur] = 1;
  for (int i = last[cur], v; i; i = edge[i].nxt)
    if ((v = edge[i].to) ^ fat) {
      dfs1(v, cur, dep + 1);
      siz[cur] += siz[v];
      if (!son[cur] || siz[v] > siz[son[cur]]) son[cur] = v;
    }
}
void dfs2(int cur, int top) {
  ::top[cur] = top;
  od[id[cur] = ++*id] = cur;
  if (siz[cur] == 1) return;
  dfs2(son[cur], top);
  for (int i = last[cur], v; i; i = edge[i].nxt)
    if (v = edge[i].to, (v ^ fat[cur]) && (v ^ son[cur])) dfs2(v, v);
}
struct Node {
  double st, et;
  int sp, ep;
  bool x, y;
} node[2500000];
int nodetot;
struct Rec {
  double tim1;
  bool tim2, opt;
  int val;
} rec[5000000];
int rectop;
bool operator<(const Rec x, const Rec y) {
  if (fabs(x.tim1 - y.tim1) > eps) return x.tim1 < y.tim1;
  if (x.tim2 ^ y.tim2) return x.tim2 < y.tim2;
  return x.opt > y.opt;
}
void work(double t, double c, int u, int v) {
  static pair<int, int> A[100], B[100];
  int Atot = 0, Btot = 0;
  while (top[u] ^ top[v]) {
    if (dep[top[u]] < dep[top[v]])
      B[++Btot] = (pair<int, int>){id[top[v]] - 1, id[v]}, v = fat[top[v]];
    else
      A[++Atot] = (pair<int, int>){id[top[u]] - 1, id[u]}, u = fat[top[u]];
  }
  if (dep[u] < dep[v])
    B[++Btot] = (pair<int, int>){id[u], id[v]};
  else if (dep[u] > dep[v])
    A[++Atot] = (pair<int, int>){id[v], id[u]};
  int s = (dep[u] < dep[v] ? id[u] : id[v]);
  for (int i = 1; i <= Atot; i++) {
    double tt = t + (A[i].second - A[i].first) / c;
    node[++nodetot] = (Node){t, tt, A[i].second, A[i].first, 0, 1};
    rec[++rectop] = (Rec){t, 0, 0, nodetot};
    rec[++rectop] = (Rec){tt, 0, 1, nodetot};
    t = tt;
  }
  node[++nodetot] = (Node){t, t, s, s, 0, 0};
  rec[++rectop] = (Rec){t, 0, 0, nodetot};
  rec[++rectop] = (Rec){t, 1, 1, nodetot};
  for (int i = Btot; i; i--) {
    double tt = t + (B[i].second - B[i].first) / c;
    node[++nodetot] = (Node){t, tt, B[i].first, B[i].second, 1, 0};
    rec[++rectop] = (Rec){t, 1, 0, nodetot};
    rec[++rectop] = (Rec){tt, 1, 1, nodetot};
    t = tt;
  }
}
double tim;
struct Cmp {
  bool operator()(int x, int y) {
    double s = (node[x].ep ^ node[x].sp
                    ? (node[x].ep - node[x].sp) / (node[x].et - node[x].st)
                    : 0),
           t = (node[y].ep ^ node[y].sp
                    ? (node[y].ep - node[y].sp) / (node[y].et - node[y].st)
                    : 0);
    double a = node[x].sp + s * (tim - node[x].st),
           b = node[y].sp + t * (tim - node[y].st);
    if (fabs(a - b) > eps) return a < b;
    if (fabs(s - t) > eps) return s < t;
    return x < y;
  }
};
set<int, Cmp> st;
void checkans(double &ans, int x, int y) {
  double myk1, myk2, myb1, myb2;
  if (node[x].sp ^ node[x].ep)
    myk1 = (node[x].sp - node[x].ep) / (node[x].st - node[x].et),
    myb1 = node[x].sp - myk1 * node[x].st;
  else
    myk1 = 0, myb1 = node[x].sp;
  if (node[y].sp ^ node[y].ep)
    myk2 = (node[y].sp - node[y].ep) / (node[y].st - node[y].et),
    myb2 = node[y].sp - myk2 * node[y].st;
  else
    myk2 = 0, myb2 = node[y].sp;
  double a;
  bool b;
  if (fabs(node[x].st - node[y].st) > eps)
    if (node[x].st < node[y].st)
      a = node[y].st, b = node[y].x;
    else
      a = node[x].st, b = node[x].x;
  else
    a = node[x].st, b = node[x].x | node[y].x;
  double c;
  bool d;
  if (fabs(node[x].et - node[y].et) > eps)
    if (node[x].et < node[y].et)
      c = node[x].et, d = node[x].y;
    else
      c = node[y].et, d = node[y].y;
  else
    c = node[x].et, d = node[x].y | node[y].y;
  if (fabs(myk1 - myk2) < eps) {
    if (fabs(myb1 - myb2) < eps)
      if (a + eps < c || fabs(a - c) < eps && !b && !d) ans = min(ans, a);
    return;
  }
  double e = (myb2 - myb1) / (myk1 - myk2);
  if ((b ? a + eps < e : a < e + eps) && (d ? e + eps < c : e < c + eps))
    ans = min(ans, e);
}
int main() {
  n = read(), m = read();
  for (int i = 1; i < n; i++) addedge(read(), read());
  dfs1(1, 0, 1);
  dfs2(1, 1);
  for (int i = 1, t, c, u, v; i <= m; i++) {
    t = read(), c = read(), u = read(), v = read();
    work(t, c, u, v);
  }
  double ans = 1e18;
  sort(rec + 1, rec + rectop + 1);
  for (int i = 1, t; i <= rectop; i++) {
    if (ans < rec[i].tim1 + eps) break;
    if (rec[i].opt) {
      set<int, Cmp>::iterator x, y;
      x = y = st.lower_bound(rec[i].val);
      if (x != st.begin() && (++y) != st.end()) checkans(ans, *--x, *y);
      st.erase(rec[i].val);
      continue;
    }
    tim = rec[i].tim1;
    set<int, Cmp>::iterator x, y, z;
    x = y = z = st.insert(rec[i].val).first;
    t = *y;
    if (x != st.begin()) checkans(ans, *--x, t);
    if ((++z) != st.end()) checkans(ans, t, *z);
  }
  if (ans == 1e18)
    puts("-1");
  else
    printf("%.10lf\n", fabs(ans) < eps ? 0.0 : ans);
  return 0;
}
