#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
int n, q;
char s[maxn << 1];
struct node {
  int pre_max, suf_max, pre_min, suf_min, pre_d, suf_d, d, sum, ans;
  void lft() {
    pre_max = suf_max = pre_d = suf_d = d = sum = ans = 1;
    pre_min = suf_min = 0;
  }
  void rgt() {
    pre_d = suf_d = d = ans = 1;
    pre_min = suf_min = sum = -1;
    pre_max = suf_max = 0;
  }
  node operator+(const node &A) const {
    node c;
    c.pre_max = max(A.pre_max + sum, pre_max);
    c.suf_max = max(A.suf_max, suf_max + A.sum);
    c.pre_min = min(A.pre_min + sum, pre_min);
    c.suf_min = min(A.suf_min, suf_min + A.sum);
    c.pre_d = max(pre_d, max(A.pre_d - sum, d + A.pre_max));
    c.suf_d = max(A.suf_d, max(A.sum + suf_d, A.d - suf_min));
    c.d = max(A.d - sum, d + A.sum);
    c.sum = sum + A.sum;
    c.ans = max(max(max(ans, A.ans), A.pre_d - suf_min), suf_d + A.pre_max);
    return c;
  }
} tree[maxn << 3];
void build(int l, int r, int rt) {
  if (l == r) {
    if (s[l] == '(') tree[rt].lft();
    if (s[l] == ')') tree[rt].rgt();
    return;
  }
  int mid = (l + r) >> 1;
  build(l, mid, rt << 1);
  build(mid + 1, r, rt << 1 | 1);
  tree[rt] = tree[rt << 1] + tree[rt << 1 | 1];
}
void update(int l, int r, int rt, int x) {
  if (l == r) {
    if (s[l] == '(') tree[rt].lft();
    if (s[l] == ')') tree[rt].rgt();
    return;
  }
  int mid = (l + r) >> 1;
  if (x <= mid)
    update(l, mid, rt << 1, x);
  else
    update(mid + 1, r, rt << 1 | 1, x);
  tree[rt] = tree[rt << 1] + tree[rt << 1 | 1];
}
int main() {
  cin >> n >> q >> s + 1;
  n = (n << 1) - 2;
  build(1, n, 1);
  printf("%d\n", tree[1].ans);
  while (q--) {
    int x, y;
    scanf("%d%d", &x, &y);
    swap(s[x], s[y]);
    update(1, n, 1, x);
    update(1, n, 1, y);
    printf("%d\n", tree[1].ans);
  }
}
