2 2
1 2 1 4 2 4
1 2 3 4 4 4
 2 2
1 2 0 9998 0 9999
2 1 0 9999 0 10000
 3 3
1 2 0 3 -4 7
2 3 -2 5 1 6
3 1 0 4 0 4
 2 2
1 2 0 3 0 3
2 1 0 4 0 4
 2 2
1 2 0 0 0 0
2 1 0 0 0 0
 5 10
4 3 -19 49 -11 65
4 4 50 12 -2 65
1 5 56 8 -5 76
5 1 -28 33 -38 49
4 2 0 0 2 9
4 2 0 0 14 8
3 1 26 67 15 85
5 3 -51 98 -44 99
1 3 -33 65 -20 65
3 4 30 6 -30 70
 5 10
4 3 -8 16 -29 72
4 4 -62 65 33 65
1 5 -58 97 -17 97
5 1 -5 10 -68 88
4 2 0 0 -9 60
4 2 0 0 -23 39
3 1 3 28 13 87
5 3 -1 25 -15 90
1 3 -12 33 6 94
3 4 -71 86 -39 86
 5 10
4 3 -1 5 -6 98
4 4 12 14 -43 98
1 5 -4 6 8 88
5 1 0 0 -9 100
4 2 0 0 6 50
4 2 0 0 -39 77
3 1 1 4 -1 100
5 3 -7 13 9 88
1 3 2 0 -7 100
3 4 2 0 3 88
 2 2
1 1 0 4 0 5
2 2 4 0 5 0
 2 2
1 2 0 4 0 4
2 1 0 4 0 4
 2 2
1 2 0 3 0 5
2 1 0 4 0 6

0
 1.0000000000
 0.2500000000
 0
 1.0000000000
 0.2121212000
 0.6666666000
 1.0000000000
 1.0000000000
 1.0000000000
 1.0000000000

#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-9;
const int N = 20000;
const int M = 20000;
int n, m;
struct data {
  int u, v, ax, bx, cx, dx;
} e[M + 10];
namespace flow {
const int INF = 1e9;
const double CINF = 1e18;
const int N = 20000;
const int M = 20000;
int n, s, t, head[N + 10], cur[N + 10], dis[N + 10], tot;
struct data {
  int next, num;
  double w;
} edge[M + 10];
queue<int> q;
void clear() {
  for (int i = 1; i <= n; i++) head[i] = -1;
  tot = -1;
}
void Addedge(int u, int v, double w) {
  edge[++tot].next = head[u];
  edge[tot].num = v;
  edge[tot].w = w;
  head[u] = tot;
}
bool Bfs() {
  for (int i = 1; i <= n; i++) dis[i] = INF;
  q.push(s);
  dis[s] = 0;
  while (!q.empty()) {
    int k = q.front();
    q.pop();
    for (int i = head[k]; i != -1; i = edge[i].next) {
      if (abs(edge[i].w) < eps) continue;
      int kx = edge[i].num;
      if (dis[k] + 1 < dis[kx]) {
        dis[kx] = dis[k] + 1;
        q.push(kx);
      }
    }
  }
  if (dis[t] == INF) return 0;
  return 1;
}
double Dfs(int x, double ax) {
  if (ax == 0 || x == t) return ax;
  double flow = 0;
  for (int &i = cur[x]; i != -1; i = edge[i].next) {
    int kx = edge[i].num;
    if (abs(edge[i].w) < 1e-12 || dis[kx] != dis[x] + 1) continue;
    double nowf = Dfs(kx, min(ax, edge[i].w));
    edge[i].w -= nowf;
    edge[i ^ 1].w += nowf;
    ax -= nowf;
    flow += nowf;
    if (ax == 0) break;
  }
  return flow;
}
double Maxflow() {
  double ans = 0;
  while (Bfs()) {
    memcpy(cur, head, sizeof(head));
    ans += Dfs(s, CINF);
  }
  return ans;
}
bool vvis[N + 10];
void Ddfs(int x) {
  vvis[x] = 1;
  for (int i = head[x]; i != -1; i = edge[i].next) {
    int kx = edge[i].num;
    if (vvis[kx] || abs(edge[i].w) < 1e-12) continue;
    Ddfs(kx);
  }
}
}  // namespace flow
namespace task {
double Runflow(double x) {
  flow::n = flow::t = n + 2;
  flow::s = n + 1;
  flow::clear();
  double sum = 0;
  for (int i = 1; i <= m; i++) {
    double lx = x * e[i].ax + e[i].bx;
    double rx = x * e[i].cx + e[i].dx;
    flow::Addedge(e[i].u, e[i].v, rx - lx);
    flow::Addedge(e[i].v, e[i].u, 0);
    flow::Addedge(flow::s, e[i].v, lx);
    flow::Addedge(e[i].v, flow::s, 0);
    flow::Addedge(e[i].u, flow::t, lx);
    flow::Addedge(flow::t, e[i].u, lx);
    sum += lx;
  }
  return sum - flow::Maxflow();
}
int Getk(double x) {
  flow::n = flow::t = n + 2;
  flow::s = n + 1;
  flow::clear();
  int k = 0;
  for (int i = 1; i <= m; i++) {
    double lx = x * e[i].ax + e[i].bx;
    double rx = x * e[i].cx + e[i].dx;
    flow::Addedge(e[i].u, e[i].v, rx - lx);
    flow::Addedge(e[i].v, e[i].u, 0);
    flow::Addedge(flow::s, e[i].v, lx);
    flow::Addedge(e[i].v, flow::s, 0);
    flow::Addedge(e[i].u, flow::t, lx);
    flow::Addedge(flow::t, e[i].u, lx);
    k += e[i].ax;
  }
  flow::Maxflow();
  for (int i = 1; i <= n; i++) flow::vvis[i] = 0;
  flow::Ddfs(flow::s);
  for (int i = 1; i <= m; i++) {
    if (flow::vvis[e[i].u] && !flow::vvis[e[i].v]) k -= e[i].cx - e[i].ax;
    if (!flow::vvis[e[i].v]) k -= e[i].ax;
    if (flow::vvis[e[i].u]) k -= e[i].ax;
  }
  return k;
}
double Find() {
  double lx = 0, rx = 1;
  for (int T = 1; T <= 50; T++) {
    double mid = (lx + rx) / 2;
    if (Getk(mid) < 0)
      lx = mid;
    else
      rx = mid;
  }
  return lx;
}
double Calc1(double rx) {
  double lx = 0;
  for (int T = 1; T <= 50; T++) {
    double mid = (lx + rx) / 2;
    if (Runflow(mid) > eps)
      lx = mid;
    else
      rx = mid;
  }
  return lx;
}
double Calc2(double lx) {
  double rx = 1;
  for (int T = 1; T <= 50; T++) {
    double mid = (lx + rx) / 2;
    if (Runflow(mid) > eps)
      rx = mid;
    else
      lx = mid;
  }
  return lx;
}
double Solve() {
  double loc = Find();
  double lx = Calc1(loc);
  double rx = Calc2(loc);
  return rx - lx;
}
}  // namespace task
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= m; i++) {
    scanf("%d%d", &e[i].u, &e[i].v);
    scanf("%d%d%d%d", &e[i].ax, &e[i].bx, &e[i].cx, &e[i].dx);
  }
  double ans = task::Solve();
  printf("%.10lf\n", ans);
  return 0;
}
