#include <bits/stdc++.h>
const int maxn = 200005, inf = 6666666;
int n, val[maxn];
char s[maxn];
struct Node {
  int left, right, delta;
  int maxa, maxab, maxcb, maxabc, minb;
} tree[maxn * 4];
inline int max3(int a, int b, int c) {
  a = a > b ? a : b;
  return a > c ? a : c;
}
inline int max4(int a, int b, int c, int d) {
  a = a > b ? a : b;
  a = a > c ? a : c;
  return a > d ? a : d;
}
inline void pushup(int p) {
  tree[p].maxa = std::max(tree[(p * 2)].maxa, tree[(p * 2 + 1)].maxa);
  tree[p].maxab = max3(tree[(p * 2)].maxab, tree[(p * 2 + 1)].maxab,
                       tree[(p * 2)].maxa - tree[(p * 2 + 1)].minb * 2);
  tree[p].maxcb = max3(tree[(p * 2)].maxcb, tree[(p * 2 + 1)].maxcb,
                       tree[(p * 2 + 1)].maxa - tree[(p * 2)].minb * 2);
  tree[p].maxabc = max4(tree[(p * 2)].maxabc, tree[(p * 2 + 1)].maxabc,
                        tree[(p * 2)].maxab + tree[(p * 2 + 1)].maxa,
                        tree[(p * 2)].maxa + tree[(p * 2 + 1)].maxcb);
  tree[p].minb = std::min(tree[(p * 2)].minb, tree[(p * 2 + 1)].minb);
}
inline void apply(int p, int d) {
  tree[p].maxa += d;
  tree[p].maxab -= d;
  tree[p].maxcb -= d;
  tree[p].minb += d;
}
inline void pushdown(int p) {
  if (tree[p].delta) {
    apply((p * 2), tree[p].delta);
    tree[(p * 2)].delta += tree[p].delta;
    apply((p * 2 + 1), tree[p].delta);
    tree[(p * 2 + 1)].delta += tree[p].delta;
    tree[p].delta = 0;
  }
}
void build_tree(int p, int left, int right) {
  tree[p].left = left;
  tree[p].right = right;
  tree[p].delta = 0;
  if (left == right) {
    tree[p].maxa = val[left];
    tree[p].maxab = -val[left];
    tree[p].maxcb = -val[left];
    tree[p].maxabc = 0;
    tree[p].minb = val[left];
    return;
  }
  int mid = (tree[p].left + tree[p].right) / 2;
  build_tree((p * 2), left, mid);
  build_tree((p * 2 + 1), mid + 1, right);
  pushup(p);
}
void modify(int p, int ql, int qr, const int& d) {
  if (ql == tree[p].left && qr == tree[p].right) {
    apply(p, d);
    tree[p].delta += d;
    return;
  }
  pushdown(p);
  int mid = (tree[p].left + tree[p].right) / 2;
  if (qr <= mid) {
    modify((p * 2), ql, qr, d);
  } else if (ql > mid) {
    modify((p * 2 + 1), ql, qr, d);
  } else {
    modify((p * 2), ql, mid, d);
    modify((p * 2 + 1), mid + 1, qr, d);
  }
  pushup(p);
}
int main() {
  int q;
  scanf("%d%d", &n, &q);
  scanf("%s", s + 1);
  n = (n - 1) * 2;
  for (int i = 1; i <= n; ++i) {
    if (s[i] == '(') {
      val[i] = val[i - 1] + 1;
    } else {
      val[i] = val[i - 1] - 1;
    }
  }
  build_tree(1, 1, n);
  printf("%d\n", tree[1].maxabc);
  int t1, t2;
  while (q--) {
    scanf("%d%d", &t1, &t2);
    if (t1 > t2) {
      std::swap(t1, t2);
    }
    if (s[t1] == '(') {
      modify(1, t1, t2 - 1, -2);
    } else {
      modify(1, t1, t2 - 1, 2);
    }
    std::swap(s[t1], s[t2]);
    printf("%d\n", tree[1].maxabc);
  }
  return 0;
}
