```go
package main
import (
"bufio"
"fmt"
"os"
"sort"
)
// Global IO
var reader *bufio.Reader
var writer *bufio.Writer
func printf(f string, a ...interface{}) { fmt.Fprintf(writer, f, a...) }
type Video struct {
l, r, id int
}
type Channel struct {
a, b, c, id int
}
func main() {
reader = bufio.NewReader(os.Stdin)
writer = bufio.NewWriter(os.Stdout)
defer writer.Flush()
scanner := bufio.NewScanner(os.Stdin)
scanner.Split(bufio.ScanWords)
scanInt := func() int {
scanner.Scan()
txt := scanner.Text()
val := 0
for _, ch := range txt {
val = val*10 + int(ch-'0')
}
return val
}
if !scanner.Scan() {
return
}
nVal := 0
for _, ch := range scanner.Text() {
nVal = nVal*10 + int(ch-'0')
}
n := nVal
m := scanInt()
videos := make([]Video, n)
for i := 0; i < n; i++ {
videos[i] = Video{l: scanInt(), r: scanInt(), id: i + 1}
}
channels := make([]Channel, m)
for i := 0; i < m; i++ {
channels[i] = Channel{a: scanInt(), b: scanInt(), c: scanInt(), id: i + 1}
}
bestEff := int64(-1)
bestV := -1
bestC := -1
update := func(eff int64, v, c int) {
if eff > bestEff {
bestEff = eff
bestV = v
bestC = c
}
}
// Phase 1: Left Anchored (l_i <= a_j)
solveLeftAnchored(n, m, videos, channels, update)
// Phase 2: Right Anchored (r_i >= b_j) - via coordinate reversal
const C = 1000000000
revVideos := make([]Video, n)
for i := 0; i < n; i++ {
revVideos[i] = Video{l: C - videos[i].r, r: C - videos[i].l, id: videos[i].id}
}
revChannels := make([]Channel, m)
for i := 0; i < m; i++ {
revChannels[i] = Channel{a: C - channels[i].b, b: C - channels[i].a, c: channels[i].c, id: channels[i].id}
}
solveLeftAnchored(n, m, revVideos, revChannels, update)
// Phase 3: Inside (a_j <= l_i <= r_i <= b_j)
solveInside(n, m, videos, channels, update)
if bestEff <= 0 {
printf("0\n")
} else {
printf("%d\n", bestEff)
printf("%d %d\n", bestV, bestC)
}
}
func solveLeftAnchored(n, m int, vs []Video, cs []Channel, update func(int64, int, int)) {
vSorted := make([]Video, n)
copy(vSorted, vs)
sort.Slice(vSorted, func(i, j int) bool {
return vSorted[i].l < vSorted[j].l
})
cSorted := make([]Channel, m)
copy(cSorted, cs)
sort.Slice(cSorted, func(i, j int) bool {
return cSorted[i].a < cSorted[j].a
})
vIdx := 0
maxR := -1
maxRIdx := -1
for _, ch := range cSorted {
for vIdx < n && vSorted[vIdx].l <= ch.a {
if vSorted[vIdx].r > maxR {
maxR = vSorted[vIdx].r
maxRIdx = vSorted[vIdx].id
}
vIdx++
}
if maxRIdx != -1 {
end := maxR
if ch.b < end {
end = ch.b
}
start := ch.a
if end > start {
eff := int64(end-start) * int64(ch.c)
update(eff, maxRIdx, ch.id)
}
}
}
}
type SegNode struct {
val, id int
}
type SegTree struct {
size int
tree []SegNode
}
func newSegTree(sz int) *SegTree {
n := 1
for n < sz {
n *= 2
}
st := &SegTree{size: n, tree: make([]SegNode, 2*n)}
for i := range st.tree {
st.tree[i] = SegNode{-1, -1}
}
return st
}
func (st *SegTree) update(pos, val, id int) {
idx := pos + st.size
if val > st.tree[idx].val {
st.tree[idx] = SegNode{val, id}
}
for idx > 1 {
idx /= 2
left := st.tree[2*idx]
right := st.tree[2*idx+1]
if left.val >= right.val {
st.tree[idx] = left
} else {
st.tree[idx] = right
}
}
}
func (st *SegTree) query(l, r int) (int, int) {
l += st.size
r += st.size
resVal := -1
resId := -1
for l < r {
if l%2 == 1 {
if st.tree[l].val > resVal {
resVal = st.tree[l].val
resId = st.tree[l].id
}
l++
}
if r%2 == 1 {
r--
if st.tree[r].val > resVal {
resVal = st.tree[r].val
resId = st.tree[r].id
}
}
l /= 2
r /= 2
}
return resVal, resId
}
func solveInside(n, m int, vs []Video, cs []Channel, update func(int64, int, int)) {
coords := make([]int, 0, n+m)
for _, v := range vs {
coords = append(coords, v.l)
}
for _, c := range cs {
coords = append(coords, c.a)
}
sort.Ints(coords)
uniqueCoords := make([]int, 0, len(coords))
if len(coords) > 0 {
uniqueCoords = append(uniqueCoords, coords[0])
for i := 1; i < len(coords); i++ {
if coords[i] != coords[i-1] {
uniqueCoords = append(uniqueCoords, coords[i])
}
}
}
rank := func(x int) int {
return sort.SearchInts(uniqueCoords, x)
}
st := newSegTree(len(uniqueCoords))
type Event struct {
pos int
kind int
index int
}
events := make([]Event, 0, n+m)
for i := range vs {
events = append(events, Event{pos: vs[i].r, kind: 0, index: i})
}
for i := range cs {
events = append(events, Event{pos: cs[i].b, kind: 1, index: i})
}
sort.Slice(events, func(i, j int) bool {
if events[i].pos != events[j].pos {
return events[i].pos < events[j].pos
}
return events[i].kind < events[j].kind
})
for _, e := range events {
if e.kind == 0 {
v := vs[e.index]
length := v.r - v.l
rPos := rank(v.l)
st.update(rPos, length, v.id)
} else {
c := cs[e.index]
rPos := rank(c.a)
maxLen, vId := st.query(rPos, len(uniqueCoords))
if vId != -1 {
eff := int64(maxLen) * int64(c.c)
update(eff, vId, c.id)
}
}
}
}
```