#include <bits/stdc++.h>
using namespace std;
int readInt() {
  int x;
  if (scanf(" %d", &x) != EOF) return x;
  return -1;
}
long long int readLint() {
  long long int x;
  if (cin >> x) return x;
  return -1;
}
string readString() {
  string s;
  if (cin >> s) return s;
  return "";
}
template <typename Data, typename Input>
class SegmentTree {
 private:
  int n;
  vector<Data> dv;

 public:
  SegmentTree(vector<Input>& input) {
    n = input.size();
    int vectorSize = 1;
    while (vectorSize < n) {
      vectorSize *= 2;
    }
    vectorSize *= 2;
    dv = vector<Data>(vectorSize, Data::identity());
    build(input, 0, 0, n);
  }
  void update(int x, Input val) { update(x, val, 0, 0, n); }
  Data query(int left, int right) {
    assert(left >= 0 && right <= n);
    return query(0, 0, n, left, right);
  }
  void print() {
    printf("Tree size for n = %d is %d\n", n, dv.size());
    int count = 0;
    for (auto& d : dv) {
      printf("Node %d: ", count++);
      d.print();
      cout << " ";
    }
    cout << endl;
  }

 private:
  Data query(int root, int tl, int tr, int l, int r) {
    if (l >= r) {
      return Data::identity();
    }
    if (l == tl && r == tr) {
      return dv[root];
    }
    int tm = (tl + tr + 1) / 2;
    Data left = query(2 * root + 1, tl, tm, l, min(r, tm));
    Data right = query(2 * root + 2, tm, tr, max(tm, l), r);
    return Data::combine(left, right);
  }
  void update(int x, Input val, int root, int tl, int tr) {
    if (tl == tr - 1) {
      dv[root] = Data::make(val);
      return;
    }
    int tm = (tl + tr + 1) / 2;
    if (x < tm)
      update(x, val, 2 * root + 1, tl, tm);
    else
      update(x, val, 2 * root + 2, tm, tr);
    dv[root] = Data::combine(dv[2 * root + 1], dv[2 * root + 2]);
  }
  Data build(vector<Input>& values, int root, int tl, int tr) {
    assert(root < dv.size());
    if (tl == tr - 1) {
      return dv[root] = Data::make(values[tl]);
    }
    int tm = (tl + tr + 1) / 2;
    Data left = build(values, 2 * root + 1, tl, tm);
    Data right = build(values, 2 * root + 2, tm, tr);
    return dv[root] = Data::combine(left, right);
  }
};
struct Value {
  int sum, a, minus2a, aMinus2b, minus2bPlusC, aMinus2bPlusC;
  bool isIdentity = false;
  Value() {}
  static Value make(int x) {
    Value ret;
    ret.sum = x;
    ret.a = x;
    ret.minus2a = -2 * x;
    ret.aMinus2b = x - 2 * x;
    ret.minus2bPlusC = -2 * x + x;
    ret.aMinus2bPlusC = x - 2 * x + x;
    return ret;
  }
  static Value identity() {
    Value ret = Value::make(0);
    ret.isIdentity = true;
    return ret;
  }
  static Value combine(Value p, Value q) {
    if (p.isIdentity) return q;
    if (q.isIdentity) return p;
    Value ret;
    ret.sum = p.sum + q.sum;
    ret.a = max(p.a, p.sum + q.a);
    ret.minus2a = max(p.minus2a, -2 * p.sum + q.minus2a);
    ret.aMinus2b =
        max(max(p.aMinus2b, -p.sum + q.aMinus2b), p.a - 2 * p.sum + q.minus2a);
    ret.minus2bPlusC = max(max(p.minus2bPlusC, -p.sum + q.minus2bPlusC),
                           p.minus2a + p.sum + q.a);
    ret.aMinus2bPlusC =
        max(max(p.aMinus2bPlusC, q.aMinus2bPlusC),
            max(p.aMinus2b + p.sum + q.a, p.a - p.sum + q.minus2bPlusC));
    return ret;
  }
  void print() {
    printf(
        "sum = %d, a = %d, minus2a = %d, aMinus2b = %d, minus2bPlusC = %d, "
        "aMinus2bPlusC = %d\n",
        sum, a, minus2a, aMinus2b, minus2bPlusC, aMinus2bPlusC);
  }
};
struct SingleCase {
  bool solveCase() {
    int blah = readInt();
    if (blah < 0) return false;
    int n = 2 * (blah - 1);
    int q = readInt();
    string s = readString();
    assert(s.size() == n);
    vector<int> v(n, 0);
    for (int i = 0; i < n; ++i) {
      v[i] = (s[i] == '(') ? 1 : -1;
    }
    SegmentTree<Value, int> tree(v);
    printf("%d\n", tree.query(0, n).aMinus2bPlusC);
    while (q--) {
      int x = readInt() - 1;
      int y = readInt() - 1;
      swap(s[x], s[y]);
      tree.update(x, s[x] == '(' ? 1 : -1);
      tree.update(y, s[y] == '(' ? 1 : -1);
      printf("%d\n", tree.query(0, n).aMinus2bPlusC);
    }
    return true;
  }
};
int main() {
  while (SingleCase().solveCase()) {
  }
}
