#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 100;
struct Node {
  int depth, Min_depth, Max_depth, Max_lv, Max_rv, Max_lrv;
} node[maxn << 2];
int n, m;
char parenthesis[maxn];
void init() { scanf("%d%d%s", &n, &m, parenthesis + 1); }
Node get_left_parenthesis() { return Node{1, 0, 1, 0, 1, 1}; }
Node get_right_parenthesis() { return Node{-1, -1, 0, 2, 1, 1}; }
Node shifted_left(int depth, int root) {
  return Node{node[root].depth + depth,     node[root].Min_depth + depth,
              node[root].Max_depth + depth, node[root].Max_lv - depth,
              node[root].Max_rv - depth,    node[root].Max_lrv};
}
void merge(int root) {
  int chl = root << 1;
  int chr = root << 1 | 1;
  Node rhs_shifted = shifted_left(node[chl].depth, chr);
  node[root].depth = rhs_shifted.depth;
  node[root].Min_depth = min(node[chl].Min_depth, rhs_shifted.Min_depth);
  node[root].Max_depth = max(node[chl].Max_depth, rhs_shifted.Max_depth);
  node[root].Max_lv = max(
      node[chl].Max_lv,
      max(rhs_shifted.Max_lv, node[chl].Max_depth - 2 * rhs_shifted.Min_depth));
  node[root].Max_rv = max(
      node[chl].Max_rv,
      max(rhs_shifted.Max_rv, rhs_shifted.Max_depth - 2 * node[chl].Min_depth));
  node[root].Max_lrv = max(max(node[chl].Max_lrv, rhs_shifted.Max_lrv),
                           max(node[chl].Max_lv + rhs_shifted.Max_depth,
                               rhs_shifted.Max_rv + node[chl].Max_depth));
}
void build_tree(int root, int l, int r) {
  if (l == r) {
    if (parenthesis[l] == '(')
      node[root] = get_left_parenthesis();
    else
      node[root] = get_right_parenthesis();
    return;
  }
  int mid = l + r >> 1;
  build_tree(root << 1, l, mid);
  build_tree(root << 1 | 1, mid + 1, r);
  merge(root);
}
int query_max() { return node[1].Max_lrv; }
void change(int root, int l, int r, int find_pos, int change_pos) {
  if (l == r) {
    if (parenthesis[change_pos] == '(')
      node[root] = get_left_parenthesis();
    else
      node[root] = get_right_parenthesis();
    return;
  }
  int mid = l + r >> 1;
  if (find_pos <= mid) {
    change(root << 1, l, mid, find_pos, change_pos);
  } else {
    change(root << 1 | 1, mid + 1, r, find_pos, change_pos);
  }
  merge(root);
}
void change(int pos1, int pos2) {
  change(1, 1, 2 * n - 2, pos1, pos2);
  change(1, 1, 2 * n - 2, pos2, pos1);
}
int main() {
  init();
  build_tree(1, 1, 2 * n - 2);
  printf("%d\n", query_max());
  while (m--) {
    int pos1, pos2;
    scanf("%d%d", &pos1, &pos2);
    change(pos1, pos2);
    swap(parenthesis[pos1], parenthesis[pos2]);
    printf("%d\n", query_max());
  }
  return 0;
}
