#include <bits/stdc++.h>
using namespace std;
const int N = 100000, C = 20;
const long long INF = 2e4;
long long gcd(long long a, long long b) { return b ? gcd(b, a % b) : a; }
struct frac {
  long long x, y;
  frac(long long X = 0, long long Y = 1) {
    x = X;
    y = Y;
  }
  frac Norm() {
    long long g = gcd(abs(x), abs(y));
    if (y < 0) g = -g;
    return frac(x / g, y / g);
  }
  frac operator+(const frac &p) const {
    return frac(x * p.y + y * p.x, y * p.y).Norm();
  }
  frac operator-(const frac &p) const {
    return frac(x * p.y - y * p.x, y * p.y).Norm();
  }
  frac operator-() const { return frac(-x, y); }
  frac operator*(const frac &p) const { return frac(x * p.x, y * p.y).Norm(); }
  frac operator/(const frac &p) const { return frac(x * p.y, y * p.x).Norm(); }
  bool operator<(const frac &p) const { return x * p.y < y * p.x; }
  bool operator>(const frac &p) const { return x * p.y > y * p.x; }
  bool operator<=(const frac &p) const { return x * p.y <= y * p.x; }
  bool operator>=(const frac &p) const { return x * p.y >= y * p.x; }
  bool operator==(const frac &p) const { return x * p.y == y * p.x; }
};
struct side {
  int y, next;
} e[N * 2 + 9];
int lin[N + 9], cs;
void Ins(int x, int y) {
  e[++cs].y = y;
  e[cs].next = lin[x];
  lin[x] = cs;
}
void Ins2(int x, int y) {
  Ins(x, y);
  Ins(y, x);
}
struct node {
  int fa, son, dep, siz, top, dfs;
} d[N + 9];
int co;
void Dfs_ord0(int k, int fa) {
  d[k].fa = fa;
  d[k].dep = d[fa].dep + 1;
  d[k].siz = 1;
  for (int i = lin[k]; i; i = e[i].next)
    if (e[i].y ^ fa) {
      Dfs_ord0(e[i].y, k);
      d[k].siz += d[e[i].y].siz;
      if (d[e[i].y].siz > d[d[k].son].siz) d[k].son = e[i].y;
    }
}
void Dfs_ord1(int k, int top) {
  d[k].top = top;
  d[k].dfs = ++co;
  if (d[k].son) Dfs_ord1(d[k].son, top);
  for (int i = lin[k]; i; i = e[i].next)
    if (e[i].y ^ d[k].fa && e[i].y ^ d[k].son) Dfs_ord1(e[i].y, e[i].y);
}
int Query_lca(int x, int y) {
  for (; d[x].top ^ d[y].top; x = d[d[x].top].fa)
    if (d[d[x].top].dep < d[d[y].top].dep) swap(x, y);
  return d[x].dep < d[y].dep ? x : y;
}
frac Query_dis(int x, int y) {
  return frac((long long)d[x].dep + d[y].dep - 2 * d[Query_lca(x, y)].dep);
}
struct line {
  frac k, b, l, r;
  line(frac K = frac(), frac B = frac(), frac L = frac(), frac R = frac()) {
    k = K;
    b = B;
    l = L;
    r = R;
  }
};
frac tim, goa;
vector<line> hv[N + 9], lt[N + 9];
void Add_q(int x, int y, frac s, frac v) {
  frac t = s + Query_dis(x, y) / v, len;
  for (; d[x].top ^ d[y].top;)
    if (d[d[x].top].dep > d[d[y].top].dep) {
      int fx = d[x].top;
      len = frac((long long)d[x].dep - d[fx].dep) / v;
      hv[fx].push_back(line(-v, frac(d[x].dep) + v * s, s, s + len));
      s = s + len;
      x = fx;
      fx = d[x].fa;
      len = frac((long long)d[x].dep - d[fx].dep) / v;
      lt[x].push_back(line(-v, frac(d[x].dep) + v * s, s, s + len));
      s = s + len;
      x = fx;
    } else {
      int fy = d[y].top;
      len = frac((long long)d[y].dep - d[fy].dep) / v;
      hv[fy].push_back(line(v, frac(d[y].dep) - v * t, t - len, t));
      t = t - len;
      y = fy;
      fy = d[y].fa;
      len = frac((long long)d[y].dep - d[fy].dep) / v;
      lt[y].push_back(line(v, frac(d[y].dep) - v * t, t - len, t));
      t = t - len;
      y = fy;
    }
  int fx = d[x].top;
  if (d[x].dep > d[y].dep)
    hv[fx].push_back(line(-v, frac(d[x].dep) + v * s, s, t));
  else
    hv[fx].push_back(line(v, frac(d[y].dep) - v * t, s, t));
}
bool operator<(line a, line b) {
  if (a.k * tim + a.b == b.k * tim + b.b)
    return a.l == b.l ? a.r == b.r ? a.k < b.k : a.r < b.r : a.l < b.l;
  else
    return a.k * tim + a.b < b.k * tim + b.b;
}
multiset<line> s;
bool cmp(pair<line, bool> x, pair<line, bool> y) {
  frac tx = x.second ? x.first.l : x.first.r;
  frac ty = y.second ? y.first.l : y.first.r;
  if (tx == ty)
    return x.second > y.second;
  else
    return tx < ty;
}
frac Get_cross(line a, line b) {
  if (a.k == b.k) return a.b == b.b ? max(a.l, b.l) : frac(INF);
  frac res = (b.b - a.b) / (a.k - b.k);
  return res >= max(a.l, b.l) && res <= min(a.r, b.r) ? res : frac(INF);
}
double ans;
void Get_ans(vector<line> &a) {
  s.clear();
  goa = frac(INF);
  vector<pair<line, bool> > b;
  for (vector<line>::iterator it = a.begin(); it != a.end(); ++it)
    b.emplace_back(*it, 1), b.emplace_back(*it, 0);
  sort(b.begin(), b.end(), cmp);
  for (vector<pair<line, bool> >::iterator it = b.begin(); it != b.end();
       ++it) {
    pair<line, bool> x = *it;
    frac now = x.second ? x.first.l : x.first.r;
    if (now >= goa) {
      ans = min(ans, 1.0 * goa.x / goa.y);
      return;
    }
    tim = now;
    if (x.second) {
      multiset<line>::iterator tmp = s.insert(x.first), pre = tmp, suf = tmp;
      if (pre != s.begin()) goa = min(goa, Get_cross(*--pre, *tmp));
      if (suf != --s.end()) goa = min(goa, Get_cross(*++suf, *tmp));
    } else {
      multiset<line>::iterator tmp = s.lower_bound(x.first), pre = tmp,
                               suf = tmp;
      if (suf != --s.end() && pre != s.begin())
        goa = min(goa, Get_cross(*--pre, *++suf));
      s.erase(tmp);
    }
  }
  ans = min(ans, 1.0 * goa.x / goa.y);
}
int n, m;
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i < n; ++i) {
    int x, y;
    scanf("%d%d", &x, &y);
    Ins2(x, y);
  }
  Dfs_ord0(1, 0);
  Dfs_ord1(1, 1);
  for (int i = 1; i <= m; ++i) {
    int x, y;
    frac t, v;
    scanf("%d%d", &x, &y);
    t = frac(x);
    v = frac(y);
    scanf("%d%d", &x, &y);
    Add_q(x, y, t, v);
  }
  ans = 1.0 * INF;
  for (int i = 1; i <= n; ++i) Get_ans(hv[i]), Get_ans(lt[i]);
  ans >= 1.0 * INF ? puts("-1") : printf("%.10lf", ans);
  return 0;
}
