```go
package main
import (
"bufio"
"container/heap"
"fmt"
"os"
)
const INF = int64(2e18)
func max(a, b int64) int64 {
if a > b {
return a
}
return b
}
type IntHeap []int64
func (h IntHeap) Len() int { return len(h) }
func (h IntHeap) Less(i, j int) bool { return h[i] > h[j] }
func (h IntHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
func (h *IntHeap) Push(x any) { *h = append(*h, x.(int64)) }
func (h *IntHeap) Pop() any {
old := *h
n := len(old)
x := old[n-1]
*h = old[0 : n-1]
return x
}
type MaxHeap struct {
add IntHeap
rem IntHeap
}
func (h *MaxHeap) push(v int64) {
heap.Push(&h.add, v)
}
func (h *MaxHeap) pop(v int64) {
heap.Push(&h.rem, v)
}
func (h *MaxHeap) top() int64 {
for h.add.Len() > 0 && h.rem.Len() > 0 && h.add[0] == h.rem[0] {
heap.Pop(&h.add)
heap.Pop(&h.rem)
}
if h.add.Len() > 0 {
return h.add[0]
}
return -INF
}
var (
M_max []int64
ans []int64
heaps []MaxHeap
)
func updateNode(idx int, isLeaf bool) {
if !isLeaf {
left := 2 * idx
right := 2*idx + 1
M_max[idx] = max(M_max[left], M_max[right])
ans[idx] = max(ans[left], ans[right])
} else {
ans[idx] = -INF
}
t := heaps[idx].top()
if t != -INF && M_max[idx] != -INF {
ans[idx] = max(ans[idx], M_max[idx]+t)
}
}
func build(idx, l, r int) {
M_max[idx] = -INF
ans[idx] = -INF
if l == r {
return
}
mid := (l + r) / 2
build(2*idx, l, mid)
build(2*idx+1, mid+1, r)
}
func activate(idx, l, r, pos int, val int64) {
if l == r {
M_max[idx] = val
updateNode(idx, true)
return
}
mid := (l + r) / 2
if pos <= mid {
activate(2*idx, l, mid, pos, val)
} else {
activate(2*idx+1, mid+1, r, pos, val)
}
updateNode(idx, false)
}
func addK(idx, l, r, ql, qr int, val int64) {
if ql <= l && r <= qr {
heaps[idx].push(val)
updateNode(idx, l == r)
return
}
mid := (l + r) / 2
if ql <= mid {
addK(2*idx, l, mid, ql, qr, val)
}
if qr > mid {
addK(2*idx+1, mid+1, r, ql, qr, val)
}
updateNode(idx, l == r)
}
func removeK(idx, l, r, ql, qr int, val int64) {
if ql <= l && r <= qr {
heaps[idx].pop(val)
updateNode(idx, l == r)
return
}
mid := (l + r) / 2
if ql <= mid {
removeK(2*idx, l, mid, ql, qr, val)
}
if qr > mid {
removeK(2*idx+1, mid+1, r, ql, qr, val)
}
updateNode(idx, l == r)
}
func query(idx, l, r, ql, qr int) int64 {
if ql <= l && r <= qr {
return ans[idx]
}
mid := (l + r) / 2
res := int64(-INF)
if ql <= mid {
res = max(res, query(2*idx, l, mid, ql, qr))
}
if qr > mid {
res = max(res, query(2*idx+1, mid+1, r, ql, qr))
}
t := heaps[idx].top()
if t != -INF {
subMax := int64(-INF)
if ql <= l && r <= qr {
subMax = M_max[idx]
} else {
subMax = queryM(idx, l, r, ql, qr)
}
if subMax != -INF {
res = max(res, subMax+t)
}
}
return res
}
func queryM(idx, l, r, ql, qr int) int64 {
if ql <= l && r <= qr {
return M_max[idx]
}
mid := (l + r) / 2
res := int64(-INF)
if ql <= mid {
res = max(res, queryM(2*idx, l, mid, ql, qr))
}
if qr > mid {
res = max(res, queryM(2*idx+1, mid+1, r, ql, qr))
}
return res
}
type Offer struct {
l, r int
k int64
}
func main() {
scanner := bufio.NewScanner(os.Stdin)
scanner.Split(bufio.ScanWords)
readInt := func() int {
scanner.Scan()
var res int
sign := 1
for i, b := range scanner.Bytes() {
if i == 0 && b == '-' {
sign = -1
continue
}
res = res*10 + int(b-'0')
}
return res * sign
}
readInt64 := func() int64 {
scanner.Scan()
var res int64
sign := int64(1)
for i, b := range scanner.Bytes() {
if i == 0 && b == '-' {
sign = -1
continue
}
res = res*10 + int64(b-'0')
}
return res * sign
}
n := readInt()
q := readInt()
a1 := make([]int64, n+1)
for i := 1; i <= n; i++ {
a1[i] = readInt64()
}
a2 := make([]int64, n+1)
for i := 1; i <= n; i++ {
a2[i] = readInt64()
}
a3 := make([]int64, n+1)
for i := 1; i <= n; i++ {
a3[i] = readInt64()
}
startAt := make([][]Offer, n+2)
endAt := make([][]Offer, n+2)
for i := 0; i < q; i++ {
l := readInt()
r := readInt()
k := readInt64()
o := Offer{l, r, k}
startAt[l] = append(startAt[l], o)
endAt[r] = append(endAt[r], o)
}
P1 := make([]int64, n+1)
P2 := make([]int64, n+1)
P3 := make([]int64, n+1)
for i := 1; i <= n; i++ {
P1[i] = P1[i-1] + a1[i]
P2[i] = P2[i-1] + a2[i]
P3[i] = P3[i-1] + a3[i]
}
X := make([]int64, n+2)
for i := 1; i <= n; i++ {
X[i] = P1[i] - P2[i-1]
}
X[n+1] = -INF
Y := make([]int64, n+2)
for i := 1; i <= n; i++ {
Y[i] = P2[i] - P3[i-1]
}
M_max = make([]int64, 4*(n+1))
ans = make([]int64, 4*(n+1))
heaps = make([]MaxHeap, 4*(n+1))
build(1, 0, n)
DP := make([]int64, n+2)
for i := 0; i <= n+1; i++ {
DP[i] = -INF
}
finalAns := int64(-INF)
for y := 1; y <= n; y++ {
mVal := X[y]
if DP[y-1] != -INF {
mVal = max(mVal, DP[y-1])
}
activate(1, 0, n, y-1, mVal)
for _, o := range startAt[y] {
addK(1, 0, n, o.l-1, o.r-1, -o.k)
}
for _, o := range endAt[y-1] {
removeK(1, 0, n, o.l-1, o.r-1, -o.k)
}
DP[y] = query(1, 0, n, 0, y-1)
if y < n {
DP[y] = max(DP[y], X[y+1])
}
if DP[y] != -INF {
finalAns = max(finalAns, DP[y]+Y[y])
}
}
fmt.Println(finalAns + P3[n])
}
```