#include <bits/stdc++.h>
using namespace std;
template <typename Arg1>
void __f(const char* name, Arg1&& arg1) {
  std::cerr << name << " : " << arg1 << '\n';
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args) {
  const char* comma = strchr(names + 1, ',');
  std::cerr.write(names, comma - names) << " : " << arg1 << " | ";
  __f(comma + 1, args...);
}
struct data {
  int mn, mx;
  data() : mn(0), mx(0){};
};
struct SegTree {
  int T;
  vector<data> st;
  vector<bool> cLazy;
  vector<int> lazy;
  void init(int n) {
    T = n;
    st.resize(4 * T + 5);
    cLazy.assign(4 * T + 5, false);
    lazy.assign(4 * T + 5, 0);
  }
  void merge(data& cur, data& l, data& r) {
    cur.mn = min(l.mn, r.mn);
    cur.mx = max(l.mx, r.mx);
  }
  void propagate(int node, int L, int R) {
    if (L != R) {
      cLazy[node * 2] = 1;
      cLazy[node * 2 + 1] = 1;
      lazy[node * 2] += lazy[node];
      lazy[node * 2 + 1] += lazy[node];
    }
    st[node].mn += lazy[node];
    st[node].mx += lazy[node];
    lazy[node] = 0;
    cLazy[node] = 0;
  }
  void build(int node, int L, int R) {
    if (L == R) {
      st[node].mn = 1e9;
      st[node].mx = -1e9;
      return;
    }
    int m = (L + R) / 2;
    build(node * 2, L, m);
    build(node * 2 + 1, m + 1, R);
    merge(st[node], st[node * 2], st[node * 2 + 1]);
  }
  data Query(int node, int L, int R, int i, int j) {
    if (cLazy[node]) propagate(node, L, R);
    if (j < L || i > R) return data();
    if (i <= L && R <= j) return st[node];
    int m = (L + R) / 2;
    data left = Query(node * 2, L, m, i, j);
    data right = Query(node * 2 + 1, m + 1, R, i, j);
    data cur;
    merge(cur, left, right);
    return cur;
  }
  data pQuery(int node, int L, int R, int pos) {
    if (cLazy[node]) propagate(node, L, R);
    if (L == R) return st[node];
    int m = (L + R) / 2;
    if (pos <= m)
      return pQuery(node * 2, L, m, pos);
    else
      return pQuery(node * 2 + 1, m + 1, R, pos);
  }
  void Update(int node, int L, int R, int i, int j, int val) {
    if (cLazy[node]) propagate(node, L, R);
    if (j < L || i > R) return;
    if (i <= L && R <= j) {
      cLazy[node] = 1;
      lazy[node] += val;
      propagate(node, L, R);
      return;
    }
    int m = (L + R) / 2;
    Update(node * 2, L, m, i, j, val);
    Update(node * 2 + 1, m + 1, R, i, j, val);
    merge(st[node], st[node * 2], st[node * 2 + 1]);
  }
  void pUpdate(int node, int L, int R, int pos, int val) {
    if (cLazy[node]) propagate(node, L, R);
    if (L == R) {
      cLazy[node] = 1;
      lazy[node] = val;
      propagate(node, L, R);
      return;
    }
    int m = (L + R) / 2;
    if (pos <= m)
      pUpdate(node * 2, L, m, pos, val);
    else
      pUpdate(node * 2 + 1, m + 1, R, pos, val);
    merge(st[node], st[node * 2], st[node * 2 + 1]);
  }
  data query(int pos) { return pQuery(1, 1, T, pos); }
  data query(int l, int r) { return Query(1, 1, T, l, r); }
  void update(int pos, int val) { pUpdate(1, 1, T, pos, val); }
  void update(int l, int r, int val) { Update(1, 1, T, l, r, val); }
};
signed main() {
  ios_base::sync_with_stdio(0);
  int TESTS = 1;
  while (TESTS--) {
    int n;
    cin >> n;
    string s;
    cin >> s;
    string a;
    for (int i = 0; i < 1000005; i++) a.push_back('0');
    SegTree st;
    st.init(1000005);
    int cur = 0;
    int curpos = 1;
    int lastans = 0;
    for (auto j : s) {
      if (j == 'R') {
        curpos++;
        cout << lastans << " ";
        continue;
      }
      if (j == 'L') {
        curpos = max(curpos - 1, 1);
        cout << lastans << " ";
        continue;
      }
      if (j == '(') {
        char c = a[curpos - 1];
        int change = 0;
        if (c == ')')
          change = 2;
        else if (c == '(')
          change = 0;
        else
          change = 1;
        st.update(curpos, 1000005 - 5, change);
        a[curpos - 1] = j;
        cur += change;
      } else if (j == ')') {
        char c = a[curpos - 1];
        int change = 0;
        if (c == '(')
          change = -2;
        else if (c == ')')
          change = 0;
        else
          change = -1;
        st.update(curpos, 1000005 - 5, change);
        a[curpos - 1] = j;
        cur += change;
      } else {
        char c = a[curpos - 1];
        int change = 0;
        if (c == '(')
          change = -1;
        else if (c == ')')
          change = 1;
        else
          change = 0;
        st.update(curpos, 1000005 - 5, change);
        a[curpos - 1] = j;
        cur += change;
      }
      data d = st.query(1, 1000005);
      if (d.mn < 0 || cur != 0) {
        cout << -1 << " ";
        lastans = -1;
      } else {
        cout << d.mx << " ";
        lastans = d.mx;
      }
    }
  }
}
