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;
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
const int MAXN = 1000;
const int MAXM = 2000;
struct E {
  int from, to, al, bl, ar, br;
  double l, r;
};
const int GMAXN = MAXN + 2;
const int GMAXM = 2 * MAXN + MAXM;
const double eps = 1e-12;
struct G {
  int n, m;
  int ghead[GMAXN], gnxt[2 * GMAXM], gto[2 * GMAXM];
  double gcap[2 * GMAXM];
  int level[GMAXN];
  int q[GMAXN], qhead, qtail;
  int gcur[GMAXN];
  int path[GMAXN], npath;
  bool incut[2 * GMAXM];
  void init(int _n) {
    n = _n, m = 0;
    for (int i = (0); i < (n); ++i) ghead[i] = -1;
  }
  int addedge(int a, int b, double cap) {
    int ret = m;
    gnxt[m] = ghead[a], ghead[a] = m, gto[m] = b, gcap[m] = cap;
    ++m;
    gnxt[m] = ghead[b], ghead[b] = m, gto[m] = a, gcap[m] = 0;
    ++m;
    return ret;
  }
  bool calclevel(int s, int t) {
    for (int i = (0); i < (n); ++i) level[i] = -1;
    qhead = qtail = 0;
    level[s] = 0, q[qhead++] = s;
    while (qtail < qhead) {
      int at = q[qtail++];
      for (int x = ghead[at]; x != -1; x = gnxt[x])
        if (gcap[x] >= eps) {
          int to = gto[x];
          if (level[to] == -1) level[to] = level[at] + 1, q[qhead++] = to;
        }
    }
    return level[t] != -1;
  }
  bool augment(int at, int t, double lim, double &flow) {
    if (at == t) {
      flow = lim;
      path[npath++] = at;
      return true;
    }
    for (; gcur[at] != -1; gcur[at] = gnxt[gcur[at]]) {
      int x = gcur[at], to = gto[x];
      if (gcap[x] < eps || level[to] != level[at] + 1) continue;
      if (augment(to, t, min(lim, gcap[x]), flow)) {
        gcap[x] -= flow;
        gcap[x ^ 1] += flow;
        path[npath++] = at;
        return true;
      }
    }
    return false;
  }
  double maxflow(int s, int t) {
    double ret = 0;
    while (calclevel(s, t)) {
      for (int i = (0); i < (n); ++i) gcur[i] = ghead[i];
      while (true) {
        double cur;
        npath = 0;
        if (!augment(s, t, 1e200, cur)) break;
        ret += cur;
      }
    }
    return ret;
  }
  void calccut(int s, int t) {
    assert(!calclevel(s, t));
    for (int i = (0); i < (m); ++i) incut[i] = false;
    for (int at = (0); at < (n); ++at)
      if (level[at] >= 0)
        for (int x = ghead[at]; x != -1; x = gnxt[x])
          if (level[gto[x]] == -1) incut[x] = true;
  }
};
int n, m;
E e[MAXM];
G g;
double insum[MAXN], outsum[MAXN];
int inid[MAXN], outid[MAXN], eid[MAXM];
void findcut(double t, int &acut, int &bcut) {
  for (int i = (0); i < (m); ++i)
    e[i].l = e[i].al * t + e[i].bl, e[i].r = e[i].ar * t + e[i].br;
  for (int i = (0); i < (n); ++i) insum[i] = outsum[i] = 0;
  for (int i = (0); i < (m); ++i)
    outsum[e[i].from] += e[i].l, insum[e[i].to] += e[i].l;
  g.init(n + 2);
  int src = n, dst = n + 1;
  for (int i = (0); i < (n); ++i)
    inid[i] = insum[i] != 0 ? g.addedge(src, i, insum[i]) : -1;
  for (int i = (0); i < (n); ++i)
    outid[i] = outsum[i] != 0 ? g.addedge(i, dst, outsum[i]) : -1;
  for (int i = (0); i < (m); ++i)
    eid[i] =
        e[i].l < e[i].r ? g.addedge(e[i].from, e[i].to, e[i].r - e[i].l) : -1;
  g.maxflow(src, dst);
  g.calccut(src, dst);
  acut = bcut = 0;
  for (int i = (0); i < (m); ++i) acut -= e[i].al, bcut -= e[i].bl;
  for (int i = (0); i < (m); ++i) {
    if (eid[i] != -1 && g.incut[eid[i]])
      acut += e[i].ar - e[i].al, bcut += e[i].br - e[i].bl;
    if (outid[e[i].from] != -1 && g.incut[outid[e[i].from]])
      acut += e[i].al, bcut += e[i].bl;
    if (inid[e[i].to] != -1 && g.incut[inid[e[i].to]])
      acut += e[i].al, bcut += e[i].bl;
  }
}
bool findnonneg(double &tres) {
  double l = 0, r = 1;
  for (int rep = (0); rep < (100); ++rep) {
    if (l > r) return false;
    double m = l + (r - l) / 2;
    int a, b;
    findcut(m, a, b);
    if (a > 0) {
      if (a * m + b >= 0) {
        tres = m;
        return true;
      }
      double nl = -1.0 * b / a;
      assert(nl > l);
      l = nl;
    } else if (a < 0) {
      if (a * m + b >= 0) {
        tres = m;
        return true;
      }
      double nr = -1.0 * b / a;
      assert(nr < r);
      r = nr;
    } else {
      if (b >= 0) {
        tres = m;
        return true;
      }
      return false;
    }
  }
  printf("err: %.15lf..%15lf\n", l, r);
  return false;
}
double findtmn(double tok) {
  double l = 0, r = tok;
  for (int rep = (0); rep < (100); ++rep) {
    if (r - l < 1e-7) break;
    double m = l + (r - l) / 2;
    int a, b;
    findcut(m, a, b);
    if (a * m + b >= 0) {
      r = m;
    } else {
      assert(a > 0);
      double nl = -1.0 * b / a;
      assert(nl > l);
      l = nl;
    }
  }
  return r;
}
double findtmx(double tok) {
  double l = tok, r = 1;
  for (int rep = (0); rep < (100); ++rep) {
    if (r - l < 1e-7) break;
    double m = l + (r - l) / 2;
    int a, b;
    findcut(m, a, b);
    if (a * m + b >= 0) {
      l = m;
    } else {
      assert(a < 0);
      double nr = -1.0 * b / a;
      assert(nr < r);
      r = nr;
    }
  }
  return l;
}
void run() {
  scanf("%d%d", &n, &m);
  for (int i = (0); i < (m); ++i)
    scanf("%d%d%d%d%d%d", &e[i].from, &e[i].to, &e[i].al, &e[i].bl, &e[i].ar,
          &e[i].br),
        --e[i].from, --e[i].to;
  double tnonneg;
  if (!findnonneg(tnonneg)) {
    printf("0\n");
    return;
  }
  double tmn = findtmn(tnonneg);
  double tmx = findtmx(tnonneg);
  printf("%.15lf\n", tmx - tmn);
}
int main() {
  run();
  return 0;
}
