#include <bits/stdc++.h>   using namespace std;   const int oo = 0x3f3f3f3f;   const double eps = 1e-9;   long long gcd(long long a, long long b) { return (b == 0) ? a : gcd(b, a % b); }   struct Frac {     long long a, b;     Frac(long long aa = 0, long long bb = 1) {       if (bb < 0) {         aa = -aa;         bb = -bb;       }       long long g = gcd(abs(aa), bb);       a = aa / g;       b = bb / g;     }     Frac& operator=(const Frac& f) {       a = f.a;       b = f.b;       return *this;     }     Frac& operator+=(const Frac& f) {       return *this = Frac(a * f.b + b * f.a, b * f.b);     }     Frac& operator-=(const Frac& f) {       return *this = Frac(a * f.b - b * f.a, b * f.b);     }     Frac& operator*=(const Frac& f) { return *this = Frac(a * f.a, b * f.b); }     Frac& operator/=(const Frac& f) { return *this = Frac(a * f.b, b * f.a); }     Frac operator-() const { return Frac(-a, b); }     Frac operator+(const Frac& f) const { return Frac(*this) += f; }     Frac operator-(const Frac& f) const { return Frac(*this) -= f; }     Frac operator*(const Frac& f) const { return Frac(*this) *= f; }     Frac operator/(const Frac& f) const { return Frac(*this) /= f; }     bool operator<(const Frac& f) const { return a * f.b < b * f.a; }     bool operator>(const Frac& f) const { return f < *this; }     bool operator<=(const Frac& f) const { return !(f < *this); }     bool operator>=(const Frac& f) const { return !(*this < f); }     bool operator==(const Frac& f) const { return !(*this < f) && !(f < *this); }     bool operator!=(const Frac& f) const { return !(*this == f); }   };   std::ostream& operator<<(std::ostream& os, const Frac& f) {     return os << f.a <<  /  << f.b;   }   Frac MAX_T = Frac(200000);   struct Event {     int from, to;     Frac time_from, time_to;     long long V;     Event(int from, int to, Frac time_from, Frac time_to, long long V)         : from(from), to(to), time_from(time_from), time_to(time_to), V(V) {       if (this->time_from > this->time_to) {         swap(this->from, this->to);         swap(this->time_from, this->time_to);       }       if ((this->from < this->to) ^ (this->V > 0)) this->V *= -1;       assert(this->time_from <= this->time_to);     }     ostream& output_me(ostream& os) const {       return os << from <<   ->   << to <<   t0=  << time_from                 <<   t1=  << time_to <<   V=  << V;     }     Frac getPoint(Frac c_time) const {       Frac dif = c_time - time_from;       Frac pos = Frac(from) + Frac(V) * dif;       return pos;     }   };   std::ostream& operator<<(std::ostream& os, const Event& e) {     return e.output_me(os);   }   const int MAXN = 100100;   vector<int> adj[MAXN];   int depth[MAXN];   int parent[MAXN];   int subsize[MAXN];   int largest[MAXN];   int leader[MAXN];   vector<int> decomposition[MAXN];   vector<Event> events[MAXN];   int lca(int a, int b) {     while (true) {       if (leader[a] == leader[b]) return ((depth[a] < depth[b]) ? a : b);       if (depth[leader[a]] > depth[leader[b]]) swap(a, b);       b = parent[leader[b]];     }   }   void init1(int n, int p, int d) {     depth[n] = d;     parent[n] = p;     subsize[n] = 1;     largest[n] = -1;     for (auto to : adj[n])       if (to != p) {         init1(to, n, d + 1);         subsize[n] += subsize[to];         if (largest[n] == -1 || subsize[to] > subsize[largest[n]]) {           largest[n] = to;         }       }   }   void init2(int n, int l) {     leader[n] = l;     decomposition[l].push_back(n);     if (largest[n] != -1) init2(largest[n], l);     for (auto to : adj[n])       if (to != parent[n] && to != largest[n]) {         decomposition[to].push_back(n);         init2(to, to);       }   }   bool insert(Frac start_t, int f, int r, int V) {     if (f == r) return false;     if (leader[f] == leader[r]) {       events[leader[f]].push_back(Event(depth[f], depth[r], start_t,                                         start_t + Frac(depth[f] - depth[r], V),                                         (V)));       return true;     }     assert(decomposition[leader[f]][0] != leader[f]);     int m = decomposition[leader[f]][0];     Frac t_m = Frac(depth[f] - depth[m], V) + start_t;     events[leader[f]].push_back(Event(depth[f], depth[m], start_t, t_m, (V)));     return insert(t_m, m, r, V);   }   Frac cur_time;   bool operator<(const Event& a, const Event& b) {     assert(a.time_from <= cur_time);     assert(a.time_to >= cur_time);     assert(b.time_from <= cur_time);     assert(b.time_to >= cur_time);     return a.getPoint(cur_time) < b.getPoint(cur_time);   }   bool operator==(const Event& a, const Event& b) {     assert(a.time_from <= cur_time);     assert(a.time_to >= cur_time);     assert(b.time_from <= cur_time);     assert(b.time_to >= cur_time);     return a.getPoint(cur_time) == b.getPoint(cur_time);   }   Frac split_(const Event& a, const Event& b) {     Frac T1 = a.time_from;     if (T1 < b.time_from) T1 = b.time_from;     Frac T2 = a.time_to;     if (T2 > b.time_to) T2 = b.time_to;     Frac sa = a.getPoint(T1), sb = b.getPoint(T1);     Frac ea = a.getPoint(T2), eb = b.getPoint(T2);     if (sa == sb) return T1;     if (ea == eb) return T2;     if ((sa < sb) ^ (ea < eb)) {       Frac d1 = sa - sb;       Frac d2 = eb - ea;       d2 = (d2 / d1);       d1 = Frac(1);       Frac rel = d1 / (d1 + d2);       Frac res = (T2 - T1) * rel + T1;       return res;     }     return MAX_T;   }   int main() {     int N, Q;     scanf( %d%d , &N, &Q);     for (int i = (0); i < (N); i++) adj[i].clear();     for (int i = (0); i < (N); i++) decomposition[i].clear();     for (int i = (1); i < (N); i++) {       int a, b;       scanf( %d%d , &a, &b);       adj[--a].push_back(--b);       adj[b].push_back(a);     }     memset(leader, -1, sizeof(leader));     init1(0, 0, 0);     init2(0, 0);     for (int q = (0); q < (Q); q++) {       int T, V, a, b;       scanf( %d%d%d%d , &T, &V, &a, &b);       --a;       --b;       int r = lca(a, b);       Frac t_start(T);       Frac t_end = t_start + Frac(depth[a] + depth[b] - 2 * depth[r], V);       bool lca_done = insert(t_start, a, r, V);       lca_done |= insert(t_end, b, r, -V);       if (!lca_done) {         Frac t_mid = t_start + Frac(depth[a] - depth[r], V);         events[leader[r]].push_back(Event(depth[r], depth[r], t_mid, t_mid, 1));       }     }     Frac split = MAX_T;     for (int ii = (0); ii < (N); ii++) {       vector<Event>& ev = events[ii];       if (int((ev).size()) == 0) continue;       set<Event> active;       set<tuple<Frac, bool, int> > change;       for (int i = (0); i < (int((ev).size())); i++) {         change.insert(make_tuple(ev[i].time_from, 0, i));         change.insert(make_tuple(ev[i].time_to, 1, i));       }       for (auto tpl : change) {         int id;         bool remove;         tie(cur_time, remove, id) = tpl;         if (split <= cur_time) break;         if (remove) {           auto it = active.find(ev[id]);           if (it != active.begin()) {             auto it1 = it;             it1--;             auto it2 = it;             it2++;             if (it2 != active.end()) {               Frac sp = split_(*it1, *it2);               if (sp < split) split = sp;             }           }           active.erase(it);         } else {           auto it = active.find(ev[id]);           if (it != active.end()) {             split = cur_time;             break;           }           active.insert(ev[id]);           it = active.find(ev[id]);           if (it != active.begin()) {             auto pr = it;             pr--;             Frac sp = split_(*pr, *it);             if (sp < split) split = sp;           }           auto ne = it;           ne++;           if (ne != active.end()) {             Frac sp = split_(*ne, *it);             if (sp < split) split = sp;           }         }       }     }     if (MAX_T == split)       printf( -1 n );     else       printf( %.10lf n , split.a / (double)split.b);     return 0;   }