#include <bits/stdc++.h>
using namespace std;
const long double inf = 3213211;
const long double eps = 1e-9;
int n, m;
vector<int> G[123123];
int d[123123];
int heavy[123123];
int anc[123123];
int root[123123];
int rep[123123];
int counter;
const int S = 1 << 18;
int tree[2 * S];
vector<pair<pair<long double, long double>, pair<long double, long double>>>
    vec[234324];
void IOS() {
  ios_base::sync_with_stdio(0);
  cout << setprecision(20) << fixed;
}
void load() {
  cin >> n >> m;
  int x, y;
  for (int i = 1; i < n; ++i) {
    cin >> x >> y;
    G[x].push_back(y);
    G[y].push_back(x);
  }
}
int dfs(int node) {
  rep[node] = counter;
  tree[counter + S] = node;
  ++counter;
  int sub = 1;
  int maxSub = 0;
  for (int i = 0; i < G[node].size(); ++i) {
    int sas = G[node][i];
    if (anc[node] == sas) {
      continue;
    }
    d[sas] = d[node] + 1;
    anc[sas] = node;
    int tmp = dfs(sas);
    sub += tmp;
    if (tmp > maxSub) {
      heavy[node] = sas;
      maxSub = tmp;
    }
    tree[counter + S] = node;
    ++counter;
  }
  return sub;
}
void build() {
  dfs(1);
  d[0] = n + 666;
  for (int i = S - 1; i > 0; --i) {
    tree[i] =
        (d[tree[2 * i]] > d[tree[2 * i + 1]] ? tree[2 * i + 1] : tree[2 * i]);
  }
  for (int i = 1; i <= n; ++i)
    if (i == 1 || heavy[anc[i]] != i) {
      root[i] = i;
      int j = heavy[i];
      while (j) {
        root[j] = i;
        j = heavy[j];
      }
    }
}
int minikRec(int l, int r, int ll, int rr, int node) {
  if (r < ll || rr < l) {
    return 0;
  }
  if (l <= ll && rr <= r) {
    return tree[node];
  }
  int ss = (ll + rr) / 2;
  int x = minikRec(l, r, ll, ss, 2 * node);
  int y = minikRec(l, r, ss + 1, rr, 2 * node + 1);
  if (d[x] < d[y]) {
    return x;
  }
  return y;
}
int minik(int l, int r) { return minikRec(l, r, 0, S - 1, 1); }
int lca(int x, int y) {
  return minik(min(rep[x], rep[y]), max(rep[x], rep[y]));
}
void divQuery() {
  long double t;
  int c, v, u;
  cin >> t >> c >> v >> u;
  int l = lca(v, u);
  vector<int> track, tmp;
  while (root[v] != root[l]) {
    track.push_back(v);
    track.push_back(root[v]);
    v = anc[root[v]];
  }
  while (root[u] != root[l]) {
    tmp.push_back(u);
    tmp.push_back(root[u]);
    u = anc[root[u]];
  }
  if (v == l) {
    if (u != l) {
      track.push_back(l);
      track.push_back(u);
    } else {
      track.push_back(l);
      track.push_back(l);
    }
  } else {
    track.push_back(v);
    track.push_back(l);
  }
  for (int i = tmp.size() - 1; i >= 0; --i) {
    track.push_back(tmp[i]);
  }
  for (int i = 0; i < track.size() - 1; ++i) {
    auto tmp1 = make_pair(d[track[i]], t);
    t += ((long double)abs(d[track[i]] - d[track[i + 1]])) / ((long double)c);
    auto tmp2 = make_pair(d[track[i + 1]], t);
    auto tmp = make_pair(tmp1, tmp2);
    if (d[track[i]] == d[track[i + 1]]) {
      vec[root[track[i]]].push_back(tmp);
      continue;
    }
    if (d[track[i]] > d[track[i + 1]]) {
      if (root[track[i]] != root[track[i + 1]]) {
        vec[track[i] + n].push_back(tmp);
        continue;
      } else {
        vec[root[track[i]]].push_back(tmp);
        continue;
      }
    }
    if (root[track[i]] != root[track[i + 1]]) {
      vec[track[i + 1] + n].push_back(tmp);
      continue;
    } else {
      vec[root[track[i]]].push_back(tmp);
      continue;
    }
  }
}
long double dist(pair<long double, long double>& a,
                 pair<long double, long double>& b) {
  return max(fabs(a.first - b.first), fabs(a.second - b.second));
}
bool pom(long double x, long double a, long double b) {
  return min(a, b) - eps < x && x < max(a, b) + eps;
}
long double inter(pair<long double, long double> a,
                  pair<long double, long double> b,
                  pair<long double, long double> c,
                  pair<long double, long double> d) {
  if (dist(a, b) < eps) {
    if (dist(c, d) < eps) {
      if (dist(a, c) < eps) {
        return a.second;
      }
      return inf;
    }
    if (dist(a, c) < eps) {
      return a.second;
    }
    if (dist(a, d) < eps) {
      return a.second;
    }
    if (pom(a.first, c.first, d.first)) {
      long double x = (a.second - c.second) / (a.first - c.first);
      long double y = (d.second - a.second) / (d.first - a.first);
      if (fabs(x - y) < eps) {
        return a.second;
      }
    }
    return inf;
  }
  if (dist(c, d) < eps) {
    return inter(c, d, a, b);
  }
  long double sA = (b.second - a.second) / (b.first - a.first);
  long double cA = a.second - sA * a.first;
  long double sB = (d.second - c.second) / (d.first - c.first);
  long double cB = c.second - sB * c.first;
  if (fabs(sA - sB) < eps) {
    if (fabs(cA - cB) < eps) {
      if (pom(c.first, a.first, b.first)) {
        return c.second;
      }
      if (pom(a.first, c.first, d.first)) {
        return a.second;
      }
    }
    return inf;
  } else {
    long double xx = (cB - cA) / (sA - sB);
    if (pom(xx, a.first, b.first) && pom(xx, c.first, d.first)) {
      return sA * xx + cA;
    }
    return inf;
  }
}
long double t;
long double tt;
int indekss;
bool cmp(int i, int j) {
  long double ti, tj;
  if (i > 0) {
    ti = vec[indekss][i - 1].second.second;
  } else {
    ti = vec[indekss][-i - 1].first.second;
  }
  if (j > 0) {
    tj = vec[indekss][j - 1].second.second;
  } else {
    tj = vec[indekss][-j - 1].first.second;
  }
  if (fabs(ti - tj) < eps) {
    return i < j;
  }
  return ti < tj;
}
struct cmp1 {
  bool operator()(int A, int B) {
    auto a = vec[indekss][A];
    auto b = vec[indekss][B];
    long double xa, xb;
    if (fabs(a.first.first - a.second.first) > eps) {
      xa = a.first.first +
           (tt - a.first.second) * ((a.second.first - a.first.first) /
                                    (a.second.second - a.first.second));
    } else {
      xa = a.first.first;
    }
    if (fabs(b.first.first - b.second.first) > eps) {
      xb = b.first.first +
           (tt - b.first.second) * ((b.second.first - b.first.first) /
                                    (b.second.second - b.first.second));
    } else {
      xb = b.first.first;
    }
    if (fabs(xa - xb) < eps) {
      return A < B;
    }
    return xa < xb;
  }
};
set<int, cmp1> secik;
long double solve(int nr) {
  t = inf;
  indekss = nr;
  vector<int> ind;
  secik.clear();
  for (int i = 0; i < vec[nr].size(); ++i) {
    ind.push_back(i + 1);
    ind.push_back(-i - 1);
  }
  sort(ind.begin(), ind.end(), cmp);
  for (int i = 0; i < ind.size(); ++i) {
    if (ind[i] < 0) {
      tt = vec[nr][-ind[i] - 1].first.second;
      if (tt > t - eps) {
        return t;
      }
      auto tmp = secik.insert(-ind[i] - 1);
      auto ptr = tmp.first;
      if (ptr != secik.begin()) {
        --ptr;
        t = min(t,
                inter(vec[nr][*ptr].first, vec[nr][*ptr].second,
                      vec[nr][-ind[i] - 1].first, vec[nr][-ind[i] - 1].second));
        ++ptr;
      }
      ++ptr;
      if (ptr != secik.end()) {
        t = min(t,
                inter(vec[nr][*ptr].first, vec[nr][*ptr].second,
                      vec[nr][-ind[i] - 1].first, vec[nr][-ind[i] - 1].second));
      }
    } else {
      tt = vec[nr][ind[i] - 1].second.second;
      if (tt > t - eps) {
        return t;
      }
      auto ptr = secik.find(ind[i] - 1);
      if (ptr != secik.begin()) {
        auto ptr2 = ptr;
        --ptr2;
        auto ptr3 = ptr;
        ++ptr3;
        if (ptr3 != secik.end()) {
          t = min(t, inter(vec[nr][*ptr2].first, vec[nr][*ptr2].second,
                           vec[nr][*ptr3].first, vec[nr][*ptr3].second));
        }
      }
      secik.erase(ptr);
    }
  }
  return t;
}
int main() {
  IOS();
  load();
  build();
  for (int i = 0; i < m; ++i) {
    divQuery();
  }
  long double ans = inf;
  for (int i = 1; i <= 2 * n; ++i) {
    ans = min(ans, solve(i));
  }
  if (ans > inf / 2) {
    cout << -1 << endl;
    return 0;
  }
  cout << ans << endl;
}
