The only difference between easy and hard versions is a number of elements in the array.You are given an array $$$a$$$ consisting of $$$n$$$ integers. The value of the $$$i$$$-th element of the array is $$$a_i$$$.You are also given a set of $$$m$$$ segments. The $$$j$$$-th segment is $$$[l_j; r_j]$$$, where $$$1 \le l_j \le r_j \le n$$$.You can choose some subset of the given set of segments and decrease values on each of the chosen segments by one (independently). For example, if the initial array $$$a = [0, 0, 0, 0, 0]$$$ and the given segments are $$$[1; 3]$$$ and $$$[2; 4]$$$ then you can choose both of them and the array will become $$$b = [-1, -2, -2, -1, 0]$$$.You have to choose some subset of the given segments (each segment can be chosen at most once) in such a way that if you apply this subset of segments to the array $$$a$$$ and obtain the array $$$b$$$ then the value $$$\max\limits_{i=1}^{n}b_i - \min\limits_{i=1}^{n}b_i$$$ will be maximum possible.Note that you can choose the empty set.If there are multiple answers, you can print any.If you are Python programmer, consider using PyPy instead of Python when you submit your code.

The first line of the input contains two integers $$$n$$$ and $$$m$$$ ($$$1 \le n \le 300, 0 \le m \le 300$$$) — the length of the array $$$a$$$ and the number of segments, respectively. The second line of the input contains $$$n$$$ integers $$$a_1, a_2, \dots, a_n$$$ ($$$-10^6 \le a_i \le 10^6$$$), where $$$a_i$$$ is the value of the $$$i$$$-th element of the array $$$a$$$. The next $$$m$$$ lines are contain two integers each. The $$$j$$$-th of them contains two integers $$$l_j$$$ and $$$r_j$$$ ($$$1 \le l_j \le r_j \le n$$$), where $$$l_j$$$ and $$$r_j$$$ are the ends of the $$$j$$$-th segment.

In the first line of the output print one integer $$$d$$$ — the maximum possible value $$$\max\limits_{i=1}^{n}b_i - \min\limits_{i=1}^{n}b_i$$$ if $$$b$$$ is the array obtained by applying some subset of the given segments to the array $$$a$$$. In the second line of the output print one integer $$$q$$$ ($$$0 \le q \le m$$$) — the number of segments you apply. In the third line print $$$q$$$ distinct integers $$$c_1, c_2, \dots, c_q$$$ in any order ($$$1 \le c_k \le m$$$) — indices of segments you apply to the array $$$a$$$ in such a way that the value $$$\max\limits_{i=1}^{n}b_i - \min\limits_{i=1}^{n}b_i$$$ of the obtained array $$$b$$$ is maximum possible. If there are multiple answers, you can print any.

NoteIn the first example the obtained array $$$b$$$ will be $$$[0, -4, 1, 1, 2]$$$ so the answer is $$$6$$$.In the second example the obtained array $$$b$$$ will be $$$[2, -3, 1, -1, 4]$$$ so the answer is $$$7$$$.In the third example you cannot do anything so the answer is $$$0$$$.

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	mat := make([]int, n+1)
	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d", &mat[i])
	}
	fmt.Fscanf(buf, "\n")
	var rg [310][2]int
	for i := 0; i < m; i++ {
		fmt.Fscanf(buf, "%d %d\n", &rg[i][0], &rg[i][1])
	}
	//fmt.Printf("v=%v\n",rg)
	ans := 0
	l := 0
	r := 0
	ansc := 0
	for i := 0; i < n; i++ {
		for j := 0; j < n; j++ {
			if i==j{
				continue
			}
			tmp := 0
			tmpc := 0
			for k := 0; k < m; k++ {
				if rg[k][0] <= i+1 && rg[k][1] >= i+1 && (rg[k][0] > j+1 || rg[k][1] < j+1) {
					tmpc++
				}
			}
			tmp = mat[i] - tmpc
			if tmp < mat[j] {
				tmp = mat[j] - tmp
			} else {
				tmp = tmp - mat[j]
			}
			if tmp > ans {
				ans = tmp
				l = i + 1
				r = j + 1
				ansc = tmpc
			}
		}
	}
	fmt.Printf("%d\n", ans)
	fmt.Printf("%d\n", ansc)
	first := true
	for i := 0; i < m; i++ {
		if rg[i][0] <= l && rg[i][1] >= l && (rg[i][0] > r || rg[i][1] < r) {
			if !first {
				fmt.Printf(" ")
			}
			fmt.Printf("%d", i+1)
			first = false
		}
	}
	if !first {
		fmt.Printf("\n")
	}
}

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

var (
	fatory *PointFatory
	debug  = false
	logger = ""
	goods  = [70]int{80, 41, 72, 28, 77, 62, 6, 14, 78, 97, 93, 48, 4, 3, 25, 94, 83, 10, 53, 22, 54, 70, 29, 27, 87, 45, 43, 76, 31, 30, 42, 20, 12, 2, 40, 16, 100, 64, 86, 44, 49, 56, 33, 11, 46, 18, 75, 5, 69, 55, 37, 50, 92, 73, 21, 57, 13, 35, 26, 65, 81, 95, 36, 32, 15, 60, 68, 89, 98, 38}
)

const (
	MAX int64 = int64(3000100)
)

type Point struct {
	l, r   int
	dirty  int
	min    int64
	cl, cr *Point
}
type Seg struct {
	l, r int
	id   int
}
type Segs []Seg

func (s Segs) Len() int {
	return len(s)
}
func (s Segs) Swap(a, b int) {
	tmp := s[a].l
	s[a].l = s[b].l
	s[b].l = tmp

	tmp = s[a].r
	s[a].r = s[b].r
	s[b].r = tmp

	tmp = s[a].id
	s[a].id = s[b].id
	s[b].id = tmp
}
func (s Segs) Less(a, b int) bool {
	if s[a].r < s[b].r {
		return true
	}
	return false
}

type PointFatory struct {
	p     []Point
	front int
	len   int
}

func (p *PointFatory) newPoint() *Point {
	return &Point{}
	//if p.front >= p.len {
	//	p.p = append(p.p, make([]Point, p.len)...)
	//	p.len = len(p.p)
	//}
	//res := &p.p[p.front]
	//p.front++
	//return res
}
func newFatory(n int) *PointFatory {
	return &PointFatory{
		p:   make([]Point, n),
		len: n,
	}
}
func (p *Point) left() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cl == nil {
		p.cl = fatory.newPoint()
		p.cl.l = p.l
		p.cl.r = (p.l + p.r) / 2
		p.cl.min = MAX
	}
	return p.cl
}
func (p *Point) right() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cr == nil {
		p.cr = fatory.newPoint()
		p.cr.l = (p.l+p.r)/2 + 1
		p.cr.r = p.r
		p.cr.min = MAX
	}
	return p.cr
}
func (p *Point) refleshMin() {
	if p.left() == nil && p.right() == nil {
		return
	}
	if p.left() == nil {
		p.min = p.right().min
	} else if p.right() == nil {
		p.min = p.left().min
	} else if p.left().min < p.right().min {
		p.min = p.left().min
	} else {
		p.min = p.right().min
	}
	if p.min == 0 &&debug{
		fmt.Printf("min=0 l=%d r=%d dirty=%d\n",p.l,p.r,p.dirty)
	}

}
func (p *Point) queryMin(l, r int) (int64, bool) {
	p.down()
	if l <= p.l && p.r <= r {
		return p.min, true
	}
	if l > p.r || r < p.l {
		return -1, false
	}
	var res int64 = 0
	find := false
	if p.left() != nil {
		leftmin, flag := p.left().queryMin(l, r)
		if flag {
			res = leftmin
			find = true
		}
	}
	if p.right() != nil {
		rightmin, flag := p.right().queryMin(l, r)
		if flag && (find == false || rightmin < res) {
			res = rightmin
		}
	}
	return res, true

}
func (p *Point) addValue(value int) {
	if p.min >= MAX {
		p.min = int64(value)
	} else {
		p.min += int64(value)
	}
	if p.min == 0 &&debug{
		fmt.Printf("min=0 l=%d r=%d dirty=%d value=%d\n",p.l,p.r,p.dirty,value)
	}
}
func (p *Point) down() {
	if p.dirty == 0 {
		return
	}
	pl := p.left()
	pr := p.right()
	if pl != nil {
		pl.dirty += p.dirty
		pl.addValue(p.dirty)
	}
	if pr != nil {
		pr.dirty += p.dirty
		pr.addValue(p.dirty)
	}
	p.dirty = 0
	//p.refleshMin()
}
func (p *Point) add(l, r int, value int) {
	if l > p.r || r < p.l {
		return
	}
	if l <= p.l && p.r <= r {
		p.addValue(value)
		p.dirty += value
		return
	}
	pl := p.left()
	pr := p.right()
	p.down()
	if pl != nil {
		pl.add(l, r, value)
	}
	if pr != nil {
		pr.add(l, r, value)
	}
	tmin := p.min
	p.refleshMin()
	if debug && p.min > tmin {
		fmt.Printf(" tmin=%d nowmin=%d pl=%d pr=%d l=%d r=%d value=%d\n", tmin, p.min,p.l,p.r,l,r,value)
	}
}
func solveE(mat []int, n int, segs Segs) (Segs, int64) {
	fatory = newFatory(n)

	maxx := make([]int, n)
	minn := mat[n-1]
	maxx[n-1] = mat[n-1]
	for i := n - 2; i >= 0; i-- {
		if mat[i] > maxx[i+1] {
			maxx[i] = mat[i]
		} else {
			maxx[i] = maxx[i+1]
		}
		if mat[i] < minn {
			minn = mat[i]
		}
	}
	partline := -1
	res := int64(maxx[0] - minn)
	root := fatory.newPoint()
	root.l = 1
	root.r = n
	root.min = MAX
	//fmt.Printf("root.min = %d l=%d r=%d\n",root.min,root.l,root.r)
	for i := 0; i < n; i++ {
		root.add(i+1, i+1, mat[i])
		//	fmt.Printf("i=%d root.min = %d value=%d\n", i,root.min,mat[i])
	}
	//fmt.Printf("root.min = %d\n", root.min)

	sort.Sort(segs)
	dbMax := 0
	for i := 0; i < len(segs); i++ {
		if segs[i].r >= n {
			continue
		}
		root.add(segs[i].l, segs[i].r, -1)
		tmpm, _ := root.queryMin(1, segs[i].r)
		//	fmt.Printf("i=%d segs.l = %d segs.r = %d min=%d maxx=%d\n", i, segs[i].l, segs[i].r, tmpm, maxx[segs[i].r])
		if res < int64(maxx[segs[i].r])-tmpm {
			partline = i
			res = int64(maxx[segs[i].r]) - tmpm
			dbMax = maxx[segs[i].r]
		}
		if debug && (segs[i].id == 36 || segs[i].id == 55 || segs[i].id == 76 || segs[i].id == 11 || segs[i].id == 37 || segs[i].id == 95 || segs[i].id == 6 || segs[i].id == 41) {
			logger += fmt.Sprintf("i=%d maxx=%d min=%d l=%d r=%d root.min=%d\n", segs[i].id, maxx[segs[i].r], tmpm, segs[i].l, segs[i].r, root.min)
			//logger += "i=" + strconv.Itoa(segs[i].id) + " maxx = " + strconv.Itoa(maxx[segs[i].r]) + " min=" + strconv.Itoa(int(tmpm)) + "\n"
		}
	}
	if debug && partline > -1 {
		logger += "partline=" + strconv.Itoa(segs[partline].r) + " maxx = " + strconv.Itoa(dbMax) + " min=" + strconv.Itoa(dbMax-int(res)) + "\n"
		//	fmt.Printf("partline=%d maxx = %d min=%d\n", segs[partline].r, dbMax,res-int64(dbMax))
	}
	as := make(Segs, partline+1)
	for i := 0; i <= partline; i++ {
		as[i] = Seg{
			l:  segs[i].l,
			r:  segs[i].r,
			id: segs[i].id,
		}
	}
	//	fmt.Printf("as = %v res=%v\n",as,res)
	return as, res
}
func reverse(mat []int, segs Segs) {
	//	fmt.Printf("before mat=%v seg=%v\n",mat,segs)
	n := len(mat)
	m := len(segs)
	for i := 0; i < n-i-1; i++ {
		tmp := mat[i]
		mat[i] = mat[n-i-1]
		mat[n-i-1] = tmp
	}
	for i := 0; i < m; i++ {
		tmp := segs[i].l
		segs[i].l = segs[i].r
		segs[i].r = tmp
		segs[i].l = n - segs[i].l + 1
		segs[i].r = n - segs[i].r + 1
	}

}
func tmpseg(segs Segs) Segs {
	lens := len(goods)
	res := make(Segs, 0)
	for j := 0; j < len(segs); j++ {
		for i := 0; i < lens; i++ {
			if goods[i] == segs[j].id {
				res = append(res, segs[j])
				break
			}
		}
	}
	return res
}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	//if n == 10000 && m == 100 {
	//	debug = true
	//}
	if debug{
		fmt.Printf("maxx=%d\n",MAX)
	}
	//	debug=true
	mat := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d", &mat[i])
	}
	fmt.Fscanf(buf, "\n")
	seg := make(Segs, m)
	for i := 0; i < m; i++ {
		fmt.Fscanf(buf, "%d %d\n", &seg[i].l, &seg[i].r)
		seg[i].id = i + 1
	}
	pl, ans := solveE(mat, n, seg)
	reverse(mat, seg)
	//	fmt.Printf("rev mat=%v seg=%d\n",mat,seg)
	pl2, ans2 := solveE(mat, n, seg)

	if ans < ans2 {
		fmt.Printf("%d\n", ans2)
		fmt.Printf("%d\n", len(pl2))
		for i := 0; i < len(pl2); i++ {
			fmt.Printf("%d ", pl2[i].id)
		}
		fmt.Printf("\n")
		if len(pl) > 0 && debug {
			c, _ := check(mat, tmpseg(seg))
			c, _ = check(mat, pl2)
			if c != ans2 {
				fmt.Printf("ERROR c = %d ans=%d\n", c, ans2)
			}
			fmt.Printf("logger--\n%s\n", logger)
		}
	} else {
		fmt.Printf("%d\n", ans)
		fmt.Printf("%d\n", len(pl))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl[i].id)
		}
		fmt.Printf("\n")

		if len(pl) > 0 && debug {
			reverse(mat, seg)
			c, _ := check(mat, tmpseg(seg))
			c, _ = check(mat, pl)

			if c != ans {
				fmt.Printf("2ERROR c = %d ans=%d\n", c, ans)
			}
			fmt.Printf("%s\n", logger)
		}
	}

}
func check(mat []int, pl Segs) (int64, int) {
	n := len(mat)
	m := len(pl)
	if m <= 0 {
		return 0, 0
	}
	maxx := -1
	minn := 10000000
	//minw := -1
	for i := 0; i < n; i++ {
		in := 0
		for j := 0; j < m; j++ {
			if pl[j].l > i+1 || pl[j].r < i+1 {
				continue
			}
			in++
		}
		if in == 0 {
			if maxx == -1 || mat[maxx] < mat[i] {
				maxx = i
			}
		}
		if minn > mat[i]-in {
			minn = mat[i] - in
			//minw = i
		}

	}
	if debug {
		maxxr := 0
		for i := 0; i < m; i++ {
			if pl[i].l <= 3119 && pl[i].r >= 3119 {
				//	fmt.Printf("range %d %d %d\n", pl[i].l, pl[i].r,pl[i].id)
			}

			if pl[i].r > maxxr {
				maxxr = pl[i].r
			}
		}
		//		fmt.Printf("check maxw = %d  minw = %d maxx=%d min=%d mat[minn]=%d maxxr=%d\n", maxx+1, minw+1, mat[maxx], minn, mat[minw],maxxr)
	}
	return int64(mat[maxx] - minn), mat[maxx]
}

/**

5 3
1 2 2 -2 3
3 5
1 5
3 5
 */

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	mat := make([]int, n+1)
	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d", &mat[i])
	}
	fmt.Fscanf(buf, "\n")
	var rg [310][2]int
	for i := 0; i < m; i++ {
		fmt.Fscanf(buf, "%d %d\n", &rg[i][0], &rg[i][1])
	}
	//fmt.Printf("v=%v\n",rg)
	ans := 0
	l := 0
	r := 0
	ansc := 0
	for i := 0; i < n; i++ {
		for j := i + 1; j < n; j++ {
			tmp := 0
			tmpc := 0
			for k := 0; k < m; k++ {
				if rg[k][0] <= i+1 && rg[k][1] >= i+1 && (rg[k][0] > j+1 || rg[k][1] < j+1) {
					tmpc++
				}
			}
			tmp = mat[i] - tmpc
			if tmp < mat[j] {
				tmp = mat[j] - tmp
			} else {
				tmp = tmp - mat[j]
			}
			if tmp > ans {
				ans = tmp
				l = i + 1
				r = j + 1
				ansc = tmpc
			}
		}
	}
	fmt.Printf("%d\n", ans)
	fmt.Printf("%d\n", ansc)
	first := true
	for i := 0; i < m; i++ {
		if rg[i][0] <= l && rg[i][1] >= l && (rg[i][0] > r || rg[i][1] < r) {
			if !first {
				fmt.Printf(" ")
			}
			fmt.Printf("%d", i+1)
			first = false
		}
	}
	if !first {
		fmt.Printf("\n")
	}

}

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

var (
	fatory *PointFatory
	debug  = false
	logger = ""
	goods  = [70]int{80, 41, 72, 28, 77, 62, 6, 14, 78, 97, 93, 48, 4, 3, 25, 94, 83, 10, 53, 22, 54, 70, 29, 27, 87, 45, 43, 76, 31, 30, 42, 20, 12, 2, 40, 16, 100, 64, 86, 44, 49, 56, 33, 11, 46, 18, 75, 5, 69, 55, 37, 50, 92, 73, 21, 57, 13, 35, 26, 65, 81, 95, 36, 32, 15, 60, 68, 89, 98, 38}
)

const (
	MAX int64 = int64(3000100)
)

type Point struct {
	l, r   int
	dirty  int
	min    int64
	cl, cr *Point
}
type Seg struct {
	l, r int
	id   int
}
type Segs []Seg

func (s Segs) Len() int {
	return len(s)
}
func (s Segs) Swap(a, b int) {
	tmp := s[a].l
	s[a].l = s[b].l
	s[b].l = tmp

	tmp = s[a].r
	s[a].r = s[b].r
	s[b].r = tmp

	tmp = s[a].id
	s[a].id = s[b].id
	s[b].id = tmp
}
func (s Segs) Less(a, b int) bool {
	if s[a].r < s[b].r {
		return true
	}
	return false
}

type PointFatory struct {
	p     []Point
	front int
	len   int
}

func (p *PointFatory) newPoint() *Point {
	return &Point{}
	//if p.front >= p.len {
	//	p.p = append(p.p, make([]Point, p.len)...)
	//	p.len = len(p.p)
	//}
	//res := &p.p[p.front]
	//p.front++
	//return res
}
func newFatory(n int) *PointFatory {
	return &PointFatory{
		p:   make([]Point, n),
		len: n,
	}
}
func (p *Point) left() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cl == nil {
		p.cl = fatory.newPoint()
		p.cl.l = p.l
		p.cl.r = (p.l + p.r) / 2
		p.cl.min = MAX
	}
	return p.cl
}
func (p *Point) right() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cr == nil {
		p.cr = fatory.newPoint()
		p.cr.l = (p.l+p.r)/2 + 1
		p.cr.r = p.r
		p.cr.min = MAX
	}
	return p.cr
}
func (p *Point) refleshMin() {
	if p.left() == nil && p.right() == nil {
		return
	}
	if p.left() == nil {
		p.min = p.right().min
	} else if p.right() == nil {
		p.min = p.left().min
	} else if p.left().min < p.right().min {
		p.min = p.left().min
	} else {
		p.min = p.right().min
	}
	if p.min == 0 &&debug{
		fmt.Printf("min=0 l=%d r=%d dirty=%d\n",p.l,p.r,p.dirty)
	}

}
func (p *Point) queryMin(l, r int) (int64, bool) {
	p.down()
	if l <= p.l && p.r <= r {
		return p.min, true
	}
	if l > p.r || r < p.l {
		return -1, false
	}
	var res int64 = 0
	find := false
	if p.left() != nil {
		leftmin, flag := p.left().queryMin(l, r)
		if flag {
			res = leftmin
			find = true
		}
	}
	if p.right() != nil {
		rightmin, flag := p.right().queryMin(l, r)
		if flag && (find == false || rightmin < res) {
			res = rightmin
		}
	}
	return res, true

}
func (p *Point) addValue(value int) {
	if p.min >= MAX {
		p.min = int64(value)
	} else {
		p.min += int64(value)
	}
	if p.min == 0 &&debug{
		fmt.Printf("min=0 l=%d r=%d dirty=%d value=%d\n",p.l,p.r,p.dirty,value)
	}
}
func (p *Point) down() {
	if p.dirty <= 0 {
		return
	}
	pl := p.left()
	pr := p.right()
	if pl != nil {
		pl.dirty += p.dirty
		pl.addValue(p.dirty)
	}
	if pr != nil {
		pr.dirty += p.dirty
		pr.addValue(p.dirty)
	}
	p.dirty = 0
	//p.refleshMin()
}
func (p *Point) add(l, r int, value int) {
	if l > p.r || r < p.l {
		return
	}
	if l <= p.l && p.r <= r {
		p.addValue(value)
		p.dirty += value
		return
	}
	pl := p.left()
	pr := p.right()
	p.down()
	if pl != nil {
		pl.add(l, r, value)
	}
	if pr != nil {
		pr.add(l, r, value)
	}
	tmin := p.min
	p.refleshMin()
	if debug && p.min > tmin {
		fmt.Printf(" tmin=%d nowmin=%d pl=%d pr=%d l=%d r=%d value=%d\n", tmin, p.min,p.l,p.r,l,r,value)
	}
}
func solveE(mat []int, n int, segs Segs) (Segs, int64) {
	fatory = newFatory(n)

	maxx := make([]int, n)
	minn := mat[n-1]
	maxx[n-1] = mat[n-1]
	for i := n - 2; i >= 0; i-- {
		if mat[i] > maxx[i+1] {
			maxx[i] = mat[i]
		} else {
			maxx[i] = maxx[i+1]
		}
		if mat[i] < minn {
			minn = mat[i]
		}
	}
	partline := -1
	res := int64(maxx[0] - minn)
	root := fatory.newPoint()
	root.l = 1
	root.r = n
	root.min = MAX
	//fmt.Printf("root.min = %d l=%d r=%d\n",root.min,root.l,root.r)
	for i := 0; i < n; i++ {
		root.add(i+1, i+1, mat[i])
		//	fmt.Printf("i=%d root.min = %d value=%d\n", i,root.min,mat[i])
	}
	//fmt.Printf("root.min = %d\n", root.min)

	sort.Sort(segs)
	dbMax := 0
	for i := 0; i < len(segs); i++ {
		if segs[i].r >= n {
			continue
		}
		root.add(segs[i].l, segs[i].r, -1)
		tmpm, _ := root.queryMin(1, segs[i].r)
		//	fmt.Printf("i=%d segs.l = %d segs.r = %d min=%d maxx=%d\n", i, segs[i].l, segs[i].r, tmpm, maxx[segs[i].r])
		if res < int64(maxx[segs[i].r])-tmpm {
			partline = i
			res = int64(maxx[segs[i].r]) - tmpm
			dbMax = maxx[segs[i].r]
		}
		if debug && (segs[i].id == 36 || segs[i].id == 55 || segs[i].id == 76 || segs[i].id == 11 || segs[i].id == 37 || segs[i].id == 95 || segs[i].id == 6 || segs[i].id == 41) {
			logger += fmt.Sprintf("i=%d maxx=%d min=%d l=%d r=%d root.min=%d\n", segs[i].id, maxx[segs[i].r], tmpm, segs[i].l, segs[i].r, root.min)
			//logger += "i=" + strconv.Itoa(segs[i].id) + " maxx = " + strconv.Itoa(maxx[segs[i].r]) + " min=" + strconv.Itoa(int(tmpm)) + "\n"
		}
	}
	if debug && partline > -1 {
		logger += "partline=" + strconv.Itoa(segs[partline].r) + " maxx = " + strconv.Itoa(dbMax) + " min=" + strconv.Itoa(dbMax-int(res)) + "\n"
		//	fmt.Printf("partline=%d maxx = %d min=%d\n", segs[partline].r, dbMax,res-int64(dbMax))
	}
	as := make(Segs, partline+1)
	for i := 0; i <= partline; i++ {
		as[i] = Seg{
			l:  segs[i].l,
			r:  segs[i].r,
			id: segs[i].id,
		}
	}
	//	fmt.Printf("as = %v res=%v\n",as,res)
	return as, res
}
func reverse(mat []int, segs Segs) {
	//	fmt.Printf("before mat=%v seg=%v\n",mat,segs)
	n := len(mat)
	m := len(segs)
	for i := 0; i < n-i-1; i++ {
		tmp := mat[i]
		mat[i] = mat[n-i-1]
		mat[n-i-1] = tmp
	}
	for i := 0; i < m; i++ {
		tmp := segs[i].l
		segs[i].l = segs[i].r
		segs[i].r = tmp
		segs[i].l = n - segs[i].l + 1
		segs[i].r = n - segs[i].r + 1
	}

}
func tmpseg(segs Segs) Segs {
	lens := len(goods)
	res := make(Segs, 0)
	for j := 0; j < len(segs); j++ {
		for i := 0; i < lens; i++ {
			if goods[i] == segs[j].id {
				res = append(res, segs[j])
				break
			}
		}
	}
	return res
}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	if n == 10000 && m == 100 {
		debug = true
	}
	if debug{
		fmt.Printf("maxx=%d\n",MAX)
	}
	//	debug=true
	mat := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d", &mat[i])
	}
	fmt.Fscanf(buf, "\n")
	seg := make(Segs, m)
	for i := 0; i < m; i++ {
		fmt.Fscanf(buf, "%d %d\n", &seg[i].l, &seg[i].r)
		seg[i].id = i + 1
	}
	pl, ans := solveE(mat, n, seg)
	reverse(mat, seg)
	//	fmt.Printf("rev mat=%v seg=%d\n",mat,seg)
	pl2, ans2 := solveE(mat, n, seg)

	if ans < ans2 {
		fmt.Printf("%d\n", ans2)
		fmt.Printf("%d\n", len(pl2))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl2[i].id)
		}
		fmt.Printf("\n")
		if len(pl) > 0 && debug {
			c, _ := check(mat, tmpseg(seg))
			c, _ = check(mat, pl2)
			if c != ans2 {
				fmt.Printf("ERROR c = %d ans=%d\n", c, ans2)
			}
			fmt.Printf("logger--\n%s\n", logger)
		}
	} else {
		fmt.Printf("%d\n", ans)
		fmt.Printf("%d\n", len(pl))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl[i].id)
		}
		fmt.Printf("\n")

		if len(pl) > 0 && debug {
			reverse(mat, seg)
			c, _ := check(mat, tmpseg(seg))
			c, _ = check(mat, pl)

			if c != ans {
				fmt.Printf("2ERROR c = %d ans=%d\n", c, ans)
			}
			fmt.Printf("%s\n", logger)
		}
	}

}
func check(mat []int, pl Segs) (int64, int) {
	n := len(mat)
	m := len(pl)
	if m <= 0 {
		return 0, 0
	}
	maxx := -1
	minn := 10000000
	//minw := -1
	for i := 0; i < n; i++ {
		in := 0
		for j := 0; j < m; j++ {
			if pl[j].l > i+1 || pl[j].r < i+1 {
				continue
			}
			in++
		}
		if in == 0 {
			if maxx == -1 || mat[maxx] < mat[i] {
				maxx = i
			}
		}
		if minn > mat[i]-in {
			minn = mat[i] - in
			//minw = i
		}

	}
	if debug {
		maxxr := 0
		for i := 0; i < m; i++ {
			if pl[i].l <= 3119 && pl[i].r >= 3119 {
				//	fmt.Printf("range %d %d %d\n", pl[i].l, pl[i].r,pl[i].id)
			}

			if pl[i].r > maxxr {
				maxxr = pl[i].r
			}
		}
		//		fmt.Printf("check maxw = %d  minw = %d maxx=%d min=%d mat[minn]=%d maxxr=%d\n", maxx+1, minw+1, mat[maxx], minn, mat[minw],maxxr)
	}
	return int64(mat[maxx] - minn), mat[maxx]
}

/**

5 3
1 2 2 -2 3
3 5
1 5
3 5
 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

var (
	fatory *PointFatory
)

const (
	MAX = 1100100
)

type Point struct {
	l, r   int
	dirty  int
	min    int
	cl, cr *Point
}
type Seg struct {
	l, r int
	id   int
}
type Segs []Seg

func (s Segs) Len() int {
	return len(s)
}
func (s Segs) Swap(a, b int) {
	tmp := s[a].l
	s[a].l = s[b].l
	s[b].l = tmp

	tmp = s[a].r
	s[a].r = s[b].r
	s[b].r = tmp

	tmp = s[a].id
	s[a].id = s[b].id
	s[b].id = tmp
}
func (s Segs) Less(a, b int) bool {
	if s[a].r < s[b].r {
		return true
	}
	return false
}

type PointFatory struct {
	p     []Point
	front int
	len   int
}

func (p *PointFatory) newPoint() *Point {
	if p.front >= p.len {
		p.p = append(p.p, make([]Point, p.len)...)
		p.len = len(p.p)
	}
	res := &p.p[p.front]
	p.front++
	return res
}
func newFatory(n int) *PointFatory {
	return &PointFatory{
		p:   make([]Point, n),
		len: n,
	}
}
func (p *Point) left() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cl == nil {
		p.cl = fatory.newPoint()
		p.cl.l = p.l
		p.cl.r = (p.l + p.r) / 2
		p.cl.min = MAX
	}
	return p.cl
}
func (p *Point) right() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cr == nil {
		p.cr = fatory.newPoint()
		p.cr.l = (p.l+p.r)/2 + 1
		p.cr.r = p.r
		p.cr.min = MAX
	}
	return p.cr
}
func (p *Point) refleshMin() {
	if p.left() == nil && p.right() == nil {
		return
	}
	if p.left() == nil {
		p.min = p.right().min
	} else if p.right() == nil {
		p.min = p.left().min
	} else if p.left().min < p.right().min {
		p.min = p.left().min
	} else {
		p.min = p.right().min
	}

}
func (p *Point) queryMin(l, r int) (int, bool) {
	p.down()
	if l <= p.l && p.r <= r {
		return p.min, true
	}
	if l > p.r || r < p.l {
		return -1, false
	}
	res := 0
	find := false
	if p.left() != nil {
		leftmin, flag := p.left().queryMin(l, r)
		if flag {
			res = leftmin
			find = true
		}
	}
	if p.right() != nil {
		rightmin, flag := p.right().queryMin(l, r)
		if flag && (find == false || rightmin < res) {
			res = rightmin
		}
	}
	return res, true

}
func (p *Point) addValue(value int){
	if p.min >= MAX{
		p.min = value
	}else{
		p.min += value
	}
}
func (p *Point) down() {
	if p.dirty == 0 {
		return
	}
	pl := p.left()
	pr := p.right()
	if pl != nil {
		pl.dirty += p.dirty
		pl.addValue(p.dirty)
	}
	if pr != nil {
		pr.dirty += p.dirty
		pr.min += p.dirty
		pr.addValue(p.dirty)
	}
	p.dirty = 0
	p.refleshMin()
}
func (p *Point) add(l, r int, value int) {
	if l > p.r || r < p.l {
		return
	}
	if l <= p.l && p.r <= r {
		p.addValue(value)
		p.dirty += value
		return
	}
	pl := p.left()
	pr := p.right()
	p.down()
	if pl != nil {
		pl.add(l, r, value)
	}
	if pr != nil {
		pr.add(l, r, value)
	}
	p.refleshMin()
}
func solveE(mat []int, n int, segs Segs) ([]int, int) {
	fatory = newFatory(n)

	maxx := make([]int, n)
	minn := mat[n-1]
	maxx[n-1] = mat[n-1]
	for i := n - 2; i >= 0; i-- {
		if mat[i] > maxx[i+1] {
			maxx[i] = mat[i]
		} else {
			maxx[i] = maxx[i+1]
		}
		if mat[i] < minn {
			minn = mat[i]
		}
	}
	partline := -1
	res := maxx[0] - minn
	root := fatory.newPoint()
	root.l = 1
	root.r = n
	//fmt.Printf("root.min = %d l=%d r=%d\n",root.min,root.l,root.r)
	for i := 0; i < n; i++ {
		root.add(i+1, i+1, mat[i])
	//	fmt.Printf("i=%d root.min = %d value=%d\n", i,root.min,mat[i])
	}
	//fmt.Printf("root.min = %d\n", root.min)

	sort.Sort(segs)
	for i := 0; i < len(segs); i++ {
		if segs[i].r >= n {
			continue
		}
		root.add(segs[i].l, segs[i].r, -1)
		tmpm, _ := root.queryMin(1, segs[i].r)
	//	fmt.Printf("i=%d segs.l = %d segs.r = %d min=%d maxx=%d\n", i, segs[i].l, segs[i].r, tmpm, maxx[segs[i].r])
		if res < maxx[segs[i].r]-tmpm {
			partline = i
			res = maxx[segs[i].r] - tmpm
		}
	}
	as := make([]int, partline+1)
	for i := 0; i <= partline; i++ {
		as[i] = segs[i].id
	}
//	fmt.Printf("as = %v res=%v\n",as,res)
	return as, res
}
func reverse(mat []int, segs Segs) {
	n := len(mat)
	m := len(segs)
	for i := 0; i < n-i-1; i++ {
		tmp := mat[i]
		mat[i] = mat[n-i-1]
		mat[n-i-1] = tmp
	}
	for i := 0; i < m; i++ {
		tmp := segs[i].l
		segs[i].l = segs[i].r
		segs[i].r = tmp
		segs[i].l = n - segs[i].l + 1
		segs[i].r = n - segs[i].r + 1
	}

}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	mat := make([]int, n+1)
	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d", &mat[i])
	}
	fmt.Fscanf(buf, "\n")
	seg := make(Segs, m)
	for i := 0; i < m; i++ {
		fmt.Fscanf(buf, "%d %d\n", &seg[i].l, &seg[i].r)
		seg[i].id = i+1
	}
	pl, ans := solveE(mat, n, seg)
	reverse(mat, seg)
	pl2, ans2 := solveE(mat, n, seg)
	if ans < ans2 {
		pl = pl2
		ans = ans2
	}
	fmt.Printf("%d\n", ans)
	fmt.Printf("%d\n", len(pl))
	for i := 0; i < len(pl); i++ {
		fmt.Printf("%d ", pl[i])
	}
	fmt.Printf("\n")

}

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

var (
	fatory *PointFatory
	debug  = false
	logger = ""
	goods  = [70]int{80, 41, 72, 28, 77, 62, 6, 14, 78, 97, 93, 48, 4, 3, 25, 94, 83, 10, 53, 22, 54, 70, 29, 27, 87, 45, 43, 76, 31, 30, 42, 20, 12, 2, 40, 16, 100, 64, 86, 44, 49, 56, 33, 11, 46, 18, 75, 5, 69, 55, 37, 50, 92, 73, 21, 57, 13, 35, 26, 65, 81, 95, 36, 32, 15, 60, 68, 89, 98, 38}
)

const (
	MAX int64 = int64(3000100)
)

type Point struct {
	l, r   int
	dirty  int
	min    int64
	cl, cr *Point
}
type Seg struct {
	l, r int
	id   int
}
type Segs []Seg

func (s Segs) Len() int {
	return len(s)
}
func (s Segs) Swap(a, b int) {
	tmp := s[a].l
	s[a].l = s[b].l
	s[b].l = tmp

	tmp = s[a].r
	s[a].r = s[b].r
	s[b].r = tmp

	tmp = s[a].id
	s[a].id = s[b].id
	s[b].id = tmp
}
func (s Segs) Less(a, b int) bool {
	if s[a].r < s[b].r {
		return true
	}
	return false
}

type PointFatory struct {
	p     []Point
	front int
	len   int
}

func (p *PointFatory) newPoint() *Point {
	return &Point{}
	//if p.front >= p.len {
	//	p.p = append(p.p, make([]Point, p.len)...)
	//	p.len = len(p.p)
	//}
	//res := &p.p[p.front]
	//p.front++
	//return res
}
func newFatory(n int) *PointFatory {
	return &PointFatory{
		p:   make([]Point, n),
		len: n,
	}
}
func (p *Point) left() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cl == nil {
		p.cl = fatory.newPoint()
		p.cl.l = p.l
		p.cl.r = (p.l + p.r) / 2
		p.cl.min = MAX
	}
	return p.cl
}
func (p *Point) right() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cr == nil {
		p.cr = fatory.newPoint()
		p.cr.l = (p.l+p.r)/2 + 1
		p.cr.r = p.r
		p.cr.min = MAX
	}
	return p.cr
}
func (p *Point) refleshMin() {
	if p.left() == nil && p.right() == nil {
		return
	}
	if p.left() == nil {
		p.min = p.right().min
	} else if p.right() == nil {
		p.min = p.left().min
	} else if p.left().min < p.right().min {
		p.min = p.left().min
	} else {
		p.min = p.right().min
	}
	if p.min == 0 &&debug{
		fmt.Printf("min=0 l=%d r=%d dirty=%d\n",p.l,p.r,p.dirty)
	}

}
func (p *Point) queryMin(l, r int) (int64, bool) {
	p.down()
	if l <= p.l && p.r <= r {
		return p.min, true
	}
	if l > p.r || r < p.l {
		return -1, false
	}
	var res int64 = 0
	find := false
	if p.left() != nil {
		leftmin, flag := p.left().queryMin(l, r)
		if flag {
			res = leftmin
			find = true
		}
	}
	if p.right() != nil {
		rightmin, flag := p.right().queryMin(l, r)
		if flag && (find == false || rightmin < res) {
			res = rightmin
		}
	}
	return res, true

}
func (p *Point) addValue(value int) {
	if p.min >= MAX {
		p.min = int64(value)
	} else {
		p.min += int64(value)
	}
	if p.min == 0 &&debug{
		fmt.Printf("min=0 l=%d r=%d dirty=%d value=%d\n",p.l,p.r,p.dirty,value)
	}
}
func (p *Point) down() {
	if p.dirty <= 0 {
		return
	}
	pl := p.left()
	pr := p.right()
	if pl != nil {
		pl.dirty += p.dirty
		pl.addValue(p.dirty)
	}
	if pr != nil {
		pr.dirty += p.dirty
		pr.addValue(p.dirty)
	}
	p.dirty = 0
	//p.refleshMin()
}
func (p *Point) add(l, r int, value int) {
	if l > p.r || r < p.l {
		return
	}
	if l <= p.l && p.r <= r {
		p.addValue(value)
		p.dirty += value
		return
	}
	pl := p.left()
	pr := p.right()
	p.down()
	if pl != nil {
		pl.add(l, r, value)
	}
	if pr != nil {
		pr.add(l, r, value)
	}
	tmin := p.min
	p.refleshMin()
	if debug && p.min > tmin {
		fmt.Printf(" tmin=%d nowmin=%d pl=%d pr=%d l=%d r=%d value=%d\n", tmin, p.min,p.l,p.r,l,r,value)
	}
}
func solveE(mat []int, n int, segs Segs) (Segs, int64) {
	fatory = newFatory(n)

	maxx := make([]int, n)
	minn := mat[n-1]
	maxx[n-1] = mat[n-1]
	for i := n - 2; i >= 0; i-- {
		if mat[i] > maxx[i+1] {
			maxx[i] = mat[i]
		} else {
			maxx[i] = maxx[i+1]
		}
		if mat[i] < minn {
			minn = mat[i]
		}
	}
	partline := -1
	res := int64(maxx[0] - minn)
	root := fatory.newPoint()
	root.l = 1
	root.r = n
	//fmt.Printf("root.min = %d l=%d r=%d\n",root.min,root.l,root.r)
	for i := 0; i < n; i++ {
		root.add(i+1, i+1, mat[i])
		//	fmt.Printf("i=%d root.min = %d value=%d\n", i,root.min,mat[i])
	}
	//fmt.Printf("root.min = %d\n", root.min)

	sort.Sort(segs)
	dbMax := 0
	for i := 0; i < len(segs); i++ {
		if segs[i].r >= n {
			continue
		}
		root.add(segs[i].l, segs[i].r, -1)
		tmpm, _ := root.queryMin(1, segs[i].r)
		//	fmt.Printf("i=%d segs.l = %d segs.r = %d min=%d maxx=%d\n", i, segs[i].l, segs[i].r, tmpm, maxx[segs[i].r])
		if res < int64(maxx[segs[i].r])-tmpm {
			partline = i
			res = int64(maxx[segs[i].r]) - tmpm
			dbMax = maxx[segs[i].r]
		}
		if debug && (segs[i].id == 36 || segs[i].id == 55 || segs[i].id == 76 || segs[i].id == 11 || segs[i].id == 37 || segs[i].id == 95 || segs[i].id == 6 || segs[i].id == 41) {
			logger += fmt.Sprintf("i=%d maxx=%d min=%d l=%d r=%d root.min=%d\n", segs[i].id, maxx[segs[i].r], tmpm, segs[i].l, segs[i].r, root.min)
			//logger += "i=" + strconv.Itoa(segs[i].id) + " maxx = " + strconv.Itoa(maxx[segs[i].r]) + " min=" + strconv.Itoa(int(tmpm)) + "\n"
		}
	}
	if debug && partline > -1 {
		logger += "partline=" + strconv.Itoa(segs[partline].r) + " maxx = " + strconv.Itoa(dbMax) + " min=" + strconv.Itoa(dbMax-int(res)) + "\n"
		//	fmt.Printf("partline=%d maxx = %d min=%d\n", segs[partline].r, dbMax,res-int64(dbMax))
	}
	as := make(Segs, partline+1)
	for i := 0; i <= partline; i++ {
		as[i] = Seg{
			l:  segs[i].l,
			r:  segs[i].r,
			id: segs[i].id,
		}
	}
	//	fmt.Printf("as = %v res=%v\n",as,res)
	return as, res
}
func reverse(mat []int, segs Segs) {
	//	fmt.Printf("before mat=%v seg=%v\n",mat,segs)
	n := len(mat)
	m := len(segs)
	for i := 0; i < n-i-1; i++ {
		tmp := mat[i]
		mat[i] = mat[n-i-1]
		mat[n-i-1] = tmp
	}
	for i := 0; i < m; i++ {
		tmp := segs[i].l
		segs[i].l = segs[i].r
		segs[i].r = tmp
		segs[i].l = n - segs[i].l + 1
		segs[i].r = n - segs[i].r + 1
	}

}
func tmpseg(segs Segs) Segs {
	lens := len(goods)
	res := make(Segs, 0)
	for j := 0; j < len(segs); j++ {
		for i := 0; i < lens; i++ {
			if goods[i] == segs[j].id {
				res = append(res, segs[j])
				break
			}
		}
	}
	return res
}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	if n == 10000 && m == 100 {
		debug = true
	}
	if debug{
		fmt.Printf("maxx=%d\n",MAX)
	}
	//	debug=true
	mat := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d", &mat[i])
	}
	fmt.Fscanf(buf, "\n")
	seg := make(Segs, m)
	for i := 0; i < m; i++ {
		fmt.Fscanf(buf, "%d %d\n", &seg[i].l, &seg[i].r)
		seg[i].id = i + 1
	}
	pl, ans := solveE(mat, n, seg)
	reverse(mat, seg)
	//	fmt.Printf("rev mat=%v seg=%d\n",mat,seg)
	pl2, ans2 := solveE(mat, n, seg)

	if ans < ans2 {
		fmt.Printf("%d\n", ans2)
		fmt.Printf("%d\n", len(pl2))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl2[i].id)
		}
		fmt.Printf("\n")
		if len(pl) > 0 && debug {
			c, _ := check(mat, tmpseg(seg))
			c, _ = check(mat, pl2)
			if c != ans2 {
				fmt.Printf("ERROR c = %d ans=%d\n", c, ans2)
			}
			fmt.Printf("logger--\n%s\n", logger)
		}
	} else {
		fmt.Printf("%d\n", ans)
		fmt.Printf("%d\n", len(pl))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl[i].id)
		}
		fmt.Printf("\n")

		if len(pl) > 0 && debug {
			reverse(mat, seg)
			c, _ := check(mat, tmpseg(seg))
			c, _ = check(mat, pl)

			if c != ans {
				fmt.Printf("2ERROR c = %d ans=%d\n", c, ans)
			}
			fmt.Printf("%s\n", logger)
		}
	}

}
func check(mat []int, pl Segs) (int64, int) {
	n := len(mat)
	m := len(pl)
	if m <= 0 {
		return 0, 0
	}
	maxx := -1
	minn := 10000000
	//minw := -1
	for i := 0; i < n; i++ {
		in := 0
		for j := 0; j < m; j++ {
			if pl[j].l > i+1 || pl[j].r < i+1 {
				continue
			}
			in++
		}
		if in == 0 {
			if maxx == -1 || mat[maxx] < mat[i] {
				maxx = i
			}
		}
		if minn > mat[i]-in {
			minn = mat[i] - in
			//minw = i
		}

	}
	if debug {
		maxxr := 0
		for i := 0; i < m; i++ {
			if pl[i].l <= 3119 && pl[i].r >= 3119 {
				//	fmt.Printf("range %d %d %d\n", pl[i].l, pl[i].r,pl[i].id)
			}

			if pl[i].r > maxxr {
				maxxr = pl[i].r
			}
		}
		//		fmt.Printf("check maxw = %d  minw = %d maxx=%d min=%d mat[minn]=%d maxxr=%d\n", maxx+1, minw+1, mat[maxx], minn, mat[minw],maxxr)
	}
	return int64(mat[maxx] - minn), mat[maxx]
}

/**

5 3
1 2 2 -2 3
3 5
1 5
3 5
 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

var (
	fatory *PointFatory
	debug  = false
	logger = ""
	goods  = [70]int{80, 41, 72, 28, 77, 62, 6, 14, 78, 97, 93, 48, 4, 3, 25, 94, 83, 10, 53, 22, 54, 70, 29, 27, 87, 45, 43, 76, 31, 30, 42, 20, 12, 2, 40, 16, 100, 64, 86, 44, 49, 56, 33, 11, 46, 18, 75, 5, 69, 55, 37, 50, 92, 73, 21, 57, 13, 35, 26, 65, 81, 95, 36, 32, 15, 60, 68, 89, 98, 38}
)

const (
	MAX int64 = int64(1000100) * 300
)

type Point struct {
	l, r   int
	dirty  int
	min    int64
	cl, cr *Point
}
type Seg struct {
	l, r int
	id   int
}
type Segs []Seg

func (s Segs) Len() int {
	return len(s)
}
func (s Segs) Swap(a, b int) {
	tmp := s[a].l
	s[a].l = s[b].l
	s[b].l = tmp

	tmp = s[a].r
	s[a].r = s[b].r
	s[b].r = tmp

	tmp = s[a].id
	s[a].id = s[b].id
	s[b].id = tmp
}
func (s Segs) Less(a, b int) bool {
	if s[a].r < s[b].r {
		return true
	}
	return false
}

type PointFatory struct {
	p     []Point
	front int
	len   int
}

func (p *PointFatory) newPoint() *Point {
	return &Point{}
	//if p.front >= p.len {
	//	p.p = append(p.p, make([]Point, p.len)...)
	//	p.len = len(p.p)
	//}
	//res := &p.p[p.front]
	//p.front++
	//return res
}
func newFatory(n int) *PointFatory {
	return &PointFatory{
		p:   make([]Point, n),
		len: n,
	}
}
func (p *Point) left() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cl == nil {
		p.cl = fatory.newPoint()
		p.cl.l = p.l
		p.cl.r = (p.l + p.r) / 2
		p.cl.min = MAX
	}
	return p.cl
}
func (p *Point) right() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cr == nil {
		p.cr = fatory.newPoint()
		p.cr.l = (p.l+p.r)/2 + 1
		p.cr.r = p.r
		p.cl.min = MAX
	}
	return p.cr
}
func (p *Point) refleshMin() {
	if p.left() == nil && p.right() == nil {
		return
	}
	if p.left() == nil {
		p.min = p.right().min
	} else if p.right() == nil {
		p.min = p.left().min
	} else if p.left().min < p.right().min {
		p.min = p.left().min
	} else {
		p.min = p.right().min
	}

}
func (p *Point) queryMin(l, r int) (int64, bool) {
	p.down()
	if l <= p.l && p.r <= r {
		return p.min, true
	}
	if l > p.r || r < p.l {
		return -1, false
	}
	var res int64 = 0
	find := false
	if p.left() != nil {
		leftmin, flag := p.left().queryMin(l, r)
		if flag {
			res = leftmin
			find = true
		}
	}
	if p.right() != nil {
		rightmin, flag := p.right().queryMin(l, r)
		if flag && (find == false || rightmin < res) {
			res = rightmin
		}
	}
	return res, true

}
func (p *Point) addValue(value int) {
	if p.min >= MAX {
		p.min = int64(value)
	} else {
		p.min += int64(value)
	}
}
func (p *Point) down() {
	if p.dirty <= 0 {
		return
	}
	pl := p.left()
	pr := p.right()
	if pl != nil {
		pl.dirty += p.dirty
		pl.addValue(p.dirty)
	}
	if pr != nil {
		pr.dirty += p.dirty
		pr.addValue(p.dirty)
	}
	p.dirty = 0
	//p.refleshMin()
}
func (p *Point) add(l, r int, value int) {
	if l > p.r || r < p.l {
		return
	}
	if l <= p.l && p.r <= r {
		p.addValue(value)
		p.dirty += value
		return
	}
	pl := p.left()
	pr := p.right()
	p.down()
	if pl != nil {
		pl.add(l, r, value)
	}
	if pr != nil {
		pr.add(l, r, value)
	}
	tmin := p.min
	p.refleshMin()
	if debug && p.min > tmin {
		fmt.Printf(" tmin=%d nowmin=%d l=%d r=%d value=%d\n", tmin, p.min,l,r,value)
	}
}
func solveE(mat []int, n int, segs Segs) (Segs, int64) {
	fatory = newFatory(n)

	maxx := make([]int, n)
	minn := mat[n-1]
	maxx[n-1] = mat[n-1]
	for i := n - 2; i >= 0; i-- {
		if mat[i] > maxx[i+1] {
			maxx[i] = mat[i]
		} else {
			maxx[i] = maxx[i+1]
		}
		if mat[i] < minn {
			minn = mat[i]
		}
	}
	partline := -1
	res := int64(maxx[0] - minn)
	root := fatory.newPoint()
	root.l = 1
	root.r = n
	//fmt.Printf("root.min = %d l=%d r=%d\n",root.min,root.l,root.r)
	for i := 0; i < n; i++ {
		root.add(i+1, i+1, mat[i])
		//	fmt.Printf("i=%d root.min = %d value=%d\n", i,root.min,mat[i])
	}
	//fmt.Printf("root.min = %d\n", root.min)

	sort.Sort(segs)
	dbMax := 0
	for i := 0; i < len(segs); i++ {
		if segs[i].r >= n {
			continue
		}
		root.add(segs[i].l, segs[i].r, -1)
		tmpm, _ := root.queryMin(1, segs[i].r)
		//	fmt.Printf("i=%d segs.l = %d segs.r = %d min=%d maxx=%d\n", i, segs[i].l, segs[i].r, tmpm, maxx[segs[i].r])
		if res < int64(maxx[segs[i].r])-tmpm {
			partline = i
			res = int64(maxx[segs[i].r]) - tmpm
			dbMax = maxx[segs[i].r]
		}
		if debug && (segs[i].id == 36 || segs[i].id == 55 || segs[i].id == 76 || segs[i].id == 11 || segs[i].id == 37 || segs[i].id == 95 || segs[i].id == 6 || segs[i].id == 41) {
			logger += fmt.Sprintf("i=%d maxx=%d min=%d l=%d r=%d root.min=%d\n", segs[i].id, maxx[segs[i].r], tmpm, segs[i].l, segs[i].r, root.min)
			//logger += "i=" + strconv.Itoa(segs[i].id) + " maxx = " + strconv.Itoa(maxx[segs[i].r]) + " min=" + strconv.Itoa(int(tmpm)) + "\n"
		}
	}
	if debug && partline > -1 {
		logger += "partline=" + strconv.Itoa(segs[partline].r) + " maxx = " + strconv.Itoa(dbMax) + " min=" + strconv.Itoa(dbMax-int(res)) + "\n"
		//	fmt.Printf("partline=%d maxx = %d min=%d\n", segs[partline].r, dbMax,res-int64(dbMax))
	}
	as := make(Segs, partline+1)
	for i := 0; i <= partline; i++ {
		as[i] = Seg{
			l:  segs[i].l,
			r:  segs[i].r,
			id: segs[i].id,
		}
	}
	//	fmt.Printf("as = %v res=%v\n",as,res)
	return as, res
}
func reverse(mat []int, segs Segs) {
	//	fmt.Printf("before mat=%v seg=%v\n",mat,segs)
	n := len(mat)
	m := len(segs)
	for i := 0; i < n-i-1; i++ {
		tmp := mat[i]
		mat[i] = mat[n-i-1]
		mat[n-i-1] = tmp
	}
	for i := 0; i < m; i++ {
		tmp := segs[i].l
		segs[i].l = segs[i].r
		segs[i].r = tmp
		segs[i].l = n - segs[i].l + 1
		segs[i].r = n - segs[i].r + 1
	}

}
func tmpseg(segs Segs) Segs {
	lens := len(goods)
	res := make(Segs, 0)
	for j := 0; j < len(segs); j++ {
		for i := 0; i < lens; i++ {
			if goods[i] == segs[j].id {
				res = append(res, segs[j])
				break
			}
		}
	}
	return res
}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	if n == 10000 && m == 100 {
		debug = true
	}
	//	debug=true
	mat := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d", &mat[i])
	}
	fmt.Fscanf(buf, "\n")
	seg := make(Segs, m)
	for i := 0; i < m; i++ {
		fmt.Fscanf(buf, "%d %d\n", &seg[i].l, &seg[i].r)
		seg[i].id = i + 1
	}
	pl, ans := solveE(mat, n, seg)
	reverse(mat, seg)
	//	fmt.Printf("rev mat=%v seg=%d\n",mat,seg)
	pl2, ans2 := solveE(mat, n, seg)

	if ans < ans2 {
		fmt.Printf("%d\n", ans2)
		fmt.Printf("%d\n", len(pl2))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl2[i].id)
		}
		fmt.Printf("\n")
		if len(pl) > 0 && debug {
			c, _ := check(mat, tmpseg(seg))
			c, _ = check(mat, pl2)
			if c != ans2 {
				fmt.Printf("ERROR c = %d ans=%d\n", c, ans2)
			}
			fmt.Printf("logger--\n%s\n", logger)
		}
	} else {
		fmt.Printf("%d\n", ans)
		fmt.Printf("%d\n", len(pl))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl[i].id)
		}
		fmt.Printf("\n")

		if len(pl) > 0 && debug {
			reverse(mat, seg)
			c, _ := check(mat, tmpseg(seg))
			c, _ = check(mat, pl)

			if c != ans {
				fmt.Printf("2ERROR c = %d ans=%d\n", c, ans)
			}
			fmt.Printf("%s\n", logger)
		}
	}

}
func check(mat []int, pl Segs) (int64, int) {
	n := len(mat)
	m := len(pl)
	if m <= 0 {
		return 0, 0
	}
	maxx := -1
	minn := 10000000
	//minw := -1
	for i := 0; i < n; i++ {
		in := 0
		for j := 0; j < m; j++ {
			if pl[j].l > i+1 || pl[j].r < i+1 {
				continue
			}
			in++
		}
		if in == 0 {
			if maxx == -1 || mat[maxx] < mat[i] {
				maxx = i
			}
		}
		if minn > mat[i]-in {
			minn = mat[i] - in
			//minw = i
		}

	}
	if debug {
		maxxr := 0
		for i := 0; i < m; i++ {
			if pl[i].l <= 3119 && pl[i].r >= 3119 {
				//	fmt.Printf("range %d %d %d\n", pl[i].l, pl[i].r,pl[i].id)
			}

			if pl[i].r > maxxr {
				maxxr = pl[i].r
			}
		}
		//		fmt.Printf("check maxw = %d  minw = %d maxx=%d min=%d mat[minn]=%d maxxr=%d\n", maxx+1, minw+1, mat[maxx], minn, mat[minw],maxxr)
	}
	return int64(mat[maxx] - minn), mat[maxx]
}

/**

5 3
1 2 2 -2 3
3 5
1 5
3 5
 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

var (
	fatory *PointFatory
	debug  = false
	logger = ""
	goods  = [70]int{80, 41, 72, 28, 77, 62, 6, 14, 78, 97, 93, 48, 4, 3, 25, 94, 83, 10, 53, 22, 54, 70, 29, 27, 87, 45, 43, 76, 31, 30, 42, 20, 12, 2, 40, 16, 100, 64, 86, 44, 49, 56, 33, 11, 46, 18, 75, 5, 69, 55, 37, 50, 92, 73, 21, 57, 13, 35, 26, 65, 81, 95, 36, 32, 15, 60, 68, 89, 98, 38}
)

const (
	MAX int64 = int64(3000100)
)

type Point struct {
	l, r   int
	dirty  int
	min    int64
	cl, cr *Point
}
type Seg struct {
	l, r int
	id   int
}
type Segs []Seg

func (s Segs) Len() int {
	return len(s)
}
func (s Segs) Swap(a, b int) {
	tmp := s[a].l
	s[a].l = s[b].l
	s[b].l = tmp

	tmp = s[a].r
	s[a].r = s[b].r
	s[b].r = tmp

	tmp = s[a].id
	s[a].id = s[b].id
	s[b].id = tmp
}
func (s Segs) Less(a, b int) bool {
	if s[a].r < s[b].r {
		return true
	}
	return false
}

type PointFatory struct {
	p     []Point
	front int
	len   int
}

func (p *PointFatory) newPoint() *Point {
	return &Point{}
	//if p.front >= p.len {
	//	p.p = append(p.p, make([]Point, p.len)...)
	//	p.len = len(p.p)
	//}
	//res := &p.p[p.front]
	//p.front++
	//return res
}
func newFatory(n int) *PointFatory {
	return &PointFatory{
		p:   make([]Point, n),
		len: n,
	}
}
func (p *Point) left() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cl == nil {
		p.cl = fatory.newPoint()
		p.cl.l = p.l
		p.cl.r = (p.l + p.r) / 2
		p.cl.min = MAX
	}
	return p.cl
}
func (p *Point) right() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cr == nil {
		p.cr = fatory.newPoint()
		p.cr.l = (p.l+p.r)/2 + 1
		p.cr.r = p.r
		p.cr.min = MAX
	}
	return p.cr
}
func (p *Point) refleshMin() {
	if p.left() == nil && p.right() == nil {
		return
	}
	if p.left() == nil {
		p.min = p.right().min
	} else if p.right() == nil {
		p.min = p.left().min
	} else if p.left().min < p.right().min {
		p.min = p.left().min
	} else {
		p.min = p.right().min
	}
	if p.min == 0 &&debug{
		fmt.Printf("min=0 l=%d r=%d dirty=%d\n",p.l,p.r,p.dirty)
	}

}
func (p *Point) queryMin(l, r int) (int64, bool) {
	p.down()
	if l <= p.l && p.r <= r {
		return p.min, true
	}
	if l > p.r || r < p.l {
		return -1, false
	}
	var res int64 = 0
	find := false
	if p.left() != nil {
		leftmin, flag := p.left().queryMin(l, r)
		if flag {
			res = leftmin
			find = true
		}
	}
	if p.right() != nil {
		rightmin, flag := p.right().queryMin(l, r)
		if flag && (find == false || rightmin < res) {
			res = rightmin
		}
	}
	return res, true

}
func (p *Point) addValue(value int) {
	if p.min >= MAX {
		p.min = int64(value)
	} else {
		p.min += int64(value)
	}
	if p.min == 0 &&debug{
		fmt.Printf("min=0 l=%d r=%d dirty=%d value=%d\n",p.l,p.r,p.dirty,value)
	}
}
func (p *Point) down() {
	if p.dirty <= 0 {
		return
	}
	pl := p.left()
	pr := p.right()
	if pl != nil {
		pl.dirty += p.dirty
		pl.addValue(p.dirty)
	}
	if pr != nil {
		pr.dirty += p.dirty
		pr.addValue(p.dirty)
	}
	p.dirty = 0
	//p.refleshMin()
}
func (p *Point) add(l, r int, value int) {
	if l > p.r || r < p.l {
		return
	}
	if l <= p.l && p.r <= r {
		p.addValue(value)
		p.dirty += value
		return
	}
	pl := p.left()
	pr := p.right()
	p.down()
	if pl != nil {
		pl.add(l, r, value)
	}
	if pr != nil {
		pr.add(l, r, value)
	}
	tmin := p.min
	p.refleshMin()
	if debug && p.min > tmin {
		fmt.Printf(" tmin=%d nowmin=%d pl=%d pr=%d l=%d r=%d value=%d\n", tmin, p.min,p.l,p.r,l,r,value)
	}
}
func solveE(mat []int, n int, segs Segs) (Segs, int64) {
	fatory = newFatory(n)

	maxx := make([]int, n)
	minn := mat[n-1]
	maxx[n-1] = mat[n-1]
	for i := n - 2; i >= 0; i-- {
		if mat[i] > maxx[i+1] {
			maxx[i] = mat[i]
		} else {
			maxx[i] = maxx[i+1]
		}
		if mat[i] < minn {
			minn = mat[i]
		}
	}
	partline := -1
	res := int64(maxx[0] - minn)
	root := fatory.newPoint()
	root.l = 1
	root.r = n
	root.min = MAX
	//fmt.Printf("root.min = %d l=%d r=%d\n",root.min,root.l,root.r)
	for i := 0; i < n; i++ {
		root.add(i+1, i+1, mat[i])
		//	fmt.Printf("i=%d root.min = %d value=%d\n", i,root.min,mat[i])
	}
	//fmt.Printf("root.min = %d\n", root.min)

	sort.Sort(segs)
	dbMax := 0
	for i := 0; i < len(segs); i++ {
		if segs[i].r >= n {
			continue
		}
		root.add(segs[i].l, segs[i].r, -1)
		tmpm, _ := root.queryMin(1, segs[i].r)
		//	fmt.Printf("i=%d segs.l = %d segs.r = %d min=%d maxx=%d\n", i, segs[i].l, segs[i].r, tmpm, maxx[segs[i].r])
		if res < int64(maxx[segs[i].r])-tmpm {
			partline = i
			res = int64(maxx[segs[i].r]) - tmpm
			dbMax = maxx[segs[i].r]
		}
		if debug && (segs[i].id == 36 || segs[i].id == 55 || segs[i].id == 76 || segs[i].id == 11 || segs[i].id == 37 || segs[i].id == 95 || segs[i].id == 6 || segs[i].id == 41) {
			logger += fmt.Sprintf("i=%d maxx=%d min=%d l=%d r=%d root.min=%d\n", segs[i].id, maxx[segs[i].r], tmpm, segs[i].l, segs[i].r, root.min)
			//logger += "i=" + strconv.Itoa(segs[i].id) + " maxx = " + strconv.Itoa(maxx[segs[i].r]) + " min=" + strconv.Itoa(int(tmpm)) + "\n"
		}
	}
	if debug && partline > -1 {
		logger += "partline=" + strconv.Itoa(segs[partline].r) + " maxx = " + strconv.Itoa(dbMax) + " min=" + strconv.Itoa(dbMax-int(res)) + "\n"
		//	fmt.Printf("partline=%d maxx = %d min=%d\n", segs[partline].r, dbMax,res-int64(dbMax))
	}
	as := make(Segs, partline+1)
	for i := 0; i <= partline; i++ {
		as[i] = Seg{
			l:  segs[i].l,
			r:  segs[i].r,
			id: segs[i].id,
		}
	}
	//	fmt.Printf("as = %v res=%v\n",as,res)
	return as, res
}
func reverse(mat []int, segs Segs) {
	//	fmt.Printf("before mat=%v seg=%v\n",mat,segs)
	n := len(mat)
	m := len(segs)
	for i := 0; i < n-i-1; i++ {
		tmp := mat[i]
		mat[i] = mat[n-i-1]
		mat[n-i-1] = tmp
	}
	for i := 0; i < m; i++ {
		tmp := segs[i].l
		segs[i].l = segs[i].r
		segs[i].r = tmp
		segs[i].l = n - segs[i].l + 1
		segs[i].r = n - segs[i].r + 1
	}

}
func tmpseg(segs Segs) Segs {
	lens := len(goods)
	res := make(Segs, 0)
	for j := 0; j < len(segs); j++ {
		for i := 0; i < lens; i++ {
			if goods[i] == segs[j].id {
				res = append(res, segs[j])
				break
			}
		}
	}
	return res
}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	//if n == 10000 && m == 100 {
	//	debug = true
	//}
	if debug{
		fmt.Printf("maxx=%d\n",MAX)
	}
	//	debug=true
	mat := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d", &mat[i])
	}
	fmt.Fscanf(buf, "\n")
	seg := make(Segs, m)
	for i := 0; i < m; i++ {
		fmt.Fscanf(buf, "%d %d\n", &seg[i].l, &seg[i].r)
		seg[i].id = i + 1
	}
	pl, ans := solveE(mat, n, seg)
	reverse(mat, seg)
	//	fmt.Printf("rev mat=%v seg=%d\n",mat,seg)
	pl2, ans2 := solveE(mat, n, seg)

	if ans < ans2 {
		fmt.Printf("%d\n", ans2)
		fmt.Printf("%d\n", len(pl2))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl2[i].id)
		}
		fmt.Printf("\n")
		if len(pl) > 0 && debug {
			c, _ := check(mat, tmpseg(seg))
			c, _ = check(mat, pl2)
			if c != ans2 {
				fmt.Printf("ERROR c = %d ans=%d\n", c, ans2)
			}
			fmt.Printf("logger--\n%s\n", logger)
		}
	} else {
		fmt.Printf("%d\n", ans)
		fmt.Printf("%d\n", len(pl))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl[i].id)
		}
		fmt.Printf("\n")

		if len(pl) > 0 && debug {
			reverse(mat, seg)
			c, _ := check(mat, tmpseg(seg))
			c, _ = check(mat, pl)

			if c != ans {
				fmt.Printf("2ERROR c = %d ans=%d\n", c, ans)
			}
			fmt.Printf("%s\n", logger)
		}
	}

}
func check(mat []int, pl Segs) (int64, int) {
	n := len(mat)
	m := len(pl)
	if m <= 0 {
		return 0, 0
	}
	maxx := -1
	minn := 10000000
	//minw := -1
	for i := 0; i < n; i++ {
		in := 0
		for j := 0; j < m; j++ {
			if pl[j].l > i+1 || pl[j].r < i+1 {
				continue
			}
			in++
		}
		if in == 0 {
			if maxx == -1 || mat[maxx] < mat[i] {
				maxx = i
			}
		}
		if minn > mat[i]-in {
			minn = mat[i] - in
			//minw = i
		}

	}
	if debug {
		maxxr := 0
		for i := 0; i < m; i++ {
			if pl[i].l <= 3119 && pl[i].r >= 3119 {
				//	fmt.Printf("range %d %d %d\n", pl[i].l, pl[i].r,pl[i].id)
			}

			if pl[i].r > maxxr {
				maxxr = pl[i].r
			}
		}
		//		fmt.Printf("check maxw = %d  minw = %d maxx=%d min=%d mat[minn]=%d maxxr=%d\n", maxx+1, minw+1, mat[maxx], minn, mat[minw],maxxr)
	}
	return int64(mat[maxx] - minn), mat[maxx]
}

/**

5 3
1 2 2 -2 3
3 5
1 5
3 5
 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

var (
	fatory *PointFatory
	debug  = false
	logger=""
)

const (
	MAX = 1000100 * 300
)

type Point struct {
	l, r   int
	dirty  int
	min    int64
	cl, cr *Point
}
type Seg struct {
	l, r int
	id   int
}
type Segs []Seg

func (s Segs) Len() int {
	return len(s)
}
func (s Segs) Swap(a, b int) {
	tmp := s[a].l
	s[a].l = s[b].l
	s[b].l = tmp

	tmp = s[a].r
	s[a].r = s[b].r
	s[b].r = tmp

	tmp = s[a].id
	s[a].id = s[b].id
	s[b].id = tmp
}
func (s Segs) Less(a, b int) bool {
	if s[a].r < s[b].r {
		return true
	}
	return false
}

type PointFatory struct {
	p     []Point
	front int
	len   int
}

func (p *PointFatory) newPoint() *Point {
	if p.front >= p.len {
		p.p = append(p.p, make([]Point, p.len)...)
		p.len = len(p.p)
	}
	res := &p.p[p.front]
	p.front++
	return res
}
func newFatory(n int) *PointFatory {
	return &PointFatory{
		p:   make([]Point, n),
		len: n,
	}
}
func (p *Point) left() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cl == nil {
		p.cl = fatory.newPoint()
		p.cl.l = p.l
		p.cl.r = (p.l + p.r) / 2
		p.cl.min = MAX
	}
	return p.cl
}
func (p *Point) right() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cr == nil {
		p.cr = fatory.newPoint()
		p.cr.l = (p.l+p.r)/2 + 1
		p.cr.r = p.r
		p.cl.min = MAX
	}
	return p.cr
}
func (p *Point) refleshMin() {
	if p.left() == nil && p.right() == nil {
		return
	}
	if p.left() == nil {
		p.min = p.right().min
	} else if p.right() == nil {
		p.min = p.left().min
	} else if p.left().min < p.right().min {
		p.min = p.left().min
	} else {
		p.min = p.right().min
	}

}
func (p *Point) queryMin(l, r int) (int64, bool) {
	p.down()
	if l <= p.l && p.r <= r {
		return p.min, true
	}
	if l > p.r || r < p.l {
		return -1, false
	}
	var res int64 = 0
	find := false
	if p.left() != nil {
		leftmin, flag := p.left().queryMin(l, r)
		if flag {
			res = leftmin
			find = true
		}
	}
	if p.right() != nil {
		rightmin, flag := p.right().queryMin(l, r)
		if flag && (find == false || rightmin < res) {
			res = rightmin
		}
	}
	return res, true

}
func (p *Point) addValue(value int) {
	if p.min >= MAX {
		p.min = int64(value)
	} else {
		p.min += int64(value)
	}
}
func (p *Point) down() {
	if p.dirty <= 0 {
		return
	}
	pl := p.left()
	pr := p.right()
	if pl != nil {
		pl.dirty += p.dirty
		pl.addValue(p.dirty)
	}
	if pr != nil {
		pr.dirty += p.dirty
		pr.addValue(p.dirty)
	}
	p.dirty = 0
	p.refleshMin()
}
func (p *Point) add(l, r int, value int) {
	if l > p.r || r < p.l {
		return
	}
	if l <= p.l && p.r <= r {
		p.addValue(value)
		p.dirty += value
		return
	}
	pl := p.left()
	pr := p.right()
	p.down()
	if pl != nil {
		pl.add(l, r, value)
	}
	if pr != nil {
		pr.add(l, r, value)
	}
	p.refleshMin()
}
func solveE(mat []int, n int, segs Segs) (Segs, int64) {
	fatory = newFatory(n)

	maxx := make([]int, n)
	minn := mat[n-1]
	maxx[n-1] = mat[n-1]
	for i := n - 2; i >= 0; i-- {
		if mat[i] > maxx[i+1] {
			maxx[i] = mat[i]
		} else {
			maxx[i] = maxx[i+1]
		}
		if mat[i] < minn {
			minn = mat[i]
		}
	}
	partline := -1
	res := int64(maxx[0] - minn)
	root := fatory.newPoint()
	root.l = 1
	root.r = n
	//fmt.Printf("root.min = %d l=%d r=%d\n",root.min,root.l,root.r)
	for i := 0; i < n; i++ {
		root.add(i+1, i+1, mat[i])
		//	fmt.Printf("i=%d root.min = %d value=%d\n", i,root.min,mat[i])
	}
	//fmt.Printf("root.min = %d\n", root.min)

	sort.Sort(segs)
	dbMax := 0
	for i := 0; i < len(segs); i++ {
		if segs[i].r >= n {
			continue
		}
		root.add(segs[i].l, segs[i].r, -1)
		tmpm, _ := root.queryMin(1, segs[i].r)
		//	fmt.Printf("i=%d segs.l = %d segs.r = %d min=%d maxx=%d\n", i, segs[i].l, segs[i].r, tmpm, maxx[segs[i].r])
		if res < int64(maxx[segs[i].r])-tmpm {
			partline = i
			res = int64(maxx[segs[i].r]) - tmpm
			dbMax = maxx[segs[i].r]
		}
	}
	if debug &&partline>-1{
		logger += "partline="+strconv.Itoa(segs[partline].r)+" maxx = "+strconv.Itoa(dbMax)+" min="+strconv.Itoa(dbMax-int(res))+"\n"
	//	fmt.Printf("partline=%d maxx = %d min=%d\n", segs[partline].r, dbMax,res-int64(dbMax))
	}
	as := make(Segs, partline+1)
	for i := 0; i <= partline; i++ {
		as[i] = segs[i]
	}
	//	fmt.Printf("as = %v res=%v\n",as,res)
	return as, res
}
func reverse(mat []int, segs Segs) {
	//	fmt.Printf("before mat=%v seg=%v\n",mat,segs)
	n := len(mat)
	m := len(segs)
	for i := 0; i < n-i-1; i++ {
		tmp := mat[i]
		mat[i] = mat[n-i-1]
		mat[n-i-1] = tmp
	}
	for i := 0; i < m; i++ {
		tmp := segs[i].l
		segs[i].l = segs[i].r
		segs[i].r = tmp
		segs[i].l = n - segs[i].l + 1
		segs[i].r = n - segs[i].r + 1
	}

}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	if n == 10000 && m == 100{
		debug = true
	}
//	debug=true
	mat := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d", &mat[i])
	}
	fmt.Fscanf(buf, "\n")
	seg := make(Segs, m)
	for i := 0; i < m; i++ {
		fmt.Fscanf(buf, "%d %d\n", &seg[i].l, &seg[i].r)
		seg[i].id = i + 1
	}
	pl, ans := solveE(mat, n, seg)
	reverse(mat, seg)
	//	fmt.Printf("rev mat=%v seg=%d\n",mat,seg)
	pl2, ans2 := solveE(mat, n, seg)

	if ans < ans2 {
		fmt.Printf("%d\n", ans2)
		fmt.Printf("%d\n", len(pl2))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl2[i].id)
		}
		fmt.Printf("\n")
		if len(pl) > 0 && debug {
			c, wei := check(mat, pl2)
			fmt.Printf("w = %d\n", wei)
			if c != ans2 {
				fmt.Printf("ERROR c = %d ans=%d\n", c, ans2)
			}
			fmt.Printf("logger--\n%s\n",logger)
		}
	} else {
		fmt.Printf("%d\n", ans)
		fmt.Printf("%d\n", len(pl))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl[i].id)
		}
		fmt.Printf("\n")

		if len(pl) > 0 && debug {
			reverse(mat, seg)
			c, wei := check(mat, pl)
			fmt.Printf("w = %d\n", wei)
			if c != ans {
				fmt.Printf("2ERROR c = %d ans=%d\n", c, ans)
			}
			fmt.Printf("logger--\n%s\n",logger)
		}
	}

}
func check(mat []int, pl Segs) (int64, int) {
	n := len(mat)
	m := len(pl)
	if m <= 0 {
		return 0, 0
	}
	maxx := -1
	minn := 10000000
	for i := 0; i < n; i++ {
		in := 0
		for j := 0; j < m; j++ {
			if pl[j].l > i+1 || pl[j].r < i+1 {
				continue
			}
			in++
		}
		if in == 0 {
			if maxx == -1 || mat[maxx] < mat[i] {
				maxx = i
			}
		}
		if minn > mat[i]-in {
			minn = mat[i] - in
		}
	}
	if debug {
		for i := 0; i < m; i++ {
			fmt.Printf("range %d %d\n", pl[i].l, pl[i].r)
		}
		fmt.Printf("check maxw = %d maxx=%d minn=%d\n", maxx,mat[maxx], minn)
	}
	return int64(mat[maxx] - minn), mat[maxx]
}

/**

5 3
1 2 2 -2 3
3 5
1 5
3 5
 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

var (
	fatory *PointFatory
	debug  = false
)

const (
	MAX = 1000100 * 300
)

type Point struct {
	l, r   int
	dirty  int
	min    int64
	cl, cr *Point
}
type Seg struct {
	l, r int
	id   int
}
type Segs []Seg

func (s Segs) Len() int {
	return len(s)
}
func (s Segs) Swap(a, b int) {
	tmp := s[a].l
	s[a].l = s[b].l
	s[b].l = tmp

	tmp = s[a].r
	s[a].r = s[b].r
	s[b].r = tmp

	tmp = s[a].id
	s[a].id = s[b].id
	s[b].id = tmp
}
func (s Segs) Less(a, b int) bool {
	if s[a].r < s[b].r {
		return true
	}
	return false
}

type PointFatory struct {
	p     []Point
	front int
	len   int
}

func (p *PointFatory) newPoint() *Point {
	if p.front >= p.len {
		p.p = append(p.p, make([]Point, p.len)...)
		p.len = len(p.p)
	}
	res := &p.p[p.front]
	p.front++
	return res
}
func newFatory(n int) *PointFatory {
	return &PointFatory{
		p:   make([]Point, n),
		len: n,
	}
}
func (p *Point) left() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cl == nil {
		p.cl = fatory.newPoint()
		p.cl.l = p.l
		p.cl.r = (p.l + p.r) / 2
		p.cl.min = MAX
	}
	return p.cl
}
func (p *Point) right() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cr == nil {
		p.cr = fatory.newPoint()
		p.cr.l = (p.l+p.r)/2 + 1
		p.cr.r = p.r
		p.cl.min = MAX
	}
	return p.cr
}
func (p *Point) refleshMin() {
	if p.left() == nil && p.right() == nil {
		return
	}
	if p.left() == nil {
		p.min = p.right().min
	} else if p.right() == nil {
		p.min = p.left().min
	} else if p.left().min < p.right().min {
		p.min = p.left().min
	} else {
		p.min = p.right().min
	}

}
func (p *Point) queryMin(l, r int) (int64, bool) {
	p.down()
	if l <= p.l && p.r <= r {
		return p.min, true
	}
	if l > p.r || r < p.l {
		return -1, false
	}
	var res int64 = 0
	find := false
	if p.left() != nil {
		leftmin, flag := p.left().queryMin(l, r)
		if flag {
			res = leftmin
			find = true
		}
	}
	if p.right() != nil {
		rightmin, flag := p.right().queryMin(l, r)
		if flag && (find == false || rightmin < res) {
			res = rightmin
		}
	}
	return res, true

}
func (p *Point) addValue(value int) {
	if p.min >= MAX {
		p.min = int64(value)
	} else {
		p.min += int64(value)
	}
}
func (p *Point) down() {
	if p.dirty <= 0 {
		return
	}
	pl := p.left()
	pr := p.right()
	if pl != nil {
		pl.dirty += p.dirty
		pl.addValue(p.dirty)
	}
	if pr != nil {
		pr.dirty += p.dirty
		pr.addValue(p.dirty)
	}
	p.dirty = 0
	p.refleshMin()
}
func (p *Point) add(l, r int, value int) {
	if l > p.r || r < p.l {
		return
	}
	if l <= p.l && p.r <= r {
		p.addValue(value)
		p.dirty += value
		return
	}
	pl := p.left()
	pr := p.right()
	p.down()
	if pl != nil {
		pl.add(l, r, value)
	}
	if pr != nil {
		pr.add(l, r, value)
	}
	p.refleshMin()
}
func solveE(mat []int, n int, segs Segs) (Segs, int64) {
	fatory = newFatory(n)

	maxx := make([]int, n)
	minn := mat[n-1]
	maxx[n-1] = mat[n-1]
	for i := n - 2; i >= 0; i-- {
		if mat[i] > maxx[i+1] {
			maxx[i] = mat[i]
		} else {
			maxx[i] = maxx[i+1]
		}
		if mat[i] < minn {
			minn = mat[i]
		}
	}
	partline := -1
	res := int64(maxx[0] - minn)
	root := fatory.newPoint()
	root.l = 1
	root.r = n
	//fmt.Printf("root.min = %d l=%d r=%d\n",root.min,root.l,root.r)
	for i := 0; i < n; i++ {
		root.add(i+1, i+1, mat[i])
		//	fmt.Printf("i=%d root.min = %d value=%d\n", i,root.min,mat[i])
	}
	//fmt.Printf("root.min = %d\n", root.min)

	sort.Sort(segs)
	dbMax := 0
	for i := 0; i < len(segs); i++ {
		if segs[i].r >= n {
			continue
		}
		root.add(segs[i].l, segs[i].r, -1)
		tmpm, _ := root.queryMin(1, segs[i].r)
		//	fmt.Printf("i=%d segs.l = %d segs.r = %d min=%d maxx=%d\n", i, segs[i].l, segs[i].r, tmpm, maxx[segs[i].r])
		if res < int64(maxx[segs[i].r])-tmpm {
			partline = i
			res = int64(maxx[segs[i].r]) - tmpm
			dbMax = maxx[segs[i].r]
		}
	}
	if debug {
		fmt.Printf("partline=%d maxx = %d\n", segs[partline].r, dbMax)
	}
	as := make(Segs, partline+1)
	for i := 0; i <= partline; i++ {
		as[i] = segs[i]
	}
	//	fmt.Printf("as = %v res=%v\n",as,res)
	return as, res
}
func reverse(mat []int, segs Segs) {
	//	fmt.Printf("before mat=%v seg=%v\n",mat,segs)
	n := len(mat)
	m := len(segs)
	for i := 0; i < n-i-1; i++ {
		tmp := mat[i]
		mat[i] = mat[n-i-1]
		mat[n-i-1] = tmp
	}
	for i := 0; i < m; i++ {
		tmp := segs[i].l
		segs[i].l = segs[i].r
		segs[i].r = tmp
		segs[i].l = n - segs[i].l + 1
		segs[i].r = n - segs[i].r + 1
	}

}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	mat := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d", &mat[i])
	}
	fmt.Fscanf(buf, "\n")
	seg := make(Segs, m)
	for i := 0; i < m; i++ {
		fmt.Fscanf(buf, "%d %d\n", &seg[i].l, &seg[i].r)
		seg[i].id = i + 1
	}
	pl, ans := solveE(mat, n, seg)
	reverse(mat, seg)
	//	fmt.Printf("rev mat=%v seg=%d\n",mat,seg)
	pl2, ans2 := solveE(mat, n, seg)
	if n == 10000 && m == 100{
		debug = true
	}
	if ans < ans2 {
		fmt.Printf("%d\n", ans2)
		fmt.Printf("%d\n", len(pl2))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl2[i].id)
		}
		fmt.Printf("\n")
		if len(pl) > 0 && debug {
			c, wei := check(mat, pl2)
			fmt.Printf("w = %d\n", wei)
			if c != ans2 {
				fmt.Printf("ERROR c = %d ans=%d\n", c, ans2)
			}
		}
	} else {
		fmt.Printf("%d\n", ans)
		fmt.Printf("%d\n", len(pl))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl[i].id)
		}
		fmt.Printf("\n")

		if len(pl) > 0 && debug {
			reverse(mat, seg)
			c, wei := check(mat, pl)
			fmt.Printf("w = %d\n", wei)
			if c != ans {
				fmt.Printf("2ERROR c = %d ans=%d\n", c, ans)
			}
		}
	}

}
func check(mat []int, pl Segs) (int64, int) {
	n := len(mat)
	m := len(pl)
	if m <= 0 {
		return 0, 0
	}
	maxx := -1
	minn := 10000000
	for i := 0; i < n; i++ {
		in := 0
		for j := 0; j < m; j++ {
			if pl[j].l > i+1 || pl[j].r < i+1 {
				continue
			}
			in++
		}
		if in == 0 {
			if maxx == -1 || mat[maxx] < mat[i] {
				maxx = i
			}
		}
		if minn > mat[i]-in {
			minn = mat[i] - in
		}
	}
	if debug {
		for i := 0; i < m; i++ {
			fmt.Printf("%d %d\n", pl[i].l, pl[i].r)
		}
		fmt.Printf("check maxx=%d minn=%d\n", pl, maxx, minn)
	}
	return int64(maxx - minn), maxx
}

/**

5 3
1 2 2 -2 3
3 5
1 5
3 5
 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

var (
	fatory *PointFatory
	debug  = false
	logger=""
)

const (
	MAX = 1000100 * 300
)

type Point struct {
	l, r   int
	dirty  int
	min    int64
	cl, cr *Point
}
type Seg struct {
	l, r int
	id   int
}
type Segs []Seg

func (s Segs) Len() int {
	return len(s)
}
func (s Segs) Swap(a, b int) {
	tmp := s[a].l
	s[a].l = s[b].l
	s[b].l = tmp

	tmp = s[a].r
	s[a].r = s[b].r
	s[b].r = tmp

	tmp = s[a].id
	s[a].id = s[b].id
	s[b].id = tmp
}
func (s Segs) Less(a, b int) bool {
	if s[a].r < s[b].r {
		return true
	}
	return false
}

type PointFatory struct {
	p     []Point
	front int
	len   int
}

func (p *PointFatory) newPoint() *Point {
	if p.front >= p.len {
		p.p = append(p.p, make([]Point, p.len)...)
		p.len = len(p.p)
	}
	res := &p.p[p.front]
	p.front++
	return res
}
func newFatory(n int) *PointFatory {
	return &PointFatory{
		p:   make([]Point, n),
		len: n,
	}
}
func (p *Point) left() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cl == nil {
		p.cl = fatory.newPoint()
		p.cl.l = p.l
		p.cl.r = (p.l + p.r) / 2
		p.cl.min = MAX
	}
	return p.cl
}
func (p *Point) right() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cr == nil {
		p.cr = fatory.newPoint()
		p.cr.l = (p.l+p.r)/2 + 1
		p.cr.r = p.r
		p.cl.min = MAX
	}
	return p.cr
}
func (p *Point) refleshMin() {
	if p.left() == nil && p.right() == nil {
		return
	}
	if p.left() == nil {
		p.min = p.right().min
	} else if p.right() == nil {
		p.min = p.left().min
	} else if p.left().min < p.right().min {
		p.min = p.left().min
	} else {
		p.min = p.right().min
	}

}
func (p *Point) queryMin(l, r int) (int64, bool) {
	p.down()
	if l <= p.l && p.r <= r {
		return p.min, true
	}
	if l > p.r || r < p.l {
		return -1, false
	}
	var res int64 = 0
	find := false
	if p.left() != nil {
		leftmin, flag := p.left().queryMin(l, r)
		if flag {
			res = leftmin
			find = true
		}
	}
	if p.right() != nil {
		rightmin, flag := p.right().queryMin(l, r)
		if flag && (find == false || rightmin < res) {
			res = rightmin
		}
	}
	return res, true

}
func (p *Point) addValue(value int) {
	if p.min >= MAX {
		p.min = int64(value)
	} else {
		p.min += int64(value)
	}
}
func (p *Point) down() {
	if p.dirty <= 0 {
		return
	}
	pl := p.left()
	pr := p.right()
	if pl != nil {
		pl.dirty += p.dirty
		pl.addValue(p.dirty)
	}
	if pr != nil {
		pr.dirty += p.dirty
		pr.addValue(p.dirty)
	}
	p.dirty = 0
	p.refleshMin()
}
func (p *Point) add(l, r int, value int) {
	if l > p.r || r < p.l {
		return
	}
	if l <= p.l && p.r <= r {
		p.addValue(value)
		p.dirty += value
		return
	}
	pl := p.left()
	pr := p.right()
	p.down()
	if pl != nil {
		pl.add(l, r, value)
	}
	if pr != nil {
		pr.add(l, r, value)
	}
	p.refleshMin()
}
func solveE(mat []int, n int, segs Segs) (Segs, int64) {
	fatory = newFatory(n)

	maxx := make([]int, n)
	minn := mat[n-1]
	maxx[n-1] = mat[n-1]
	for i := n - 2; i >= 0; i-- {
		if mat[i] > maxx[i+1] {
			maxx[i] = mat[i]
		} else {
			maxx[i] = maxx[i+1]
		}
		if mat[i] < minn {
			minn = mat[i]
		}
	}
	partline := -1
	res := int64(maxx[0] - minn)
	root := fatory.newPoint()
	root.l = 1
	root.r = n
	//fmt.Printf("root.min = %d l=%d r=%d\n",root.min,root.l,root.r)
	for i := 0; i < n; i++ {
		root.add(i+1, i+1, mat[i])
		//	fmt.Printf("i=%d root.min = %d value=%d\n", i,root.min,mat[i])
	}
	//fmt.Printf("root.min = %d\n", root.min)

	sort.Sort(segs)
	dbMax := 0
	for i := 0; i < len(segs); i++ {
		if segs[i].r >= n {
			continue
		}
		root.add(segs[i].l, segs[i].r, -1)
		tmpm, _ := root.queryMin(1, segs[i].r)
		//	fmt.Printf("i=%d segs.l = %d segs.r = %d min=%d maxx=%d\n", i, segs[i].l, segs[i].r, tmpm, maxx[segs[i].r])
		if res < int64(maxx[segs[i].r])-tmpm {
			partline = i
			res = int64(maxx[segs[i].r]) - tmpm
			dbMax = maxx[segs[i].r]
		}
	}
	if debug &&partline>-1{
		logger += "partline="+strconv.Itoa(segs[partline].r)+" maxx = "+strconv.Itoa(dbMax)+" min="+strconv.Itoa(dbMax-int(res))+"\n"
	//	fmt.Printf("partline=%d maxx = %d min=%d\n", segs[partline].r, dbMax,res-int64(dbMax))
	}
	as := make(Segs, partline+1)
	for i := 0; i <= partline; i++ {
		as[i] = segs[i]
	}
	//	fmt.Printf("as = %v res=%v\n",as,res)
	return as, res
}
func reverse(mat []int, segs Segs) {
	//	fmt.Printf("before mat=%v seg=%v\n",mat,segs)
	n := len(mat)
	m := len(segs)
	for i := 0; i < n-i-1; i++ {
		tmp := mat[i]
		mat[i] = mat[n-i-1]
		mat[n-i-1] = tmp
	}
	for i := 0; i < m; i++ {
		tmp := segs[i].l
		segs[i].l = segs[i].r
		segs[i].r = tmp
		segs[i].l = n - segs[i].l + 1
		segs[i].r = n - segs[i].r + 1
	}

}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	if n == 10000 && m == 100{
		debug = true
	}
//	debug=true
	mat := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d", &mat[i])
	}
	fmt.Fscanf(buf, "\n")
	seg := make(Segs, m)
	for i := 0; i < m; i++ {
		fmt.Fscanf(buf, "%d %d\n", &seg[i].l, &seg[i].r)
		seg[i].id = i + 1
	}
	pl, ans := solveE(mat, n, seg)
	reverse(mat, seg)
	//	fmt.Printf("rev mat=%v seg=%d\n",mat,seg)
	pl2, ans2 := solveE(mat, n, seg)

	if ans < ans2 {
		fmt.Printf("%d\n", ans2)
		fmt.Printf("%d\n", len(pl2))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl2[i].id)
		}
		fmt.Printf("\n")
		if len(pl) > 0 && debug {
			c, wei := check(mat, pl2)
			fmt.Printf("w = %d\n", wei)
			if c != ans2 {
				fmt.Printf("ERROR c = %d ans=%d\n", c, ans2)
			}
			fmt.Printf("logger--\n%s\n",logger)
		}
	} else {
		fmt.Printf("%d\n", ans)
		fmt.Printf("%d\n", len(pl))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl[i].id)
		}
		fmt.Printf("\n")

		if len(pl) > 0 && debug {
			reverse(mat, seg)
			c, wei := check(mat, pl)
			fmt.Printf("w = %d\n", wei)
			if c != ans {
				fmt.Printf("2ERROR c = %d ans=%d\n", c, ans)
			}
			fmt.Printf("logger--\n%s\n",logger)
		}
	}

}
func check(mat []int, pl Segs) (int64, int) {
	n := len(mat)
	m := len(pl)
	if m <= 0 {
		return 0, 0
	}
	maxx := -1
	minn := 10000000
	minw := -1
	for i := 0; i < n; i++ {
		in := 0
		for j := 0; j < m; j++ {
			if pl[j].l > i+1 || pl[j].r < i+1 {
				continue
			}
			in++
		}
		if in == 0 {
			if maxx == -1 || mat[maxx] < mat[i] {
				maxx = i
			}
		}
		if minn > mat[i]-in {
			minn = mat[i] - in
			minw = i
		}
	}
	if debug {
		for i := 0; i < m; i++ {
			fmt.Printf("range %d %d\n", pl[i].l, pl[i].r)
		}
		fmt.Printf("check maxw = %d  minw = %d maxx=%d min=%d mat[minn]=%d\n", maxx+1,minw+1,mat[maxx],minn, mat[minw])
	}
	return int64(mat[maxx] - minn), mat[maxx]
}

/**

5 3
1 2 2 -2 3
3 5
1 5
3 5
 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

var (
	fatory *PointFatory
	debug  = false
	logger = ""
	goods  = [70]int{80, 41, 72, 28, 77, 62, 6, 14, 78, 97, 93, 48, 4, 3, 25, 94, 83, 10, 53, 22, 54, 70, 29, 27, 87, 45, 43, 76, 31, 30, 42, 20, 12, 2, 40, 16, 100, 64, 86, 44, 49, 56, 33, 11, 46, 18, 75, 5, 69, 55, 37, 50, 92, 73, 21, 57, 13, 35, 26, 65, 81, 95, 36, 32, 15, 60, 68, 89, 98, 38}
)

const (
	MAX = 1000100 * 300
)

type Point struct {
	l, r   int
	dirty  int
	min    int64
	cl, cr *Point
}
type Seg struct {
	l, r int
	id   int
}
type Segs []Seg

func (s Segs) Len() int {
	return len(s)
}
func (s Segs) Swap(a, b int) {
	tmp := s[a].l
	s[a].l = s[b].l
	s[b].l = tmp

	tmp = s[a].r
	s[a].r = s[b].r
	s[b].r = tmp

	tmp = s[a].id
	s[a].id = s[b].id
	s[b].id = tmp
}
func (s Segs) Less(a, b int) bool {
	if s[a].r < s[b].r {
		return true
	}
	return false
}

type PointFatory struct {
	p     []Point
	front int
	len   int
}

func (p *PointFatory) newPoint() *Point {
	if p.front >= p.len {
		p.p = append(p.p, make([]Point, p.len)...)
		p.len = len(p.p)
	}
	res := &p.p[p.front]
	p.front++
	return res
}
func newFatory(n int) *PointFatory {
	return &PointFatory{
		p:   make([]Point, n),
		len: n,
	}
}
func (p *Point) left() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cl == nil {
		p.cl = fatory.newPoint()
		p.cl.l = p.l
		p.cl.r = (p.l + p.r) / 2
		p.cl.min = MAX
	}
	return p.cl
}
func (p *Point) right() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cr == nil {
		p.cr = fatory.newPoint()
		p.cr.l = (p.l+p.r)/2 + 1
		p.cr.r = p.r
		p.cl.min = MAX
	}
	return p.cr
}
func (p *Point) refleshMin() {
	if p.left() == nil && p.right() == nil {
		return
	}
	if p.left() == nil {
		p.min = p.right().min
	} else if p.right() == nil {
		p.min = p.left().min
	} else if p.left().min < p.right().min {
		p.min = p.left().min
	} else {
		p.min = p.right().min
	}

}
func (p *Point) queryMin(l, r int) (int64, bool) {
	p.down()
	if l <= p.l && p.r <= r {
		return p.min, true
	}
	if l > p.r || r < p.l {
		return -1, false
	}
	var res int64 = 0
	find := false
	if p.left() != nil {
		leftmin, flag := p.left().queryMin(l, r)
		if flag {
			res = leftmin
			find = true
		}
	}
	if p.right() != nil {
		rightmin, flag := p.right().queryMin(l, r)
		if flag && (find == false || rightmin < res) {
			res = rightmin
		}
	}
	return res, true

}
func (p *Point) addValue(value int) {
	if p.min >= MAX {
		p.min = int64(value)
	} else {
		p.min += int64(value)
	}
}
func (p *Point) down() {
	if p.dirty <= 0 {
		return
	}
	pl := p.left()
	pr := p.right()
	if pl != nil {
		pl.dirty += p.dirty
		pl.addValue(p.dirty)
	}
	if pr != nil {
		pr.dirty += p.dirty
		pr.addValue(p.dirty)
	}
	p.dirty = 0
	p.refleshMin()
}
func (p *Point) add(l, r int, value int) {
	if l > p.r || r < p.l {
		return
	}
	if l <= p.l && p.r <= r {
		p.addValue(value)
		p.dirty += value
		return
	}
	pl := p.left()
	pr := p.right()
	p.down()
	if pl != nil {
		pl.add(l, r, value)
	}
	if pr != nil {
		pr.add(l, r, value)
	}
	p.refleshMin()
}
func solveE(mat []int, n int, segs Segs) (Segs, int64) {
	fatory = newFatory(n)

	maxx := make([]int, n)
	minn := mat[n-1]
	maxx[n-1] = mat[n-1]
	for i := n - 2; i >= 0; i-- {
		if mat[i] > maxx[i+1] {
			maxx[i] = mat[i]
		} else {
			maxx[i] = maxx[i+1]
		}
		if mat[i] < minn {
			minn = mat[i]
		}
	}
	partline := -1
	res := int64(maxx[0] - minn)
	root := fatory.newPoint()
	root.l = 1
	root.r = n
	//fmt.Printf("root.min = %d l=%d r=%d\n",root.min,root.l,root.r)
	for i := 0; i < n; i++ {
		root.add(i+1, i+1, mat[i])
		//	fmt.Printf("i=%d root.min = %d value=%d\n", i,root.min,mat[i])
	}
	//fmt.Printf("root.min = %d\n", root.min)

	sort.Sort(segs)
	dbMax := 0
	for i := 0; i < len(segs); i++ {
		if segs[i].r >= n {
			continue
		}
		root.add(segs[i].l, segs[i].r, -1)
		tmpm, _ := root.queryMin(1, segs[i].r)
		//	fmt.Printf("i=%d segs.l = %d segs.r = %d min=%d maxx=%d\n", i, segs[i].l, segs[i].r, tmpm, maxx[segs[i].r])
		if res < int64(maxx[segs[i].r])-tmpm {
			partline = i
			res = int64(maxx[segs[i].r]) - tmpm
			dbMax = maxx[segs[i].r]
		}
		if debug && (segs[i].id ==36||segs[i].id ==55||segs[i].id ==76){
			logger += "i=" + strconv.Itoa(i) + " maxx = " + strconv.Itoa(maxx[segs[i].r]) + " min=" + strconv.Itoa(int(tmpm)) + "\n"
		}
	}
	if debug && partline > -1 {
		logger += "partline=" + strconv.Itoa(segs[partline].r) + " maxx = " + strconv.Itoa(dbMax) + " min=" + strconv.Itoa(dbMax-int(res)) + "\n"
		//	fmt.Printf("partline=%d maxx = %d min=%d\n", segs[partline].r, dbMax,res-int64(dbMax))
	}
	as := make(Segs, partline+1)
	for i := 0; i <= partline; i++ {
		as[i] = segs[i]
	}
	//	fmt.Printf("as = %v res=%v\n",as,res)
	return as, res
}
func reverse(mat []int, segs Segs) {
	//	fmt.Printf("before mat=%v seg=%v\n",mat,segs)
	n := len(mat)
	m := len(segs)
	for i := 0; i < n-i-1; i++ {
		tmp := mat[i]
		mat[i] = mat[n-i-1]
		mat[n-i-1] = tmp
	}
	for i := 0; i < m; i++ {
		tmp := segs[i].l
		segs[i].l = segs[i].r
		segs[i].r = tmp
		segs[i].l = n - segs[i].l + 1
		segs[i].r = n - segs[i].r + 1
	}

}
func tmpseg(segs Segs) Segs {
	lens := len(goods)
	res := make(Segs, 0)
	for j := 0; j < len(segs); j++ {
		for i := 0; i < lens; i++ {
			if goods[i] == segs[j].id {
				res = append(res, segs[j])
				break
			}
		}
	}
	return res
}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	if n == 10000 && m == 100 {
		debug = true
	}
	//	debug=true
	mat := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d", &mat[i])
	}
	fmt.Fscanf(buf, "\n")
	seg := make(Segs, m)
	for i := 0; i < m; i++ {
		fmt.Fscanf(buf, "%d %d\n", &seg[i].l, &seg[i].r)
		seg[i].id = i + 1
	}
	pl, ans := solveE(mat, n, seg)
	reverse(mat, seg)
	//	fmt.Printf("rev mat=%v seg=%d\n",mat,seg)
	pl2, ans2 := solveE(mat, n, seg)

	if ans < ans2 {
		fmt.Printf("%d\n", ans2)
		fmt.Printf("%d\n", len(pl2))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl2[i].id)
		}
		fmt.Printf("\n")
		if len(pl) > 0 && debug {
			c, _ := check(mat, tmpseg(seg))
			c, wei := check(mat, pl2)
			fmt.Printf("w = %d\n", wei)
			if c != ans2 {
				fmt.Printf("ERROR c = %d ans=%d\n", c, ans2)
			}
			fmt.Printf("logger--\n%s\n", logger)
		}
	} else {
		fmt.Printf("%d\n", ans)
		fmt.Printf("%d\n", len(pl))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl[i].id)
		}
		fmt.Printf("\n")

		if len(pl) > 0 && debug {
			reverse(mat, seg)
			c, _ := check(mat, tmpseg(seg))
			c, wei := check(mat, pl)
			fmt.Printf("w = %d\n", wei)
			if c != ans {
				fmt.Printf("2ERROR c = %d ans=%d\n", c, ans)
			}
			fmt.Printf("logger--\n%s\n", logger)
		}
	}

}
func check(mat []int, pl Segs) (int64, int) {
	n := len(mat)
	m := len(pl)
	if m <= 0 {
		return 0, 0
	}
	maxx := -1
	minn := 10000000
	minw := -1
	for i := 0; i < n; i++ {
		in := 0
		for j := 0; j < m; j++ {
			if pl[j].l > i+1 || pl[j].r < i+1 {
				continue
			}
			in++
		}
		if in == 0 {
			if maxx == -1 || mat[maxx] < mat[i] {
				maxx = i
			}
		}
		if minn > mat[i]-in {
			minn = mat[i] - in
			minw = i
		}

	}
	if debug {
		maxxr := 0
		for i := 0; i < m; i++ {
			if pl[i].l <= 3119 && pl[i].r >= 3119{
				fmt.Printf("range %d %d %d\n", pl[i].l, pl[i].r,pl[i].id)
			}

			if pl[i].r > maxxr {
				maxxr = pl[i].r
			}
		}
		fmt.Printf("check maxw = %d  minw = %d maxx=%d min=%d mat[minn]=%d maxxr=%d\n", maxx+1, minw+1, mat[maxx], minn, mat[minw],maxxr)
	}
	return int64(mat[maxx] - minn), mat[maxx]
}

/**

5 3
1 2 2 -2 3
3 5
1 5
3 5
 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

var (
	fatory *PointFatory
	debug  = false
	logger = ""
	goods  = [70]int{80, 41, 72, 28, 77, 62, 6, 14, 78, 97, 93, 48, 4, 3, 25, 94, 83, 10, 53, 22, 54, 70, 29, 27, 87, 45, 43, 76, 31, 30, 42, 20, 12, 2, 40, 16, 100, 64, 86, 44, 49, 56, 33, 11, 46, 18, 75, 5, 69, 55, 37, 50, 92, 73, 21, 57, 13, 35, 26, 65, 81, 95, 36, 32, 15, 60, 68, 89, 98, 38}
)

const (
	MAX = 1000100 * 300
)

type Point struct {
	l, r   int
	dirty  int
	min    int64
	cl, cr *Point
}
type Seg struct {
	l, r int
	id   int
}
type Segs []Seg

func (s Segs) Len() int {
	return len(s)
}
func (s Segs) Swap(a, b int) {
	tmp := s[a].l
	s[a].l = s[b].l
	s[b].l = tmp

	tmp = s[a].r
	s[a].r = s[b].r
	s[b].r = tmp

	tmp = s[a].id
	s[a].id = s[b].id
	s[b].id = tmp
}
func (s Segs) Less(a, b int) bool {
	if s[a].r < s[b].r {
		return true
	}
	return false
}

type PointFatory struct {
	p     []Point
	front int
	len   int
}

func (p *PointFatory) newPoint() *Point {
	if p.front >= p.len {
		p.p = append(p.p, make([]Point, p.len)...)
		p.len = len(p.p)
	}
	res := &p.p[p.front]
	p.front++
	return res
}
func newFatory(n int) *PointFatory {
	return &PointFatory{
		p:   make([]Point, n),
		len: n,
	}
}
func (p *Point) left() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cl == nil {
		p.cl = fatory.newPoint()
		p.cl.l = p.l
		p.cl.r = (p.l + p.r) / 2
		p.cl.min = MAX
	}
	return p.cl
}
func (p *Point) right() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cr == nil {
		p.cr = fatory.newPoint()
		p.cr.l = (p.l+p.r)/2 + 1
		p.cr.r = p.r
		p.cl.min = MAX
	}
	return p.cr
}
func (p *Point) refleshMin() {
	if p.left() == nil && p.right() == nil {
		return
	}
	if p.left() == nil {
		p.min = p.right().min
	} else if p.right() == nil {
		p.min = p.left().min
	} else if p.left().min < p.right().min {
		p.min = p.left().min
	} else {
		p.min = p.right().min
	}

}
func (p *Point) queryMin(l, r int) (int64, bool) {
	p.down()
	if l <= p.l && p.r <= r {
		return p.min, true
	}
	if l > p.r || r < p.l {
		return -1, false
	}
	var res int64 = 0
	find := false
	if p.left() != nil {
		leftmin, flag := p.left().queryMin(l, r)
		if flag {
			res = leftmin
			find = true
		}
	}
	if p.right() != nil {
		rightmin, flag := p.right().queryMin(l, r)
		if flag && (find == false || rightmin < res) {
			res = rightmin
		}
	}
	return res, true

}
func (p *Point) addValue(value int) {
	if p.min >= MAX {
		p.min = int64(value)
	} else {
		p.min += int64(value)
	}
}
func (p *Point) down() {
	if p.dirty <= 0 {
		return
	}
	pl := p.left()
	pr := p.right()
	if pl != nil {
		pl.dirty += p.dirty
		pl.addValue(p.dirty)
	}
	if pr != nil {
		pr.dirty += p.dirty
		pr.addValue(p.dirty)
	}
	p.dirty = 0
	p.refleshMin()
}
func (p *Point) add(l, r int, value int) {
	if l > p.r || r < p.l {
		return
	}
	if l <= p.l && p.r <= r {
		p.addValue(value)
		p.dirty += value
		return
	}
	pl := p.left()
	pr := p.right()
	p.down()
	if pl != nil {
		pl.add(l, r, value)
	}
	if pr != nil {
		pr.add(l, r, value)
	}
	p.refleshMin()
}
func solveE(mat []int, n int, segs Segs) (Segs, int64) {
	fatory = newFatory(n)

	maxx := make([]int, n)
	minn := mat[n-1]
	maxx[n-1] = mat[n-1]
	for i := n - 2; i >= 0; i-- {
		if mat[i] > maxx[i+1] {
			maxx[i] = mat[i]
		} else {
			maxx[i] = maxx[i+1]
		}
		if mat[i] < minn {
			minn = mat[i]
		}
	}
	partline := -1
	res := int64(maxx[0] - minn)
	root := fatory.newPoint()
	root.l = 1
	root.r = n
	//fmt.Printf("root.min = %d l=%d r=%d\n",root.min,root.l,root.r)
	for i := 0; i < n; i++ {
		root.add(i+1, i+1, mat[i])
		//	fmt.Printf("i=%d root.min = %d value=%d\n", i,root.min,mat[i])
	}
	//fmt.Printf("root.min = %d\n", root.min)

	sort.Sort(segs)
	dbMax := 0
	for i := 0; i < len(segs); i++ {
		if segs[i].r >= n {
			continue
		}
		root.add(segs[i].l, segs[i].r, -1)
		tmpm, _ := root.queryMin(1, segs[i].r)
		//	fmt.Printf("i=%d segs.l = %d segs.r = %d min=%d maxx=%d\n", i, segs[i].l, segs[i].r, tmpm, maxx[segs[i].r])
		if res < int64(maxx[segs[i].r])-tmpm {
			partline = i
			res = int64(maxx[segs[i].r]) - tmpm
			dbMax = maxx[segs[i].r]
		}
	}
	if debug && partline > -1 {
		logger += "partline=" + strconv.Itoa(segs[partline].r) + " maxx = " + strconv.Itoa(dbMax) + " min=" + strconv.Itoa(dbMax-int(res)) + "\n"
		//	fmt.Printf("partline=%d maxx = %d min=%d\n", segs[partline].r, dbMax,res-int64(dbMax))
	}
	as := make(Segs, partline+1)
	for i := 0; i <= partline; i++ {
		as[i] = segs[i]
	}
	//	fmt.Printf("as = %v res=%v\n",as,res)
	return as, res
}
func reverse(mat []int, segs Segs) {
	//	fmt.Printf("before mat=%v seg=%v\n",mat,segs)
	n := len(mat)
	m := len(segs)
	for i := 0; i < n-i-1; i++ {
		tmp := mat[i]
		mat[i] = mat[n-i-1]
		mat[n-i-1] = tmp
	}
	for i := 0; i < m; i++ {
		tmp := segs[i].l
		segs[i].l = segs[i].r
		segs[i].r = tmp
		segs[i].l = n - segs[i].l + 1
		segs[i].r = n - segs[i].r + 1
	}

}
func tmpseg(segs Segs) Segs {
	lens := len(goods)
	res := make(Segs, 0)
	for j := 0; j < len(segs); j++ {
		for i := 0; i < lens; i++ {
			if goods[i] == segs[j].id {
				res = append(res, segs[j])
				break
			}
		}
	}
	return res
}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	if n == 10000 && m == 100 {
		debug = true
	}
	//	debug=true
	mat := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d", &mat[i])
	}
	fmt.Fscanf(buf, "\n")
	seg := make(Segs, m)
	for i := 0; i < m; i++ {
		fmt.Fscanf(buf, "%d %d\n", &seg[i].l, &seg[i].r)
		seg[i].id = i + 1
	}
	pl, ans := solveE(mat, n, seg)
	reverse(mat, seg)
	//	fmt.Printf("rev mat=%v seg=%d\n",mat,seg)
	pl2, ans2 := solveE(mat, n, seg)

	if ans < ans2 {
		fmt.Printf("%d\n", ans2)
		fmt.Printf("%d\n", len(pl2))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl2[i].id)
		}
		fmt.Printf("\n")
		if len(pl) > 0 && debug {
			c, _ := check(mat, tmpseg(seg))
			c, wei := check(mat, pl2)
			fmt.Printf("w = %d\n", wei)
			if c != ans2 {
				fmt.Printf("ERROR c = %d ans=%d\n", c, ans2)
			}
			fmt.Printf("logger--\n%s\n", logger)
		}
	} else {
		fmt.Printf("%d\n", ans)
		fmt.Printf("%d\n", len(pl))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl[i].id)
		}
		fmt.Printf("\n")

		if len(pl) > 0 && debug {
			reverse(mat, seg)
			c, _ := check(mat, tmpseg(seg))
			c, wei := check(mat, pl)
			fmt.Printf("w = %d\n", wei)
			if c != ans {
				fmt.Printf("2ERROR c = %d ans=%d\n", c, ans)
			}
			fmt.Printf("logger--\n%s\n", logger)
		}
	}

}
func check(mat []int, pl Segs) (int64, int) {
	n := len(mat)
	m := len(pl)
	if m <= 0 {
		return 0, 0
	}
	maxx := -1
	minn := 10000000
	minw := -1
	for i := 0; i < n; i++ {
		in := 0
		for j := 0; j < m; j++ {
			if pl[j].l > i+1 || pl[j].r < i+1 {
				continue
			}
			in++
		}
		if in == 0 {
			if maxx == -1 || mat[maxx] < mat[i] {
				maxx = i
			}
		}
		if minn > mat[i]-in {
			minn = mat[i] - in
			minw = i
		}

	}
	if debug {
		maxxr := 0
		for i := 0; i < m; i++ {
			if pl[i].l <= 3119 && pl[i].r >= 3119{
				fmt.Printf("range %d %d %d\n", pl[i].l, pl[i].r,pl[i].id)
			}

			if pl[i].r > maxxr {
				maxxr = pl[i].r
			}
		}
		fmt.Printf("check maxw = %d  minw = %d maxx=%d min=%d mat[minn]=%d maxxr=%d\n", maxx+1, minw+1, mat[maxx], minn, mat[minw],maxxr)
	}
	return int64(mat[maxx] - minn), mat[maxx]
}

/**

5 3
1 2 2 -2 3
3 5
1 5
3 5
 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

var (
	fatory *PointFatory
)

const (
	MAX = 1000100
)

type Point struct {
	l, r   int
	dirty  int
	min    int
	cl, cr *Point
}
type Seg struct {
	l, r int
	id   int
}
type Segs []Seg

func (s Segs) Len() int {
	return len(s)
}
func (s Segs) Swap(a, b int) {
	tmp := s[a].l
	s[a].l = s[b].l
	s[b].l = tmp

	tmp = s[a].r
	s[a].r = s[b].r
	s[b].r = tmp

	tmp = s[a].id
	s[a].id = s[b].id
	s[b].id = tmp
}
func (s Segs) Less(a, b int) bool {
	if s[a].r < s[b].r {
		return true
	}
	return false
}

type PointFatory struct {
	p     []Point
	front int
	len   int
}

func (p *PointFatory) newPoint() *Point {
	if p.front >= p.len {
		p.p = append(p.p, make([]Point, p.len)...)
		p.len = len(p.p)
	}
	res := &p.p[p.front]
	p.front++
	return res
}
func newFatory(n int) *PointFatory {
	return &PointFatory{
		p:   make([]Point, n),
		len: n,
	}
}
func (p *Point) left() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cl == nil {
		p.cl = fatory.newPoint()
		p.cl.l = p.l
		p.cl.r = (p.l + p.r) / 2
		p.cl.min = MAX
	}
	return p.cl
}
func (p *Point) right() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cr == nil {
		p.cr = fatory.newPoint()
		p.cr.l = (p.l+p.r)/2 + 1
		p.cr.r = p.r
		p.cl.min = MAX
	}
	return p.cr
}
func (p *Point) refleshMin() {
	if p.left() == nil && p.right() == nil {
		return
	}
	if p.left() == nil {
		p.min = p.right().min
	} else if p.right() == nil {
		p.min = p.left().min
	} else if p.left().min < p.right().min {
		p.min = p.left().min
	} else {
		p.min = p.right().min
	}

}
func (p *Point) queryMin(l, r int) (int, bool) {
	p.down()
	if l <= p.l && p.r <= r {
		return p.min, true
	}
	if l > p.r || r < p.l {
		return -1, false
	}
	res := 0
	find := false
	if p.left() != nil {
		leftmin, flag := p.left().queryMin(l, r)
		if flag {
			res = leftmin
			find = true
		}
	}
	if p.right() != nil {
		rightmin, flag := p.right().queryMin(l, r)
		if flag && (find == false || rightmin < res) {
			res = rightmin
		}
	}
	return res, true

}
func (p *Point) addValue(value int){
	if p.min >= MAX{
		p.min = value
	}else{
		p.min += value
	}
}
func (p *Point) down() {
	if p.dirty <= 0 {
		return
	}
	pl := p.left()
	pr := p.right()
	if pl != nil {
		pl.dirty += p.dirty
		pl.addValue(p.dirty)
	}
	if pr != nil {
		pr.dirty += p.dirty
		pr.min += p.dirty
		pr.addValue(p.dirty)
	}
	p.dirty = 0
	p.refleshMin()
}
func (p *Point) add(l, r int, value int) {
	if l > p.r || r < p.l {
		return
	}
	if l <= p.l && p.r <= r {
		p.addValue(value)
		p.dirty += value
		return
	}
	pl := p.left()
	pr := p.right()
	p.down()
	if pl != nil {
		pl.add(l, r, value)
	}
	if pr != nil {
		pr.add(l, r, value)
	}
	p.refleshMin()
}
func solveE(mat []int, n int, segs Segs) ([]int, int) {
	fatory = newFatory(n)

	maxx := make([]int, n)
	minn := mat[n-1]
	maxx[n-1] = mat[n-1]
	for i := n - 2; i >= 0; i-- {
		if mat[i] > maxx[i+1] {
			maxx[i] = mat[i]
		} else {
			maxx[i] = maxx[i+1]
		}
		if mat[i] < minn {
			minn = mat[i]
		}
	}
	partline := -1
	res := maxx[0] - minn
	root := fatory.newPoint()
	root.l = 1
	root.r = n
	//fmt.Printf("root.min = %d l=%d r=%d\n",root.min,root.l,root.r)
	for i := 0; i < n; i++ {
		root.add(i+1, i+1, mat[i])
	//	fmt.Printf("i=%d root.min = %d value=%d\n", i,root.min,mat[i])
	}
	//fmt.Printf("root.min = %d\n", root.min)

	sort.Sort(segs)
	for i := 0; i < len(segs); i++ {
		if segs[i].r >= n {
			continue
		}
		root.add(segs[i].l, segs[i].r, -1)
		tmpm, _ := root.queryMin(1, segs[i].r)
	//	fmt.Printf("i=%d segs.l = %d segs.r = %d min=%d maxx=%d\n", i, segs[i].l, segs[i].r, tmpm, maxx[segs[i].r])
		if res < maxx[segs[i].r]-tmpm {
			partline = i
			res = maxx[segs[i].r] - tmpm
		}
	}
	as := make([]int, partline+1)
	for i := 0; i <= partline; i++ {
		as[i] = segs[i].id
	}
//	fmt.Printf("as = %v res=%v\n",as,res)
	return as, res
}
func reverse(mat []int, segs Segs) {
	n := len(mat)
	m := len(segs)
	for i := 0; i < n-i-1; i++ {
		tmp := mat[i]
		mat[i] = mat[n-i-1]
		mat[n-i-1] = tmp
	}
	for i := 0; i < m; i++ {
		tmp := segs[i].l
		segs[i].l = segs[i].r
		segs[i].r = tmp
		segs[i].l = n - segs[i].l + 1
		segs[i].r = n - segs[i].r + 1
	}

}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	mat := make([]int, n+1)
	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d", &mat[i])
	}
	fmt.Fscanf(buf, "\n")
	seg := make(Segs, m)
	for i := 0; i < m; i++ {
		fmt.Fscanf(buf, "%d %d\n", &seg[i].l, &seg[i].r)
		seg[i].id = i+1
	}
	pl, ans := solveE(mat, n, seg)
	reverse(mat, seg)
	pl2, ans2 := solveE(mat, n, seg)
	if ans < ans2 {
		pl = pl2
		ans = ans2
	}
	fmt.Printf("%d\n", ans)
	fmt.Printf("%d\n", len(pl))
	for i := 0; i < len(pl); i++ {
		fmt.Printf("%d ", pl[i])
	}
	fmt.Printf("\n")

}
/**

5 3
1 2 2 -2 3
3 5
1 5
3 5
 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

var (
	fatory *PointFatory
)

const (
	MAX = 1000100 * 300
)

type Point struct {
	l, r   int
	dirty  int
	min    int64
	cl, cr *Point
}
type Seg struct {
	l, r int
	id   int
}
type Segs []Seg

func (s Segs) Len() int {
	return len(s)
}
func (s Segs) Swap(a, b int) {
	tmp := s[a].l
	s[a].l = s[b].l
	s[b].l = tmp

	tmp = s[a].r
	s[a].r = s[b].r
	s[b].r = tmp

	tmp = s[a].id
	s[a].id = s[b].id
	s[b].id = tmp
}
func (s Segs) Less(a, b int) bool {
	if s[a].r < s[b].r {
		return true
	}
	return false
}

type PointFatory struct {
	p     []Point
	front int
	len   int
}

func (p *PointFatory) newPoint() *Point {
	if p.front >= p.len {
		p.p = append(p.p, make([]Point, p.len)...)
		p.len = len(p.p)
	}
	res := &p.p[p.front]
	p.front++
	return res
}
func newFatory(n int) *PointFatory {
	return &PointFatory{
		p:   make([]Point, n),
		len: n,
	}
}
func (p *Point) left() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cl == nil {
		p.cl = fatory.newPoint()
		p.cl.l = p.l
		p.cl.r = (p.l + p.r) / 2
		p.cl.min = MAX
	}
	return p.cl
}
func (p *Point) right() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cr == nil {
		p.cr = fatory.newPoint()
		p.cr.l = (p.l+p.r)/2 + 1
		p.cr.r = p.r
		p.cl.min = MAX
	}
	return p.cr
}
func (p *Point) refleshMin() {
	if p.left() == nil && p.right() == nil {
		return
	}
	if p.left() == nil {
		p.min = p.right().min
	} else if p.right() == nil {
		p.min = p.left().min
	} else if p.left().min < p.right().min {
		p.min = p.left().min
	} else {
		p.min = p.right().min
	}

}
func (p *Point) queryMin(l, r int) (int64, bool) {
	p.down()
	if l <= p.l && p.r <= r {
		return p.min, true
	}
	if l > p.r || r < p.l {
		return -1, false
	}
	var res int64 = 0
	find := false
	if p.left() != nil {
		leftmin, flag := p.left().queryMin(l, r)
		if flag {
			res = leftmin
			find = true
		}
	}
	if p.right() != nil {
		rightmin, flag := p.right().queryMin(l, r)
		if flag && (find == false || rightmin < res) {
			res = rightmin
		}
	}
	return res, true

}
func (p *Point) addValue(value int) {
	if p.min >= MAX {
		p.min = int64(value)
	} else {
		p.min += int64(value)
	}
}
func (p *Point) down() {
	if p.dirty <= 0 {
		return
	}
	pl := p.left()
	pr := p.right()
	if pl != nil {
		pl.dirty += p.dirty
		pl.addValue(p.dirty)
	}
	if pr != nil {
		pr.dirty += p.dirty
		pr.addValue(p.dirty)
	}
	p.dirty = 0
	p.refleshMin()
}
func (p *Point) add(l, r int, value int) {
	if l > p.r || r < p.l {
		return
	}
	if l <= p.l && p.r <= r {
		p.addValue(value)
		p.dirty += value
		return
	}
	pl := p.left()
	pr := p.right()
	p.down()
	if pl != nil {
		pl.add(l, r, value)
	}
	if pr != nil {
		pr.add(l, r, value)
	}
	p.refleshMin()
}
func solveE(mat []int, n int, segs Segs) (Segs, int64) {
	fatory = newFatory(n)

	maxx := make([]int, n)
	minn := mat[n-1]
	maxx[n-1] = mat[n-1]
	for i := n - 2; i >= 0; i-- {
		if mat[i] > maxx[i+1] {
			maxx[i] = mat[i]
		} else {
			maxx[i] = maxx[i+1]
		}
		if mat[i] < minn {
			minn = mat[i]
		}
	}
	partline := -1
	res := int64(maxx[0] - minn)
	root := fatory.newPoint()
	root.l = 1
	root.r = n
	//fmt.Printf("root.min = %d l=%d r=%d\n",root.min,root.l,root.r)
	for i := 0; i < n; i++ {
		root.add(i+1, i+1, mat[i])
		//	fmt.Printf("i=%d root.min = %d value=%d\n", i,root.min,mat[i])
	}
	//fmt.Printf("root.min = %d\n", root.min)

	sort.Sort(segs)
	for i := 0; i < len(segs); i++ {
		if segs[i].r >= n {
			continue
		}
		root.add(segs[i].l, segs[i].r, -1)
		tmpm, _ := root.queryMin(1, segs[i].r)
		//	fmt.Printf("i=%d segs.l = %d segs.r = %d min=%d maxx=%d\n", i, segs[i].l, segs[i].r, tmpm, maxx[segs[i].r])
		if res < int64(maxx[segs[i].r])-tmpm {
			partline = i
			res = int64(maxx[segs[i].r]) - tmpm
		}
	}
	as := make(Segs, partline+1)
	for i := 0; i <= partline; i++ {
		as[i] = segs[i]
	}
	//	fmt.Printf("as = %v res=%v\n",as,res)
	return as, res
}
func reverse(mat []int, segs Segs) {
	//	fmt.Printf("before mat=%v seg=%v\n",mat,segs)
	n := len(mat)
	m := len(segs)
	for i := 0; i < n-i-1; i++ {
		tmp := mat[i]
		mat[i] = mat[n-i-1]
		mat[n-i-1] = tmp
	}
	for i := 0; i < m; i++ {
		tmp := segs[i].l
		segs[i].l = segs[i].r
		segs[i].r = tmp
		segs[i].l = n - segs[i].l + 1
		segs[i].r = n - segs[i].r + 1
	}

}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	mat := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d", &mat[i])
	}
	fmt.Fscanf(buf, "\n")
	seg := make(Segs, m)
	for i := 0; i < m; i++ {
		fmt.Fscanf(buf, "%d %d\n", &seg[i].l, &seg[i].r)
		seg[i].id = i + 1
	}
	pl, ans := solveE(mat, n, seg)
	reverse(mat, seg)
	//	fmt.Printf("rev mat=%v seg=%d\n",mat,seg)
	pl2, ans2 := solveE(mat, n, seg)
	if ans < ans2 {
		fmt.Printf("%d\n", ans2)
		fmt.Printf("%d\n", len(pl2))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl2[i].id)
		}
		fmt.Printf("\n")
		if len(pl) > 0 && n == 10000 && m == 100 {
			c,wei := check(mat, pl2)
			fmt.Printf("w = %d\n",wei)
			for i:= 0;i < len(pl);i++{
				fmt.Printf("rang %d %d\n",seg[i].l,seg[i].r)
			}
			if c != ans2 {
				fmt.Printf("ERROR c = %d ans=%d\n", c, ans2)
			}
		}
	} else {
		fmt.Printf("%d\n", ans)
		fmt.Printf("%d\n", len(pl))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl[i].id)
		}
		fmt.Printf("\n")
		reverse(mat, seg)
		if len(pl) > 0 && n == 10000 && m == 100 {

			c,wei := check(mat, pl)
			fmt.Printf("w = %d\n",wei)
			for i:= 0;i < len(pl);i++{
				fmt.Printf("rang %d %d\n",seg[i].l,seg[i].r)
			}
			if c != ans {
				fmt.Printf("2ERROR c = %d ans=%d\n", c, ans)
			}
		}
	}

}
func check(mat []int, pl Segs) (int64,int) {
	n := len(mat)
	m := len(pl)
	maxx := -1
	minn := 10000000
	for i := 0; i < n; i++ {
		in := 0
		for j := 0; j < m; j++ {
			if pl[j].l > i+1 || pl[j].r < i+1 {
				continue
			}
			in++
		}
		if in == 0 {
			if maxx == -1||mat[maxx] < mat[i] {
				maxx = i
			}
		} else {
			if minn > mat[i]-in {
				minn = mat[i] - in
			}
		}
	}
	//	fmt.Printf("v pl=%v mat=%v\n",pl,mat)
	return int64(maxx - minn),maxx
}

/**

5 3
1 2 2 -2 3
3 5
1 5
3 5
 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

var (
	fatory *PointFatory
	debug  = false
	logger = ""
	goods  = [70]int{80, 41, 72, 28, 77, 62, 6, 14, 78, 97, 93, 48, 4, 3, 25, 94, 83, 10, 53, 22, 54, 70, 29, 27, 87, 45, 43, 76, 31, 30, 42, 20, 12, 2, 40, 16, 100, 64, 86, 44, 49, 56, 33, 11, 46, 18, 75, 5, 69, 55, 37, 50, 92, 73, 21, 57, 13, 35, 26, 65, 81, 95, 36, 32, 15, 60, 68, 89, 98, 38}
)

const (
	MAX int64 = int64(3000100)
)

type Point struct {
	l, r   int
	dirty  int
	min    int64
	cl, cr *Point
}
type Seg struct {
	l, r int
	id   int
}
type Segs []Seg

func (s Segs) Len() int {
	return len(s)
}
func (s Segs) Swap(a, b int) {
	tmp := s[a].l
	s[a].l = s[b].l
	s[b].l = tmp

	tmp = s[a].r
	s[a].r = s[b].r
	s[b].r = tmp

	tmp = s[a].id
	s[a].id = s[b].id
	s[b].id = tmp
}
func (s Segs) Less(a, b int) bool {
	if s[a].r < s[b].r {
		return true
	}
	return false
}

type PointFatory struct {
	p     []Point
	front int
	len   int
}

func (p *PointFatory) newPoint() *Point {
	return &Point{}
	//if p.front >= p.len {
	//	p.p = append(p.p, make([]Point, p.len)...)
	//	p.len = len(p.p)
	//}
	//res := &p.p[p.front]
	//p.front++
	//return res
}
func newFatory(n int) *PointFatory {
	return &PointFatory{
		p:   make([]Point, n),
		len: n,
	}
}
func (p *Point) left() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cl == nil {
		p.cl = fatory.newPoint()
		p.cl.l = p.l
		p.cl.r = (p.l + p.r) / 2
		p.cl.min = MAX
	}
	return p.cl
}
func (p *Point) right() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cr == nil {
		p.cr = fatory.newPoint()
		p.cr.l = (p.l+p.r)/2 + 1
		p.cr.r = p.r
		p.cr.min = MAX
	}
	return p.cr
}
func (p *Point) refleshMin() {
	if p.left() == nil && p.right() == nil {
		return
	}
	if p.left() == nil {
		p.min = p.right().min
	} else if p.right() == nil {
		p.min = p.left().min
	} else if p.left().min < p.right().min {
		p.min = p.left().min
	} else {
		p.min = p.right().min
	}
	if p.min == 0 &&debug{
		fmt.Printf("min=0 l=%d r=%d dirty=%d\n",p.l,p.r,p.dirty)
	}

}
func (p *Point) queryMin(l, r int) (int64, bool) {
	p.down()
	if l <= p.l && p.r <= r {
		return p.min, true
	}
	if l > p.r || r < p.l {
		return -1, false
	}
	var res int64 = 0
	find := false
	if p.left() != nil {
		leftmin, flag := p.left().queryMin(l, r)
		if flag {
			res = leftmin
			find = true
		}
	}
	if p.right() != nil {
		rightmin, flag := p.right().queryMin(l, r)
		if flag && (find == false || rightmin < res) {
			res = rightmin
		}
	}
	return res, true

}
func (p *Point) addValue(value int) {
	if p.min >= MAX {
		p.min = int64(value)
	} else {
		p.min += int64(value)
	}
	if p.min == 0 &&debug{
		fmt.Printf("min=0 l=%d r=%d dirty=%d value=%d\n",p.l,p.r,p.dirty,value)
	}
}
func (p *Point) down() {
	if p.dirty == 0 {
		return
	}
	pl := p.left()
	pr := p.right()
	if pl != nil {
		pl.dirty += p.dirty
		pl.addValue(p.dirty)
	}
	if pr != nil {
		pr.dirty += p.dirty
		pr.addValue(p.dirty)
	}
	p.dirty = 0
	//p.refleshMin()
}
func (p *Point) add(l, r int, value int) {
	if l > p.r || r < p.l {
		return
	}
	if l <= p.l && p.r <= r {
		p.addValue(value)
		p.dirty += value
		return
	}
	pl := p.left()
	pr := p.right()
	p.down()
	if pl != nil {
		pl.add(l, r, value)
	}
	if pr != nil {
		pr.add(l, r, value)
	}
	tmin := p.min
	p.refleshMin()
	if debug && p.min > tmin {
		fmt.Printf(" tmin=%d nowmin=%d pl=%d pr=%d l=%d r=%d value=%d\n", tmin, p.min,p.l,p.r,l,r,value)
	}
}
func solveE(mat []int, n int, segs Segs) (Segs, int64) {
	fatory = newFatory(n)

	maxx := make([]int, n)
	minn := mat[n-1]
	maxx[n-1] = mat[n-1]
	for i := n - 2; i >= 0; i-- {
		if mat[i] > maxx[i+1] {
			maxx[i] = mat[i]
		} else {
			maxx[i] = maxx[i+1]
		}
		if mat[i] < minn {
			minn = mat[i]
		}
	}
	partline := -1
	res := int64(maxx[0] - minn)
	root := fatory.newPoint()
	root.l = 1
	root.r = n
	root.min = MAX
	//fmt.Printf("root.min = %d l=%d r=%d\n",root.min,root.l,root.r)
	for i := 0; i < n; i++ {
		root.add(i+1, i+1, mat[i])
		//	fmt.Printf("i=%d root.min = %d value=%d\n", i,root.min,mat[i])
	}
	//fmt.Printf("root.min = %d\n", root.min)

	sort.Sort(segs)
	dbMax := 0
	for i := 0; i < len(segs); i++ {
		if segs[i].r >= n {
			continue
		}
		root.add(segs[i].l, segs[i].r, -1)
		tmpm, _ := root.queryMin(1, segs[i].r)
		//	fmt.Printf("i=%d segs.l = %d segs.r = %d min=%d maxx=%d\n", i, segs[i].l, segs[i].r, tmpm, maxx[segs[i].r])
		if res < int64(maxx[segs[i].r])-tmpm {
			partline = i
			res = int64(maxx[segs[i].r]) - tmpm
			dbMax = maxx[segs[i].r]
		}
		if debug && (segs[i].id == 36 || segs[i].id == 55 || segs[i].id == 76 || segs[i].id == 11 || segs[i].id == 37 || segs[i].id == 95 || segs[i].id == 6 || segs[i].id == 41) {
			logger += fmt.Sprintf("i=%d maxx=%d min=%d l=%d r=%d root.min=%d\n", segs[i].id, maxx[segs[i].r], tmpm, segs[i].l, segs[i].r, root.min)
			//logger += "i=" + strconv.Itoa(segs[i].id) + " maxx = " + strconv.Itoa(maxx[segs[i].r]) + " min=" + strconv.Itoa(int(tmpm)) + "\n"
		}
	}
	if debug && partline > -1 {
		logger += "partline=" + strconv.Itoa(segs[partline].r) + " maxx = " + strconv.Itoa(dbMax) + " min=" + strconv.Itoa(dbMax-int(res)) + "\n"
		//	fmt.Printf("partline=%d maxx = %d min=%d\n", segs[partline].r, dbMax,res-int64(dbMax))
	}
	as := make(Segs, partline+1)
	for i := 0; i <= partline; i++ {
		as[i] = Seg{
			l:  segs[i].l,
			r:  segs[i].r,
			id: segs[i].id,
		}
	}
	//	fmt.Printf("as = %v res=%v\n",as,res)
	return as, res
}
func reverse(mat []int, segs Segs) {
	//	fmt.Printf("before mat=%v seg=%v\n",mat,segs)
	n := len(mat)
	m := len(segs)
	for i := 0; i < n-i-1; i++ {
		tmp := mat[i]
		mat[i] = mat[n-i-1]
		mat[n-i-1] = tmp
	}
	for i := 0; i < m; i++ {
		tmp := segs[i].l
		segs[i].l = segs[i].r
		segs[i].r = tmp
		segs[i].l = n - segs[i].l + 1
		segs[i].r = n - segs[i].r + 1
	}

}
func tmpseg(segs Segs) Segs {
	lens := len(goods)
	res := make(Segs, 0)
	for j := 0; j < len(segs); j++ {
		for i := 0; i < lens; i++ {
			if goods[i] == segs[j].id {
				res = append(res, segs[j])
				break
			}
		}
	}
	return res
}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	if n == 10000 && m == 100 {
		debug = true
	}
	if debug{
		fmt.Printf("maxx=%d\n",MAX)
	}
	//	debug=true
	mat := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d", &mat[i])
	}
	fmt.Fscanf(buf, "\n")
	seg := make(Segs, m)
	for i := 0; i < m; i++ {
		fmt.Fscanf(buf, "%d %d\n", &seg[i].l, &seg[i].r)
		seg[i].id = i + 1
	}
	pl, ans := solveE(mat, n, seg)
	reverse(mat, seg)
	//	fmt.Printf("rev mat=%v seg=%d\n",mat,seg)
	pl2, ans2 := solveE(mat, n, seg)

	if ans < ans2 {
		fmt.Printf("%d\n", ans2)
		fmt.Printf("%d\n", len(pl2))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl2[i].id)
		}
		fmt.Printf("\n")
		if len(pl) > 0 && debug {
			c, _ := check(mat, tmpseg(seg))
			c, _ = check(mat, pl2)
			if c != ans2 {
				fmt.Printf("ERROR c = %d ans=%d\n", c, ans2)
			}
			fmt.Printf("logger--\n%s\n", logger)
		}
	} else {
		fmt.Printf("%d\n", ans)
		fmt.Printf("%d\n", len(pl))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl[i].id)
		}
		fmt.Printf("\n")

		if len(pl) > 0 && debug {
			reverse(mat, seg)
			c, _ := check(mat, tmpseg(seg))
			c, _ = check(mat, pl)

			if c != ans {
				fmt.Printf("2ERROR c = %d ans=%d\n", c, ans)
			}
			fmt.Printf("%s\n", logger)
		}
	}

}
func check(mat []int, pl Segs) (int64, int) {
	n := len(mat)
	m := len(pl)
	if m <= 0 {
		return 0, 0
	}
	maxx := -1
	minn := 10000000
	//minw := -1
	for i := 0; i < n; i++ {
		in := 0
		for j := 0; j < m; j++ {
			if pl[j].l > i+1 || pl[j].r < i+1 {
				continue
			}
			in++
		}
		if in == 0 {
			if maxx == -1 || mat[maxx] < mat[i] {
				maxx = i
			}
		}
		if minn > mat[i]-in {
			minn = mat[i] - in
			//minw = i
		}

	}
	if debug {
		maxxr := 0
		for i := 0; i < m; i++ {
			if pl[i].l <= 3119 && pl[i].r >= 3119 {
				//	fmt.Printf("range %d %d %d\n", pl[i].l, pl[i].r,pl[i].id)
			}

			if pl[i].r > maxxr {
				maxxr = pl[i].r
			}
		}
		//		fmt.Printf("check maxw = %d  minw = %d maxx=%d min=%d mat[minn]=%d maxxr=%d\n", maxx+1, minw+1, mat[maxx], minn, mat[minw],maxxr)
	}
	return int64(mat[maxx] - minn), mat[maxx]
}

/**

5 3
1 2 2 -2 3
3 5
1 5
3 5
 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

var (
	fatory *PointFatory
	debug  = false
	logger = ""
	goods  = [70]int{80, 41, 72, 28, 77, 62, 6, 14, 78, 97, 93, 48, 4, 3, 25, 94, 83, 10, 53, 22, 54, 70, 29, 27, 87, 45, 43, 76, 31, 30, 42, 20, 12, 2, 40, 16, 100, 64, 86, 44, 49, 56, 33, 11, 46, 18, 75, 5, 69, 55, 37, 50, 92, 73, 21, 57, 13, 35, 26, 65, 81, 95, 36, 32, 15, 60, 68, 89, 98, 38}
)

const (
	MAX = 1000100 * 300
)

type Point struct {
	l, r   int
	dirty  int
	min    int64
	cl, cr *Point
}
type Seg struct {
	l, r int
	id   int
}
type Segs []Seg

func (s Segs) Len() int {
	return len(s)
}
func (s Segs) Swap(a, b int) {
	tmp := s[a].l
	s[a].l = s[b].l
	s[b].l = tmp

	tmp = s[a].r
	s[a].r = s[b].r
	s[b].r = tmp

	tmp = s[a].id
	s[a].id = s[b].id
	s[b].id = tmp
}
func (s Segs) Less(a, b int) bool {
	if s[a].r < s[b].r {
		return true
	}
	return false
}

type PointFatory struct {
	p     []Point
	front int
	len   int
}

func (p *PointFatory) newPoint() *Point {
	return &Point{}
	//if p.front >= p.len {
	//	p.p = append(p.p, make([]Point, p.len)...)
	//	p.len = len(p.p)
	//}
	//res := &p.p[p.front]
	//p.front++
	//return res
}
func newFatory(n int) *PointFatory {
	return &PointFatory{
		p:   make([]Point, n),
		len: n,
	}
}
func (p *Point) left() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cl == nil {
		p.cl = fatory.newPoint()
		p.cl.l = p.l
		p.cl.r = (p.l + p.r) / 2
		p.cl.min = MAX
	}
	return p.cl
}
func (p *Point) right() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cr == nil {
		p.cr = fatory.newPoint()
		p.cr.l = (p.l+p.r)/2 + 1
		p.cr.r = p.r
		p.cl.min = MAX
	}
	return p.cr
}
func (p *Point) refleshMin() {
	if p.left() == nil && p.right() == nil {
		return
	}
	if p.left() == nil {
		p.min = p.right().min
	} else if p.right() == nil {
		p.min = p.left().min
	} else if p.left().min < p.right().min {
		p.min = p.left().min
	} else {
		p.min = p.right().min
	}

}
func (p *Point) queryMin(l, r int) (int64, bool) {
	p.down()
	if l <= p.l && p.r <= r {
		return p.min, true
	}
	if l > p.r || r < p.l {
		return -1, false
	}
	var res int64 = 0
	find := false
	if p.left() != nil {
		leftmin, flag := p.left().queryMin(l, r)
		if flag {
			res = leftmin
			find = true
		}
	}
	if p.right() != nil {
		rightmin, flag := p.right().queryMin(l, r)
		if flag && (find == false || rightmin < res) {
			res = rightmin
		}
	}
	return res, true

}
func (p *Point) addValue(value int) {
	if p.min >= MAX {
		p.min = int64(value)
	} else {
		p.min += int64(value)
	}
}
func (p *Point) down() {
	if p.dirty <= 0 {
		return
	}
	pl := p.left()
	pr := p.right()
	if pl != nil {
		pl.dirty += p.dirty
		pl.addValue(p.dirty)
	}
	if pr != nil {
		pr.dirty += p.dirty
		pr.addValue(p.dirty)
	}
	p.dirty = 0
	p.refleshMin()
}
func (p *Point) add(l, r int, value int) {
	if l > p.r || r < p.l {
		return
	}
	if l <= p.l && p.r <= r {
		p.addValue(value)
		p.dirty += value
		return
	}
	pl := p.left()
	pr := p.right()
	p.down()
	if pl != nil {
		pl.add(l, r, value)
	}
	if pr != nil {
		pr.add(l, r, value)
	}
	p.refleshMin()
}
func solveE(mat []int, n int, segs Segs) (Segs, int64) {
	fatory = newFatory(n)

	maxx := make([]int, n)
	minn := mat[n-1]
	maxx[n-1] = mat[n-1]
	for i := n - 2; i >= 0; i-- {
		if mat[i] > maxx[i+1] {
			maxx[i] = mat[i]
		} else {
			maxx[i] = maxx[i+1]
		}
		if mat[i] < minn {
			minn = mat[i]
		}
	}
	partline := -1
	res := int64(maxx[0] - minn)
	root := fatory.newPoint()
	root.l = 1
	root.r = n
	//fmt.Printf("root.min = %d l=%d r=%d\n",root.min,root.l,root.r)
	for i := 0; i < n; i++ {
		root.add(i+1, i+1, mat[i])
		//	fmt.Printf("i=%d root.min = %d value=%d\n", i,root.min,mat[i])
	}
	//fmt.Printf("root.min = %d\n", root.min)

	sort.Sort(segs)
	dbMax := 0
	for i := 0; i < len(segs); i++ {
		if segs[i].r >= n {
			continue
		}
		root.add(segs[i].l, segs[i].r, -1)
		tmpm, _ := root.queryMin(1, segs[i].r)
		//	fmt.Printf("i=%d segs.l = %d segs.r = %d min=%d maxx=%d\n", i, segs[i].l, segs[i].r, tmpm, maxx[segs[i].r])
		if res < int64(maxx[segs[i].r])-tmpm {
			partline = i
			res = int64(maxx[segs[i].r]) - tmpm
			dbMax = maxx[segs[i].r]
		}
		if debug && (segs[i].id ==36||segs[i].id ==55||segs[i].id ==76||segs[i].id ==11||segs[i].id ==37||segs[i].id ==95||segs[i].id ==6||segs[i].id ==41){
			logger+=fmt.Sprintf("i=%d maxx=%d min=%d l=%d r=%d root.min=%d\n",segs[i].id,maxx[segs[i].r],tmpm,segs[i].l,segs[i].r,root.min)
			//logger += "i=" + strconv.Itoa(segs[i].id) + " maxx = " + strconv.Itoa(maxx[segs[i].r]) + " min=" + strconv.Itoa(int(tmpm)) + "\n"
		}
	}
	if debug && partline > -1 {
		logger += "partline=" + strconv.Itoa(segs[partline].r) + " maxx = " + strconv.Itoa(dbMax) + " min=" + strconv.Itoa(dbMax-int(res)) + "\n"
		//	fmt.Printf("partline=%d maxx = %d min=%d\n", segs[partline].r, dbMax,res-int64(dbMax))
	}
	as := make(Segs, partline+1)
	for i := 0; i <= partline; i++ {
		as[i] = Seg{
			l:segs[i].l,
			r:segs[i].r,
			id:segs[i].id,
		}
	}
	//	fmt.Printf("as = %v res=%v\n",as,res)
	return as, res
}
func reverse(mat []int, segs Segs) {
	//	fmt.Printf("before mat=%v seg=%v\n",mat,segs)
	n := len(mat)
	m := len(segs)
	for i := 0; i < n-i-1; i++ {
		tmp := mat[i]
		mat[i] = mat[n-i-1]
		mat[n-i-1] = tmp
	}
	for i := 0; i < m; i++ {
		tmp := segs[i].l
		segs[i].l = segs[i].r
		segs[i].r = tmp
		segs[i].l = n - segs[i].l + 1
		segs[i].r = n - segs[i].r + 1
	}

}
func tmpseg(segs Segs) Segs {
	lens := len(goods)
	res := make(Segs, 0)
	for j := 0; j < len(segs); j++ {
		for i := 0; i < lens; i++ {
			if goods[i] == segs[j].id {
				res = append(res, segs[j])
				break
			}
		}
	}
	return res
}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	if n == 10000 && m == 100 {
		debug = true
	}
	//	debug=true
	mat := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d", &mat[i])
	}
	fmt.Fscanf(buf, "\n")
	seg := make(Segs, m)
	for i := 0; i < m; i++ {
		fmt.Fscanf(buf, "%d %d\n", &seg[i].l, &seg[i].r)
		seg[i].id = i + 1
	}
	pl, ans := solveE(mat, n, seg)
	reverse(mat, seg)
	//	fmt.Printf("rev mat=%v seg=%d\n",mat,seg)
	pl2, ans2 := solveE(mat, n, seg)

	if ans < ans2 {
		fmt.Printf("%d\n", ans2)
		fmt.Printf("%d\n", len(pl2))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl2[i].id)
		}
		fmt.Printf("\n")
		if len(pl) > 0 && debug {
			c, _ := check(mat, tmpseg(seg))
			c,_ = check(mat, pl2)
			if c != ans2 {
				fmt.Printf("ERROR c = %d ans=%d\n", c, ans2)
			}
			fmt.Printf("logger--\n%s\n", logger)
		}
	} else {
		fmt.Printf("%d\n", ans)
		fmt.Printf("%d\n", len(pl))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl[i].id)
		}
		fmt.Printf("\n")

		if len(pl) > 0 && debug {
			reverse(mat, seg)
			c, _ := check(mat, tmpseg(seg))
			c, _ = check(mat, pl)

			if c != ans {
				fmt.Printf("2ERROR c = %d ans=%d\n", c, ans)
			}
			fmt.Printf("%s\n", logger)
		}
	}

}
func check(mat []int, pl Segs) (int64, int) {
	n := len(mat)
	m := len(pl)
	if m <= 0 {
		return 0, 0
	}
	maxx := -1
	minn := 10000000
	minw := -1
	for i := 0; i < n; i++ {
		in := 0
		for j := 0; j < m; j++ {
			if pl[j].l > i+1 || pl[j].r < i+1 {
				continue
			}
			in++
		}
		if in == 0 {
			if maxx == -1 || mat[maxx] < mat[i] {
				maxx = i
			}
		}
		if minn > mat[i]-in {
			minn = mat[i] - in
			minw = i
		}

	}
	if debug {
		maxxr := 0
		for i := 0; i < m; i++ {
			if pl[i].l <= 3119 && pl[i].r >= 3119{
			//	fmt.Printf("range %d %d %d\n", pl[i].l, pl[i].r,pl[i].id)
			}

			if pl[i].r > maxxr {
				maxxr = pl[i].r
			}
		}
		fmt.Printf("check maxw = %d  minw = %d maxx=%d min=%d mat[minn]=%d maxxr=%d\n", maxx+1, minw+1, mat[maxx], minn, mat[minw],maxxr)
	}
	return int64(mat[maxx] - minn), mat[maxx]
}

/**

5 3
1 2 2 -2 3
3 5
1 5
3 5
 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

var (
	fatory *PointFatory
	debug  = false
	logger = ""
	goods  = [70]int{80, 41, 72, 28, 77, 62, 6, 14, 78, 97, 93, 48, 4, 3, 25, 94, 83, 10, 53, 22, 54, 70, 29, 27, 87, 45, 43, 76, 31, 30, 42, 20, 12, 2, 40, 16, 100, 64, 86, 44, 49, 56, 33, 11, 46, 18, 75, 5, 69, 55, 37, 50, 92, 73, 21, 57, 13, 35, 26, 65, 81, 95, 36, 32, 15, 60, 68, 89, 98, 38}
)

const (
	MAX int64 = int64(3000100)
)

type Point struct {
	l, r   int
	dirty  int
	min    int64
	cl, cr *Point
}
type Seg struct {
	l, r int
	id   int
}
type Segs []Seg

func (s Segs) Len() int {
	return len(s)
}
func (s Segs) Swap(a, b int) {
	tmp := s[a].l
	s[a].l = s[b].l
	s[b].l = tmp

	tmp = s[a].r
	s[a].r = s[b].r
	s[b].r = tmp

	tmp = s[a].id
	s[a].id = s[b].id
	s[b].id = tmp
}
func (s Segs) Less(a, b int) bool {
	if s[a].r < s[b].r {
		return true
	}
	return false
}

type PointFatory struct {
	p     []Point
	front int
	len   int
}

func (p *PointFatory) newPoint() *Point {
	return &Point{}
	//if p.front >= p.len {
	//	p.p = append(p.p, make([]Point, p.len)...)
	//	p.len = len(p.p)
	//}
	//res := &p.p[p.front]
	//p.front++
	//return res
}
func newFatory(n int) *PointFatory {
	return &PointFatory{
		p:   make([]Point, n),
		len: n,
	}
}
func (p *Point) left() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cl == nil {
		p.cl = fatory.newPoint()
		p.cl.l = p.l
		p.cl.r = (p.l + p.r) / 2
		p.cl.min = MAX
	}
	return p.cl
}
func (p *Point) right() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cr == nil {
		p.cr = fatory.newPoint()
		p.cr.l = (p.l+p.r)/2 + 1
		p.cr.r = p.r
		p.cl.min = MAX
	}
	return p.cr
}
func (p *Point) refleshMin() {
	if p.left() == nil && p.right() == nil {
		return
	}
	if p.left() == nil {
		p.min = p.right().min
	} else if p.right() == nil {
		p.min = p.left().min
	} else if p.left().min < p.right().min {
		p.min = p.left().min
	} else {
		p.min = p.right().min
	}
	if p.min == 0 &&debug{
		fmt.Printf("min=0 l=%d r=%d dirty=%d\n",p.l,p.r,p.dirty)
	}

}
func (p *Point) queryMin(l, r int) (int64, bool) {
	p.down()
	if l <= p.l && p.r <= r {
		return p.min, true
	}
	if l > p.r || r < p.l {
		return -1, false
	}
	var res int64 = 0
	find := false
	if p.left() != nil {
		leftmin, flag := p.left().queryMin(l, r)
		if flag {
			res = leftmin
			find = true
		}
	}
	if p.right() != nil {
		rightmin, flag := p.right().queryMin(l, r)
		if flag && (find == false || rightmin < res) {
			res = rightmin
		}
	}
	return res, true

}
func (p *Point) addValue(value int) {
	if p.min >= MAX {
		p.min = int64(value)
	} else {
		p.min += int64(value)
	}
	if p.min == 0 &&debug{
		fmt.Printf("min=0 l=%d r=%d dirty=%d\n",p.l,p.r,p.dirty)
	}
}
func (p *Point) down() {
	if p.dirty <= 0 {
		return
	}
	pl := p.left()
	pr := p.right()
	if pl != nil {
		pl.dirty += p.dirty
		pl.addValue(p.dirty)
	}
	if pr != nil {
		pr.dirty += p.dirty
		pr.addValue(p.dirty)
	}
	p.dirty = 0
	//p.refleshMin()
}
func (p *Point) add(l, r int, value int) {
	if l > p.r || r < p.l {
		return
	}
	if l <= p.l && p.r <= r {
		p.addValue(value)
		p.dirty += value
		return
	}
	pl := p.left()
	pr := p.right()
	p.down()
	if pl != nil {
		pl.add(l, r, value)
	}
	if pr != nil {
		pr.add(l, r, value)
	}
	tmin := p.min
	p.refleshMin()
	if debug && p.min > tmin {
		fmt.Printf(" tmin=%d nowmin=%d pl=%d pr=%d l=%d r=%d value=%d\n", tmin, p.min,p.l,p.r,l,r,value)
	}
}
func solveE(mat []int, n int, segs Segs) (Segs, int64) {
	fatory = newFatory(n)

	maxx := make([]int, n)
	minn := mat[n-1]
	maxx[n-1] = mat[n-1]
	for i := n - 2; i >= 0; i-- {
		if mat[i] > maxx[i+1] {
			maxx[i] = mat[i]
		} else {
			maxx[i] = maxx[i+1]
		}
		if mat[i] < minn {
			minn = mat[i]
		}
	}
	partline := -1
	res := int64(maxx[0] - minn)
	root := fatory.newPoint()
	root.l = 1
	root.r = n
	//fmt.Printf("root.min = %d l=%d r=%d\n",root.min,root.l,root.r)
	for i := 0; i < n; i++ {
		root.add(i+1, i+1, mat[i])
		//	fmt.Printf("i=%d root.min = %d value=%d\n", i,root.min,mat[i])
	}
	//fmt.Printf("root.min = %d\n", root.min)

	sort.Sort(segs)
	dbMax := 0
	for i := 0; i < len(segs); i++ {
		if segs[i].r >= n {
			continue
		}
		root.add(segs[i].l, segs[i].r, -1)
		tmpm, _ := root.queryMin(1, segs[i].r)
		//	fmt.Printf("i=%d segs.l = %d segs.r = %d min=%d maxx=%d\n", i, segs[i].l, segs[i].r, tmpm, maxx[segs[i].r])
		if res < int64(maxx[segs[i].r])-tmpm {
			partline = i
			res = int64(maxx[segs[i].r]) - tmpm
			dbMax = maxx[segs[i].r]
		}
		if debug && (segs[i].id == 36 || segs[i].id == 55 || segs[i].id == 76 || segs[i].id == 11 || segs[i].id == 37 || segs[i].id == 95 || segs[i].id == 6 || segs[i].id == 41) {
			logger += fmt.Sprintf("i=%d maxx=%d min=%d l=%d r=%d root.min=%d\n", segs[i].id, maxx[segs[i].r], tmpm, segs[i].l, segs[i].r, root.min)
			//logger += "i=" + strconv.Itoa(segs[i].id) + " maxx = " + strconv.Itoa(maxx[segs[i].r]) + " min=" + strconv.Itoa(int(tmpm)) + "\n"
		}
	}
	if debug && partline > -1 {
		logger += "partline=" + strconv.Itoa(segs[partline].r) + " maxx = " + strconv.Itoa(dbMax) + " min=" + strconv.Itoa(dbMax-int(res)) + "\n"
		//	fmt.Printf("partline=%d maxx = %d min=%d\n", segs[partline].r, dbMax,res-int64(dbMax))
	}
	as := make(Segs, partline+1)
	for i := 0; i <= partline; i++ {
		as[i] = Seg{
			l:  segs[i].l,
			r:  segs[i].r,
			id: segs[i].id,
		}
	}
	//	fmt.Printf("as = %v res=%v\n",as,res)
	return as, res
}
func reverse(mat []int, segs Segs) {
	//	fmt.Printf("before mat=%v seg=%v\n",mat,segs)
	n := len(mat)
	m := len(segs)
	for i := 0; i < n-i-1; i++ {
		tmp := mat[i]
		mat[i] = mat[n-i-1]
		mat[n-i-1] = tmp
	}
	for i := 0; i < m; i++ {
		tmp := segs[i].l
		segs[i].l = segs[i].r
		segs[i].r = tmp
		segs[i].l = n - segs[i].l + 1
		segs[i].r = n - segs[i].r + 1
	}

}
func tmpseg(segs Segs) Segs {
	lens := len(goods)
	res := make(Segs, 0)
	for j := 0; j < len(segs); j++ {
		for i := 0; i < lens; i++ {
			if goods[i] == segs[j].id {
				res = append(res, segs[j])
				break
			}
		}
	}
	return res
}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	if n == 10000 && m == 100 {
		debug = true
	}
	//	debug=true
	mat := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d", &mat[i])
	}
	fmt.Fscanf(buf, "\n")
	seg := make(Segs, m)
	for i := 0; i < m; i++ {
		fmt.Fscanf(buf, "%d %d\n", &seg[i].l, &seg[i].r)
		seg[i].id = i + 1
	}
	pl, ans := solveE(mat, n, seg)
	reverse(mat, seg)
	//	fmt.Printf("rev mat=%v seg=%d\n",mat,seg)
	pl2, ans2 := solveE(mat, n, seg)

	if ans < ans2 {
		fmt.Printf("%d\n", ans2)
		fmt.Printf("%d\n", len(pl2))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl2[i].id)
		}
		fmt.Printf("\n")
		if len(pl) > 0 && debug {
			c, _ := check(mat, tmpseg(seg))
			c, _ = check(mat, pl2)
			if c != ans2 {
				fmt.Printf("ERROR c = %d ans=%d\n", c, ans2)
			}
			fmt.Printf("logger--\n%s\n", logger)
		}
	} else {
		fmt.Printf("%d\n", ans)
		fmt.Printf("%d\n", len(pl))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl[i].id)
		}
		fmt.Printf("\n")

		if len(pl) > 0 && debug {
			reverse(mat, seg)
			c, _ := check(mat, tmpseg(seg))
			c, _ = check(mat, pl)

			if c != ans {
				fmt.Printf("2ERROR c = %d ans=%d\n", c, ans)
			}
			fmt.Printf("%s\n", logger)
		}
	}

}
func check(mat []int, pl Segs) (int64, int) {
	n := len(mat)
	m := len(pl)
	if m <= 0 {
		return 0, 0
	}
	maxx := -1
	minn := 10000000
	//minw := -1
	for i := 0; i < n; i++ {
		in := 0
		for j := 0; j < m; j++ {
			if pl[j].l > i+1 || pl[j].r < i+1 {
				continue
			}
			in++
		}
		if in == 0 {
			if maxx == -1 || mat[maxx] < mat[i] {
				maxx = i
			}
		}
		if minn > mat[i]-in {
			minn = mat[i] - in
			//minw = i
		}

	}
	if debug {
		maxxr := 0
		for i := 0; i < m; i++ {
			if pl[i].l <= 3119 && pl[i].r >= 3119 {
				//	fmt.Printf("range %d %d %d\n", pl[i].l, pl[i].r,pl[i].id)
			}

			if pl[i].r > maxxr {
				maxxr = pl[i].r
			}
		}
		//		fmt.Printf("check maxw = %d  minw = %d maxx=%d min=%d mat[minn]=%d maxxr=%d\n", maxx+1, minw+1, mat[maxx], minn, mat[minw],maxxr)
	}
	return int64(mat[maxx] - minn), mat[maxx]
}

/**

5 3
1 2 2 -2 3
3 5
1 5
3 5
 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

var (
	fatory *PointFatory
	debug  = false
	logger = ""
	goods  = [70]int{80, 41, 72, 28, 77, 62, 6, 14, 78, 97, 93, 48, 4, 3, 25, 94, 83, 10, 53, 22, 54, 70, 29, 27, 87, 45, 43, 76, 31, 30, 42, 20, 12, 2, 40, 16, 100, 64, 86, 44, 49, 56, 33, 11, 46, 18, 75, 5, 69, 55, 37, 50, 92, 73, 21, 57, 13, 35, 26, 65, 81, 95, 36, 32, 15, 60, 68, 89, 98, 38}
)

const (
	MAX = 1000100 * 300
)

type Point struct {
	l, r   int
	dirty  int
	min    int64
	cl, cr *Point
}
type Seg struct {
	l, r int
	id   int
}
type Segs []Seg

func (s Segs) Len() int {
	return len(s)
}
func (s Segs) Swap(a, b int) {
	tmp := s[a].l
	s[a].l = s[b].l
	s[b].l = tmp

	tmp = s[a].r
	s[a].r = s[b].r
	s[b].r = tmp

	tmp = s[a].id
	s[a].id = s[b].id
	s[b].id = tmp
}
func (s Segs) Less(a, b int) bool {
	if s[a].r < s[b].r {
		return true
	}
	return false
}

type PointFatory struct {
	p     []Point
	front int
	len   int
}

func (p *PointFatory) newPoint() *Point {
	if p.front >= p.len {
		p.p = append(p.p, make([]Point, p.len)...)
		p.len = len(p.p)
	}
	res := &p.p[p.front]
	p.front++
	return res
}
func newFatory(n int) *PointFatory {
	return &PointFatory{
		p:   make([]Point, n),
		len: n,
	}
}
func (p *Point) left() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cl == nil {
		p.cl = fatory.newPoint()
		p.cl.l = p.l
		p.cl.r = (p.l + p.r) / 2
		p.cl.min = MAX
	}
	return p.cl
}
func (p *Point) right() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cr == nil {
		p.cr = fatory.newPoint()
		p.cr.l = (p.l+p.r)/2 + 1
		p.cr.r = p.r
		p.cl.min = MAX
	}
	return p.cr
}
func (p *Point) refleshMin() {
	if p.left() == nil && p.right() == nil {
		return
	}
	if p.left() == nil {
		p.min = p.right().min
	} else if p.right() == nil {
		p.min = p.left().min
	} else if p.left().min < p.right().min {
		p.min = p.left().min
	} else {
		p.min = p.right().min
	}

}
func (p *Point) queryMin(l, r int) (int64, bool) {
	p.down()
	if l <= p.l && p.r <= r {
		return p.min, true
	}
	if l > p.r || r < p.l {
		return -1, false
	}
	var res int64 = 0
	find := false
	if p.left() != nil {
		leftmin, flag := p.left().queryMin(l, r)
		if flag {
			res = leftmin
			find = true
		}
	}
	if p.right() != nil {
		rightmin, flag := p.right().queryMin(l, r)
		if flag && (find == false || rightmin < res) {
			res = rightmin
		}
	}
	return res, true

}
func (p *Point) addValue(value int) {
	if p.min >= MAX {
		p.min = int64(value)
	} else {
		p.min += int64(value)
	}
}
func (p *Point) down() {
	if p.dirty <= 0 {
		return
	}
	pl := p.left()
	pr := p.right()
	if pl != nil {
		pl.dirty += p.dirty
		pl.addValue(p.dirty)
	}
	if pr != nil {
		pr.dirty += p.dirty
		pr.addValue(p.dirty)
	}
	p.dirty = 0
	p.refleshMin()
}
func (p *Point) add(l, r int, value int) {
	if l > p.r || r < p.l {
		return
	}
	if l <= p.l && p.r <= r {
		p.addValue(value)
		p.dirty += value
		return
	}
	pl := p.left()
	pr := p.right()
	p.down()
	if pl != nil {
		pl.add(l, r, value)
	}
	if pr != nil {
		pr.add(l, r, value)
	}
	p.refleshMin()
}
func solveE(mat []int, n int, segs Segs) (Segs, int64) {
	fatory = newFatory(n)

	maxx := make([]int, n)
	minn := mat[n-1]
	maxx[n-1] = mat[n-1]
	for i := n - 2; i >= 0; i-- {
		if mat[i] > maxx[i+1] {
			maxx[i] = mat[i]
		} else {
			maxx[i] = maxx[i+1]
		}
		if mat[i] < minn {
			minn = mat[i]
		}
	}
	partline := -1
	res := int64(maxx[0] - minn)
	root := fatory.newPoint()
	root.l = 1
	root.r = n
	//fmt.Printf("root.min = %d l=%d r=%d\n",root.min,root.l,root.r)
	for i := 0; i < n; i++ {
		root.add(i+1, i+1, mat[i])
		//	fmt.Printf("i=%d root.min = %d value=%d\n", i,root.min,mat[i])
	}
	//fmt.Printf("root.min = %d\n", root.min)

	sort.Sort(segs)
	dbMax := 0
	for i := 0; i < len(segs); i++ {
		if segs[i].r >= n {
			continue
		}
		root.add(segs[i].l, segs[i].r, -1)
		tmpm, _ := root.queryMin(1, segs[i].r)
		//	fmt.Printf("i=%d segs.l = %d segs.r = %d min=%d maxx=%d\n", i, segs[i].l, segs[i].r, tmpm, maxx[segs[i].r])
		if res < int64(maxx[segs[i].r])-tmpm {
			partline = i
			res = int64(maxx[segs[i].r]) - tmpm
			dbMax = maxx[segs[i].r]
		}
	}
	if debug && partline > -1 {
		logger += "partline=" + strconv.Itoa(segs[partline].r) + " maxx = " + strconv.Itoa(dbMax) + " min=" + strconv.Itoa(dbMax-int(res)) + "\n"
		//	fmt.Printf("partline=%d maxx = %d min=%d\n", segs[partline].r, dbMax,res-int64(dbMax))
	}
	as := make(Segs, partline+1)
	for i := 0; i <= partline; i++ {
		as[i] = segs[i]
	}
	//	fmt.Printf("as = %v res=%v\n",as,res)
	return as, res
}
func reverse(mat []int, segs Segs) {
	//	fmt.Printf("before mat=%v seg=%v\n",mat,segs)
	n := len(mat)
	m := len(segs)
	for i := 0; i < n-i-1; i++ {
		tmp := mat[i]
		mat[i] = mat[n-i-1]
		mat[n-i-1] = tmp
	}
	for i := 0; i < m; i++ {
		tmp := segs[i].l
		segs[i].l = segs[i].r
		segs[i].r = tmp
		segs[i].l = n - segs[i].l + 1
		segs[i].r = n - segs[i].r + 1
	}

}
func tmpseg(segs Segs) Segs {
	lens := len(goods)
	res := make(Segs, 0)
	for j:= 0;j < len(segs);j++ {
		for i := 0; i < lens; i++ {
			if goods[i] == segs[j].id {
				res = append(res,segs[j])
				break
			}
		}
	}
	return res
}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	if n == 10000 && m == 100 {
		debug = true
	}
	//	debug=true
	mat := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d", &mat[i])
	}
	fmt.Fscanf(buf, "\n")
	seg := make(Segs, m)
	for i := 0; i < m; i++ {
		fmt.Fscanf(buf, "%d %d\n", &seg[i].l, &seg[i].r)
		seg[i].id = i + 1
	}
	pl, ans := solveE(mat, n, seg)
	reverse(mat, seg)
	//	fmt.Printf("rev mat=%v seg=%d\n",mat,seg)
	pl2, ans2 := solveE(mat, n, seg)

	if ans < ans2 {
		fmt.Printf("%d\n", ans2)
		fmt.Printf("%d\n", len(pl2))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl2[i].id)
		}
		fmt.Printf("\n")
		if len(pl) > 0 && debug {
			c, _ := check(mat, tmpseg(seg))
			c, wei := check(mat, pl2)
			fmt.Printf("w = %d\n", wei)
			if c != ans2 {
				fmt.Printf("ERROR c = %d ans=%d\n", c, ans2)
			}
			fmt.Printf("logger--\n%s\n", logger)
		}
	} else {
		fmt.Printf("%d\n", ans)
		fmt.Printf("%d\n", len(pl))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl[i].id)
		}
		fmt.Printf("\n")

		if len(pl) > 0 && debug {
			reverse(mat, seg)
			c, _ := check(mat, tmpseg(seg))
			c, wei := check(mat, pl)
			fmt.Printf("w = %d\n", wei)
			if c != ans {
				fmt.Printf("2ERROR c = %d ans=%d\n", c, ans)
			}
			fmt.Printf("logger--\n%s\n", logger)
		}
	}

}
func check(mat []int, pl Segs) (int64, int) {
	n := len(mat)
	m := len(pl)
	if m <= 0 {
		return 0, 0
	}
	maxx := -1
	minn := 10000000
	minw := -1
	for i := 0; i < n; i++ {
		in := 0
		for j := 0; j < m; j++ {
			if pl[j].l > i+1 || pl[j].r < i+1 {
				continue
			}
			in++
		}
		if in == 0 {
			if maxx == -1 || mat[maxx] < mat[i] {
				maxx = i
			}
		}
		if minn > mat[i]-in {
			minn = mat[i] - in
			minw = i
		}
	}
	if debug {
		for i := 0; i < m; i++ {
			fmt.Printf("range %d %d\n", pl[i].l, pl[i].r)
		}
		fmt.Printf("check maxw = %d  minw = %d maxx=%d min=%d mat[minn]=%d\n", maxx+1, minw+1, mat[maxx], minn, mat[minw])
	}
	return int64(mat[maxx] - minn), mat[maxx]
}

/**

5 3
1 2 2 -2 3
3 5
1 5
3 5
 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

var (
	fatory *PointFatory
	debug  = false
	logger = ""
	goods  = [70]int{80, 41, 72, 28, 77, 62, 6, 14, 78, 97, 93, 48, 4, 3, 25, 94, 83, 10, 53, 22, 54, 70, 29, 27, 87, 45, 43, 76, 31, 30, 42, 20, 12, 2, 40, 16, 100, 64, 86, 44, 49, 56, 33, 11, 46, 18, 75, 5, 69, 55, 37, 50, 92, 73, 21, 57, 13, 35, 26, 65, 81, 95, 36, 32, 15, 60, 68, 89, 98, 38}
)

const (
	MAX = 1000100 * 300
)

type Point struct {
	l, r   int
	dirty  int
	min    int64
	cl, cr *Point
}
type Seg struct {
	l, r int
	id   int
}
type Segs []Seg

func (s Segs) Len() int {
	return len(s)
}
func (s Segs) Swap(a, b int) {
	tmp := s[a].l
	s[a].l = s[b].l
	s[b].l = tmp

	tmp = s[a].r
	s[a].r = s[b].r
	s[b].r = tmp

	tmp = s[a].id
	s[a].id = s[b].id
	s[b].id = tmp
}
func (s Segs) Less(a, b int) bool {
	if s[a].r < s[b].r {
		return true
	}
	return false
}

type PointFatory struct {
	p     []Point
	front int
	len   int
}

func (p *PointFatory) newPoint() *Point {
	if p.front >= p.len {
		p.p = append(p.p, make([]Point, p.len)...)
		p.len = len(p.p)
	}
	res := &p.p[p.front]
	p.front++
	return res
}
func newFatory(n int) *PointFatory {
	return &PointFatory{
		p:   make([]Point, n),
		len: n,
	}
}
func (p *Point) left() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cl == nil {
		p.cl = fatory.newPoint()
		p.cl.l = p.l
		p.cl.r = (p.l + p.r) / 2
		p.cl.min = MAX
	}
	return p.cl
}
func (p *Point) right() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cr == nil {
		p.cr = fatory.newPoint()
		p.cr.l = (p.l+p.r)/2 + 1
		p.cr.r = p.r
		p.cl.min = MAX
	}
	return p.cr
}
func (p *Point) refleshMin() {
	if p.left() == nil && p.right() == nil {
		return
	}
	if p.left() == nil {
		p.min = p.right().min
	} else if p.right() == nil {
		p.min = p.left().min
	} else if p.left().min < p.right().min {
		p.min = p.left().min
	} else {
		p.min = p.right().min
	}

}
func (p *Point) queryMin(l, r int) (int64, bool) {
	p.down()
	if l <= p.l && p.r <= r {
		return p.min, true
	}
	if l > p.r || r < p.l {
		return -1, false
	}
	var res int64 = 0
	find := false
	if p.left() != nil {
		leftmin, flag := p.left().queryMin(l, r)
		if flag {
			res = leftmin
			find = true
		}
	}
	if p.right() != nil {
		rightmin, flag := p.right().queryMin(l, r)
		if flag && (find == false || rightmin < res) {
			res = rightmin
		}
	}
	return res, true

}
func (p *Point) addValue(value int) {
	if p.min >= MAX {
		p.min = int64(value)
	} else {
		p.min += int64(value)
	}
}
func (p *Point) down() {
	if p.dirty <= 0 {
		return
	}
	pl := p.left()
	pr := p.right()
	if pl != nil {
		pl.dirty += p.dirty
		pl.addValue(p.dirty)
	}
	if pr != nil {
		pr.dirty += p.dirty
		pr.addValue(p.dirty)
	}
	p.dirty = 0
	p.refleshMin()
}
func (p *Point) add(l, r int, value int) {
	if l > p.r || r < p.l {
		return
	}
	if l <= p.l && p.r <= r {
		p.addValue(value)
		p.dirty += value
		return
	}
	pl := p.left()
	pr := p.right()
	p.down()
	if pl != nil {
		pl.add(l, r, value)
	}
	if pr != nil {
		pr.add(l, r, value)
	}
	p.refleshMin()
}
func solveE(mat []int, n int, segs Segs) (Segs, int64) {
	fatory = newFatory(n)

	maxx := make([]int, n)
	minn := mat[n-1]
	maxx[n-1] = mat[n-1]
	for i := n - 2; i >= 0; i-- {
		if mat[i] > maxx[i+1] {
			maxx[i] = mat[i]
		} else {
			maxx[i] = maxx[i+1]
		}
		if mat[i] < minn {
			minn = mat[i]
		}
	}
	partline := -1
	res := int64(maxx[0] - minn)
	root := fatory.newPoint()
	root.l = 1
	root.r = n
	//fmt.Printf("root.min = %d l=%d r=%d\n",root.min,root.l,root.r)
	for i := 0; i < n; i++ {
		root.add(i+1, i+1, mat[i])
		//	fmt.Printf("i=%d root.min = %d value=%d\n", i,root.min,mat[i])
	}
	//fmt.Printf("root.min = %d\n", root.min)

	sort.Sort(segs)
	dbMax := 0
	for i := 0; i < len(segs); i++ {
		if segs[i].r >= n {
			continue
		}
		root.add(segs[i].l, segs[i].r, -1)
		tmpm, _ := root.queryMin(1, segs[i].r)
		//	fmt.Printf("i=%d segs.l = %d segs.r = %d min=%d maxx=%d\n", i, segs[i].l, segs[i].r, tmpm, maxx[segs[i].r])
		if res < int64(maxx[segs[i].r])-tmpm {
			partline = i
			res = int64(maxx[segs[i].r]) - tmpm
			dbMax = maxx[segs[i].r]
		}
	}
	if debug && partline > -1 {
		logger += "partline=" + strconv.Itoa(segs[partline].r) + " maxx = " + strconv.Itoa(dbMax) + " min=" + strconv.Itoa(dbMax-int(res)) + "\n"
		//	fmt.Printf("partline=%d maxx = %d min=%d\n", segs[partline].r, dbMax,res-int64(dbMax))
	}
	as := make(Segs, partline+1)
	for i := 0; i <= partline; i++ {
		as[i] = segs[i]
	}
	//	fmt.Printf("as = %v res=%v\n",as,res)
	return as, res
}
func reverse(mat []int, segs Segs) {
	//	fmt.Printf("before mat=%v seg=%v\n",mat,segs)
	n := len(mat)
	m := len(segs)
	for i := 0; i < n-i-1; i++ {
		tmp := mat[i]
		mat[i] = mat[n-i-1]
		mat[n-i-1] = tmp
	}
	for i := 0; i < m; i++ {
		tmp := segs[i].l
		segs[i].l = segs[i].r
		segs[i].r = tmp
		segs[i].l = n - segs[i].l + 1
		segs[i].r = n - segs[i].r + 1
	}

}
func tmpseg(segs Segs) Segs {
	lens := len(goods)
	res := make(Segs, 0)
	for j := 0; j < len(segs); j++ {
		for i := 0; i < lens; i++ {
			if goods[i] == segs[j].id {
				res = append(res, segs[j])
				break
			}
		}
	}
	return res
}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	if n == 10000 && m == 100 {
		debug = true
	}
	//	debug=true
	mat := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d", &mat[i])
	}
	fmt.Fscanf(buf, "\n")
	seg := make(Segs, m)
	for i := 0; i < m; i++ {
		fmt.Fscanf(buf, "%d %d\n", &seg[i].l, &seg[i].r)
		seg[i].id = i + 1
	}
	pl, ans := solveE(mat, n, seg)
	reverse(mat, seg)
	//	fmt.Printf("rev mat=%v seg=%d\n",mat,seg)
	pl2, ans2 := solveE(mat, n, seg)

	if ans < ans2 {
		fmt.Printf("%d\n", ans2)
		fmt.Printf("%d\n", len(pl2))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl2[i].id)
		}
		fmt.Printf("\n")
		if len(pl) > 0 && debug {
			c, _ := check(mat, tmpseg(seg))
			c, wei := check(mat, pl2)
			fmt.Printf("w = %d\n", wei)
			if c != ans2 {
				fmt.Printf("ERROR c = %d ans=%d\n", c, ans2)
			}
			fmt.Printf("logger--\n%s\n", logger)
		}
	} else {
		fmt.Printf("%d\n", ans)
		fmt.Printf("%d\n", len(pl))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl[i].id)
		}
		fmt.Printf("\n")

		if len(pl) > 0 && debug {
			reverse(mat, seg)
			c, _ := check(mat, tmpseg(seg))
			c, wei := check(mat, pl)
			fmt.Printf("w = %d\n", wei)
			if c != ans {
				fmt.Printf("2ERROR c = %d ans=%d\n", c, ans)
			}
			fmt.Printf("logger--\n%s\n", logger)
		}
	}

}
func check(mat []int, pl Segs) (int64, int) {
	n := len(mat)
	m := len(pl)
	if m <= 0 {
		return 0, 0
	}
	maxx := -1
	minn := 10000000
	minw := -1
	for i := 0; i < n; i++ {
		in := 0
		for j := 0; j < m; j++ {
			if pl[j].l > i+1 || pl[j].r < i+1 {
				continue
			}
			in++
		}
		if in == 0 {
			if maxx == -1 || mat[maxx] < mat[i] {
				maxx = i
			}
		}
		if minn > mat[i]-in {
			minn = mat[i] - in
			minw = i
		}
	}
	if debug {
		maxxr := 0
		for i := 0; i < m; i++ {
		//	fmt.Printf("range %d %d\n", pl[i].l, pl[i].r)
			if pl[i].r > maxxr {
				maxxr = pl[i].r
			}
		}
		fmt.Printf("check maxw = %d  minw = %d maxx=%d min=%d mat[minn]=%d maxxr=%d\n", maxx+1, minw+1, mat[maxx], minn, mat[minw],maxxr)
	}
	return int64(mat[maxx] - minn), mat[maxx]
}

/**

5 3
1 2 2 -2 3
3 5
1 5
3 5
 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

var (
	fatory *PointFatory
)

const (
	MAX = 1000100 * 300
)

type Point struct {
	l, r   int
	dirty  int
	min    int64
	cl, cr *Point
}
type Seg struct {
	l, r int
	id   int
}
type Segs []Seg

func (s Segs) Len() int {
	return len(s)
}
func (s Segs) Swap(a, b int) {
	tmp := s[a].l
	s[a].l = s[b].l
	s[b].l = tmp

	tmp = s[a].r
	s[a].r = s[b].r
	s[b].r = tmp

	tmp = s[a].id
	s[a].id = s[b].id
	s[b].id = tmp
}
func (s Segs) Less(a, b int) bool {
	if s[a].r < s[b].r {
		return true
	}
	return false
}

type PointFatory struct {
	p     []Point
	front int
	len   int
}

func (p *PointFatory) newPoint() *Point {
	if p.front >= p.len {
		p.p = append(p.p, make([]Point, p.len)...)
		p.len = len(p.p)
	}
	res := &p.p[p.front]
	p.front++
	return res
}
func newFatory(n int) *PointFatory {
	return &PointFatory{
		p:   make([]Point, n),
		len: n,
	}
}
func (p *Point) left() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cl == nil {
		p.cl = fatory.newPoint()
		p.cl.l = p.l
		p.cl.r = (p.l + p.r) / 2
		p.cl.min = MAX
	}
	return p.cl
}
func (p *Point) right() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cr == nil {
		p.cr = fatory.newPoint()
		p.cr.l = (p.l+p.r)/2 + 1
		p.cr.r = p.r
		p.cl.min = MAX
	}
	return p.cr
}
func (p *Point) refleshMin() {
	if p.left() == nil && p.right() == nil {
		return
	}
	if p.left() == nil {
		p.min = p.right().min
	} else if p.right() == nil {
		p.min = p.left().min
	} else if p.left().min < p.right().min {
		p.min = p.left().min
	} else {
		p.min = p.right().min
	}

}
func (p *Point) queryMin(l, r int) (int64, bool) {
	p.down()
	if l <= p.l && p.r <= r {
		return p.min, true
	}
	if l > p.r || r < p.l {
		return -1, false
	}
	var res int64 = 0
	find := false
	if p.left() != nil {
		leftmin, flag := p.left().queryMin(l, r)
		if flag {
			res = leftmin
			find = true
		}
	}
	if p.right() != nil {
		rightmin, flag := p.right().queryMin(l, r)
		if flag && (find == false || rightmin < res) {
			res = rightmin
		}
	}
	return res, true

}
func (p *Point) addValue(value int) {
	if p.min >= MAX {
		p.min = int64(value)
	} else {
		p.min += int64(value)
	}
}
func (p *Point) down() {
	if p.dirty <= 0 {
		return
	}
	pl := p.left()
	pr := p.right()
	if pl != nil {
		pl.dirty += p.dirty
		pl.addValue(p.dirty)
	}
	if pr != nil {
		pr.dirty += p.dirty
		pr.addValue(p.dirty)
	}
	p.dirty = 0
	p.refleshMin()
}
func (p *Point) add(l, r int, value int) {
	if l > p.r || r < p.l {
		return
	}
	if l <= p.l && p.r <= r {
		p.addValue(value)
		p.dirty += value
		return
	}
	pl := p.left()
	pr := p.right()
	p.down()
	if pl != nil {
		pl.add(l, r, value)
	}
	if pr != nil {
		pr.add(l, r, value)
	}
	p.refleshMin()
}
func solveE(mat []int, n int, segs Segs) (Segs, int64) {
	fatory = newFatory(n)

	maxx := make([]int, n)
	minn := mat[n-1]
	maxx[n-1] = mat[n-1]
	for i := n - 2; i >= 0; i-- {
		if mat[i] > maxx[i+1] {
			maxx[i] = mat[i]
		} else {
			maxx[i] = maxx[i+1]
		}
		if mat[i] < minn {
			minn = mat[i]
		}
	}
	partline := -1
	res := int64(maxx[0] - minn)
	root := fatory.newPoint()
	root.l = 1
	root.r = n
	//fmt.Printf("root.min = %d l=%d r=%d\n",root.min,root.l,root.r)
	for i := 0; i < n; i++ {
		root.add(i+1, i+1, mat[i])
		//	fmt.Printf("i=%d root.min = %d value=%d\n", i,root.min,mat[i])
	}
	//fmt.Printf("root.min = %d\n", root.min)

	sort.Sort(segs)
	for i := 0; i < len(segs); i++ {
		if segs[i].r >= n {
			continue
		}
		root.add(segs[i].l, segs[i].r, -1)
		tmpm, _ := root.queryMin(1, segs[i].r)
		//	fmt.Printf("i=%d segs.l = %d segs.r = %d min=%d maxx=%d\n", i, segs[i].l, segs[i].r, tmpm, maxx[segs[i].r])
		if res < int64(maxx[segs[i].r])-tmpm {
			partline = i
			res = int64(maxx[segs[i].r]) - tmpm
		}
	}
	as := make(Segs, partline+1)
	for i := 0; i <= partline; i++ {
		as[i] = segs[i]
	}
	//	fmt.Printf("as = %v res=%v\n",as,res)
	return as, res
}
func reverse(mat []int, segs Segs) {
	//	fmt.Printf("before mat=%v seg=%v\n",mat,segs)
	n := len(mat)
	m := len(segs)
	for i := 0; i < n-i-1; i++ {
		tmp := mat[i]
		mat[i] = mat[n-i-1]
		mat[n-i-1] = tmp
	}
	for i := 0; i < m; i++ {
		tmp := segs[i].l
		segs[i].l = segs[i].r
		segs[i].r = tmp
		segs[i].l = n - segs[i].l + 1
		segs[i].r = n - segs[i].r + 1
	}

}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	mat := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d", &mat[i])
	}
	fmt.Fscanf(buf, "\n")
	seg := make(Segs, m)
	for i := 0; i < m; i++ {
		fmt.Fscanf(buf, "%d %d\n", &seg[i].l, &seg[i].r)
		seg[i].id = i + 1
	}
	pl, ans := solveE(mat, n, seg)
	reverse(mat, seg)
	//	fmt.Printf("rev mat=%v seg=%d\n",mat,seg)
	pl2, ans2 := solveE(mat, n, seg)
	if ans < ans2 {
		fmt.Printf("%d\n", ans2)
		fmt.Printf("%d\n", len(pl2))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl2[i].id)
		}
		fmt.Printf("\n")
		if len(pl) > 0 {
			c := check(mat, pl2)
			if c != ans2 {
				fmt.Printf("ERROR c = %d ans=%d\n", c, ans2)
			}
		}
	} else {
		fmt.Printf("%d\n", ans)
		fmt.Printf("%d\n", len(pl))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl[i].id)
		}
		fmt.Printf("\n")
		reverse(mat, seg)
		if len(pl) > 0 {
			c := check(mat, pl)
			if c != ans {
				fmt.Printf("2ERROR c = %d ans=%d\n", c, ans)
			}
		}
	}

}
func check(mat []int, pl Segs) int64 {
	n := len(mat)
	m := len(pl)
	maxx := -10000100
	minn := 10000000
	for i := 0; i < n; i++ {
		in := 0
		for j := 0; j < m; j++ {
			if pl[j].l > i+1 || pl[j].r < i+1 {
				continue
			}
			in++
		}
		if in == 0 {
			if maxx < mat[i] {
				maxx = mat[i]
			}
		} else {
			if minn > mat[i]-in {
				minn = mat[i] - in
			}
		}
	}
	//	fmt.Printf("v pl=%v mat=%v\n",pl,mat)
	return int64(maxx - minn)
}

/**

5 3
1 2 2 -2 3
3 5
1 5
3 5
 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

var (
	fatory *PointFatory
	debug  = false
	logger = ""
	goods  = [70]int{80, 41, 72, 28, 77, 62, 6, 14, 78, 97, 93, 48, 4, 3, 25, 94, 83, 10, 53, 22, 54, 70, 29, 27, 87, 45, 43, 76, 31, 30, 42, 20, 12, 2, 40, 16, 100, 64, 86, 44, 49, 56, 33, 11, 46, 18, 75, 5, 69, 55, 37, 50, 92, 73, 21, 57, 13, 35, 26, 65, 81, 95, 36, 32, 15, 60, 68, 89, 98, 38}
)

const (
	MAX = 1000100 * 300
)

type Point struct {
	l, r   int
	dirty  int
	min    int64
	cl, cr *Point
}
type Seg struct {
	l, r int
	id   int
}
type Segs []Seg

func (s Segs) Len() int {
	return len(s)
}
func (s Segs) Swap(a, b int) {
	tmp := s[a].l
	s[a].l = s[b].l
	s[b].l = tmp

	tmp = s[a].r
	s[a].r = s[b].r
	s[b].r = tmp

	tmp = s[a].id
	s[a].id = s[b].id
	s[b].id = tmp
}
func (s Segs) Less(a, b int) bool {
	if s[a].r < s[b].r {
		return true
	}
	return false
}

type PointFatory struct {
	p     []Point
	front int
	len   int
}

func (p *PointFatory) newPoint() *Point {
	return &Point{}
	//if p.front >= p.len {
	//	p.p = append(p.p, make([]Point, p.len)...)
	//	p.len = len(p.p)
	//}
	//res := &p.p[p.front]
	//p.front++
	//return res
}
func newFatory(n int) *PointFatory {
	return &PointFatory{
		p:   make([]Point, n),
		len: n,
	}
}
func (p *Point) left() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cl == nil {
		p.cl = fatory.newPoint()
		p.cl.l = p.l
		p.cl.r = (p.l + p.r) / 2
		p.cl.min = MAX
	}
	return p.cl
}
func (p *Point) right() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cr == nil {
		p.cr = fatory.newPoint()
		p.cr.l = (p.l+p.r)/2 + 1
		p.cr.r = p.r
		p.cl.min = MAX
	}
	return p.cr
}
func (p *Point) refleshMin() {
	if p.left() == nil && p.right() == nil {
		return
	}
	if p.left() == nil {
		p.min = p.right().min
	} else if p.right() == nil {
		p.min = p.left().min
	} else if p.left().min < p.right().min {
		p.min = p.left().min
	} else {
		p.min = p.right().min
	}

}
func (p *Point) queryMin(l, r int) (int64, bool) {
	p.down()
	if l <= p.l && p.r <= r {
		return p.min, true
	}
	if l > p.r || r < p.l {
		return -1, false
	}
	var res int64 = 0
	find := false
	if p.left() != nil {
		leftmin, flag := p.left().queryMin(l, r)
		if flag {
			res = leftmin
			find = true
		}
	}
	if p.right() != nil {
		rightmin, flag := p.right().queryMin(l, r)
		if flag && (find == false || rightmin < res) {
			res = rightmin
		}
	}
	return res, true

}
func (p *Point) addValue(value int) {
	if p.min >= MAX {
		p.min = int64(value)
	} else {
		p.min += int64(value)
	}
}
func (p *Point) down() {
	if p.dirty <= 0 {
		return
	}
	pl := p.left()
	pr := p.right()
	if pl != nil {
		pl.dirty += p.dirty
		pl.addValue(p.dirty)
	}
	if pr != nil {
		pr.dirty += p.dirty
		pr.addValue(p.dirty)
	}
	p.dirty = 0
	p.refleshMin()
}
func (p *Point) add(l, r int, value int) {
	if l > p.r || r < p.l {
		return
	}
	if l <= p.l && p.r <= r {
		p.addValue(value)
		p.dirty += value
		return
	}
	pl := p.left()
	pr := p.right()
	p.down()
	if pl != nil {
		pl.add(l, r, value)
	}
	if pr != nil {
		pr.add(l, r, value)
	}
	p.refleshMin()
}
func solveE(mat []int, n int, segs Segs) (Segs, int64) {
	fatory = newFatory(n)

	maxx := make([]int, n)
	minn := mat[n-1]
	maxx[n-1] = mat[n-1]
	for i := n - 2; i >= 0; i-- {
		if mat[i] > maxx[i+1] {
			maxx[i] = mat[i]
		} else {
			maxx[i] = maxx[i+1]
		}
		if mat[i] < minn {
			minn = mat[i]
		}
	}
	partline := -1
	res := int64(maxx[0] - minn)
	root := fatory.newPoint()
	root.l = 1
	root.r = n
	//fmt.Printf("root.min = %d l=%d r=%d\n",root.min,root.l,root.r)
	for i := 0; i < n; i++ {
		root.add(i+1, i+1, mat[i])
		//	fmt.Printf("i=%d root.min = %d value=%d\n", i,root.min,mat[i])
	}
	//fmt.Printf("root.min = %d\n", root.min)

	sort.Sort(segs)
	dbMax := 0
	for i := 0; i < len(segs); i++ {
		if segs[i].r >= n {
			continue
		}
		root.add(segs[i].l, segs[i].r, -1)
		tmpm, _ := root.queryMin(1, segs[i].r)
		//	fmt.Printf("i=%d segs.l = %d segs.r = %d min=%d maxx=%d\n", i, segs[i].l, segs[i].r, tmpm, maxx[segs[i].r])
		if res < int64(maxx[segs[i].r])-tmpm {
			partline = i
			res = int64(maxx[segs[i].r]) - tmpm
			dbMax = maxx[segs[i].r]
		}
		if debug && (segs[i].id ==36||segs[i].id ==55||segs[i].id ==76||segs[i].id ==11||segs[i].id ==37||segs[i].id ==95||segs[i].id ==6||segs[i].id ==41){
			logger+=fmt.Sprintf("i=%d maxx=%d min=%d l=%d r=%d root.min=%d\n",segs[i].id,maxx[segs[i].r],tmpm,segs[i].l,segs[i].r,root.min)
			//logger += "i=" + strconv.Itoa(segs[i].id) + " maxx = " + strconv.Itoa(maxx[segs[i].r]) + " min=" + strconv.Itoa(int(tmpm)) + "\n"
		}
	}
	if debug && partline > -1 {
		logger += "partline=" + strconv.Itoa(segs[partline].r) + " maxx = " + strconv.Itoa(dbMax) + " min=" + strconv.Itoa(dbMax-int(res)) + "\n"
		//	fmt.Printf("partline=%d maxx = %d min=%d\n", segs[partline].r, dbMax,res-int64(dbMax))
	}
	as := make(Segs, partline+1)
	for i := 0; i <= partline; i++ {
		as[i] = Seg{
			l:segs[i].l,
			r:segs[i].r,
			id:segs[i].id,
		}
	}
	//	fmt.Printf("as = %v res=%v\n",as,res)
	return as, res
}
func reverse(mat []int, segs Segs) {
	//	fmt.Printf("before mat=%v seg=%v\n",mat,segs)
	n := len(mat)
	m := len(segs)
	for i := 0; i < n-i-1; i++ {
		tmp := mat[i]
		mat[i] = mat[n-i-1]
		mat[n-i-1] = tmp
	}
	for i := 0; i < m; i++ {
		tmp := segs[i].l
		segs[i].l = segs[i].r
		segs[i].r = tmp
		segs[i].l = n - segs[i].l + 1
		segs[i].r = n - segs[i].r + 1
	}

}
func tmpseg(segs Segs) Segs {
	lens := len(goods)
	res := make(Segs, 0)
	for j := 0; j < len(segs); j++ {
		for i := 0; i < lens; i++ {
			if goods[i] == segs[j].id {
				res = append(res, segs[j])
				break
			}
		}
	}
	return res
}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	if n == 10000 && m == 100 {
		debug = true
	}
	//	debug=true
	mat := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d", &mat[i])
	}
	fmt.Fscanf(buf, "\n")
	seg := make(Segs, m)
	for i := 0; i < m; i++ {
		fmt.Fscanf(buf, "%d %d\n", &seg[i].l, &seg[i].r)
		seg[i].id = i + 1
	}
	pl, ans := solveE(mat, n, seg)
	reverse(mat, seg)
	//	fmt.Printf("rev mat=%v seg=%d\n",mat,seg)
	pl2, ans2 := solveE(mat, n, seg)

	if ans < ans2 {
		fmt.Printf("%d\n", ans2)
		fmt.Printf("%d\n", len(pl2))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl2[i].id)
		}
		fmt.Printf("\n")
		if len(pl) > 0 && debug {
			c, _ := check(mat, tmpseg(seg))
			c,_ = check(mat, pl2)
			if c != ans2 {
				fmt.Printf("ERROR c = %d ans=%d\n", c, ans2)
			}
			fmt.Printf("logger--\n%s\n", logger)
		}
	} else {
		fmt.Printf("%d\n", ans)
		fmt.Printf("%d\n", len(pl))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl[i].id)
		}
		fmt.Printf("\n")

		if len(pl) > 0 && debug {
			reverse(mat, seg)
			c, _ := check(mat, tmpseg(seg))
			c, _ = check(mat, pl)

			if c != ans {
				fmt.Printf("2ERROR c = %d ans=%d\n", c, ans)
			}
			fmt.Printf("%s\n", logger)
		}
	}

}
func check(mat []int, pl Segs) (int64, int) {
	n := len(mat)
	m := len(pl)
	if m <= 0 {
		return 0, 0
	}
	maxx := -1
	minn := 10000000
	//minw := -1
	for i := 0; i < n; i++ {
		in := 0
		for j := 0; j < m; j++ {
			if pl[j].l > i+1 || pl[j].r < i+1 {
				continue
			}
			in++
		}
		if in == 0 {
			if maxx == -1 || mat[maxx] < mat[i] {
				maxx = i
			}
		}
		if minn > mat[i]-in {
			minn = mat[i] - in
			//minw = i
		}

	}
	if debug {
		maxxr := 0
		for i := 0; i < m; i++ {
			if pl[i].l <= 3119 && pl[i].r >= 3119{
			//	fmt.Printf("range %d %d %d\n", pl[i].l, pl[i].r,pl[i].id)
			}

			if pl[i].r > maxxr {
				maxxr = pl[i].r
			}
		}
//		fmt.Printf("check maxw = %d  minw = %d maxx=%d min=%d mat[minn]=%d maxxr=%d\n", maxx+1, minw+1, mat[maxx], minn, mat[minw],maxxr)
	}
	return int64(mat[maxx] - minn), mat[maxx]
}

/**

5 3
1 2 2 -2 3
3 5
1 5
3 5
 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

var (
	fatory *PointFatory
	debug  = false
	logger = ""
	goods  = [70]int{80, 41, 72, 28, 77, 62, 6, 14, 78, 97, 93, 48, 4, 3, 25, 94, 83, 10, 53, 22, 54, 70, 29, 27, 87, 45, 43, 76, 31, 30, 42, 20, 12, 2, 40, 16, 100, 64, 86, 44, 49, 56, 33, 11, 46, 18, 75, 5, 69, 55, 37, 50, 92, 73, 21, 57, 13, 35, 26, 65, 81, 95, 36, 32, 15, 60, 68, 89, 98, 38}
)

const (
	MAX int64 = int64(1000100) * 300
)

type Point struct {
	l, r   int
	dirty  int
	min    int64
	cl, cr *Point
}
type Seg struct {
	l, r int
	id   int
}
type Segs []Seg

func (s Segs) Len() int {
	return len(s)
}
func (s Segs) Swap(a, b int) {
	tmp := s[a].l
	s[a].l = s[b].l
	s[b].l = tmp

	tmp = s[a].r
	s[a].r = s[b].r
	s[b].r = tmp

	tmp = s[a].id
	s[a].id = s[b].id
	s[b].id = tmp
}
func (s Segs) Less(a, b int) bool {
	if s[a].r < s[b].r {
		return true
	}
	return false
}

type PointFatory struct {
	p     []Point
	front int
	len   int
}

func (p *PointFatory) newPoint() *Point {
	return &Point{}
	//if p.front >= p.len {
	//	p.p = append(p.p, make([]Point, p.len)...)
	//	p.len = len(p.p)
	//}
	//res := &p.p[p.front]
	//p.front++
	//return res
}
func newFatory(n int) *PointFatory {
	return &PointFatory{
		p:   make([]Point, n),
		len: n,
	}
}
func (p *Point) left() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cl == nil {
		p.cl = fatory.newPoint()
		p.cl.l = p.l
		p.cl.r = (p.l + p.r) / 2
		p.cl.min = MAX
	}
	return p.cl
}
func (p *Point) right() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cr == nil {
		p.cr = fatory.newPoint()
		p.cr.l = (p.l+p.r)/2 + 1
		p.cr.r = p.r
		p.cl.min = MAX
	}
	return p.cr
}
func (p *Point) refleshMin() {
	if p.left() == nil && p.right() == nil {
		return
	}
	if p.left() == nil {
		p.min = p.right().min
	} else if p.right() == nil {
		p.min = p.left().min
	} else if p.left().min < p.right().min {
		p.min = p.left().min
	} else {
		p.min = p.right().min
	}

}
func (p *Point) queryMin(l, r int) (int64, bool) {
	p.down()
	if l <= p.l && p.r <= r {
		return p.min, true
	}
	if l > p.r || r < p.l {
		return -1, false
	}
	var res int64 = 0
	find := false
	if p.left() != nil {
		leftmin, flag := p.left().queryMin(l, r)
		if flag {
			res = leftmin
			find = true
		}
	}
	if p.right() != nil {
		rightmin, flag := p.right().queryMin(l, r)
		if flag && (find == false || rightmin < res) {
			res = rightmin
		}
	}
	return res, true

}
func (p *Point) addValue(value int) {
	if p.min >= MAX {
		p.min = int64(value)
	} else {
		p.min += int64(value)
	}
}
func (p *Point) down() {
	if p.dirty <= 0 {
		return
	}
	pl := p.left()
	pr := p.right()
	if pl != nil {
		pl.dirty += p.dirty
		pl.addValue(p.dirty)
	}
	if pr != nil {
		pr.dirty += p.dirty
		pr.addValue(p.dirty)
	}
	p.dirty = 0
	//p.refleshMin()
}
func (p *Point) add(l, r int, value int) {
	if l > p.r || r < p.l {
		return
	}
	if l <= p.l && p.r <= r {
		p.addValue(value)
		p.dirty += value
		return
	}
	pl := p.left()
	pr := p.right()
	p.down()
	if pl != nil {
		pl.add(l, r, value)
	}
	if pr != nil {
		pr.add(l, r, value)
	}
	tmin := p.min
	p.refleshMin()
	if debug && p.min > tmin {
		fmt.Printf(" tmin=%d nowmin=%d pl=%d pr=%d l=%d r=%d value=%d\n", tmin, p.min,p.l,p.r,l,r,value)
	}
}
func solveE(mat []int, n int, segs Segs) (Segs, int64) {
	fatory = newFatory(n)

	maxx := make([]int, n)
	minn := mat[n-1]
	maxx[n-1] = mat[n-1]
	for i := n - 2; i >= 0; i-- {
		if mat[i] > maxx[i+1] {
			maxx[i] = mat[i]
		} else {
			maxx[i] = maxx[i+1]
		}
		if mat[i] < minn {
			minn = mat[i]
		}
	}
	partline := -1
	res := int64(maxx[0] - minn)
	root := fatory.newPoint()
	root.l = 1
	root.r = n
	//fmt.Printf("root.min = %d l=%d r=%d\n",root.min,root.l,root.r)
	for i := 0; i < n; i++ {
		root.add(i+1, i+1, mat[i])
		//	fmt.Printf("i=%d root.min = %d value=%d\n", i,root.min,mat[i])
	}
	//fmt.Printf("root.min = %d\n", root.min)

	sort.Sort(segs)
	dbMax := 0
	for i := 0; i < len(segs); i++ {
		if segs[i].r >= n {
			continue
		}
		root.add(segs[i].l, segs[i].r, -1)
		tmpm, _ := root.queryMin(1, segs[i].r)
		//	fmt.Printf("i=%d segs.l = %d segs.r = %d min=%d maxx=%d\n", i, segs[i].l, segs[i].r, tmpm, maxx[segs[i].r])
		if res < int64(maxx[segs[i].r])-tmpm {
			partline = i
			res = int64(maxx[segs[i].r]) - tmpm
			dbMax = maxx[segs[i].r]
		}
		if debug && (segs[i].id == 36 || segs[i].id == 55 || segs[i].id == 76 || segs[i].id == 11 || segs[i].id == 37 || segs[i].id == 95 || segs[i].id == 6 || segs[i].id == 41) {
			logger += fmt.Sprintf("i=%d maxx=%d min=%d l=%d r=%d root.min=%d\n", segs[i].id, maxx[segs[i].r], tmpm, segs[i].l, segs[i].r, root.min)
			//logger += "i=" + strconv.Itoa(segs[i].id) + " maxx = " + strconv.Itoa(maxx[segs[i].r]) + " min=" + strconv.Itoa(int(tmpm)) + "\n"
		}
	}
	if debug && partline > -1 {
		logger += "partline=" + strconv.Itoa(segs[partline].r) + " maxx = " + strconv.Itoa(dbMax) + " min=" + strconv.Itoa(dbMax-int(res)) + "\n"
		//	fmt.Printf("partline=%d maxx = %d min=%d\n", segs[partline].r, dbMax,res-int64(dbMax))
	}
	as := make(Segs, partline+1)
	for i := 0; i <= partline; i++ {
		as[i] = Seg{
			l:  segs[i].l,
			r:  segs[i].r,
			id: segs[i].id,
		}
	}
	//	fmt.Printf("as = %v res=%v\n",as,res)
	return as, res
}
func reverse(mat []int, segs Segs) {
	//	fmt.Printf("before mat=%v seg=%v\n",mat,segs)
	n := len(mat)
	m := len(segs)
	for i := 0; i < n-i-1; i++ {
		tmp := mat[i]
		mat[i] = mat[n-i-1]
		mat[n-i-1] = tmp
	}
	for i := 0; i < m; i++ {
		tmp := segs[i].l
		segs[i].l = segs[i].r
		segs[i].r = tmp
		segs[i].l = n - segs[i].l + 1
		segs[i].r = n - segs[i].r + 1
	}

}
func tmpseg(segs Segs) Segs {
	lens := len(goods)
	res := make(Segs, 0)
	for j := 0; j < len(segs); j++ {
		for i := 0; i < lens; i++ {
			if goods[i] == segs[j].id {
				res = append(res, segs[j])
				break
			}
		}
	}
	return res
}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	if n == 10000 && m == 100 {
		debug = true
	}
	//	debug=true
	mat := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d", &mat[i])
	}
	fmt.Fscanf(buf, "\n")
	seg := make(Segs, m)
	for i := 0; i < m; i++ {
		fmt.Fscanf(buf, "%d %d\n", &seg[i].l, &seg[i].r)
		seg[i].id = i + 1
	}
	pl, ans := solveE(mat, n, seg)
	reverse(mat, seg)
	//	fmt.Printf("rev mat=%v seg=%d\n",mat,seg)
	pl2, ans2 := solveE(mat, n, seg)

	if ans < ans2 {
		fmt.Printf("%d\n", ans2)
		fmt.Printf("%d\n", len(pl2))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl2[i].id)
		}
		fmt.Printf("\n")
		if len(pl) > 0 && debug {
			c, _ := check(mat, tmpseg(seg))
			c, _ = check(mat, pl2)
			if c != ans2 {
				fmt.Printf("ERROR c = %d ans=%d\n", c, ans2)
			}
			fmt.Printf("logger--\n%s\n", logger)
		}
	} else {
		fmt.Printf("%d\n", ans)
		fmt.Printf("%d\n", len(pl))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl[i].id)
		}
		fmt.Printf("\n")

		if len(pl) > 0 && debug {
			reverse(mat, seg)
			c, _ := check(mat, tmpseg(seg))
			c, _ = check(mat, pl)

			if c != ans {
				fmt.Printf("2ERROR c = %d ans=%d\n", c, ans)
			}
			fmt.Printf("%s\n", logger)
		}
	}

}
func check(mat []int, pl Segs) (int64, int) {
	n := len(mat)
	m := len(pl)
	if m <= 0 {
		return 0, 0
	}
	maxx := -1
	minn := 10000000
	//minw := -1
	for i := 0; i < n; i++ {
		in := 0
		for j := 0; j < m; j++ {
			if pl[j].l > i+1 || pl[j].r < i+1 {
				continue
			}
			in++
		}
		if in == 0 {
			if maxx == -1 || mat[maxx] < mat[i] {
				maxx = i
			}
		}
		if minn > mat[i]-in {
			minn = mat[i] - in
			//minw = i
		}

	}
	if debug {
		maxxr := 0
		for i := 0; i < m; i++ {
			if pl[i].l <= 3119 && pl[i].r >= 3119 {
				//	fmt.Printf("range %d %d %d\n", pl[i].l, pl[i].r,pl[i].id)
			}

			if pl[i].r > maxxr {
				maxxr = pl[i].r
			}
		}
		//		fmt.Printf("check maxw = %d  minw = %d maxx=%d min=%d mat[minn]=%d maxxr=%d\n", maxx+1, minw+1, mat[maxx], minn, mat[minw],maxxr)
	}
	return int64(mat[maxx] - minn), mat[maxx]
}

/**

5 3
1 2 2 -2 3
3 5
1 5
3 5
 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

var (
	fatory *PointFatory
)

const (
	MAX = 1000100*300
)

type Point struct {
	l, r   int
	dirty  int
	min    int64
	cl, cr *Point
}
type Seg struct {
	l, r int
	id   int
}
type Segs []Seg

func (s Segs) Len() int {
	return len(s)
}
func (s Segs) Swap(a, b int) {
	tmp := s[a].l
	s[a].l = s[b].l
	s[b].l = tmp

	tmp = s[a].r
	s[a].r = s[b].r
	s[b].r = tmp

	tmp = s[a].id
	s[a].id = s[b].id
	s[b].id = tmp
}
func (s Segs) Less(a, b int) bool {
	if s[a].r < s[b].r {
		return true
	}
	return false
}

type PointFatory struct {
	p     []Point
	front int
	len   int
}

func (p *PointFatory) newPoint() *Point {
	if p.front >= p.len {
		p.p = append(p.p, make([]Point, p.len)...)
		p.len = len(p.p)
	}
	res := &p.p[p.front]
	p.front++
	return res
}
func newFatory(n int) *PointFatory {
	return &PointFatory{
		p:   make([]Point, n),
		len: n,
	}
}
func (p *Point) left() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cl == nil {
		p.cl = fatory.newPoint()
		p.cl.l = p.l
		p.cl.r = (p.l + p.r) / 2
		p.cl.min = MAX
	}
	return p.cl
}
func (p *Point) right() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cr == nil {
		p.cr = fatory.newPoint()
		p.cr.l = (p.l+p.r)/2 + 1
		p.cr.r = p.r
		p.cl.min = MAX
	}
	return p.cr
}
func (p *Point) refleshMin() {
	if p.left() == nil && p.right() == nil {
		return
	}
	if p.left() == nil {
		p.min = p.right().min
	} else if p.right() == nil {
		p.min = p.left().min
	} else if p.left().min < p.right().min {
		p.min = p.left().min
	} else {
		p.min = p.right().min
	}

}
func (p *Point) queryMin(l, r int) (int64, bool) {
	p.down()
	if l <= p.l && p.r <= r {
		return p.min, true
	}
	if l > p.r || r < p.l {
		return -1, false
	}
	var res int64 = 0
	find := false
	if p.left() != nil {
		leftmin, flag := p.left().queryMin(l, r)
		if flag {
			res = leftmin
			find = true
		}
	}
	if p.right() != nil {
		rightmin, flag := p.right().queryMin(l, r)
		if flag && (find == false || rightmin < res) {
			res = rightmin
		}
	}
	return res, true

}
func (p *Point) addValue(value int) {
	if p.min >= MAX {
		p.min = int64(value)
	} else {
		p.min += int64(value)
	}
}
func (p *Point) down() {
	if p.dirty <= 0 {
		return
	}
	pl := p.left()
	pr := p.right()
	if pl != nil {
		pl.dirty += p.dirty
		pl.addValue(p.dirty)
	}
	if pr != nil {
		pr.dirty += p.dirty
		pr.addValue(p.dirty)
	}
	p.dirty = 0
	p.refleshMin()
}
func (p *Point) add(l, r int, value int) {
	if l > p.r || r < p.l {
		return
	}
	if l <= p.l && p.r <= r {
		p.addValue(value)
		p.dirty += value
		return
	}
	pl := p.left()
	pr := p.right()
	p.down()
	if pl != nil {
		pl.add(l, r, value)
	}
	if pr != nil {
		pr.add(l, r, value)
	}
	p.refleshMin()
}
func solveE(mat []int, n int, segs Segs) ([]int, int64) {
	fatory = newFatory(n)

	maxx := make([]int, n)
	minn := mat[n-1]
	maxx[n-1] = mat[n-1]
	for i := n - 2; i >= 0; i-- {
		if mat[i] > maxx[i+1] {
			maxx[i] = mat[i]
		} else {
			maxx[i] = maxx[i+1]
		}
		if mat[i] < minn {
			minn = mat[i]
		}
	}
	partline := -1
	res := int64(maxx[0] - minn)
	root := fatory.newPoint()
	root.l = 1
	root.r = n
	//fmt.Printf("root.min = %d l=%d r=%d\n",root.min,root.l,root.r)
	for i := 0; i < n; i++ {
		root.add(i+1, i+1, mat[i])
		//	fmt.Printf("i=%d root.min = %d value=%d\n", i,root.min,mat[i])
	}
	//fmt.Printf("root.min = %d\n", root.min)

	sort.Sort(segs)
	for i := 0; i < len(segs); i++ {
		if segs[i].r >= n {
			continue
		}
		root.add(segs[i].l, segs[i].r, -1)
		tmpm, _ := root.queryMin(1, segs[i].r)
		//	fmt.Printf("i=%d segs.l = %d segs.r = %d min=%d maxx=%d\n", i, segs[i].l, segs[i].r, tmpm, maxx[segs[i].r])
		if res < int64(maxx[segs[i].r])-tmpm {
			partline = i
			res = int64(maxx[segs[i].r]) - tmpm
		}
	}
	as := make([]int, partline+1)
	for i := 0; i <= partline; i++ {
		as[i] = segs[i].id
	}
	//	fmt.Printf("as = %v res=%v\n",as,res)
	return as, res
}
func reverse(mat []int, segs Segs) {
	n := len(mat)
	m := len(segs)
	for i := 0; i < n-i-1; i++ {
		tmp := mat[i]
		mat[i] = mat[n-i-1]
		mat[n-i-1] = tmp
	}
	for i := 0; i < m; i++ {
		tmp := segs[i].l
		segs[i].l = segs[i].r
		segs[i].r = tmp
		segs[i].l = n - segs[i].l + 1
		segs[i].r = n - segs[i].r + 1
	}

}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	mat := make([]int, n+1)
	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d", &mat[i])
	}
	fmt.Fscanf(buf, "\n")
	seg := make(Segs, m)
	for i := 0; i < m; i++ {
		fmt.Fscanf(buf, "%d %d\n", &seg[i].l, &seg[i].r)
		seg[i].id = i + 1
	}
	pl, ans := solveE(mat, n, seg)
	reverse(mat, seg)
	pl2, ans2 := solveE(mat, n, seg)
	if ans < ans2 {
		pl = pl2
		ans = ans2
	}
	fmt.Printf("%d\n", ans)
	fmt.Printf("%d\n", len(pl))
	for i := 0; i < len(pl); i++ {
		fmt.Printf("%d ", pl[i])
	}
	fmt.Printf("\n")

}

/**

5 3
1 2 2 -2 3
3 5
1 5
3 5
 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

var (
	fatory *PointFatory
	debug  = false
	logger = ""
	goods  = [70]int{80, 41, 72, 28, 77, 62, 6, 14, 78, 97, 93, 48, 4, 3, 25, 94, 83, 10, 53, 22, 54, 70, 29, 27, 87, 45, 43, 76, 31, 30, 42, 20, 12, 2, 40, 16, 100, 64, 86, 44, 49, 56, 33, 11, 46, 18, 75, 5, 69, 55, 37, 50, 92, 73, 21, 57, 13, 35, 26, 65, 81, 95, 36, 32, 15, 60, 68, 89, 98, 38}
)

const (
	MAX = 1000100 * 300
)

type Point struct {
	l, r   int
	dirty  int
	min    int64
	cl, cr *Point
}
type Seg struct {
	l, r int
	id   int
}
type Segs []Seg

func (s Segs) Len() int {
	return len(s)
}
func (s Segs) Swap(a, b int) {
	tmp := s[a].l
	s[a].l = s[b].l
	s[b].l = tmp

	tmp = s[a].r
	s[a].r = s[b].r
	s[b].r = tmp

	tmp = s[a].id
	s[a].id = s[b].id
	s[b].id = tmp
}
func (s Segs) Less(a, b int) bool {
	if s[a].r < s[b].r {
		return true
	}
	return false
}

type PointFatory struct {
	p     []Point
	front int
	len   int
}

func (p *PointFatory) newPoint() *Point {
	if p.front >= p.len {
		p.p = append(p.p, make([]Point, p.len)...)
		p.len = len(p.p)
	}
	res := &p.p[p.front]
	p.front++
	return res
}
func newFatory(n int) *PointFatory {
	return &PointFatory{
		p:   make([]Point, n),
		len: n,
	}
}
func (p *Point) left() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cl == nil {
		p.cl = fatory.newPoint()
		p.cl.l = p.l
		p.cl.r = (p.l + p.r) / 2
		p.cl.min = MAX
	}
	return p.cl
}
func (p *Point) right() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cr == nil {
		p.cr = fatory.newPoint()
		p.cr.l = (p.l+p.r)/2 + 1
		p.cr.r = p.r
		p.cl.min = MAX
	}
	return p.cr
}
func (p *Point) refleshMin() {
	if p.left() == nil && p.right() == nil {
		return
	}
	if p.left() == nil {
		p.min = p.right().min
	} else if p.right() == nil {
		p.min = p.left().min
	} else if p.left().min < p.right().min {
		p.min = p.left().min
	} else {
		p.min = p.right().min
	}

}
func (p *Point) queryMin(l, r int) (int64, bool) {
	p.down()
	if l <= p.l && p.r <= r {
		return p.min, true
	}
	if l > p.r || r < p.l {
		return -1, false
	}
	var res int64 = 0
	find := false
	if p.left() != nil {
		leftmin, flag := p.left().queryMin(l, r)
		if flag {
			res = leftmin
			find = true
		}
	}
	if p.right() != nil {
		rightmin, flag := p.right().queryMin(l, r)
		if flag && (find == false || rightmin < res) {
			res = rightmin
		}
	}
	return res, true

}
func (p *Point) addValue(value int) {
	if p.min >= MAX {
		p.min = int64(value)
	} else {
		p.min += int64(value)
	}
}
func (p *Point) down() {
	if p.dirty <= 0 {
		return
	}
	pl := p.left()
	pr := p.right()
	if pl != nil {
		pl.dirty += p.dirty
		pl.addValue(p.dirty)
	}
	if pr != nil {
		pr.dirty += p.dirty
		pr.addValue(p.dirty)
	}
	p.dirty = 0
	p.refleshMin()
}
func (p *Point) add(l, r int, value int) {
	if l > p.r || r < p.l {
		return
	}
	if l <= p.l && p.r <= r {
		p.addValue(value)
		p.dirty += value
		return
	}
	pl := p.left()
	pr := p.right()
	p.down()
	if pl != nil {
		pl.add(l, r, value)
	}
	if pr != nil {
		pr.add(l, r, value)
	}
	p.refleshMin()
}
func solveE(mat []int, n int, segs Segs) (Segs, int64) {
	fatory = newFatory(n)

	maxx := make([]int, n)
	minn := mat[n-1]
	maxx[n-1] = mat[n-1]
	for i := n - 2; i >= 0; i-- {
		if mat[i] > maxx[i+1] {
			maxx[i] = mat[i]
		} else {
			maxx[i] = maxx[i+1]
		}
		if mat[i] < minn {
			minn = mat[i]
		}
	}
	partline := -1
	res := int64(maxx[0] - minn)
	root := fatory.newPoint()
	root.l = 1
	root.r = n
	//fmt.Printf("root.min = %d l=%d r=%d\n",root.min,root.l,root.r)
	for i := 0; i < n; i++ {
		root.add(i+1, i+1, mat[i])
		//	fmt.Printf("i=%d root.min = %d value=%d\n", i,root.min,mat[i])
	}
	//fmt.Printf("root.min = %d\n", root.min)

	sort.Sort(segs)
	dbMax := 0
	for i := 0; i < len(segs); i++ {
		if segs[i].r >= n {
			continue
		}
		root.add(segs[i].l, segs[i].r, -1)
		tmpm, _ := root.queryMin(1, segs[i].r)
		//	fmt.Printf("i=%d segs.l = %d segs.r = %d min=%d maxx=%d\n", i, segs[i].l, segs[i].r, tmpm, maxx[segs[i].r])
		if res < int64(maxx[segs[i].r])-tmpm {
			partline = i
			res = int64(maxx[segs[i].r]) - tmpm
			dbMax = maxx[segs[i].r]
		}
		if debug && (segs[i].id ==36||segs[i].id ==55||segs[i].id ==76){
			logger += "i=" + strconv.Itoa(segs[i].id) + " maxx = " + strconv.Itoa(maxx[segs[i].r]) + " min=" + strconv.Itoa(int(tmpm)) + "\n"
		}
	}
	if debug && partline > -1 {
		logger += "partline=" + strconv.Itoa(segs[partline].r) + " maxx = " + strconv.Itoa(dbMax) + " min=" + strconv.Itoa(dbMax-int(res)) + "\n"
		//	fmt.Printf("partline=%d maxx = %d min=%d\n", segs[partline].r, dbMax,res-int64(dbMax))
	}
	as := make(Segs, partline+1)
	for i := 0; i <= partline; i++ {
		as[i] = Seg{
			l:segs[i].l,
			r:segs[i].r,
			id:segs[i].id,
		}
	}
	//	fmt.Printf("as = %v res=%v\n",as,res)
	return as, res
}
func reverse(mat []int, segs Segs) {
	//	fmt.Printf("before mat=%v seg=%v\n",mat,segs)
	n := len(mat)
	m := len(segs)
	for i := 0; i < n-i-1; i++ {
		tmp := mat[i]
		mat[i] = mat[n-i-1]
		mat[n-i-1] = tmp
	}
	for i := 0; i < m; i++ {
		tmp := segs[i].l
		segs[i].l = segs[i].r
		segs[i].r = tmp
		segs[i].l = n - segs[i].l + 1
		segs[i].r = n - segs[i].r + 1
	}

}
func tmpseg(segs Segs) Segs {
	lens := len(goods)
	res := make(Segs, 0)
	for j := 0; j < len(segs); j++ {
		for i := 0; i < lens; i++ {
			if goods[i] == segs[j].id {
				res = append(res, segs[j])
				break
			}
		}
	}
	return res
}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	if n == 10000 && m == 100 {
		debug = true
	}
	//	debug=true
	mat := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d", &mat[i])
	}
	fmt.Fscanf(buf, "\n")
	seg := make(Segs, m)
	for i := 0; i < m; i++ {
		fmt.Fscanf(buf, "%d %d\n", &seg[i].l, &seg[i].r)
		seg[i].id = i + 1
	}
	pl, ans := solveE(mat, n, seg)
	reverse(mat, seg)
	//	fmt.Printf("rev mat=%v seg=%d\n",mat,seg)
	pl2, ans2 := solveE(mat, n, seg)

	if ans < ans2 {
		fmt.Printf("%d\n", ans2)
		fmt.Printf("%d\n", len(pl2))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl2[i].id)
		}
		fmt.Printf("\n")
		if len(pl) > 0 && debug {
			c, _ := check(mat, tmpseg(seg))
			c,_ = check(mat, pl2)
			if c != ans2 {
				fmt.Printf("ERROR c = %d ans=%d\n", c, ans2)
			}
			fmt.Printf("logger--\n%s\n", logger)
		}
	} else {
		fmt.Printf("%d\n", ans)
		fmt.Printf("%d\n", len(pl))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl[i].id)
		}
		fmt.Printf("\n")

		if len(pl) > 0 && debug {
			reverse(mat, seg)
			c, _ := check(mat, tmpseg(seg))
			c, _ = check(mat, pl)

			if c != ans {
				fmt.Printf("2ERROR c = %d ans=%d\n", c, ans)
			}
			fmt.Printf("%s\n", logger)
		}
	}

}
func check(mat []int, pl Segs) (int64, int) {
	n := len(mat)
	m := len(pl)
	if m <= 0 {
		return 0, 0
	}
	maxx := -1
	minn := 10000000
	minw := -1
	for i := 0; i < n; i++ {
		in := 0
		for j := 0; j < m; j++ {
			if pl[j].l > i+1 || pl[j].r < i+1 {
				continue
			}
			in++
		}
		if in == 0 {
			if maxx == -1 || mat[maxx] < mat[i] {
				maxx = i
			}
		}
		if minn > mat[i]-in {
			minn = mat[i] - in
			minw = i
		}

	}
	if debug {
		maxxr := 0
		for i := 0; i < m; i++ {
			if pl[i].l <= 3119 && pl[i].r >= 3119{
				fmt.Printf("range %d %d %d\n", pl[i].l, pl[i].r,pl[i].id)
			}

			if pl[i].r > maxxr {
				maxxr = pl[i].r
			}
		}
		fmt.Printf("check maxw = %d  minw = %d maxx=%d min=%d mat[minn]=%d maxxr=%d\n", maxx+1, minw+1, mat[maxx], minn, mat[minw],maxxr)
	}
	return int64(mat[maxx] - minn), mat[maxx]
}

/**

5 3
1 2 2 -2 3
3 5
1 5
3 5
 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

var (
	fatory *PointFatory
	debug  = false
	logger = ""
	goods  = [70]int{80, 41, 72, 28, 77, 62, 6, 14, 78, 97, 93, 48, 4, 3, 25, 94, 83, 10, 53, 22, 54, 70, 29, 27, 87, 45, 43, 76, 31, 30, 42, 20, 12, 2, 40, 16, 100, 64, 86, 44, 49, 56, 33, 11, 46, 18, 75, 5, 69, 55, 37, 50, 92, 73, 21, 57, 13, 35, 26, 65, 81, 95, 36, 32, 15, 60, 68, 89, 98, 38}
)

const (
	MAX int64 = int64(3000100)
)

type Point struct {
	l, r   int
	dirty  int
	min    int64
	cl, cr *Point
}
type Seg struct {
	l, r int
	id   int
}
type Segs []Seg

func (s Segs) Len() int {
	return len(s)
}
func (s Segs) Swap(a, b int) {
	tmp := s[a].l
	s[a].l = s[b].l
	s[b].l = tmp

	tmp = s[a].r
	s[a].r = s[b].r
	s[b].r = tmp

	tmp = s[a].id
	s[a].id = s[b].id
	s[b].id = tmp
}
func (s Segs) Less(a, b int) bool {
	if s[a].r < s[b].r {
		return true
	}
	return false
}

type PointFatory struct {
	p     []Point
	front int
	len   int
}

func (p *PointFatory) newPoint() *Point {
	return &Point{}
	//if p.front >= p.len {
	//	p.p = append(p.p, make([]Point, p.len)...)
	//	p.len = len(p.p)
	//}
	//res := &p.p[p.front]
	//p.front++
	//return res
}
func newFatory(n int) *PointFatory {
	return &PointFatory{
		p:   make([]Point, n),
		len: n,
	}
}
func (p *Point) left() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cl == nil {
		p.cl = fatory.newPoint()
		p.cl.l = p.l
		p.cl.r = (p.l + p.r) / 2
		p.cl.min = MAX
	}
	return p.cl
}
func (p *Point) right() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cr == nil {
		p.cr = fatory.newPoint()
		p.cr.l = (p.l+p.r)/2 + 1
		p.cr.r = p.r
		p.cr.min = MAX
	}
	return p.cr
}
func (p *Point) refleshMin() {
	if p.left() == nil && p.right() == nil {
		return
	}
	if p.left() == nil {
		p.min = p.right().min
	} else if p.right() == nil {
		p.min = p.left().min
	} else if p.left().min < p.right().min {
		p.min = p.left().min
	} else {
		p.min = p.right().min
	}
	if p.min == 0 &&debug{
		fmt.Printf("min=0 l=%d r=%d dirty=%d\n",p.l,p.r,p.dirty)
	}

}
func (p *Point) queryMin(l, r int) (int64, bool) {
	p.down()
	if l <= p.l && p.r <= r {
		return p.min, true
	}
	if l > p.r || r < p.l {
		return -1, false
	}
	var res int64 = 0
	find := false
	if p.left() != nil {
		leftmin, flag := p.left().queryMin(l, r)
		if flag {
			res = leftmin
			find = true
		}
	}
	if p.right() != nil {
		rightmin, flag := p.right().queryMin(l, r)
		if flag && (find == false || rightmin < res) {
			res = rightmin
		}
	}
	return res, true

}
func (p *Point) addValue(value int) {
	if p.min >= MAX {
		p.min = int64(value)
	} else {
		p.min += int64(value)
	}
	if p.min == 0 &&debug{
		fmt.Printf("min=0 l=%d r=%d dirty=%d value=%d\n",p.l,p.r,p.dirty,value)
	}
}
func (p *Point) down() {
	if p.dirty == 0 {
		return
	}
	pl := p.left()
	pr := p.right()
	if pl != nil {
		pl.dirty += p.dirty
		pl.addValue(p.dirty)
	}
	if pr != nil {
		pr.dirty += p.dirty
		pr.addValue(p.dirty)
	}
	p.dirty = 0
	//p.refleshMin()
}
func (p *Point) add(l, r int, value int) {
	if l > p.r || r < p.l {
		return
	}
	if l <= p.l && p.r <= r {
		p.addValue(value)
		p.dirty += value
		return
	}
	pl := p.left()
	pr := p.right()
	p.down()
	if pl != nil {
		pl.add(l, r, value)
	}
	if pr != nil {
		pr.add(l, r, value)
	}
	tmin := p.min
	p.refleshMin()
	if debug && p.min > tmin {
		fmt.Printf(" tmin=%d nowmin=%d pl=%d pr=%d l=%d r=%d value=%d\n", tmin, p.min,p.l,p.r,l,r,value)
	}
}
func solveE(mat []int, n int, segs Segs) (Segs, int64) {
	fatory = newFatory(n)

	maxx := make([]int, n)
	minn := mat[n-1]
	maxx[n-1] = mat[n-1]
	for i := n - 2; i >= 0; i-- {
		if mat[i] > maxx[i+1] {
			maxx[i] = mat[i]
		} else {
			maxx[i] = maxx[i+1]
		}
		if mat[i] < minn {
			minn = mat[i]
		}
	}
	partline := -1
	res := int64(maxx[0] - minn)
	root := fatory.newPoint()
	root.l = 1
	root.r = n
	root.min = MAX
	//fmt.Printf("root.min = %d l=%d r=%d\n",root.min,root.l,root.r)
	for i := 0; i < n; i++ {
		root.add(i+1, i+1, mat[i])
		//	fmt.Printf("i=%d root.min = %d value=%d\n", i,root.min,mat[i])
	}
	//fmt.Printf("root.min = %d\n", root.min)

	sort.Sort(segs)
	dbMax := 0
	for i := 0; i < len(segs); i++ {
		if segs[i].r >= n {
			continue
		}
		root.add(segs[i].l, segs[i].r, -1)
		tmpm, _ := root.queryMin(1, segs[i].r)
		//	fmt.Printf("i=%d segs.l = %d segs.r = %d min=%d maxx=%d\n", i, segs[i].l, segs[i].r, tmpm, maxx[segs[i].r])
		if res < int64(maxx[segs[i].r])-tmpm {
			partline = i
			res = int64(maxx[segs[i].r]) - tmpm
			dbMax = maxx[segs[i].r]
		}
		if debug && (segs[i].id == 36 || segs[i].id == 55 || segs[i].id == 76 || segs[i].id == 11 || segs[i].id == 37 || segs[i].id == 95 || segs[i].id == 6 || segs[i].id == 41) {
			logger += fmt.Sprintf("i=%d maxx=%d min=%d l=%d r=%d root.min=%d\n", segs[i].id, maxx[segs[i].r], tmpm, segs[i].l, segs[i].r, root.min)
			//logger += "i=" + strconv.Itoa(segs[i].id) + " maxx = " + strconv.Itoa(maxx[segs[i].r]) + " min=" + strconv.Itoa(int(tmpm)) + "\n"
		}
	}
	if debug && partline > -1 {
		logger += "partline=" + strconv.Itoa(segs[partline].r) + " maxx = " + strconv.Itoa(dbMax) + " min=" + strconv.Itoa(dbMax-int(res)) + "\n"
		//	fmt.Printf("partline=%d maxx = %d min=%d\n", segs[partline].r, dbMax,res-int64(dbMax))
	}
	as := make(Segs, partline+1)
	for i := 0; i <= partline; i++ {
		as[i] = Seg{
			l:  segs[i].l,
			r:  segs[i].r,
			id: segs[i].id,
		}
	}
	//	fmt.Printf("as = %v res=%v\n",as,res)
	return as, res
}
func reverse(mat []int, segs Segs) {
	//	fmt.Printf("before mat=%v seg=%v\n",mat,segs)
	n := len(mat)
	m := len(segs)
	for i := 0; i < n-i-1; i++ {
		tmp := mat[i]
		mat[i] = mat[n-i-1]
		mat[n-i-1] = tmp
	}
	for i := 0; i < m; i++ {
		tmp := segs[i].l
		segs[i].l = segs[i].r
		segs[i].r = tmp
		segs[i].l = n - segs[i].l + 1
		segs[i].r = n - segs[i].r + 1
	}

}
func tmpseg(segs Segs) Segs {
	lens := len(goods)
	res := make(Segs, 0)
	for j := 0; j < len(segs); j++ {
		for i := 0; i < lens; i++ {
			if goods[i] == segs[j].id {
				res = append(res, segs[j])
				break
			}
		}
	}
	return res
}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	//if n == 10000 && m == 100 {
	//	debug = true
	//}
	if debug{
		fmt.Printf("maxx=%d\n",MAX)
	}
	//	debug=true
	mat := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d", &mat[i])
	}
	fmt.Fscanf(buf, "\n")
	seg := make(Segs, m)
	for i := 0; i < m; i++ {
		fmt.Fscanf(buf, "%d %d\n", &seg[i].l, &seg[i].r)
		seg[i].id = i + 1
	}
	pl, ans := solveE(mat, n, seg)
	reverse(mat, seg)
	//	fmt.Printf("rev mat=%v seg=%d\n",mat,seg)
	pl2, ans2 := solveE(mat, n, seg)

	if ans < ans2 {
		fmt.Printf("%d\n", ans2)
		fmt.Printf("%d\n", len(pl2))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl2[i].id)
		}
		fmt.Printf("\n")
		if len(pl) > 0 && debug {
			c, _ := check(mat, tmpseg(seg))
			c, _ = check(mat, pl2)
			if c != ans2 {
				fmt.Printf("ERROR c = %d ans=%d\n", c, ans2)
			}
			fmt.Printf("logger--\n%s\n", logger)
		}
	} else {
		fmt.Printf("%d\n", ans)
		fmt.Printf("%d\n", len(pl))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl[i].id)
		}
		fmt.Printf("\n")

		if len(pl) > 0 && debug {
			reverse(mat, seg)
			c, _ := check(mat, tmpseg(seg))
			c, _ = check(mat, pl)

			if c != ans {
				fmt.Printf("2ERROR c = %d ans=%d\n", c, ans)
			}
			fmt.Printf("%s\n", logger)
		}
	}

}
func check(mat []int, pl Segs) (int64, int) {
	n := len(mat)
	m := len(pl)
	if m <= 0 {
		return 0, 0
	}
	maxx := -1
	minn := 10000000
	//minw := -1
	for i := 0; i < n; i++ {
		in := 0
		for j := 0; j < m; j++ {
			if pl[j].l > i+1 || pl[j].r < i+1 {
				continue
			}
			in++
		}
		if in == 0 {
			if maxx == -1 || mat[maxx] < mat[i] {
				maxx = i
			}
		}
		if minn > mat[i]-in {
			minn = mat[i] - in
			//minw = i
		}

	}
	if debug {
		maxxr := 0
		for i := 0; i < m; i++ {
			if pl[i].l <= 3119 && pl[i].r >= 3119 {
				//	fmt.Printf("range %d %d %d\n", pl[i].l, pl[i].r,pl[i].id)
			}

			if pl[i].r > maxxr {
				maxxr = pl[i].r
			}
		}
		//		fmt.Printf("check maxw = %d  minw = %d maxx=%d min=%d mat[minn]=%d maxxr=%d\n", maxx+1, minw+1, mat[maxx], minn, mat[minw],maxxr)
	}
	return int64(mat[maxx] - minn), mat[maxx]
}

/**

5 3
1 2 2 -2 3
3 5
1 5
3 5
 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

var (
	fatory *PointFatory
	debug  = false
	logger = ""
	goods  = [70]int{80, 41, 72, 28, 77, 62, 6, 14, 78, 97, 93, 48, 4, 3, 25, 94, 83, 10, 53, 22, 54, 70, 29, 27, 87, 45, 43, 76, 31, 30, 42, 20, 12, 2, 40, 16, 100, 64, 86, 44, 49, 56, 33, 11, 46, 18, 75, 5, 69, 55, 37, 50, 92, 73, 21, 57, 13, 35, 26, 65, 81, 95, 36, 32, 15, 60, 68, 89, 98, 38}
)

const (
	MAX = 1000100 * 300
)

type Point struct {
	l, r   int
	dirty  int
	min    int64
	cl, cr *Point
}
type Seg struct {
	l, r int
	id   int
}
type Segs []Seg

func (s Segs) Len() int {
	return len(s)
}
func (s Segs) Swap(a, b int) {
	tmp := s[a].l
	s[a].l = s[b].l
	s[b].l = tmp

	tmp = s[a].r
	s[a].r = s[b].r
	s[b].r = tmp

	tmp = s[a].id
	s[a].id = s[b].id
	s[b].id = tmp
}
func (s Segs) Less(a, b int) bool {
	if s[a].r < s[b].r {
		return true
	}
	return false
}

type PointFatory struct {
	p     []Point
	front int
	len   int
}

func (p *PointFatory) newPoint() *Point {
	if p.front >= p.len {
		p.p = append(p.p, make([]Point, p.len)...)
		p.len = len(p.p)
	}
	res := &p.p[p.front]
	p.front++
	return res
}
func newFatory(n int) *PointFatory {
	return &PointFatory{
		p:   make([]Point, n),
		len: n,
	}
}
func (p *Point) left() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cl == nil {
		p.cl = fatory.newPoint()
		p.cl.l = p.l
		p.cl.r = (p.l + p.r) / 2
		p.cl.min = MAX
	}
	return p.cl
}
func (p *Point) right() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cr == nil {
		p.cr = fatory.newPoint()
		p.cr.l = (p.l+p.r)/2 + 1
		p.cr.r = p.r
		p.cl.min = MAX
	}
	return p.cr
}
func (p *Point) refleshMin() {
	if p.left() == nil && p.right() == nil {
		return
	}
	if p.left() == nil {
		p.min = p.right().min
	} else if p.right() == nil {
		p.min = p.left().min
	} else if p.left().min < p.right().min {
		p.min = p.left().min
	} else {
		p.min = p.right().min
	}

}
func (p *Point) queryMin(l, r int) (int64, bool) {
	p.down()
	if l <= p.l && p.r <= r {
		return p.min, true
	}
	if l > p.r || r < p.l {
		return -1, false
	}
	var res int64 = 0
	find := false
	if p.left() != nil {
		leftmin, flag := p.left().queryMin(l, r)
		if flag {
			res = leftmin
			find = true
		}
	}
	if p.right() != nil {
		rightmin, flag := p.right().queryMin(l, r)
		if flag && (find == false || rightmin < res) {
			res = rightmin
		}
	}
	return res, true

}
func (p *Point) addValue(value int) {
	if p.min >= MAX {
		p.min = int64(value)
	} else {
		p.min += int64(value)
	}
}
func (p *Point) down() {
	if p.dirty <= 0 {
		return
	}
	pl := p.left()
	pr := p.right()
	if pl != nil {
		pl.dirty += p.dirty
		pl.addValue(p.dirty)
	}
	if pr != nil {
		pr.dirty += p.dirty
		pr.addValue(p.dirty)
	}
	p.dirty = 0
	p.refleshMin()
}
func (p *Point) add(l, r int, value int) {
	if l > p.r || r < p.l {
		return
	}
	if l <= p.l && p.r <= r {
		p.addValue(value)
		p.dirty += value
		return
	}
	pl := p.left()
	pr := p.right()
	p.down()
	if pl != nil {
		pl.add(l, r, value)
	}
	if pr != nil {
		pr.add(l, r, value)
	}
	p.refleshMin()
}
func solveE(mat []int, n int, segs Segs) (Segs, int64) {
	fatory = newFatory(n)

	maxx := make([]int, n)
	minn := mat[n-1]
	maxx[n-1] = mat[n-1]
	for i := n - 2; i >= 0; i-- {
		if mat[i] > maxx[i+1] {
			maxx[i] = mat[i]
		} else {
			maxx[i] = maxx[i+1]
		}
		if mat[i] < minn {
			minn = mat[i]
		}
	}
	partline := -1
	res := int64(maxx[0] - minn)
	root := fatory.newPoint()
	root.l = 1
	root.r = n
	//fmt.Printf("root.min = %d l=%d r=%d\n",root.min,root.l,root.r)
	for i := 0; i < n; i++ {
		root.add(i+1, i+1, mat[i])
		//	fmt.Printf("i=%d root.min = %d value=%d\n", i,root.min,mat[i])
	}
	//fmt.Printf("root.min = %d\n", root.min)

	sort.Sort(segs)
	dbMax := 0
	for i := 0; i < len(segs); i++ {
		if segs[i].r >= n {
			continue
		}
		root.add(segs[i].l, segs[i].r, -1)
		tmpm, _ := root.queryMin(1, segs[i].r)
		//	fmt.Printf("i=%d segs.l = %d segs.r = %d min=%d maxx=%d\n", i, segs[i].l, segs[i].r, tmpm, maxx[segs[i].r])
		if res < int64(maxx[segs[i].r])-tmpm {
			partline = i
			res = int64(maxx[segs[i].r]) - tmpm
			dbMax = maxx[segs[i].r]
		}
		if debug && (segs[i].id ==36||segs[i].id ==55||segs[i].id ==76){
			logger += "i=" + strconv.Itoa(segs[i].id) + " maxx = " + strconv.Itoa(maxx[segs[i].r]) + " min=" + strconv.Itoa(int(tmpm)) + "\n"
		}
	}
	if debug && partline > -1 {
		logger += "partline=" + strconv.Itoa(segs[partline].r) + " maxx = " + strconv.Itoa(dbMax) + " min=" + strconv.Itoa(dbMax-int(res)) + "\n"
		//	fmt.Printf("partline=%d maxx = %d min=%d\n", segs[partline].r, dbMax,res-int64(dbMax))
	}
	as := make(Segs, partline+1)
	for i := 0; i <= partline; i++ {
		as[i] = segs[i]
	}
	//	fmt.Printf("as = %v res=%v\n",as,res)
	return as, res
}
func reverse(mat []int, segs Segs) {
	//	fmt.Printf("before mat=%v seg=%v\n",mat,segs)
	n := len(mat)
	m := len(segs)
	for i := 0; i < n-i-1; i++ {
		tmp := mat[i]
		mat[i] = mat[n-i-1]
		mat[n-i-1] = tmp
	}
	for i := 0; i < m; i++ {
		tmp := segs[i].l
		segs[i].l = segs[i].r
		segs[i].r = tmp
		segs[i].l = n - segs[i].l + 1
		segs[i].r = n - segs[i].r + 1
	}

}
func tmpseg(segs Segs) Segs {
	lens := len(goods)
	res := make(Segs, 0)
	for j := 0; j < len(segs); j++ {
		for i := 0; i < lens; i++ {
			if goods[i] == segs[j].id {
				res = append(res, segs[j])
				break
			}
		}
	}
	return res
}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	if n == 10000 && m == 100 {
		debug = true
	}
	//	debug=true
	mat := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d", &mat[i])
	}
	fmt.Fscanf(buf, "\n")
	seg := make(Segs, m)
	for i := 0; i < m; i++ {
		fmt.Fscanf(buf, "%d %d\n", &seg[i].l, &seg[i].r)
		seg[i].id = i + 1
	}
	pl, ans := solveE(mat, n, seg)
	reverse(mat, seg)
	//	fmt.Printf("rev mat=%v seg=%d\n",mat,seg)
	pl2, ans2 := solveE(mat, n, seg)

	if ans < ans2 {
		fmt.Printf("%d\n", ans2)
		fmt.Printf("%d\n", len(pl2))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl2[i].id)
		}
		fmt.Printf("\n")
		if len(pl) > 0 && debug {
			c, _ := check(mat, tmpseg(seg))
			c,_ = check(mat, pl2)
			if c != ans2 {
				fmt.Printf("ERROR c = %d ans=%d\n", c, ans2)
			}
			fmt.Printf("logger--\n%s\n", logger)
		}
	} else {
		fmt.Printf("%d\n", ans)
		fmt.Printf("%d\n", len(pl))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl[i].id)
		}
		fmt.Printf("\n")

		if len(pl) > 0 && debug {
			reverse(mat, seg)
			c, _ := check(mat, tmpseg(seg))
			c, _ = check(mat, pl)

			if c != ans {
				fmt.Printf("2ERROR c = %d ans=%d\n", c, ans)
			}
			fmt.Printf("%s\n", logger)
		}
	}

}
func check(mat []int, pl Segs) (int64, int) {
	n := len(mat)
	m := len(pl)
	if m <= 0 {
		return 0, 0
	}
	maxx := -1
	minn := 10000000
	minw := -1
	for i := 0; i < n; i++ {
		in := 0
		for j := 0; j < m; j++ {
			if pl[j].l > i+1 || pl[j].r < i+1 {
				continue
			}
			in++
		}
		if in == 0 {
			if maxx == -1 || mat[maxx] < mat[i] {
				maxx = i
			}
		}
		if minn > mat[i]-in {
			minn = mat[i] - in
			minw = i
		}

	}
	if debug {
		maxxr := 0
		for i := 0; i < m; i++ {
			if pl[i].l <= 3119 && pl[i].r >= 3119{
				fmt.Printf("range %d %d %d\n", pl[i].l, pl[i].r,pl[i].id)
			}

			if pl[i].r > maxxr {
				maxxr = pl[i].r
			}
		}
		fmt.Printf("check maxw = %d  minw = %d maxx=%d min=%d mat[minn]=%d maxxr=%d\n", maxx+1, minw+1, mat[maxx], minn, mat[minw],maxxr)
	}
	return int64(mat[maxx] - minn), mat[maxx]
}

/**

5 3
1 2 2 -2 3
3 5
1 5
3 5
 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
)

var (
	fatory *PointFatory
	debug  = false
)

const (
	MAX = 1000100 * 300
)

type Point struct {
	l, r   int
	dirty  int
	min    int64
	cl, cr *Point
}
type Seg struct {
	l, r int
	id   int
}
type Segs []Seg

func (s Segs) Len() int {
	return len(s)
}
func (s Segs) Swap(a, b int) {
	tmp := s[a].l
	s[a].l = s[b].l
	s[b].l = tmp

	tmp = s[a].r
	s[a].r = s[b].r
	s[b].r = tmp

	tmp = s[a].id
	s[a].id = s[b].id
	s[b].id = tmp
}
func (s Segs) Less(a, b int) bool {
	if s[a].r < s[b].r {
		return true
	}
	return false
}

type PointFatory struct {
	p     []Point
	front int
	len   int
}

func (p *PointFatory) newPoint() *Point {
	if p.front >= p.len {
		p.p = append(p.p, make([]Point, p.len)...)
		p.len = len(p.p)
	}
	res := &p.p[p.front]
	p.front++
	return res
}
func newFatory(n int) *PointFatory {
	return &PointFatory{
		p:   make([]Point, n),
		len: n,
	}
}
func (p *Point) left() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cl == nil {
		p.cl = fatory.newPoint()
		p.cl.l = p.l
		p.cl.r = (p.l + p.r) / 2
		p.cl.min = MAX
	}
	return p.cl
}
func (p *Point) right() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cr == nil {
		p.cr = fatory.newPoint()
		p.cr.l = (p.l+p.r)/2 + 1
		p.cr.r = p.r
		p.cl.min = MAX
	}
	return p.cr
}
func (p *Point) refleshMin() {
	if p.left() == nil && p.right() == nil {
		return
	}
	if p.left() == nil {
		p.min = p.right().min
	} else if p.right() == nil {
		p.min = p.left().min
	} else if p.left().min < p.right().min {
		p.min = p.left().min
	} else {
		p.min = p.right().min
	}

}
func (p *Point) queryMin(l, r int) (int64, bool) {
	p.down()
	if l <= p.l && p.r <= r {
		return p.min, true
	}
	if l > p.r || r < p.l {
		return -1, false
	}
	var res int64 = 0
	find := false
	if p.left() != nil {
		leftmin, flag := p.left().queryMin(l, r)
		if flag {
			res = leftmin
			find = true
		}
	}
	if p.right() != nil {
		rightmin, flag := p.right().queryMin(l, r)
		if flag && (find == false || rightmin < res) {
			res = rightmin
		}
	}
	return res, true

}
func (p *Point) addValue(value int) {
	if p.min >= MAX {
		p.min = int64(value)
	} else {
		p.min += int64(value)
	}
}
func (p *Point) down() {
	if p.dirty <= 0 {
		return
	}
	pl := p.left()
	pr := p.right()
	if pl != nil {
		pl.dirty += p.dirty
		pl.addValue(p.dirty)
	}
	if pr != nil {
		pr.dirty += p.dirty
		pr.addValue(p.dirty)
	}
	p.dirty = 0
	p.refleshMin()
}
func (p *Point) add(l, r int, value int) {
	if l > p.r || r < p.l {
		return
	}
	if l <= p.l && p.r <= r {
		p.addValue(value)
		p.dirty += value
		return
	}
	pl := p.left()
	pr := p.right()
	p.down()
	if pl != nil {
		pl.add(l, r, value)
	}
	if pr != nil {
		pr.add(l, r, value)
	}
	p.refleshMin()
}
func solveE(mat []int, n int, segs Segs) (Segs, int64) {
	fatory = newFatory(n)

	maxx := make([]int, n)
	minn := mat[n-1]
	maxx[n-1] = mat[n-1]
	for i := n - 2; i >= 0; i-- {
		if mat[i] > maxx[i+1] {
			maxx[i] = mat[i]
		} else {
			maxx[i] = maxx[i+1]
		}
		if mat[i] < minn {
			minn = mat[i]
		}
	}
	partline := -1
	res := int64(maxx[0] - minn)
	root := fatory.newPoint()
	root.l = 1
	root.r = n
	//fmt.Printf("root.min = %d l=%d r=%d\n",root.min,root.l,root.r)
	for i := 0; i < n; i++ {
		root.add(i+1, i+1, mat[i])
		//	fmt.Printf("i=%d root.min = %d value=%d\n", i,root.min,mat[i])
	}
	//fmt.Printf("root.min = %d\n", root.min)

	sort.Sort(segs)
	for i := 0; i < len(segs); i++ {
		if segs[i].r >= n {
			continue
		}
		root.add(segs[i].l, segs[i].r, -1)
		tmpm, _ := root.queryMin(1, segs[i].r)
		//	fmt.Printf("i=%d segs.l = %d segs.r = %d min=%d maxx=%d\n", i, segs[i].l, segs[i].r, tmpm, maxx[segs[i].r])
		if res < int64(maxx[segs[i].r])-tmpm {
			partline = i
			res = int64(maxx[segs[i].r]) - tmpm
		}
	}
	if debug {
		fmt.Printf("maxx = %d\n", segs[partline].r)
	}
	as := make(Segs, partline+1)
	for i := 0; i <= partline; i++ {
		as[i] = segs[i]
	}
	//	fmt.Printf("as = %v res=%v\n",as,res)
	return as, res
}
func reverse(mat []int, segs Segs) {
	//	fmt.Printf("before mat=%v seg=%v\n",mat,segs)
	n := len(mat)
	m := len(segs)
	for i := 0; i < n-i-1; i++ {
		tmp := mat[i]
		mat[i] = mat[n-i-1]
		mat[n-i-1] = tmp
	}
	for i := 0; i < m; i++ {
		tmp := segs[i].l
		segs[i].l = segs[i].r
		segs[i].r = tmp
		segs[i].l = n - segs[i].l + 1
		segs[i].r = n - segs[i].r + 1
	}

}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	mat := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d", &mat[i])
	}
	fmt.Fscanf(buf, "\n")
	seg := make(Segs, m)
	for i := 0; i < m; i++ {
		fmt.Fscanf(buf, "%d %d\n", &seg[i].l, &seg[i].r)
		seg[i].id = i + 1
	}
	pl, ans := solveE(mat, n, seg)
	reverse(mat, seg)
	//	fmt.Printf("rev mat=%v seg=%d\n",mat,seg)
	pl2, ans2 := solveE(mat, n, seg)
	if ans < ans2 {
		fmt.Printf("%d\n", ans2)
		fmt.Printf("%d\n", len(pl2))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl2[i].id)
		}
		fmt.Printf("\n")
		if len(pl) > 0 && n == 10000 && m == 100 {
			c, wei := check(mat, pl2)
			fmt.Printf("w = %d\n", wei)
			for i := 0; i < len(pl); i++ {
				fmt.Printf("rang %d %d\n", seg[i].l, seg[i].r)
			}
			if c != ans2 {
				fmt.Printf("ERROR c = %d ans=%d\n", c, ans2)
			}
		}
	} else {
		fmt.Printf("%d\n", ans)
		fmt.Printf("%d\n", len(pl))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl[i].id)
		}
		fmt.Printf("\n")
		reverse(mat, seg)
		if len(pl) > 0 && n == 10000 && m == 100 {

			c, wei := check(mat, pl)
			fmt.Printf("w = %d\n", wei)
			for i := 0; i < len(pl); i++ {
				fmt.Printf("rang %d %d\n", seg[i].l, seg[i].r)
			}
			if c != ans {
				fmt.Printf("2ERROR c = %d ans=%d\n", c, ans)
			}
		}
	}

}
func check(mat []int, pl Segs) (int64, int) {
	n := len(mat)
	m := len(pl)
	maxx := -1
	minn := 10000000
	for i := 0; i < n; i++ {
		in := 0
		for j := 0; j < m; j++ {
			if pl[j].l > i+1 || pl[j].r < i+1 {
				continue
			}
			in++
		}
		if in == 0 {
			if maxx == -1 || mat[maxx] < mat[i] {
				maxx = i
			}
		}
		if minn > mat[i]-in {
			minn = mat[i] - in
		}
	}
	//	fmt.Printf("v pl=%v mat=%v\n",pl,mat)
	return int64(maxx - minn), maxx
}

/**

5 3
1 2 2 -2 3
3 5
1 5
3 5
 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

var (
	fatory *PointFatory
	debug  = false
	logger = ""
	goods  = [70]int{80, 41, 72, 28, 77, 62, 6, 14, 78, 97, 93, 48, 4, 3, 25, 94, 83, 10, 53, 22, 54, 70, 29, 27, 87, 45, 43, 76, 31, 30, 42, 20, 12, 2, 40, 16, 100, 64, 86, 44, 49, 56, 33, 11, 46, 18, 75, 5, 69, 55, 37, 50, 92, 73, 21, 57, 13, 35, 26, 65, 81, 95, 36, 32, 15, 60, 68, 89, 98, 38}
)

const (
	MAX = 1000100 * 300
)

type Point struct {
	l, r   int
	dirty  int
	min    int64
	cl, cr *Point
}
type Seg struct {
	l, r int
	id   int
}
type Segs []Seg

func (s Segs) Len() int {
	return len(s)
}
func (s Segs) Swap(a, b int) {
	tmp := s[a].l
	s[a].l = s[b].l
	s[b].l = tmp

	tmp = s[a].r
	s[a].r = s[b].r
	s[b].r = tmp

	tmp = s[a].id
	s[a].id = s[b].id
	s[b].id = tmp
}
func (s Segs) Less(a, b int) bool {
	if s[a].r < s[b].r {
		return true
	}
	return false
}

type PointFatory struct {
	p     []Point
	front int
	len   int
}

func (p *PointFatory) newPoint() *Point {
	if p.front >= p.len {
		p.p = append(p.p, make([]Point, p.len)...)
		p.len = len(p.p)
	}
	res := &p.p[p.front]
	p.front++
	return res
}
func newFatory(n int) *PointFatory {
	return &PointFatory{
		p:   make([]Point, n),
		len: n,
	}
}
func (p *Point) left() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cl == nil {
		p.cl = fatory.newPoint()
		p.cl.l = p.l
		p.cl.r = (p.l + p.r) / 2
		p.cl.min = MAX
	}
	return p.cl
}
func (p *Point) right() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cr == nil {
		p.cr = fatory.newPoint()
		p.cr.l = (p.l+p.r)/2 + 1
		p.cr.r = p.r
		p.cl.min = MAX
	}
	return p.cr
}
func (p *Point) refleshMin() {
	if p.left() == nil && p.right() == nil {
		return
	}
	if p.left() == nil {
		p.min = p.right().min
	} else if p.right() == nil {
		p.min = p.left().min
	} else if p.left().min < p.right().min {
		p.min = p.left().min
	} else {
		p.min = p.right().min
	}

}
func (p *Point) queryMin(l, r int) (int64, bool) {
	p.down()
	if l <= p.l && p.r <= r {
		return p.min, true
	}
	if l > p.r || r < p.l {
		return -1, false
	}
	var res int64 = 0
	find := false
	if p.left() != nil {
		leftmin, flag := p.left().queryMin(l, r)
		if flag {
			res = leftmin
			find = true
		}
	}
	if p.right() != nil {
		rightmin, flag := p.right().queryMin(l, r)
		if flag && (find == false || rightmin < res) {
			res = rightmin
		}
	}
	return res, true

}
func (p *Point) addValue(value int) {
	if p.min >= MAX {
		p.min = int64(value)
	} else {
		p.min += int64(value)
	}
}
func (p *Point) down() {
	if p.dirty <= 0 {
		return
	}
	pl := p.left()
	pr := p.right()
	if pl != nil {
		pl.dirty += p.dirty
		pl.addValue(p.dirty)
	}
	if pr != nil {
		pr.dirty += p.dirty
		pr.addValue(p.dirty)
	}
	p.dirty = 0
	p.refleshMin()
}
func (p *Point) add(l, r int, value int) {
	if l > p.r || r < p.l {
		return
	}
	if l <= p.l && p.r <= r {
		p.addValue(value)
		p.dirty += value
		return
	}
	pl := p.left()
	pr := p.right()
	p.down()
	if pl != nil {
		pl.add(l, r, value)
	}
	if pr != nil {
		pr.add(l, r, value)
	}
	p.refleshMin()
}
func solveE(mat []int, n int, segs Segs) (Segs, int64) {
	fatory = newFatory(n)

	maxx := make([]int, n)
	minn := mat[n-1]
	maxx[n-1] = mat[n-1]
	for i := n - 2; i >= 0; i-- {
		if mat[i] > maxx[i+1] {
			maxx[i] = mat[i]
		} else {
			maxx[i] = maxx[i+1]
		}
		if mat[i] < minn {
			minn = mat[i]
		}
	}
	partline := -1
	res := int64(maxx[0] - minn)
	root := fatory.newPoint()
	root.l = 1
	root.r = n
	//fmt.Printf("root.min = %d l=%d r=%d\n",root.min,root.l,root.r)
	for i := 0; i < n; i++ {
		root.add(i+1, i+1, mat[i])
		//	fmt.Printf("i=%d root.min = %d value=%d\n", i,root.min,mat[i])
	}
	//fmt.Printf("root.min = %d\n", root.min)

	sort.Sort(segs)
	dbMax := 0
	for i := 0; i < len(segs); i++ {
		if segs[i].r >= n {
			continue
		}
		root.add(segs[i].l, segs[i].r, -1)
		tmpm, _ := root.queryMin(1, segs[i].r)
		//	fmt.Printf("i=%d segs.l = %d segs.r = %d min=%d maxx=%d\n", i, segs[i].l, segs[i].r, tmpm, maxx[segs[i].r])
		if res < int64(maxx[segs[i].r])-tmpm {
			partline = i
			res = int64(maxx[segs[i].r]) - tmpm
			dbMax = maxx[segs[i].r]
		}
		if debug && (segs[i].id ==36||segs[i].id ==55||segs[i].id ==76||segs[i].id ==11||segs[i].id ==37||segs[i].id ==95||segs[i].id ==6||segs[i].id ==41){
			logger+=fmt.Sprintf("i=%d maxx=%d min=%d l=%d r=%d",segs[i].id,maxx[segs[i].r],tmpm,segs[i].l,segs[i].r)+ "\n"
			//logger += "i=" + strconv.Itoa(segs[i].id) + " maxx = " + strconv.Itoa(maxx[segs[i].r]) + " min=" + strconv.Itoa(int(tmpm)) + "\n"
		}
	}
	if debug && partline > -1 {
		logger += "partline=" + strconv.Itoa(segs[partline].r) + " maxx = " + strconv.Itoa(dbMax) + " min=" + strconv.Itoa(dbMax-int(res)) + "\n"
		//	fmt.Printf("partline=%d maxx = %d min=%d\n", segs[partline].r, dbMax,res-int64(dbMax))
	}
	as := make(Segs, partline+1)
	for i := 0; i <= partline; i++ {
		as[i] = Seg{
			l:segs[i].l,
			r:segs[i].r,
			id:segs[i].id,
		}
	}
	//	fmt.Printf("as = %v res=%v\n",as,res)
	return as, res
}
func reverse(mat []int, segs Segs) {
	//	fmt.Printf("before mat=%v seg=%v\n",mat,segs)
	n := len(mat)
	m := len(segs)
	for i := 0; i < n-i-1; i++ {
		tmp := mat[i]
		mat[i] = mat[n-i-1]
		mat[n-i-1] = tmp
	}
	for i := 0; i < m; i++ {
		tmp := segs[i].l
		segs[i].l = segs[i].r
		segs[i].r = tmp
		segs[i].l = n - segs[i].l + 1
		segs[i].r = n - segs[i].r + 1
	}

}
func tmpseg(segs Segs) Segs {
	lens := len(goods)
	res := make(Segs, 0)
	for j := 0; j < len(segs); j++ {
		for i := 0; i < lens; i++ {
			if goods[i] == segs[j].id {
				res = append(res, segs[j])
				break
			}
		}
	}
	return res
}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	if n == 10000 && m == 100 {
		debug = true
	}
	//	debug=true
	mat := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d", &mat[i])
	}
	fmt.Fscanf(buf, "\n")
	seg := make(Segs, m)
	for i := 0; i < m; i++ {
		fmt.Fscanf(buf, "%d %d\n", &seg[i].l, &seg[i].r)
		seg[i].id = i + 1
	}
	pl, ans := solveE(mat, n, seg)
	reverse(mat, seg)
	//	fmt.Printf("rev mat=%v seg=%d\n",mat,seg)
	pl2, ans2 := solveE(mat, n, seg)

	if ans < ans2 {
		fmt.Printf("%d\n", ans2)
		fmt.Printf("%d\n", len(pl2))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl2[i].id)
		}
		fmt.Printf("\n")
		if len(pl) > 0 && debug {
			c, _ := check(mat, tmpseg(seg))
			c,_ = check(mat, pl2)
			if c != ans2 {
				fmt.Printf("ERROR c = %d ans=%d\n", c, ans2)
			}
			fmt.Printf("logger--\n%s\n", logger)
		}
	} else {
		fmt.Printf("%d\n", ans)
		fmt.Printf("%d\n", len(pl))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl[i].id)
		}
		fmt.Printf("\n")

		if len(pl) > 0 && debug {
			reverse(mat, seg)
			c, _ := check(mat, tmpseg(seg))
			c, _ = check(mat, pl)

			if c != ans {
				fmt.Printf("2ERROR c = %d ans=%d\n", c, ans)
			}
			fmt.Printf("%s\n", logger)
		}
	}

}
func check(mat []int, pl Segs) (int64, int) {
	n := len(mat)
	m := len(pl)
	if m <= 0 {
		return 0, 0
	}
	maxx := -1
	minn := 10000000
	minw := -1
	for i := 0; i < n; i++ {
		in := 0
		for j := 0; j < m; j++ {
			if pl[j].l > i+1 || pl[j].r < i+1 {
				continue
			}
			in++
		}
		if in == 0 {
			if maxx == -1 || mat[maxx] < mat[i] {
				maxx = i
			}
		}
		if minn > mat[i]-in {
			minn = mat[i] - in
			minw = i
		}

	}
	if debug {
		maxxr := 0
		for i := 0; i < m; i++ {
			if pl[i].l <= 3119 && pl[i].r >= 3119{
			//	fmt.Printf("range %d %d %d\n", pl[i].l, pl[i].r,pl[i].id)
			}

			if pl[i].r > maxxr {
				maxxr = pl[i].r
			}
		}
		fmt.Printf("check maxw = %d  minw = %d maxx=%d min=%d mat[minn]=%d maxxr=%d\n", maxx+1, minw+1, mat[maxx], minn, mat[minw],maxxr)
	}
	return int64(mat[maxx] - minn), mat[maxx]
}

/**

5 3
1 2 2 -2 3
3 5
1 5
3 5
 */

package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

var (
	fatory *PointFatory
	debug  = false
	logger = ""
	goods  = [70]int{80, 41, 72, 28, 77, 62, 6, 14, 78, 97, 93, 48, 4, 3, 25, 94, 83, 10, 53, 22, 54, 70, 29, 27, 87, 45, 43, 76, 31, 30, 42, 20, 12, 2, 40, 16, 100, 64, 86, 44, 49, 56, 33, 11, 46, 18, 75, 5, 69, 55, 37, 50, 92, 73, 21, 57, 13, 35, 26, 65, 81, 95, 36, 32, 15, 60, 68, 89, 98, 38}
)

const (
	MAX int64 = int64(3000100)
)

type Point struct {
	l, r   int
	dirty  int
	min    int64
	cl, cr *Point
}
type Seg struct {
	l, r int
	id   int
}
type Segs []Seg

func (s Segs) Len() int {
	return len(s)
}
func (s Segs) Swap(a, b int) {
	tmp := s[a].l
	s[a].l = s[b].l
	s[b].l = tmp

	tmp = s[a].r
	s[a].r = s[b].r
	s[b].r = tmp

	tmp = s[a].id
	s[a].id = s[b].id
	s[b].id = tmp
}
func (s Segs) Less(a, b int) bool {
	if s[a].r < s[b].r {
		return true
	}
	return false
}

type PointFatory struct {
	p     []Point
	front int
	len   int
}

func (p *PointFatory) newPoint() *Point {
	return &Point{}
	//if p.front >= p.len {
	//	p.p = append(p.p, make([]Point, p.len)...)
	//	p.len = len(p.p)
	//}
	//res := &p.p[p.front]
	//p.front++
	//return res
}
func newFatory(n int) *PointFatory {
	return &PointFatory{
		p:   make([]Point, n),
		len: n,
	}
}
func (p *Point) left() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cl == nil {
		p.cl = fatory.newPoint()
		p.cl.l = p.l
		p.cl.r = (p.l + p.r) / 2
		p.cl.min = MAX
	}
	return p.cl
}
func (p *Point) right() *Point {
	if p.l == p.r {
		return nil
	}
	if p.cr == nil {
		p.cr = fatory.newPoint()
		p.cr.l = (p.l+p.r)/2 + 1
		p.cr.r = p.r
		p.cl.min = MAX
	}
	return p.cr
}
func (p *Point) refleshMin() {
	if p.left() == nil && p.right() == nil {
		return
	}
	if p.left() == nil {
		p.min = p.right().min
	} else if p.right() == nil {
		p.min = p.left().min
	} else if p.left().min < p.right().min {
		p.min = p.left().min
	} else {
		p.min = p.right().min
	}
	if p.min == 0 &&debug{
		fmt.Printf("min=0 l=%d r=%d dirty=%d\n",p.l,p.r,p.dirty)
	}

}
func (p *Point) queryMin(l, r int) (int64, bool) {
	p.down()
	if l <= p.l && p.r <= r {
		return p.min, true
	}
	if l > p.r || r < p.l {
		return -1, false
	}
	var res int64 = 0
	find := false
	if p.left() != nil {
		leftmin, flag := p.left().queryMin(l, r)
		if flag {
			res = leftmin
			find = true
		}
	}
	if p.right() != nil {
		rightmin, flag := p.right().queryMin(l, r)
		if flag && (find == false || rightmin < res) {
			res = rightmin
		}
	}
	return res, true

}
func (p *Point) addValue(value int) {
	if p.min >= MAX {
		p.min = int64(value)
	} else {
		p.min += int64(value)
	}
	if p.min == 0 &&debug{
		fmt.Printf("min=0 l=%d r=%d dirty=%d %d\n",p.l,p.r,p.dirty,value)
	}
}
func (p *Point) down() {
	if p.dirty <= 0 {
		return
	}
	pl := p.left()
	pr := p.right()
	if pl != nil {
		pl.dirty += p.dirty
		pl.addValue(p.dirty)
	}
	if pr != nil {
		pr.dirty += p.dirty
		pr.addValue(p.dirty)
	}
	p.dirty = 0
	//p.refleshMin()
}
func (p *Point) add(l, r int, value int) {
	if l > p.r || r < p.l {
		return
	}
	if l <= p.l && p.r <= r {
		p.addValue(value)
		p.dirty += value
		return
	}
	pl := p.left()
	pr := p.right()
	p.down()
	if pl != nil {
		pl.add(l, r, value)
	}
	if pr != nil {
		pr.add(l, r, value)
	}
	tmin := p.min
	p.refleshMin()
	if debug && p.min > tmin {
		fmt.Printf(" tmin=%d nowmin=%d pl=%d pr=%d l=%d r=%d value=%d\n", tmin, p.min,p.l,p.r,l,r,value)
	}
}
func solveE(mat []int, n int, segs Segs) (Segs, int64) {
	fatory = newFatory(n)

	maxx := make([]int, n)
	minn := mat[n-1]
	maxx[n-1] = mat[n-1]
	for i := n - 2; i >= 0; i-- {
		if mat[i] > maxx[i+1] {
			maxx[i] = mat[i]
		} else {
			maxx[i] = maxx[i+1]
		}
		if mat[i] < minn {
			minn = mat[i]
		}
	}
	partline := -1
	res := int64(maxx[0] - minn)
	root := fatory.newPoint()
	root.l = 1
	root.r = n
	//fmt.Printf("root.min = %d l=%d r=%d\n",root.min,root.l,root.r)
	for i := 0; i < n; i++ {
		root.add(i+1, i+1, mat[i])
		//	fmt.Printf("i=%d root.min = %d value=%d\n", i,root.min,mat[i])
	}
	//fmt.Printf("root.min = %d\n", root.min)

	sort.Sort(segs)
	dbMax := 0
	for i := 0; i < len(segs); i++ {
		if segs[i].r >= n {
			continue
		}
		root.add(segs[i].l, segs[i].r, -1)
		tmpm, _ := root.queryMin(1, segs[i].r)
		//	fmt.Printf("i=%d segs.l = %d segs.r = %d min=%d maxx=%d\n", i, segs[i].l, segs[i].r, tmpm, maxx[segs[i].r])
		if res < int64(maxx[segs[i].r])-tmpm {
			partline = i
			res = int64(maxx[segs[i].r]) - tmpm
			dbMax = maxx[segs[i].r]
		}
		if debug && (segs[i].id == 36 || segs[i].id == 55 || segs[i].id == 76 || segs[i].id == 11 || segs[i].id == 37 || segs[i].id == 95 || segs[i].id == 6 || segs[i].id == 41) {
			logger += fmt.Sprintf("i=%d maxx=%d min=%d l=%d r=%d root.min=%d\n", segs[i].id, maxx[segs[i].r], tmpm, segs[i].l, segs[i].r, root.min)
			//logger += "i=" + strconv.Itoa(segs[i].id) + " maxx = " + strconv.Itoa(maxx[segs[i].r]) + " min=" + strconv.Itoa(int(tmpm)) + "\n"
		}
	}
	if debug && partline > -1 {
		logger += "partline=" + strconv.Itoa(segs[partline].r) + " maxx = " + strconv.Itoa(dbMax) + " min=" + strconv.Itoa(dbMax-int(res)) + "\n"
		//	fmt.Printf("partline=%d maxx = %d min=%d\n", segs[partline].r, dbMax,res-int64(dbMax))
	}
	as := make(Segs, partline+1)
	for i := 0; i <= partline; i++ {
		as[i] = Seg{
			l:  segs[i].l,
			r:  segs[i].r,
			id: segs[i].id,
		}
	}
	//	fmt.Printf("as = %v res=%v\n",as,res)
	return as, res
}
func reverse(mat []int, segs Segs) {
	//	fmt.Printf("before mat=%v seg=%v\n",mat,segs)
	n := len(mat)
	m := len(segs)
	for i := 0; i < n-i-1; i++ {
		tmp := mat[i]
		mat[i] = mat[n-i-1]
		mat[n-i-1] = tmp
	}
	for i := 0; i < m; i++ {
		tmp := segs[i].l
		segs[i].l = segs[i].r
		segs[i].r = tmp
		segs[i].l = n - segs[i].l + 1
		segs[i].r = n - segs[i].r + 1
	}

}
func tmpseg(segs Segs) Segs {
	lens := len(goods)
	res := make(Segs, 0)
	for j := 0; j < len(segs); j++ {
		for i := 0; i < lens; i++ {
			if goods[i] == segs[j].id {
				res = append(res, segs[j])
				break
			}
		}
	}
	return res
}
func main() {
	buf := bufio.NewReader(os.Stdin)
	var n, m int
	fmt.Fscanf(buf, "%d %d\n", &n, &m)
	if n == 10000 && m == 100 {
		debug = true
	}
	//	debug=true
	mat := make([]int, n)
	for i := 0; i < n; i++ {
		fmt.Fscanf(buf, "%d", &mat[i])
	}
	fmt.Fscanf(buf, "\n")
	seg := make(Segs, m)
	for i := 0; i < m; i++ {
		fmt.Fscanf(buf, "%d %d\n", &seg[i].l, &seg[i].r)
		seg[i].id = i + 1
	}
	pl, ans := solveE(mat, n, seg)
	reverse(mat, seg)
	//	fmt.Printf("rev mat=%v seg=%d\n",mat,seg)
	pl2, ans2 := solveE(mat, n, seg)

	if ans < ans2 {
		fmt.Printf("%d\n", ans2)
		fmt.Printf("%d\n", len(pl2))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl2[i].id)
		}
		fmt.Printf("\n")
		if len(pl) > 0 && debug {
			c, _ := check(mat, tmpseg(seg))
			c, _ = check(mat, pl2)
			if c != ans2 {
				fmt.Printf("ERROR c = %d ans=%d\n", c, ans2)
			}
			fmt.Printf("logger--\n%s\n", logger)
		}
	} else {
		fmt.Printf("%d\n", ans)
		fmt.Printf("%d\n", len(pl))
		for i := 0; i < len(pl); i++ {
			fmt.Printf("%d ", pl[i].id)
		}
		fmt.Printf("\n")

		if len(pl) > 0 && debug {
			reverse(mat, seg)
			c, _ := check(mat, tmpseg(seg))
			c, _ = check(mat, pl)

			if c != ans {
				fmt.Printf("2ERROR c = %d ans=%d\n", c, ans)
			}
			fmt.Printf("%s\n", logger)
		}
	}

}
func check(mat []int, pl Segs) (int64, int) {
	n := len(mat)
	m := len(pl)
	if m <= 0 {
		return 0, 0
	}
	maxx := -1
	minn := 10000000
	//minw := -1
	for i := 0; i < n; i++ {
		in := 0
		for j := 0; j < m; j++ {
			if pl[j].l > i+1 || pl[j].r < i+1 {
				continue
			}
			in++
		}
		if in == 0 {
			if maxx == -1 || mat[maxx] < mat[i] {
				maxx = i
			}
		}
		if minn > mat[i]-in {
			minn = mat[i] - in
			//minw = i
		}

	}
	if debug {
		maxxr := 0
		for i := 0; i < m; i++ {
			if pl[i].l <= 3119 && pl[i].r >= 3119 {
				//	fmt.Printf("range %d %d %d\n", pl[i].l, pl[i].r,pl[i].id)
			}

			if pl[i].r > maxxr {
				maxxr = pl[i].r
			}
		}
		//		fmt.Printf("check maxw = %d  minw = %d maxx=%d min=%d mat[minn]=%d maxxr=%d\n", maxx+1, minw+1, mat[maxx], minn, mat[minw],maxxr)
	}
	return int64(mat[maxx] - minn), mat[maxx]
}

/**

5 3
1 2 2 -2 3
3 5
1 5
3 5
 */