#include <bits/stdc++.h>
using namespace std;
const int maxn = 200005;
int a[maxn << 1];
struct Tree {
  int l, r, lz, mxV, miV, lMx, rMx, mx, ans;
} tree[maxn << 2];
void update(int rt, int lz) {
  tree[rt].lz += lz;
  tree[rt].mxV += lz;
  tree[rt].miV += lz;
  if (tree[rt].l != tree[rt].r) {
    tree[rt].lMx -= lz;
    tree[rt].rMx -= lz;
  }
  tree[rt].ans = max(tree[rt].mxV, tree[rt].ans);
}
void pushup(int rt) {
  tree[rt].mxV = max(tree[rt << 1].mxV, tree[rt << 1 | 1].mxV);
  tree[rt].miV = min(tree[rt << 1].miV, tree[rt << 1 | 1].miV);
  if (tree[rt].r - tree[rt].l >= 2) {
    if (tree[rt << 1].r == tree[rt << 1].l) {
      tree[rt].lMx = max(tree[rt << 1].mxV - 2 * tree[rt << 1 | 1].miV,
                         tree[rt << 1 | 1].lMx);
      tree[rt].rMx = max(-2 * tree[rt << 1].miV + tree[rt << 1 | 1].mxV,
                         tree[rt << 1 | 1].rMx);
      tree[rt].mx = tree[rt << 1].mxV + tree[rt << 1 | 1].rMx;
    } else if (tree[rt << 1 | 1].r == tree[rt << 1 | 1].l) {
      tree[rt].lMx =
          max(tree[rt << 1].mxV - 2 * tree[rt << 1 | 1].miV, tree[rt << 1].lMx);
      tree[rt].rMx = max(-2 * tree[rt << 1].miV + tree[rt << 1 | 1].mxV,
                         tree[rt << 1].rMx);
      tree[rt].mx = tree[rt << 1].lMx + tree[rt << 1 | 1].mxV;
    } else if (tree[rt << 1].r - tree[rt << 1].l >= 2 &&
               tree[rt << 1 | 1].r - tree[rt << 1 | 1].l >= 2) {
      tree[rt].lMx = max(tree[rt << 1].mxV - 2 * tree[rt << 1 | 1].miV,
                         max(tree[rt << 1].lMx, tree[rt << 1 | 1].lMx));
      tree[rt].rMx = max(-2 * tree[rt << 1].miV + tree[rt << 1 | 1].mxV,
                         max(tree[rt << 1].rMx, tree[rt << 1 | 1].rMx));
      tree[rt].mx = max(max(tree[rt << 1].lMx + tree[rt << 1 | 1].mxV,
                            tree[rt << 1].mxV + tree[rt << 1 | 1].rMx),
                        max(tree[rt << 1].mx, tree[rt << 1 | 1].mx));
    } else if (tree[rt << 1].r - tree[rt << 1].l >= 2) {
      tree[rt].lMx = max(tree[rt << 1].mxV - 2 * tree[rt << 1 | 1].miV,
                         max(tree[rt << 1].lMx, tree[rt << 1 | 1].lMx));
      tree[rt].rMx = max(-2 * tree[rt << 1].miV + tree[rt << 1 | 1].mxV,
                         max(tree[rt << 1].rMx, tree[rt << 1 | 1].rMx));
      tree[rt].mx = max(max(tree[rt << 1].lMx + tree[rt << 1 | 1].mxV,
                            tree[rt << 1].mxV + tree[rt << 1 | 1].rMx),
                        tree[rt << 1].mx);
    } else if (tree[rt << 1 | 1].r - tree[rt << 1 | 1].l >= 2) {
      tree[rt].lMx = max(tree[rt << 1].mxV - 2 * tree[rt << 1 | 1].miV,
                         max(tree[rt << 1].lMx, tree[rt << 1 | 1].lMx));
      tree[rt].rMx = max(-2 * tree[rt << 1].miV + tree[rt << 1 | 1].mxV,
                         max(tree[rt << 1].rMx, tree[rt << 1 | 1].rMx));
      tree[rt].mx = max(max(tree[rt << 1].lMx + tree[rt << 1 | 1].mxV,
                            tree[rt << 1].mxV + tree[rt << 1 | 1].rMx),
                        tree[rt << 1 | 1].mx);
    } else {
      tree[rt].lMx = max(tree[rt << 1].mxV - 2 * tree[rt << 1 | 1].miV,
                         max(tree[rt << 1].lMx, tree[rt << 1 | 1].lMx));
      tree[rt].rMx = max(-2 * tree[rt << 1].miV + tree[rt << 1 | 1].mxV,
                         max(tree[rt << 1].rMx, tree[rt << 1 | 1].rMx));
      tree[rt].mx = max(tree[rt << 1].lMx + tree[rt << 1 | 1].mxV,
                        tree[rt << 1].mxV + tree[rt << 1 | 1].rMx);
    }
    tree[rt].ans = max(tree[rt].mx, tree[rt].mxV);
  } else {
    tree[rt].lMx = tree[rt << 1].mxV - 2 * tree[rt << 1 | 1].miV;
    tree[rt].rMx = -2 * tree[rt << 1].miV + tree[rt << 1 | 1].mxV;
    tree[rt].ans = tree[rt].mx;
  }
}
void pushdown(int rt) {
  if (tree[rt].lz) {
    update(rt << 1, tree[rt].lz);
    update(rt << 1 | 1, tree[rt].lz);
    tree[rt].lz = 0;
  }
}
void build(int rt, int l, int r) {
  tree[rt].l = l;
  tree[rt].r = r;
  tree[rt].lz = 0;
  tree[rt].mx = tree[rt].lMx = tree[rt].rMx = 0;
  if (l == r) {
    tree[rt].ans = tree[rt].mxV = tree[rt].miV = a[l - 1];
    return;
  }
  int mid = (l + r) >> 1;
  build(rt << 1, l, mid);
  build(rt << 1 | 1, mid + 1, r);
  pushup(rt);
}
void modify(int rt, int l, int r, int x) {
  if (l == tree[rt].l && r == tree[rt].r) {
    update(rt, x);
    return;
  }
  pushdown(rt);
  int mid = (tree[rt].l + tree[rt].r) >> 1;
  if (r <= mid) {
    modify(rt << 1, l, r, x);
  } else if (l > mid) {
    modify(rt << 1 | 1, l, r, x);
  } else {
    modify(rt << 1, l, mid, x);
    modify(rt << 1 | 1, mid + 1, r, x);
  }
  pushup(rt);
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n, q;
  cin >> n >> q;
  {
    string s;
    cin >> s;
    int sum = 0;
    for (int i = 0; i < s.length(); ++i) {
      if (s[i] == '(')
        ++sum;
      else
        --sum;
      a[i] = sum;
    }
    build(1, 1, 2 * (n - 1));
    cout << tree[1].ans << "\n";
    for (int i = 0; i < q; ++i) {
      int x, y;
      cin >> x >> y;
      --x;
      --y;
      if (s[x] != s[y]) {
        if (x < y) {
          if (s[x] == '(') {
            modify(1, x + 1, y, -2);
          } else {
            modify(1, x + 1, y, 2);
          }
        } else {
          if (s[y] == '(') {
            modify(1, y + 1, x, -2);
          } else {
            modify(1, y + 1, x, 2);
          }
        }
        swap(s[x], s[y]);
      }
      cout << tree[1].ans << "\n";
    }
    cout << flush;
  }
  return 0;
}
