← Home
package main

import (
	"fmt"
	"io"
	"os"
)

var buf []byte
var bufIdx int

func nextInt() int {
	for bufIdx < len(buf) && (buf[bufIdx] < '0' || buf[bufIdx] > '9') && buf[bufIdx] != '-' {
		bufIdx++
	}
	if bufIdx >= len(buf) {
		return 0
	}
	sign := 1
	if buf[bufIdx] == '-' {
		sign = -1
		bufIdx++
	}
	res := 0
	for bufIdx < len(buf) && buf[bufIdx] >= '0' && buf[bufIdx] <= '9' {
		res = res*10 + int(buf[bufIdx]-'0')
		bufIdx++
	}
	return res * sign
}

func main() {
	buf, _ = io.ReadAll(os.Stdin)
	n := nextInt()
	m := nextInt()
	if n == 0 {
		return
	}

	parent := make([]int, n+1)
	size := make([]int, n+1)
	diff := make([]int64, n+1)
	min_D := make([]int64, n+1)
	min_C := make([]int, n+1)
	max_D := make([]int64, n+1)
	max_C := make([]int, n+1)
	has_1 := make([]bool, n+1)
	has_n := make([]bool, n+1)
	val_1 := make([]int64, n+1)
	val_n := make([]int64, n+1)

	for i := 1; i <= n; i++ {
		parent[i] = i
		size[i] = 1
		diff[i] = 0
		min_D[i] = 0
		min_C[i] = 1
		max_D[i] = 0
		max_C[i] = 1
		if i == 1 {
			has_1[i] = true
		}
		if i == n {
			has_n[i] = true
		}
	}

	var find func(i int) int
	find = func(i int) int {
		if parent[i] == i {
			return i
		}
		p := parent[i]
		root := find(p)
		diff[i] += diff[p]
		parent[i] = root
		return root
	}

	K_limit := int64(-1)

	for i := 1; i <= m; i++ {
		u := nextInt()
		v := nextInt()
		w := int64(nextInt())
		b := int64(nextInt())

		delta := b * w
		ru := find(u)
		rv := find(v)

		if ru == rv {
			if diff[v]-diff[u] != delta {
				fmt.Printf("BAD %d\n", i)
				return
			}
			continue
		}

		offset := delta + diff[u] - diff[v]

		if size[ru] < size[rv] {
			ru, rv = rv, ru
			offset = -offset
		}

		new_min_D := min_D[ru]
		if min_D[rv]+offset < new_min_D {
			new_min_D = min_D[rv] + offset
		}
		new_min_C := 0
		if new_min_D == min_D[ru] {
			new_min_C += min_C[ru]
		}
		if new_min_D == min_D[rv]+offset {
			new_min_C += min_C[rv]
		}

		new_max_D := max_D[ru]
		if max_D[rv]+offset > new_max_D {
			new_max_D = max_D[rv] + offset
		}
		new_max_C := 0
		if new_max_D == max_D[ru] {
			new_max_C += max_C[ru]
		}
		if new_max_D == max_D[rv]+offset {
			new_max_C += max_C[rv]
		}

		new_has_1 := has_1[ru] || has_1[rv]
		new_val_1 := int64(0)
		if has_1[ru] {
			new_val_1 = val_1[ru]
		} else if has_1[rv] {
			new_val_1 = val_1[rv] + offset
		}

		new_has_n := has_n[ru] || has_n[rv]
		new_val_n := int64(0)
		if has_n[ru] {
			new_val_n = val_n[ru]
		} else if has_n[rv] {
			new_val_n = val_n[rv] + offset
		}

		if new_has_1 {
			if new_min_D != new_val_1 || new_min_C != 1 {
				fmt.Printf("BAD %d\n", i)
				return
			}
		}
		if new_has_n {
			if new_max_D != new_val_n || new_max_C != 1 {
				fmt.Printf("BAD %d\n", i)
				return
			}
		}

		if new_has_1 && new_has_n {
			K := new_val_n - new_val_1
			if K <= 0 {
				fmt.Printf("BAD %d\n", i)
				return
			}
			if K_limit == -1 {
				K_limit = K
				for j := 1; j <= n; j++ {
					if parent[j] == j && j != ru && j != rv {
						if max_D[j]-min_D[j] >= K_limit {
							fmt.Printf("BAD %d\n", i)
							return
						}
					}
				}
			} else {
				if K != K_limit {
					fmt.Printf("BAD %d\n", i)
					return
				}
			}
		} else {
			if K_limit != -1 {
				if new_max_D-new_min_D >= K_limit {
					fmt.Printf("BAD %d\n", i)
					return
				}
			}
		}

		parent[rv] = ru
		size[ru] += size[rv]
		diff[rv] = offset
		min_D[ru] = new_min_D
		min_C[ru] = new_min_C
		max_D[ru] = new_max_D
		max_C[ru] = new_max_C
		has_1[ru] = new_has_1
		val_1[ru] = new_val_1
		has_n[ru] = new_has_n
		val_n[ru] = new_val_n
	}

	if K_limit != -1 {
		fmt.Println(K_limit)
	} else {
		fmt.Println("UNKNOWN")
	}
}