← Home
package main

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

var (
	maxP []int
	minP []int
	Lmax []int
	Rmax []int
	ans  []int
	lazy []int
	P    []int
)

func max(a, b int) int {
	if a > b {
		return a
	}
	return b
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func build(node, l, r int) {
	if l == r {
		maxP[node] = P[l]
		minP[node] = P[l]
		Lmax[node] = -P[l]
		Rmax[node] = -P[l]
		ans[node] = 0
		return
	}
	mid := (l + r) / 2
	build(node*2, l, mid)
	build(node*2+1, mid+1, r)
	pull(node)
}

func apply(node, val int) {
	maxP[node] += val
	minP[node] += val
	Lmax[node] -= val
	Rmax[node] -= val
	lazy[node] += val
}

func push(node int) {
	if lazy[node] != 0 {
		apply(node*2, lazy[node])
		apply(node*2+1, lazy[node])
		lazy[node] = 0
	}
}

func pull(node int) {
	l := node * 2
	r := node * 2 + 1

	maxP[node] = max(maxP[l], maxP[r])
	minP[node] = min(minP[l], minP[r])

	Lmax[node] = max(max(Lmax[l], Lmax[r]), maxP[l]-2*minP[r])
	Rmax[node] = max(max(Rmax[l], Rmax[r]), -2*minP[l]+maxP[r])

	ans[node] = max(max(ans[l], ans[r]), max(Lmax[l]+maxP[r], maxP[l]+Rmax[r]))
}

func update(node, l, r, ql, qr, val int) {
	if ql <= l && r <= qr {
		apply(node, val)
		return
	}
	push(node)
	mid := (l + r) / 2
	if ql <= mid {
		update(node*2, l, mid, ql, qr, val)
	}
	if qr > mid {
		update(node*2+1, mid+1, r, ql, qr, val)
	}
	pull(node)
}

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Split(bufio.ScanWords)
	scanner.Buffer(make([]byte, 1024*1024), 10*1024*1024)

	scanInt := func() int {
		scanner.Scan()
		res, _ := strconv.Atoi(scanner.Text())
		return res
	}

	if !scanner.Scan() {
		return
	}
	n, _ := strconv.Atoi(scanner.Text())
	q := scanInt()

	scanner.Scan()
	sBytes := []byte(scanner.Text())

	L := 2*n - 2
	P = make([]int, L+1)
	for i := 1; i <= L; i++ {
		if sBytes[i-1] == '(' {
			P[i] = P[i-1] + 1
		} else {
			P[i] = P[i-1] - 1
		}
	}

	treeSize := 4 * (L + 1)
	maxP = make([]int, treeSize)
	minP = make([]int, treeSize)
	Lmax = make([]int, treeSize)
	Rmax = make([]int, treeSize)
	ans = make([]int, treeSize)
	lazy = make([]int, treeSize)

	build(1, 0, L)

	out := bufio.NewWriter(os.Stdout)
	defer out.Flush()

	fmt.Fprintln(out, ans[1])

	for i := 0; i < q; i++ {
		a := scanInt()
		b := scanInt()
		if a > b {
			a, b = b, a
		}
		if sBytes[a-1] != sBytes[b-1] {
			diff := 0
			if sBytes[a-1] == '(' {
				diff = -2
			} else {
				diff = 2
			}
			update(1, 0, L, a, b-1, diff)
			sBytes[a-1], sBytes[b-1] = sBytes[b-1], sBytes[a-1]
		}
		fmt.Fprintln(out, ans[1])
	}
}