← Home
```go
package main

import (
	"container/heap"
	"fmt"
	"io"
	"os"
	"sort"
)

type Edge struct {
	to     int
	weight int64
}

type Item struct {
	v int
	d int64
}

type MinHeap []Item

func (h MinHeap) Len() int           { return len(h) }
func (h MinHeap) Less(i, j int) bool { return h[i].d < h[j].d }
func (h MinHeap) Swap(i, j int)      { h[i], h[j] = h[j], h[i] }
func (h *MinHeap) Push(x interface{}) {
	*h = append(*h, x.(Item))
}
func (h *MinHeap) Pop() interface{} {
	old := *h
	n := len(old)
	x := old[n-1]
	*h = old[0 : n-1]
	return x
}

func dijkstra(start int, n int, adj [][]Edge) []int64 {
	dist := make([]int64, n+1)
	for i := 1; i <= n; i++ {
		dist[i] = -1
	}
	dist[start] = 0
	h := &MinHeap{}
	heap.Init(h)
	heap.Push(h, Item{v: start, d: 0})
	for h.Len() > 0 {
		curr := heap.Pop(h).(Item)
		u := curr.v
		d := curr.d
		if d > dist[u] {
			continue
		}
		for _, edge := range adj[u] {
			v := edge.to
			w := edge.weight
			if dist[v] == -1 || dist[u]+w < dist[v] {
				dist[v] = dist[u] + w
				heap.Push(h, Item{v: v, d: dist[v]})
			}
		}
	}
	return dist
}

func unique(a []int64) []int64 {
	sort.Slice(a, func(i, j int) bool { return a[i] < a[j] })
	res := make([]int64, 0, len(a))
	for i, v := range a {
		if i == 0 || v != a[i-1] {
			res = append(res, v)
		}
	}
	return res
}

func getRank(a []int64, val int64) int {
	l, r := 0, len(a)-1
	for l <= r {
		m := l + (r-l)/2
		if a[m] == val {
			return m
		} else if a[m] < val {
			l = m + 1
		} else {
			r = m - 1
		}
	}
	return -1
}

func main() {
	data, _ := io.ReadAll(os.Stdin)
	pos := 0

	nextInt := func() int {
		for pos < len(data) && data[pos] <= ' ' {
			pos++
		}
		if pos >= len(data) {
			return 0
		}
		sign := 1
		if data[pos] == '-' {
			sign = -1
			pos++
		}
		res := 0
		for pos < len(data) && data[pos] > ' ' {
			res = res*10 + int(data[pos]-'0')
			pos++
		}
		return res * sign
	}

	nextInt64 := func() int64 {
		for pos < len(data) && data[pos] <= ' ' {
			pos++
		}
		if pos >= len(data) {
			return 0
		}
		sign := int64(1)
		if data[pos] == '-' {
			sign = -1
			pos++
		}
		res := int64(0)
		for pos < len(data) && data[pos] > ' ' {
			res = res*10 + int64(data[pos]-'0')
			pos++
		}
		return res * sign
	}

	n := nextInt()
	if n == 0 {
		return
	}
	m := nextInt()
	s := nextInt()
	t := nextInt()

	P := make([]int64, n+1)
	for i := 1; i <= n; i++ {
		P[i] = nextInt64()
	}

	adj := make([][]Edge, n+1)
	for i := 0; i < m; i++ {
		u := nextInt()
		v := nextInt()
		w := nextInt64()
		adj[u] = append(adj[u], Edge{to: v, weight: w})
		adj[v] = append(adj[v], Edge{to: u, weight: w})
	}

	distS := dijkstra(s, n, adj)
	distT := dijkstra(t, n, adj)

	distS_copy := make([]int64, 0, n+1)
	distT_copy := make([]int64, 0, n+1)
	distS_copy = append(distS_copy, -1)
	distT_copy = append(distT_copy, -1)

	for i := 1; i <= n; i++ {
		distS_copy = append(distS_copy, distS[i])
		distT_copy = append(distT_copy, distT[i])
	}

	distS_distinct := unique(distS_copy)
	distT_distinct := unique(distT_copy)

	ks := len(distS_distinct) - 1
	kt := len(distT_distinct) - 1

	Rs := make([]int, n+1)
	Rt := make([]int, n+1)
	for i := 1; i <= n; i++ {
		Rs[i] = getRank(distS_distinct, distS[i])
		Rt[i] = getRank(distT_distinct, distT[i])
	}

	cols := kt + 1
	sumP := make([]int64, (ks+1)*cols)
	for v := 1; v <= n; v++ {
		sumP[Rs[v]*cols+Rt[v]] += P[v]
	}

	F := make([]int64, (ks+1)*cols)
	row_suf := make([]int64, kt+2)
	for i := 0; i <= ks; i++ {
		for j := 0; j <= kt+1; j++ {
			row_suf[j] = 0
		}
		for j := kt; j >= 0; j-- {
			row_suf[j] = row_suf[j+1] + sumP[i*cols+j]
		}
		for j := 0; j <= kt; j++ {
			if i > 0 {
				F[i*cols+j] = F[(i-1)*cols+j] + row_suf[j+1]
			} else {
				F[i*cols+j] = row_suf[j+1]
			}
		}
	}

	G := make([]int64, (ks+1)*cols)
	col_suf := make([]int64, ks+2)
	for j := 0; j <= kt; j++ {
		for i := 0; i <= ks+1; i++ {
			col_suf[i] = 0
		}
		for i := ks; i >= 0; i-- {
			col_suf[i] = col_suf[i+1] + sumP[i*cols+j]
		}
		for i := 0; i <= ks; i++ {
			if j > 0 {
				G[i*cols+j] = G[i*cols+(j-1)] + col_suf[i+1]
			} else {
				G[i*cols+j] = col_suf[i+1]
			}
		}
	}

	max_Rt := make([]int, ks+1)
	max_Rs := make([]int, kt+1)
	for i := 0; i <= ks; i++ {
		max_Rt[i] = -1
	}
	for j := 0; j <= kt; j++ {
		max_Rs[j] = -1
	}
	for v := 1; v <= n; v++ {
		rS := Rs[v]
		rT := Rt[v]
		if rT > max_Rt[rS] {
			max_Rt[rS] = rT
		}
		if rS > max_Rs[rT] {
			max_Rs[rT] = rS
		}
	}

	next_i := make([]int32, (ks+1)*cols)
	for j := 0; j <= kt; j++ {
		next_i[ks*cols+j] = int32(ks + 1)
		for i := ks - 1; i >= 0; i-- {
			if max_Rt[i+1] > j {
				next_i[i*cols+j] = int32(i + 1)
			} else {
				next_i[i*cols+j] = next_i[(i+1)*cols+j]
			}
		}
	}

	next_j := make([]int32, (ks+1)*cols)
	for i := 0; i <= ks; i++ {
		next_j[i*cols+kt] = int32(kt + 1)
		for j := kt - 1; j >= 0; j-- {
			if max_Rs[j+1] > i {
				next_j[i*cols+j] = int32(j + 1)
			} else {
				next_j[i*cols+j] = next_j[i*cols+(j+1)]
			}
		}
	}

	suf_T := make([]int64, (ks+2)*cols)
	suf_N := make([]int64, kt+2)
	const INF = int64(2e18)

	for i := 0; i < len(suf_T); i++ {
		suf_T[i] = -INF
	}

	var dp0_00 int64

	for i := ks; i >= 0; i-- {
		for j := 0; j <= kt+1; j++ {
			suf_N[j] = -INF
		}

		for j := kt; j >= 0; j-- {
			idx := i*cols + j

			var dp0 int64
			ni := int(next_i[idx])
			if ni > ks {
				dp0 = 0
			} else {
				dp0 = -F[idx] + suf_T[ni*cols+j]
			}

			var dp1 int64
			nj := int(next_j[idx])
			if nj > kt {
				dp1 = 0
			} else {
				dp1 = -G[idx] + suf_N[nj]
			}

			if i == 0 && j == 0 {
				dp0_00 = dp0
			}

			val_T := F[idx] - dp1
			if val_T > suf_T[(i+1)*cols+j] {
				suf_T[i*cols+j] = val_T
			} else {
				suf_T[i*cols+j] = suf_T[(i+1)*cols+j]
			}

			val_N := G[idx] - dp0
			if val_N > suf_N[j+1] {
				suf_N[j] = val_N
			} else {
				suf_N[j] = suf_N[j+1]
			}
		}
	}

	if dp0_00 > 0 {
		fmt.Println("Break a heart")
	} else if dp0_00 < 0 {
		fmt.Println("Cry")
	} else {
		fmt.Println("Flowers")
	}
}
```