#include <bits/stdc++.h>
using namespace std;
const int N = 100005 * 2;
struct SegmentTree {
  int l, r;
  int sum, lmx, rmn, ansl, ansr, ans, Ans;
} t[N << 2];
int s[N];
char ss[N];
void merge(int p) {
  t[p].sum = t[p * 2].sum + t[p * 2 + 1].sum;
  t[p].lmx = max(t[p * 2].lmx, t[p * 2].sum + t[p * 2 + 1].lmx);
  t[p].rmn = min(t[p * 2 + 1].rmn, t[p * 2 + 1].sum + t[p * 2].rmn);
  t[p].ansl = max(max(t[p * 2].ansl, t[p * 2 + 1].ansl - t[p * 2].sum),
                  t[p * 2].ans + t[p * 2 + 1].lmx);
  t[p].ansr = max(max(t[p * 2 + 1].ansr, t[p * 2].ansr + t[p * 2 + 1].sum),
                  t[p * 2 + 1].ans - t[p * 2].rmn);
  t[p].ans =
      max(t[p * 2].ans + t[p * 2 + 1].sum, t[p * 2 + 1].ans - t[p * 2].sum);
  t[p].Ans = max(max(max(t[p * 2].Ans, t[p * 2 + 1].Ans),
                     t[p * 2 + 1].ansl - t[p * 2].rmn),
                 t[p * 2].ansr + t[p * 2 + 1].lmx);
}
void build(int p, int l, int r) {
  t[p].l = l, t[p].r = r;
  if (l == r) {
    t[p].sum = s[l];
    t[p].lmx = max(s[l], 0);
    t[p].rmn = min(s[l], 0);
    t[p].ansl = t[p].ansr = t[p].ans = t[p].Ans = 1;
    return;
  }
  int mid = (l + r) / 2;
  build(p * 2, l, mid);
  build(p * 2 + 1, mid + 1, r);
  merge(p);
}
void change(int p, int x, int d) {
  if (t[p].l == t[p].r) {
    t[p].sum = d;
    t[p].lmx = max(d, 0);
    t[p].rmn = min(d, 0);
    t[p].ansl = t[p].ansr = t[p].ans = t[p].Ans = 1;
    return;
  }
  int mid = (t[p].l + t[p].r) / 2;
  if (x <= mid)
    change(p * 2, x, d);
  else
    change(p * 2 + 1, x, d);
  merge(p);
}
int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  scanf("%s", ss + 1);
  for (int i = 1; i <= 2 * (n - 1); i++) s[i] = (ss[i] == '(' ? 1 : -1);
  build(1, 1, 2 * (n - 1));
  printf("%d\n", t[1].Ans);
  for (int i = 1; i <= m; i++) {
    int l, r;
    scanf("%d%d", &l, &r);
    change(1, l, s[r]);
    change(1, r, s[l]);
    swap(s[l], s[r]);
    printf("%d\n", t[1].Ans);
  }
}
