#include <bits/stdc++.h>
using namespace std;
const int INF = 1e8;
template <typename T>
struct LazySegtree {
  int n;
  vector<T> laz;
  vector<T> A, B, AB, BC, ABC;
  vector<bool> lazflag;
  T e = -INF;
  LazySegtree() {}
  LazySegtree(int n_input) { initialize(n_input); }
  void initialize(int n_input) {
    n = 1;
    while (n < n_input) n <<= 1;
    laz.resize(2 * n - 1, 0);
    lazflag.resize(2 * n - 1, false);
    A.resize(2 * n - 1, e);
    B.resize(2 * n - 1, e);
    AB.resize(2 * n - 1, e);
    BC.resize(2 * n - 1, e);
    ABC.resize(2 * n - 1, e);
  }
  void calc(int k) {
    int l = 2 * k + 1, r = 2 * k + 2;
    A[k] = max(A[l], A[r]);
    B[k] = max(B[l], B[r]);
    AB[k] = max({AB[l], AB[r], A[l] + B[r]});
    BC[k] = max({BC[l], BC[r], B[l] + A[r]});
    ABC[k] = max({ABC[l], ABC[r], AB[l] + A[r], A[l] + BC[r]});
  }
  void build(vector<T>& v) {
    for (int k = 0; k < v.size(); k++) {
      A[k + n - 1] = v[k];
      B[k + n - 1] = -2 * v[k];
    }
    for (int k = n - 2; k >= 0; k--) calc(k);
  }
  void eval(int k, int l, int r) {
    if (!lazflag[k]) return;
    A[k] += laz[k];
    B[k] += -2 * laz[k];
    AB[k] += -laz[k];
    BC[k] += -laz[k];
    if (r - l > 1) {
      laz[2 * k + 1] += laz[k];
      laz[2 * k + 2] += laz[k];
      lazflag[2 * k + 1] = lazflag[2 * k + 2] = true;
    }
    laz[k] = 0;
    lazflag[k] = false;
  }
  void update_between(int a, int b, T x) { update(a, b + 1, x, 0, 0, n); }
  void update(int a, int b, T x, int k, int l, int r) {
    eval(k, l, r);
    if (b <= l || r <= a) return;
    if (a <= l && r <= b) {
      laz[k] += x;
      lazflag[k] = true;
      eval(k, l, r);
    } else {
      update(a, b, x, 2 * k + 1, l, (l + r) / 2);
      update(a, b, x, 2 * k + 2, (l + r) / 2, r);
      calc(k);
    }
  }
  T get() { return query(0, n, 0, 0, n); }
  T query(int a, int b, int k, int l, int r) {
    eval(k, l, r);
    if (r <= a || b <= l) return e;
    if (a <= l && r <= b) return ABC[k];
    T vl = query(a, b, 2 * k + 1, l, (l + r) / 2);
    T vr = query(a, b, 2 * k + 2, (l + r) / 2, r);
    return max(vl, vr);
  }
};
int main() {
  int N, Q;
  cin >> N >> Q;
  string S;
  cin >> S;
  vector<int> D(2 * N);
  for (int i = 0; i < 2 * N - 2; i++) {
    D[i + 1] = D[i] + (S[i] == '(' ? 1 : -1);
  }
  LazySegtree<int> st(2 * N);
  st.build(D);
  int ans = st.get();
  printf("%d\n", ans);
  while (Q--) {
    int l, r;
    scanf("%d %d", &l, &r);
    l--;
    r--;
    if (l > r) swap(l, r);
    if (S[l] == S[r]) {
      printf("%d\n", ans);
      continue;
    }
    int c = (S[l] == '(' ? -2 : 2);
    swap(S[l], S[r]);
    l++;
    st.update_between(l, r, c);
    ans = st.get();
    printf("%d\n", ans);
  }
  return 0;
}
