#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,abm,mmx,tune=native")
using namespace std;
const int64_t INF = (int64_t)(2e18);
const int inf = (int)(1e9 + 7);
const int maxn = 500 * 1000 + 100;
chrono::time_point<chrono::steady_clock> cl;
double current_time() {
  return (double)(chrono::steady_clock::now() - cl).count() / 1e9;
}
int s, t;
int n, m;
int from[maxn];
int to[maxn];
int flow[maxn];
int cost[maxn];
int cp[maxn];
int cnts[maxn];
int cntst[maxn];
int cntsval[maxn];
int used[maxn];
int pot[maxn];
int minpot[maxn];
int maxpot[maxn];
vector<pair<int, int>> g[maxn];
vector<pair<int, int>> gt[maxn];
vector<array<int, 3>> gval[maxn];
void minmaxdfs(int v) {
  used[v] = 1;
  minpot[v] = pot[v];
  maxpot[v] = pot[v];
  for (int i = 0; i < cnts[v]; ++i) {
    auto& it = g[v][i];
    int to = it.first;
    int ind = it.second;
    if (used[to]) continue;
    minmaxdfs(to);
    minpot[v] = min(minpot[v], minpot[to]);
    maxpot[v] = max(maxpot[v], maxpot[to]);
  }
}
void dfspot(int v) {
  used[v] = 1;
  for (int i = 0; i < cntsval[v]; ++i) {
    auto& it = gval[v][i];
    int to = it[0];
    int ind = it[1];
    int mult = it[2];
    if (used[to]) continue;
    pot[to] = pot[v] - mult * flow[ind] * cost[ind];
    dfspot(to);
  }
}
bool can = true;
bool good(int k) {
  fill(minpot, minpot + n, inf);
  fill(maxpot, maxpot + n, -inf);
  fill(cnts, cnts + n, 0);
  fill(cntst, cntst + n, 0);
  fill(cntsval, cntsval + n, 0);
  for (int i = 0; i <= k; ++i) {
    ++cnts[from[i]];
    ++cntst[to[i]];
    ++cntsval[from[i]];
    ++cntsval[to[i]];
  }
  fill(used, used + n, 0);
  fill(pot, pot + n, 0);
  dfspot(s);
  for (int i = 0; i < n; ++i) {
    if (used[i] == 0) continue;
    if (i != s && pot[i] >= pot[s]) return false;
  }
  fill(used, used + n, 0);
  fill(pot, pot + n, 0);
  dfspot(t);
  for (int i = 0; i < n; ++i) {
    if (used[i] == 0) continue;
    if (i != t && pot[i] <= pot[t]) return false;
  }
  fill(used, used + n, 0);
  fill(pot, pot + n, 0);
  for (int i = 0; i < n; ++i) {
    if (used[i]) continue;
    pot[i] = 0;
    dfspot(i);
    if (i == 0) {
      can = used[t];
      for (int j = 0; j < n; ++j) cp[j] = used[j];
    }
  }
  for (int i = 0; i <= k; ++i) {
    if (pot[from[i]] - flow[i] * cost[i] != pot[to[i]]) return false;
  }
  fill(used, used + n, 0);
  for (int i = 0; i < n; ++i) {
    if (used[i]) continue;
    minmaxdfs(i);
  }
  if (can == false) return true;
  for (int i = 0; i < n; ++i) {
    int val = maxpot[i] - minpot[i];
    if (cp[i] == 0)
      if (pot[s] - pot[t] <= val) return false;
  }
  return true;
}
int32_t main() {
  cl = chrono::steady_clock::now();
  ios_base::sync_with_stdio(false);
  cout << fixed << setprecision(10);
  cin.tie(nullptr);
  cin >> n >> m;
  s = 0;
  t = n - 1;
  for (int i = 0; i < m; ++i) {
    cin >> from[i] >> to[i];
    --from[i];
    --to[i];
    cin >> flow[i] >> cost[i];
  }
  for (int i = 0; i < m; ++i) {
    g[from[i]].push_back(make_pair(to[i], i));
    gt[to[i]].push_back(make_pair(from[i], i));
    gval[from[i]].push_back({to[i], i, 1});
    gval[to[i]].push_back({from[i], i, -1});
  }
  int l = 0;
  int r = m;
  while (l < r) {
    int mid = (l + r) / 2;
    bool curres = good(mid);
    if (curres)
      l = mid + 1;
    else
      r = mid;
  }
  if (l != m) {
    cout << "BAD " << r + 1;
    return 0;
  }
  good(m - 1);
  if (can) {
    cout << pot[s] - pot[t];
  } else {
    cout << "UNKNOWN";
  }
  return 0;
}
