← Home
package main

import (
	"io"
	"os"
	"strconv"
)

type FastScanner struct {
	data []byte
	idx  int
	n    int
}

func NewFastScanner() *FastScanner {
	data, _ := io.ReadAll(os.Stdin)
	return &FastScanner{data: data, n: len(data)}
}

func (fs *FastScanner) NextInt() int {
	for fs.idx < fs.n && (fs.data[fs.idx] < '0' || fs.data[fs.idx] > '9') {
		fs.idx++
	}
	val := 0
	for fs.idx < fs.n && fs.data[fs.idx] >= '0' && fs.data[fs.idx] <= '9' {
		val = val*10 + int(fs.data[fs.idx]-'0')
		fs.idx++
	}
	return val
}

func (fs *FastScanner) NextBytes() []byte {
	for fs.idx < fs.n && fs.data[fs.idx] <= ' ' {
		fs.idx++
	}
	start := fs.idx
	for fs.idx < fs.n && fs.data[fs.idx] > ' ' {
		fs.idx++
	}
	return fs.data[start:fs.idx]
}

type Node struct {
	len         int32
	pni, sni    int32
	bni         int32
	pnd, snd    int32
	bnd         int32
	first, last uint8
}

var tr []Node
var lazy []bool
var str []byte

func merge(a, b Node) Node {
	if a.len == 0 {
		return b
	}
	if b.len == 0 {
		return a
	}
	var r Node
	r.len = a.len + b.len
	r.first = a.first
	r.last = b.last

	condNI := a.last >= b.first
	condND := a.last <= b.first

	r.pni = a.pni
	if a.pni == a.len && condNI {
		r.pni = a.len + b.pni
	}
	r.sni = b.sni
	if b.sni == b.len && condNI {
		r.sni = b.len + a.sni
	}
	r.bni = a.bni
	if b.bni > r.bni {
		r.bni = b.bni
	}
	if condNI {
		t := a.sni + b.pni
		if t > r.bni {
			r.bni = t
		}
	}

	r.pnd = a.pnd
	if a.pnd == a.len && condND {
		r.pnd = a.len + b.pnd
	}
	r.snd = b.snd
	if b.snd == b.len && condND {
		r.snd = b.len + a.snd
	}
	r.bnd = a.bnd
	if b.bnd > r.bnd {
		r.bnd = b.bnd
	}
	if condND {
		t := a.snd + b.pnd
		if t > r.bnd {
			r.bnd = t
		}
	}

	return r
}

func apply(v int) {
	tr[v].first ^= 1
	tr[v].last ^= 1
	tr[v].pni, tr[v].pnd = tr[v].pnd, tr[v].pni
	tr[v].sni, tr[v].snd = tr[v].snd, tr[v].sni
	tr[v].bni, tr[v].bnd = tr[v].bnd, tr[v].bni
	lazy[v] = !lazy[v]
}

func push(v int) {
	if lazy[v] {
		apply(v << 1)
		apply(v<<1 | 1)
		lazy[v] = false
	}
}

func build(v, l, r int) {
	if l == r {
		bit := uint8(0)
		if str[l-1] == '>' {
			bit = 1
		}
		tr[v] = Node{
			len:   1,
			pni:   1,
			sni:   1,
			bni:   1,
			pnd:   1,
			snd:   1,
			bnd:   1,
			first: bit,
			last:  bit,
		}
		return
	}
	m := (l + r) >> 1
	build(v<<1, l, m)
	build(v<<1|1, m+1, r)
	tr[v] = merge(tr[v<<1], tr[v<<1|1])
}

func update(v, l, r, ql, qr int) {
	if ql <= l && r <= qr {
		apply(v)
		return
	}
	push(v)
	m := (l + r) >> 1
	if ql <= m {
		update(v<<1, l, m, ql, qr)
	}
	if qr > m {
		update(v<<1|1, m+1, r, ql, qr)
	}
	tr[v] = merge(tr[v<<1], tr[v<<1|1])
}

func query(v, l, r, ql, qr int) Node {
	if ql <= l && r <= qr {
		return tr[v]
	}
	push(v)
	m := (l + r) >> 1
	if qr <= m {
		return query(v<<1, l, m, ql, qr)
	}
	if ql > m {
		return query(v<<1|1, m+1, r, ql, qr)
	}
	left := query(v<<1, l, m, ql, qr)
	right := query(v<<1|1, m+1, r, ql, qr)
	return merge(left, right)
}

func main() {
	fs := NewFastScanner()
	n := fs.NextInt()
	q := fs.NextInt()
	str = fs.NextBytes()

	tr = make([]Node, 4*n+5)
	lazy = make([]bool, 4*n+5)

	build(1, 1, n)

	out := make([]byte, 0, q*6)
	for i := 0; i < q; i++ {
		l := fs.NextInt()
		r := fs.NextInt()
		update(1, 1, n, l, r)
		res := query(1, 1, n, l, r)
		out = strconv.AppendInt(out, int64(res.bni), 10)
		out = append(out, '\n')
	}
	_, _ = os.Stdout.Write(out)
}