#include <bits/stdc++.h>
using namespace std;
const int maxn = 1000005;
const int inf = 0x3f3f3f3f;
const int ninf = 0x80000000;
char s[maxn];
int d[maxn];
struct Seg {
  int MIN, MAX;
  int lazy;
} t[maxn * 2];
void push_down(int l, int r) {
  if (t[(l + r) | (l != r)].lazy) {
    t[(l + (l + r) / 2) | (l != (l + r) / 2)].MIN += t[(l + r) | (l != r)].lazy;
    t[(l + (l + r) / 2) | (l != (l + r) / 2)].MAX += t[(l + r) | (l != r)].lazy;
    t[(l + (l + r) / 2) | (l != (l + r) / 2)].lazy +=
        t[(l + r) | (l != r)].lazy;
    t[((l + r) / 2 + 1 + r) | ((l + r) / 2 + 1 != r)].MIN +=
        t[(l + r) | (l != r)].lazy;
    t[((l + r) / 2 + 1 + r) | ((l + r) / 2 + 1 != r)].MAX +=
        t[(l + r) | (l != r)].lazy;
    t[((l + r) / 2 + 1 + r) | ((l + r) / 2 + 1 != r)].lazy +=
        t[(l + r) | (l != r)].lazy;
    t[(l + r) | (l != r)].lazy = 0;
  }
}
void push_up(int l, int r) {
  t[(l + r) | (l != r)].MIN =
      min(t[(l + (l + r) / 2) | (l != (l + r) / 2)].MIN,
          t[((l + r) / 2 + 1 + r) | ((l + r) / 2 + 1 != r)].MIN);
  t[(l + r) | (l != r)].MAX =
      max(t[(l + (l + r) / 2) | (l != (l + r) / 2)].MAX,
          t[((l + r) / 2 + 1 + r) | ((l + r) / 2 + 1 != r)].MAX);
}
void update(int l, int r, int L, int R, int x) {
  if (L <= l && r <= R) {
    t[(l + r) | (l != r)].MIN += x;
    t[(l + r) | (l != r)].MAX += x;
    t[(l + r) | (l != r)].lazy += x;
  } else {
    push_down(l, r);
    if (L <= (l + r) / 2) update(l, (l + r) / 2, L, R, x);
    if (R > (l + r) / 2) update((l + r) / 2 + 1, r, L, R, x);
    push_up(l, r);
  }
}
int query_min(int l, int r, int L, int R) {
  if (L <= l && r <= R) {
    return t[(l + r) | (l != r)].MIN;
  } else {
    push_down(l, r);
    int res = inf;
    if (L <= (l + r) / 2) res = min(res, query_min(l, (l + r) / 2, L, R));
    if (R > (l + r) / 2) res = min(res, query_min((l + r) / 2 + 1, r, L, R));
    return res;
  }
}
int query_max(int l, int r, int L, int R) {
  if (L <= l && r <= R) {
    return t[(l + r) | (l != r)].MAX;
  } else {
    push_down(l, r);
    int res = ninf;
    if (L <= (l + r) / 2) res = max(res, query_max(l, (l + r) / 2, L, R));
    if (R > (l + r) / 2) res = max(res, query_max((l + r) / 2 + 1, r, L, R));
    return res;
  }
}
int main() {
  int n;
  scanf("%d", &n);
  scanf("%s", s);
  int pos = 1;
  for (int i = 0; i < n; i++) {
    if (s[i] == 'L') {
      if (pos >= 2) pos--;
    } else if (s[i] == 'R')
      pos++;
    else if (s[i] == '(') {
      update(1, 1e6 + 1, pos, 1e6 + 1, 1 - d[pos]);
      d[pos] = 1;
    } else if (s[i] == ')') {
      update(1, 1e6 + 1, pos, 1e6 + 1, -1 - d[pos]);
      d[pos] = -1;
    } else {
      update(1, 1e6 + 1, pos, 1e6 + 1, -d[pos]);
      d[pos] = 0;
    }
    if (query_min(1, 1e6 + 1, 1, 1e6 + 1) == 0 &&
        query_min(1, 1e6 + 1, 1e6 + 1, 1e6 + 1) == 0)
      printf("%d%c", query_max(1, 1e6 + 1, 1, 1e6 + 1),
             i == n - 1 ? '\n' : ' ');
    else
      printf("-1%c", i == n - 1 ? '\n' : ' ');
  }
  return 0;
}
