#include <bits/stdc++.h>
using namespace std;
template <typename T, typename E>
struct SegmentTree {
  using F = function<T(T, T)>;
  using G = function<T(T, E, int)>;
  using H = function<E(E, E)>;
  int n;
  F f;
  G g;
  H h;
  T ti;
  E ei;
  vector<T> dat;
  vector<E> laz;
  SegmentTree(F f, G g, H h, T ti, E ei) : f(f), g(g), h(h), ti(ti), ei(ei) {}
  void init(int n_) {
    n = 1;
    while (n < n_) n <<= 1;
    dat.assign((n << 1) - 1, ti);
    laz.assign((n << 1) - 1, ei);
  }
  void build(const vector<T> &v) {
    int n_ = v.size();
    init(n_);
    for (int i = 0; i < n_; i++) dat[n + i - 1] = v[i];
    for (int i = n - 2; i >= 0; i--)
      dat[i] = f(dat[(i << 1) + 2], dat[(i << 1) | 1]);
  }
  void eval(int k, int l, int r) {
    if (laz[k] == ei) return;
    dat[k] = g(dat[k], laz[k], r - l);
    if (r - l > 1) {
      laz[(k << 1) | 1] = h(laz[(k << 1) | 1], laz[k]);
      laz[(k << 1) + 2] = h(laz[(k << 1) + 2], laz[k]);
    }
    laz[k] = ei;
  }
  void update(int a, int b, E x, int k = 0, int l = 0, int r = -1) {
    if (r < 0) r = n;
    eval(k, l, r);
    if (r <= a || b <= l) return;
    if (a <= l && r <= b) {
      laz[k] = h(laz[k], x);
      eval(k, l, r);
    } else {
      update(a, b, x, (k << 1) | 1, l, (l + r) / 2);
      update(a, b, x, (k << 1) + 2, (l + r) / 2, r);
      dat[k] = f(dat[(k << 1) | 1], dat[(k << 1) + 2]);
    }
  }
  T query(int a, int b, int k = 0, int l = 0, int r = -1) {
    if (r < 0) r = n;
    eval(k, l, r);
    if (r <= a || b <= l) return ti;
    if (a <= l && r <= b) return dat[k];
    T xl = query(a, b, (k << 1) | 1, l, (l + r) / 2);
    T xr = query(a, b, (k << 1) + 2, (l + r) / 2, r);
    return f(xl, xr);
  }
  template <typename C>
  int lower_find(int a, int b, C &check, T x, int k = 1, int l = 0,
                 int r = -1) {
    if (r < 0) r = n;
    if (!check(f(x, dat[k])) || r <= a || b <= l) return -1;
    if (r - l == 1) return l;
    int xl = lower_find(a, b, check, x, (k << 1), l, (l + r) / 2);
    if (xl >= 0) return xl;
    x = f(x, dat[(k << 1)]);
    return lower_find(a, b, check, x, (k << 1) | 1, (l + r) / 2, r);
  }
  template <typename C>
  int lower_find(int a, int b, C &check) {
    T x = ti;
    return lower_find(a, b, check, x);
  }
  template <typename C>
  int upper_find(int a, int b, C &check, T x, int k = 2, int l = 0,
                 int r = -1) {
    if (r < 0) r = n;
    if (r <= a || b <= l) return -1;
    if (r - l == 1) return l;
    if (check(f(x, dat[k]))) {
      int xr =
          upper_find(a, b, check, f(x, dat[k]), ((k + 1) << 1), (l + r) / 2, r);
      if (xr >= 0) return xr;
    }
    return upper_find(a, b, check, x, (k << 1), l, (l + r) / 2);
  }
  template <typename C>
  int upper_find(int a, int b, C &check) {
    T x = ti;
    return upper_find(a, b, check, x);
  }
};
signed main() {
  int n;
  char s[(int)1e6 + 10];
  scanf("%d", &n);
  scanf("%s", s);
  int N = (n + 10) / 2;
  vector<int> sum(N, 0);
  auto f = [](int a, int b) { return min(a, b); };
  auto ff = [](int a, int b) { return max(a, b); };
  auto g = [](int a, int b, int len) { return a + b; };
  auto h = [](int a, int b) { return a + b; };
  SegmentTree<int, int> mn(f, g, h, (1 << 30), 0), mx(ff, g, h, -(1 << 30), 0);
  mn.build(sum);
  mx.build(sum);
  int id = 1, mxx = 1;
  int cnt = 0;
  string t(N, '-');
  for (int i = (0); i < ((n)); ++i) {
    if (s[i] == '(') {
      int v = 1;
      if (t[id] == '(') v--;
      if (t[id] == ')') v++;
      t[id] = s[i];
      cnt += v;
      mn.update(id, N, v);
      mx.update(id, N, v);
    } else if (s[i] == ')') {
      int v = -1;
      if (t[id] == '(') v--;
      if (t[id] == ')') v++;
      t[id] = s[i];
      cnt += v;
      mn.update(id, N, v);
      mx.update(id, N, v);
    } else if (s[i] == 'L')
      id = max(1, id - 1);
    else if (s[i] == 'R')
      id++;
    else {
      int v = 0;
      if (t[id] == '(') v--;
      if (t[id] == ')') v++;
      t[id] = s[i];
      cnt += v;
      mn.update(id, N, v);
      mx.update(id, N, v);
    }
    mxx = max(mxx, id);
    if (cnt == 0 && mn.query(0, mxx + 1) >= 0)
      printf("%d ", mx.query(0, mxx + 1));
    else
      printf("%d ", -1);
  }
  return 0;
}
