#include <bits/stdc++.h>
using namespace std;
const int N = 200005;
int read() {
  int f = 1, g = 0;
  char ch = getchar();
  for (; !isdigit(ch); ch = getchar())
    if (ch == '-') f = -1;
  for (; isdigit(ch); ch = getchar()) g = g * 10 + ch - '0';
  return f * g;
}
int n, q;
char ch[N];
struct node {
  int f[4], ansl, ansr, sum;
  node() {}
  node(int _a, int _b, int _c, int _d, int _x, int _y, int _z) {
    f[0] = _a;
    f[1] = _b;
    f[2] = _c;
    f[3] = _d;
    ansl = _x;
    ansr = _y;
    sum = _z;
  }
} r1(1, 1, 1, 1, 1, 0, 1), r2(1, 1, 1, 1, 0, -1, -1);
node operator+(node x, node y) {
  node z;
  z.f[0] = max(x.f[0] + y.sum, y.f[0] - x.sum);
  z.f[1] = max(max(x.f[1], x.f[0] + y.ansl), y.f[1] - x.sum);
  z.f[2] = max(x.f[2] + y.sum, max(y.f[2], y.f[0] - x.ansr));
  z.f[3] = max(max(x.f[3], x.f[2] + y.ansl), max(y.f[3], y.f[1] - x.ansr));
  z.ansl = max(x.ansl, x.sum + y.ansl);
  z.ansr = min(y.ansr, y.sum + x.ansr);
  z.sum = x.sum + y.sum;
  return z;
}
node calc(int pos) { return (ch[pos] == '(') ? r1 : r2; }
struct segment_tree {
  node f[N << 2];
  void build(int x, int l, int r) {
    if (l == r) {
      f[x] = calc(l);
      return;
    }
    int mid = (l + r) >> 1;
    build(x * 2, l, mid);
    build(x * 2 + 1, mid + 1, r);
    f[x] = f[x * 2] + f[x * 2 + 1];
  }
  void modi(int x, int l, int r, int &pos) {
    if (l == r) {
      f[x] = calc(l);
      return;
    }
    int mid = (l + r) >> 1;
    if (pos <= mid)
      modi(x * 2, l, mid, pos);
    else
      modi(x * 2 + 1, mid + 1, r, pos);
    f[x] = f[x * 2] + f[x * 2 + 1];
  }
  void modify(int pos) { modi(1, 1, n, pos); }
} f;
int main() {
  n = (read() - 1) * 2;
  q = read();
  scanf("%s", ch + 1);
  f.build(1, 1, n);
  printf("%d\n", f.f[1].f[3]);
  while (q--) {
    int x = read(), y = read();
    swap(ch[x], ch[y]);
    f.modify(x);
    f.modify(y);
    printf("%d\n", f.f[1].f[3]);
  }
  return 0;
}
