← Home
package main

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

type Update struct {
	t int64
	h int64
}

func main() {
	data, _ := io.ReadAll(os.Stdin)
	fs := &fastScanner{b: data}
	n := int(fs.nextInt())
	m := int(fs.nextInt())
	bounty := fs.nextInt()
	increase := fs.nextInt()
	damage := fs.nextInt()

	maxH := make([]int64, n)
	startH := make([]int64, n)
	regen := make([]int64, n)
	for i := 0; i < n; i++ {
		maxH[i] = fs.nextInt()
		startH[i] = fs.nextInt()
		regen[i] = fs.nextInt()
	}

	ups := make([][]Update, n)
	for i := 0; i < m; i++ {
		t := fs.nextInt()
		e := int(fs.nextInt()) - 1
		h := fs.nextInt()
		ups[e] = append(ups[e], Update{t: t, h: h})
	}
	for i := 0; i < n; i++ {
		if len(ups[i]) > 0 {
			sort.Slice(ups[i], func(a, b int) bool { return ups[i][a].t < ups[i][b].t })
		}
	}

	diff := make(map[int64]int64)
	const INF int64 = 1 << 60
	incPos := increase > 0
	tailCount := int64(0)

	for i := 0; i < n; i++ {
		prevT := int64(0)
		baseH := startH[i]
		r := regen[i]
		mx := maxH[i]
		u := ups[i]
		for j := 0; j <= len(u); j++ {
			nextT := INF
			if j < len(u) {
				nextT = u[j].t
			}
			if mx <= damage {
				if incPos {
					fmt.Println(-1)
					return
				} else {
					if nextT < INF {
						L := prevT
						R := nextT - 1
						if R >= L {
							diff[L]++
							diff[R+1]--
						}
					} else {
						tailCount++
					}
				}
			} else {
				if r == 0 {
					if baseH <= damage {
						if nextT < INF {
							L := prevT
							R := nextT - 1
							if R >= L {
								diff[L]++
								diff[R+1]--
							}
						} else {
							if incPos {
								fmt.Println(-1)
								return
							} else {
								tailCount++
							}
						}
					}
				} else {
					if baseH <= damage {
						endCand := prevT + (damage-baseH)/r
						R := endCand
						if nextT < INF && R > nextT-1 {
							R = nextT - 1
						}
						if R >= prevT {
							diff[prevT]++
							diff[R+1]--
						}
					}
				}
			}
			if j < len(u) {
				prevT = nextT
				baseH = u[j].h
			}
		}
	}

	if incPos && tailCount > 0 {
		fmt.Println(-1)
		return
	}

	if len(diff) == 0 {
		if incPos {
			fmt.Println(0)
		} else {
			fmt.Println(tailCount * bounty)
		}
		return
	}

	keys := make([]int64, 0, len(diff))
	for k := range diff {
		keys = append(keys, k)
	}
	sort.Slice(keys, func(i, j int) bool { return keys[i] < keys[j] })

	cur := int64(0)
	best := int64(0)
	for i := 0; i < len(keys); i++ {
		cur += diff[keys[i]]
		if incPos {
			if i+1 < len(keys) {
				tr := keys[i+1] - 1
				if tr >= keys[i] {
					val := cur * (bounty + increase*tr)
					if val > best {
						best = val
					}
				}
			}
		} else {
			val := cur * bounty
			if val > best {
				best = val
			}
		}
	}
	if !incPos {
		val := tailCount * bounty
		if val > best {
			best = val
		}
	}
	fmt.Println(best)
}

type fastScanner struct {
	b []byte
	i int
}

func (fs *fastScanner) nextInt() int64 {
	n := int64(0)
	sign := int64(1)
	for fs.i < len(fs.b) && (fs.b[fs.i] == ' ' || fs.b[fs.i] == '\n' || fs.b[fs.i] == '\r' || fs.b[fs.i] == '\t') {
		fs.i++
	}
	if fs.i < len(fs.b) && fs.b[fs.i] == '-' {
		sign = -1
		fs.i++
	}
	for fs.i < len(fs.b) {
		c := fs.b[fs.i]
		if c < '0' || c > '9' {
			break
		}
		n = n*10 + int64(c-'0')
		fs.i++
	}
	for fs.i < len(fs.b) && (fs.b[fs.i] == ' ' || fs.b[fs.i] == '\n' || fs.b[fs.i] == '\r' || fs.b[fs.i] == '\t') {
		fs.i++
	}
	return n * sign
}

func _(_ ...interface{}) {}