#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<set>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int maxn = 1e6+2;
struct node{
	int l,r;
	int Min,Max;
	int val;
	int lazy;
}tree[maxn*4];
void pushdown(int index){
    if(tree[index].lazy){
        tree[index<<1].val += (tree[index<<1].r-tree[index<<1].l+1)*tree[index].lazy;
        tree[index<<1|1].val +=(tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].lazy;
        tree[index<<1].Max += tree[index].lazy;
        tree[index<<1|1].Max += tree[index].lazy;
        tree[index<<1].Min += tree[index].lazy;
        tree[index<<1|1].Min += tree[index].lazy;
        tree[index<<1].lazy += tree[index].lazy;
        tree[index<<1|1].lazy += tree[index].lazy;
        tree[index].lazy = 0;
    }
}
void pushup(int index){
    tree[index].val = tree[index<<1].val+tree[index<<1|1].val;
    tree[index].Max = max(tree[index<<1].Max,tree[index<<1|1].Max);
    tree[index].Min = min(tree[index<<1].Min,tree[index<<1|1].Min);
}

void build(int l,int r,int index){//建树
	tree[index].l = l,tree[index].r = r,tree[index].lazy = 0;
	if(l == r){
        //scanf("%d",&tree[index].val);
        tree[index].val = 0;
        tree[index].Max = tree[index].Min = tree[index].val;
        return ;
	}
	int mid = (l+r)/2;//分段
    build(l,mid,index<<1);
    build(mid+1,r,index<<1|1);
    pushup(index);
}
void update(int l,int r,int index,int val){//区间修改
	if(l <= tree[index].l && r >= tree[index].r){
        /*把原来的值替换成val,因为该区间有tree[index].r-tree[index].l+1
        个数，所以区间和 以及 最值为：
        */
        /*tree[index].sum = (tree[index].r-tree[index].l+1)*val;
        tree[index].mn = val;
        tree[index].mx = val;
        tree[index].add = val;//延时标记*/
        //在原来的值的基础上加上val,因为该区间有tree[index].r-tree[index].l+1
        //个数，所以区间和 以及 最值为：
        tree[index].val += (tree[index].r-tree[index].l+1)*val;
        tree[index].Max += val;
        tree[index].Min += val;
        tree[index].lazy += val;//延时标记
        return ;
	}
	pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    if(l <= mid){
        update(l,r,index<<1,val);
    }
    if(r > mid){
        update(l,r,index<<1|1,val);
    }
    pushup(index);
}
LL query_range(int l,int r,int index){//区间查询
	if(l <= tree[index].l && r >= tree[index].r){
        return tree[index].val;
        //return tree[index].mn;
    }
    pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    LL res = 0;
    LL Max = 0;
    LL Min = inf;
    if(l <= mid){
        res += query_range(l,r,index<<1);
    }
    if(r > mid){
        res += query_range(l,r,index<<1|1);
    }
    return res;
}

LL query_max(int l,int r,int index){//最大值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Max;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MAX = max(query_max(l,r,index<<1),MAX);
	if(r > mid) MAX = max(query_max(l,r,index<<1|1),MAX);
	return MAX;
}
LL query_min(int l,int r,int index){//最小值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Min;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MIN = min(query_min(l,r,index<<1),MIN);
	if(r > mid) MIN = min(query_min(l,r,index<<1|1),MIN);
	return MIN;
}
string s;
int main(){
	int n;
	scanf("%d",&n);
	cin>>s;
	build(1,n+2,1);
	LL ss[n+1];
	memset(ss,0,sizeof(ss));
	int pos = 1;
	vector<int> ans;
	for(int i = 0;i<s.length() ;i++){
		if(s[i] == '('){
			update(pos,n,1,1-ss[pos]);
			ss[pos] = 1;
		}
		else if(s[i] == ')'){
			update(pos,n,1,-1-ss[pos]);
			ss[pos] = -1;
		}
		else if(s[i] == 'R'){
			pos++;
		}
		else if(s[i] == 'L'){
			if(pos>1) pos--;
		}
		else{
			if(ss[pos] == 1){
				update(pos,n,1,-1);
			}
			else if(ss[pos] == -1){
				update(pos,n,1,1);
			}
			ss[pos] = 0;
		}
		if(query_min(1,n,1) == 0 && query_range(n,n,1) == 0){
			ans.push_back(query_max(1,n,1));
		}
		else{
			ans.push_back(-1);
		}
	}
	for(int i = 0;i<ans.size() ;i++){
		cout<<ans[i]<<" ";
	}
	return 0;
}


#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<set>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int maxn = 1e6+200;
struct node{
	int l,r;
	int Min,Max;
	int val;
	int lazy;
}tree[maxn*4];
void pushdown(int index){
    if(tree[index].lazy){
        tree[index<<1].val += (tree[index<<1].r-tree[index<<1].l+1)*tree[index].lazy;
        tree[index<<1|1].val +=(tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].lazy;
        tree[index<<1].Max += tree[index].lazy;
        tree[index<<1|1].Max += tree[index].lazy;
        tree[index<<1].Min += tree[index].lazy;
        tree[index<<1|1].Min += tree[index].lazy;
        tree[index<<1].lazy += tree[index].lazy;
        tree[index<<1|1].lazy += tree[index].lazy;
        tree[index].lazy = 0;
    }
}
void pushup(int index){
    tree[index].val = tree[index<<1].val+tree[index<<1|1].val;
    tree[index].Max = max(tree[index<<1].Max,tree[index<<1|1].Max);
    tree[index].Min = min(tree[index<<1].Min,tree[index<<1|1].Min);
}

void build(int l,int r,int index){//建树
	tree[index].l = l,tree[index].r = r,tree[index].lazy = 0;
	if(l == r){
        //scanf("%d",&tree[index].val);
        tree[index].val = 0;
        tree[index].Max = tree[index].Min = tree[index].val;
        return ;
	}
	int mid = (l+r)/2;//分段
    build(l,mid,index<<1);
    build(mid+1,r,index<<1|1);
    pushup(index);
}
void update(int l,int r,int index,int val){//区间修改
	if(l <= tree[index].l && r >= tree[index].r){
        /*把原来的值替换成val,因为该区间有tree[index].r-tree[index].l+1
        个数，所以区间和 以及 最值为：
        */
        /*tree[index].sum = (tree[index].r-tree[index].l+1)*val;
        tree[index].mn = val;
        tree[index].mx = val;
        tree[index].add = val;//延时标记*/
        //在原来的值的基础上加上val,因为该区间有tree[index].r-tree[index].l+1
        //个数，所以区间和 以及 最值为：
        tree[index].val += (tree[index].r-tree[index].l+1)*val;
        tree[index].Max += val;
        tree[index].Min += val;
        tree[index].lazy += val;//延时标记
        return ;
	}
	pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    if(l <= mid){
        update(l,r,index<<1,val);
    }
    if(r > mid){
        update(l,r,index<<1|1,val);
    }
    pushup(index);
}
LL query_range(int l,int r,int index){//区间查询
	if(l <= tree[index].l && r >= tree[index].r){
        return tree[index].val;
        //return tree[index].mn;
    }
    pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    LL res = 0;
    LL Max = 0;
    LL Min = inf;
    if(l <= mid){
        res += query_range(l,r,index<<1);
    }
    if(r > mid){
        res += query_range(l,r,index<<1|1);
    }
    return res;
}

LL query_max(int l,int r,int index){//最大值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Max;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MAX = max(query_max(l,r,index<<1),MAX);
	if(r > mid) MAX = max(query_max(l,r,index<<1|1),MAX);
	return MAX;
}
LL query_min(int l,int r,int index){//最小值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Min;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MIN = min(query_min(l,r,index<<1),MIN);
	if(r > mid) MIN = min(query_min(l,r,index<<1|1),MIN);
	return MIN;
}
string s;
int main(){
	//ios::sync_with_stdio(false);
	int n;
	scanf("%d",&n);
	build(1,n+10,1);
	cin>>s;
	LL ss[maxn];
	memset(ss,0,sizeof(ss));
	int pos = 1;
	vector<int> ans;
	for(int i = 0;i<s.length() ;i++){
		if(s[i] == '('){
			update(pos,n,1,1-ss[pos]);
			ss[pos] = 1;
		}
		else if(s[i] == ')'){
			update(pos,n,1,-1-ss[pos]);
			ss[pos] = -1;
		}
		else if(s[i] == 'R'){
			pos++;
		}
		else if(s[i] == 'L'){
			if(pos>1) pos--;
		}
		else{
			if(ss[pos] == 1){
				update(pos,n,1,-1);
			}
			else if(ss[pos] == -1){
				update(pos,n,1,1);
			}
			ss[pos] = 0;
		}
		if(query_min(1,n,1) == 0 && query_range(n,n,1) == 0){
			ans.push_back(query_max(1,n,1));
		}
		else{
			ans.push_back(-1);
		}
	}
	for(int i = 0;i<ans.size() ;i++){
		cout<<ans[i]<<" ";
	}
	return 0;
}


#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<set>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int maxn = 1e6+110;
struct node{
	int l,r;
	int Min,Max;
	int val;
	int lazy;
}tree[maxn*4+5];
void pushdown(int index){
    if(tree[index].lazy){
        tree[index<<1].val += (tree[index<<1].r-tree[index<<1].l+1)*tree[index].lazy;
        tree[index<<1|1].val +=(tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].lazy;
        tree[index<<1].Max += tree[index].lazy;
        tree[index<<1|1].Max += tree[index].lazy;
        tree[index<<1].Min += tree[index].lazy;
        tree[index<<1|1].Min += tree[index].lazy;
        tree[index<<1].lazy += tree[index].lazy;
        tree[index<<1|1].lazy += tree[index].lazy;
        tree[index].lazy = 0;
    }
}
void pushup(int index){
    tree[index].val = tree[index<<1].val+tree[index<<1|1].val;
    tree[index].Max = max(tree[index<<1].Max,tree[index<<1|1].Max);
    tree[index].Min = min(tree[index<<1].Min,tree[index<<1|1].Min);
}

void build(int l,int r,int index){//建树
	tree[index].l = l,tree[index].r = r,tree[index].lazy = 0;
	if(l == r){
        //scanf("%d",&tree[index].val);
       tree[index].val = 0;
        tree[index].Max = tree[index].Min = tree[index].val;
        return;
	}
	int mid = (l+r)>>1;//分段
    build(l,mid,index<<1);
    build(mid+1,r,index<<1|1);
    pushup(index);
}
void update(int l,int r,int index,int val){//区间修改
	if(l <= tree[index].l && r >= tree[index].r){
        /*把原来的值替换成val,因为该区间有tree[index].r-tree[index].l+1
        个数，所以区间和 以及 最值为：
        */
        /*tree[index].sum = (tree[index].r-tree[index].l+1)*val;
        tree[index].mn = val;
        tree[index].mx = val;
        tree[index].add = val;//延时标记*/
        //在原来的值的基础上加上val,因为该区间有tree[index].r-tree[index].l+1
        //个数，所以区间和 以及 最值为：
        tree[index].val += (tree[index].r-tree[index].l+1)*val;
        tree[index].Max += val;
        tree[index].Min += val;
        tree[index].lazy += val;//延时标记
        return ;
	}
	pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    if(l <= mid){
        update(l,r,index<<1,val);
    }
    if(r > mid){
        update(l,r,index<<1|1,val);
    }
    pushup(index);
}
LL query_range(int l,int r,int index){//区间查询
	if(l <= tree[index].l && r >= tree[index].r){
        return tree[index].val;
        //return tree[index].mn;
    }
    pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    LL res = 0;
    LL Max = 0;
    LL Min = inf;
    if(l <= mid){
        res += query_range(l,r,index<<1);
    }
    if(r > mid){
        res += query_range(l,r,index<<1|1);
    }
    return res;
}

LL query_max(int l,int r,int index){//最大值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Max;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MAX = max(query_max(l,r,index<<1),MAX);
	if(r > mid) MAX = max(query_max(l,r,index<<1|1),MAX);
	return MAX;
}
LL query_min(int l,int r,int index){//最小值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Min;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MIN = min(query_min(l,r,index<<1),MIN);
	if(r > mid) MIN = min(query_min(l,r,index<<1|1),MIN);
	return MIN;
}
string s;
LL ss[maxn];
int main(){
	//ios::sync_with_stdio(false);
	int n;
	scanf("%d",&n);
	build(1,n+5,1);
	cin>>s;
	int pos = 1;
	vector<int> ans;
	for(int i = 0;i<s.length() ;i++){
		if(s[i] == '('){
			update(pos,n,1,1-ss[pos]);
			ss[pos] = 1;
		}
		else if(s[i] == ')'){
			update(pos,n,1,-1-ss[pos]);
			ss[pos] = -1;
		}
		else if(s[i] == 'R'){
			pos++;
		}
		else if(s[i] == 'L'){
			if(pos>1) pos--;
		}
		else{
			if(ss[pos] == 1){
				update(pos,n,1,-1);
			}
			else if(ss[pos] == -1){
				update(pos,n,1,1);
			}
			ss[pos] = 0;
		}
		if(query_min(1,n,1) == 0 && query_range(n,n,1) == 0){
			ans.push_back(query_max(1,n,1));
		}
		else{
			ans.push_back(-1);
		}
	}
	for(int i = 0;i<ans.size() ;i++){
		cout<<ans[i]<<" ";
	}
	return 0;
}


#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<set>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int maxn = 1e6+2;
struct node{
	int l,r;
	int Min,Max;
	int val;
	int lazy;
}tree[maxn*4];
void pushdown(int index){
    if(tree[index].lazy){
        tree[index<<1].val += (tree[index<<1].r-tree[index<<1].l+1)*tree[index].lazy;
        tree[index<<1|1].val +=(tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].lazy;
        tree[index<<1].Max += tree[index].lazy;
        tree[index<<1|1].Max += tree[index].lazy;
        tree[index<<1].Min += tree[index].lazy;
        tree[index<<1|1].Min += tree[index].lazy;
        tree[index<<1].lazy += tree[index].lazy;
        tree[index<<1|1].lazy += tree[index].lazy;
        tree[index].lazy = 0;
    }
}
void pushup(int index){
    tree[index].val = tree[index<<1].val+tree[index<<1|1].val;
    tree[index].Max = max(tree[index<<1].Max,tree[index<<1|1].Max);
    tree[index].Min = min(tree[index<<1].Min,tree[index<<1|1].Min);
}

void build(int l,int r,int index){//建树
	tree[index].l = l,tree[index].r = r,tree[index].lazy = 0;
	if(l == r){
        //scanf("%d",&tree[index].val);
        tree[index].val = 0;
        tree[index].Max = tree[index].Min = tree[index].val;
        return ;
	}
	int mid = (l+r)/2;//分段
    build(l,mid,index<<1);
    build(mid+1,r,index<<1|1);
    pushup(index);
}
void update(int l,int r,int index,int val){//区间修改
	if(l <= tree[index].l && r >= tree[index].r){
        /*把原来的值替换成val,因为该区间有tree[index].r-tree[index].l+1
        个数，所以区间和 以及 最值为：
        */
        /*tree[index].sum = (tree[index].r-tree[index].l+1)*val;
        tree[index].mn = val;
        tree[index].mx = val;
        tree[index].add = val;//延时标记*/
        //在原来的值的基础上加上val,因为该区间有tree[index].r-tree[index].l+1
        //个数，所以区间和 以及 最值为：
        tree[index].val += (tree[index].r-tree[index].l+1)*val;
        tree[index].Max += val;
        tree[index].Min += val;
        tree[index].lazy += val;//延时标记
        return ;
	}
	pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    if(l <= mid){
        update(l,r,index<<1,val);
    }
    if(r > mid){
        update(l,r,index<<1|1,val);
    }
    pushup(index);
}
LL query_range(int l,int r,int index){//区间查询
	if(l <= tree[index].l && r >= tree[index].r){
        return tree[index].val;
        //return tree[index].mn;
    }
    pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    LL res = 0;
    LL Max = 0;
    LL Min = inf;
    if(l <= mid){
        res += query_range(l,r,index<<1);
    }
    if(r > mid){
        res += query_range(l,r,index<<1|1);
    }
    return res;
}

LL query_max(int l,int r,int index){//最大值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Max;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MAX = max(query_max(l,r,index<<1),MAX);
	if(r > mid) MAX = max(query_max(l,r,index<<1|1),MAX);
	return MAX;
}
LL query_min(int l,int r,int index){//最小值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Min;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MIN = min(query_min(l,r,index<<1),MIN);
	if(r > mid) MIN = min(query_min(l,r,index<<1|1),MIN);
	return MIN;
}
string s;
int main(){
	ios::sync_with_stdio(false);
	int n;
	scanf("%d",&n);
	build(1,n+2,1);
	cin>>s;
	LL ss[n+1];
	memset(ss,0,sizeof(ss));
	int pos = 1;
	vector<int> ans;
	for(int i = 0;i<s.length() ;i++){
		if(s[i] == '('){
			update(pos,n,1,1-ss[pos]);
			ss[pos] = 1;
		}
		else if(s[i] == ')'){
			update(pos,n,1,-1-ss[pos]);
			ss[pos] = -1;
		}
		else if(s[i] == 'R'){
			pos++;
		}
		else if(s[i] == 'L'){
			if(pos>1) pos--;
		}
		else{
			if(ss[pos] == 1){
				update(pos,n,1,-1);
			}
			else if(ss[pos] == -1){
				update(pos,n,1,1);
			}
			ss[pos] = 0;
		}
		if(query_min(1,n,1) == 0 && query_range(n,n,1) == 0){
			ans.push_back(query_max(1,n,1));
		}
		else{
			ans.push_back(-1);
		}
	}
	for(int i = 0;i<ans.size() ;i++){
		cout<<ans[i]<<" ";
	}
	return 0;
}


#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<set>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int maxn = 1e6+2;
struct node{
	int l,r;
	int Min,Max;
	int val;
	int lazy;
}tree[maxn*4+5];
void pushdown(int index){
    if(tree[index].lazy){
        tree[index<<1].val += (tree[index<<1].r-tree[index<<1].l+1)*tree[index].lazy;
        tree[index<<1|1].val +=(tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].lazy;
        tree[index<<1].Max += tree[index].lazy;
        tree[index<<1|1].Max += tree[index].lazy;
        tree[index<<1].Min += tree[index].lazy;
        tree[index<<1|1].Min += tree[index].lazy;
        tree[index<<1].lazy += tree[index].lazy;
        tree[index<<1|1].lazy += tree[index].lazy;
        tree[index].lazy = 0;
    }
}
void pushup(int index){
    tree[index].val = tree[index<<1].val+tree[index<<1|1].val;
    tree[index].Max = max(tree[index<<1].Max,tree[index<<1|1].Max);
    tree[index].Min = min(tree[index<<1].Min,tree[index<<1|1].Min);
}

void build(int l,int r,int index){//建树
	tree[index].l = l,tree[index].r = r,tree[index].lazy = 0;
	if(l == r){
        scanf("%d",&tree[index].val);
        //tree[index].val = 0;
        tree[index].Max = tree[index].Min = tree[index].val;
        return;
    }
	int mid = (l+r)>>1;//
    build(l,mid,index<<1);
    build(mid+1,r,index<<1|1);
    pushup(index);
}
void update(int l,int r,int index,int val){//区间修改
	if(l <= tree[index].l && r >= tree[index].r){
        tree[index].val += (tree[index].r-tree[index].l+1)*val;
        tree[index].Max += val;
        tree[index].Min += val;
        tree[index].lazy += val;//延时标记
        return ;
	}
	pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    if(l <= mid){
        update(l,r,index<<1,val);
    }
    if(r > mid){
        update(l,r,index<<1|1,val);
    }
    pushup(index);
}

LL query_range(int l,int r,int index){//区间查询
	if(l <= tree[index].l && r >= tree[index].r){
        return tree[index].val;
        //return tree[index].mn;
    }
    pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    LL res = 0;
    LL Max = 0;
    LL Min = inf;
    if(l <= mid){
        res += query_range(l,r,index<<1);
    }
    if(r > mid){
        res += query_range(l,r,index<<1|1);
    }
    return res;
}

LL query_max(int l,int r,int index){//最大值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Max;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MAX = max(query_max(l,r,index<<1),MAX);
	if(r > mid) MAX = max(query_max(l,r,index<<1|1),MAX);
	return MAX;
}
LL query_min(int l,int r,int index){//最小值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Min;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MIN = min(query_min(l,r,index<<1),MIN);
	if(r > mid) MIN = min(query_min(l,r,index<<1|1),MIN);
	return MIN;
}
string s;
LL ss[maxn];
int main(){
	int n;
	scanf("%d",&n);
	n = n+10;
	build(1,n,1);
	cin>>s;
	int pos = 1;
	vector<int> ans;
	for(int i = 0;i<s.length() ;i++){
		if(s[i] == '('){
			update(pos,n,1,1-ss[pos]);
			ss[pos] = 1;
		}
		else if(s[i] == ')'){
			update(pos,n,1,-1-ss[pos]);
			ss[pos] = -1;
		}
		else if(s[i] == 'R'){
			pos++;
		}
		else if(s[i] == 'L'){
			if(pos>1) pos--;
		}
		else{
			if(ss[pos] == 1){
				update(pos,n,1,-1);
			}
			else if(ss[pos] == -1){
				update(pos,n,1,1);
			}
			ss[pos] = 0;
		}
		if(query_min(1,n,1) == 0 && query_range(n,n,1) == 0){
			ans.push_back(query_max(1,n,1));
		}
		else{
			ans.push_back(-1);
		}
	}
	for(int i = 0;i<ans.size() ;i++){
		cout<<ans[i]<<" ";
	}
	//cout<<endl;
	return 0;
}


#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<set>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int maxn = 1e6+2;
struct node{
	int l,r;
	int Min,Max;
	int val;
	int lazy;
}tree[maxn*4];
void pushdown(int index){
    if(tree[index].lazy){
        tree[index<<1].val += (tree[index<<1].r-tree[index<<1].l+1)*tree[index].lazy;
        tree[index<<1|1].val +=(tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].lazy;
        tree[index<<1].Max += tree[index].lazy;
        tree[index<<1|1].Max += tree[index].lazy;
        tree[index<<1].Min += tree[index].lazy;
        tree[index<<1|1].Min += tree[index].lazy;
        tree[index<<1].lazy += tree[index].lazy;
        tree[index<<1|1].lazy += tree[index].lazy;
        tree[index].lazy = 0;
    }
}
void pushup(int index){
    tree[index].val = tree[index<<1].val+tree[index<<1|1].val;
    tree[index].Max = max(tree[index<<1].Max,tree[index<<1|1].Max);
    tree[index].Min = min(tree[index<<1].Min,tree[index<<1|1].Min);
}

void build(int l,int r,int index){//建树
	tree[index].l = l,tree[index].r = r,tree[index].lazy = 0;
	if(l == r){
        //scanf("%d",&tree[index].val);
        tree[index].val = 0;
        tree[index].Max = tree[index].Min = tree[index].val;
        return ;
	}
	int mid = (l+r)/2;//分段
    build(l,mid,index<<1);
    build(mid+1,r,index<<1|1);
    pushup(index);
}
void update(int l,int r,int index,int val){//区间修改
	if(l <= tree[index].l && r >= tree[index].r){
        /*把原来的值替换成val,因为该区间有tree[index].r-tree[index].l+1
        个数，所以区间和 以及 最值为：
        */
        /*tree[index].sum = (tree[index].r-tree[index].l+1)*val;
        tree[index].mn = val;
        tree[index].mx = val;
        tree[index].add = val;//延时标记*/
        //在原来的值的基础上加上val,因为该区间有tree[index].r-tree[index].l+1
        //个数，所以区间和 以及 最值为：
        tree[index].val += (tree[index].r-tree[index].l+1)*val;
        tree[index].Max += val;
        tree[index].Min += val;
        tree[index].lazy += val;//延时标记
        return ;
	}
	pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    if(l <= mid){
        update(l,r,index<<1,val);
    }
    if(r > mid){
        update(l,r,index<<1|1,val);
    }
    pushup(index);
}
LL query_range(int l,int r,int index){//区间查询
	if(l <= tree[index].l && r >= tree[index].r){
        return tree[index].val;
        //return tree[index].mn;
    }
    pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    LL res = 0;
    LL Max = 0;
    LL Min = inf;
    if(l <= mid){
        res += query_range(l,r,index<<1);
    }
    if(r > mid){
        res += query_range(l,r,index<<1|1);
    }
    return res;
}

LL query_max(int l,int r,int index){//最大值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Max;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MAX = max(query_max(l,r,index<<1),MAX);
	if(r > mid) MAX = max(query_max(l,r,index<<1|1),MAX);
	return MAX;
}
LL query_min(int l,int r,int index){//最小值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Min;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MIN = min(query_min(l,r,index<<1),MIN);
	if(r > mid) MIN = min(query_min(l,r,index<<1|1),MIN);
	return MIN;
}
string s;
int main(){
	//ios::sync_with_stdio(false);
	int n;
	scanf("%d",&n);
	build(1,n+10,1);
	cin>>s;
	LL ss[n+1];
	memset(ss,0,sizeof(ss));
	int pos = 1;
	vector<int> ans;
	for(int i = 0;i<s.length() ;i++){
		if(s[i] == '('){
			update(pos,n,1,1-ss[pos]);
			ss[pos] = 1;
		}
		else if(s[i] == ')'){
			update(pos,n,1,-1-ss[pos]);
			ss[pos] = -1;
		}
		else if(s[i] == 'R'){
			pos++;
		}
		else if(s[i] == 'L'){
			if(pos>1) pos--;
		}
		else{
			if(ss[pos] == 1){
				update(pos,n,1,-1);
			}
			else if(ss[pos] == -1){
				update(pos,n,1,1);
			}
			ss[pos] = 0;
		}
		if(query_min(1,n,1) == 0 && query_range(n,n,1) == 0){
			ans.push_back(query_max(1,n,1));
		}
		else{
			ans.push_back(-1);
		}
	}
	for(int i = 0;i<ans.size() ;i++){
		cout<<ans[i]<<" ";
	}
	return 0;
}


#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<set>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int maxn = 1e6+100;
struct node{
	int l,r;
	int Min,Max;
	int val;
	int lazy;
}tree[maxn*4];
void pushdown(int index){
    if(tree[index].lazy){
        tree[index<<1].val += (tree[index<<1].r-tree[index<<1].l+1)*tree[index].lazy;
        tree[index<<1|1].val +=(tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].lazy;
        tree[index<<1].Max += tree[index].lazy;
        tree[index<<1|1].Max += tree[index].lazy;
        tree[index<<1].Min += tree[index].lazy;
        tree[index<<1|1].Min += tree[index].lazy;
        tree[index<<1].lazy += tree[index].lazy;
        tree[index<<1|1].lazy += tree[index].lazy;
        tree[index].lazy = 0;
    }
}
void pushup(int index){
    tree[index].val = tree[index<<1].val+tree[index<<1|1].val;
    tree[index].Max = max(tree[index<<1].Max,tree[index<<1|1].Max);
    tree[index].Min = min(tree[index<<1].Min,tree[index<<1|1].Min);
}

void build(int l,int r,int index){//建树
	tree[index].l = l,tree[index].r = r,tree[index].lazy = 0;
	if(l == r){
        //scanf("%d",&tree[index].val);
        tree[index].val = 0;
        tree[index].Max = tree[index].Min = tree[index].val;
        return;
	}
	int mid = (l+r)>>1;//分段
    build(l,mid,index<<1);
    build(mid+1,r,index<<1|1);
    pushup(index);
}
void update(int l,int r,int index,int val){//区间修改
	if(l <= tree[index].l && r >= tree[index].r){
        /*把原来的值替换成val,因为该区间有tree[index].r-tree[index].l+1
        个数，所以区间和 以及 最值为：
        */
        /*tree[index].sum = (tree[index].r-tree[index].l+1)*val;
        tree[index].mn = val;
        tree[index].mx = val;
        tree[index].add = val;//延时标记*/
        //在原来的值的基础上加上val,因为该区间有tree[index].r-tree[index].l+1
        //个数，所以区间和 以及 最值为：
        tree[index].val += (tree[index].r-tree[index].l+1)*val;
        tree[index].Max += val;
        tree[index].Min += val;
        tree[index].lazy += val;//延时标记
        return ;
	}
	pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    if(l <= mid){
        update(l,r,index<<1,val);
    }
    if(r > mid){
        update(l,r,index<<1|1,val);
    }
    pushup(index);
}
LL query_range(int l,int r,int index){//区间查询
	if(l <= tree[index].l && r >= tree[index].r){
        return tree[index].val;
        //return tree[index].mn;
    }
    pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    LL res = 0;
    LL Max = 0;
    LL Min = inf;
    if(l <= mid){
        res += query_range(l,r,index<<1);
    }
    if(r > mid){
        res += query_range(l,r,index<<1|1);
    }
    return res;
}

LL query_max(int l,int r,int index){//最大值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Max;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MAX = max(query_max(l,r,index<<1),MAX);
	if(r > mid) MAX = max(query_max(l,r,index<<1|1),MAX);
	return MAX;
}
LL query_min(int l,int r,int index){//最小值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Min;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MIN = min(query_min(l,r,index<<1),MIN);
	if(r > mid) MIN = min(query_min(l,r,index<<1|1),MIN);
	return MIN;
}
string s;
LL ss[maxn];
int main(){
	//ios::sync_with_stdio(false);
	int n;
	scanf("%d",&n);
	build(1,n+5,1);
	cin>>s;
	int pos = 1;
	vector<int> ans;
	for(int i = 0;i<s.length() ;i++){
		if(s[i] == '('){
			update(pos,n,1,1-ss[pos]);
			ss[pos] = 1;
		}
		else if(s[i] == ')'){
			update(pos,n,1,-1-ss[pos]);
			ss[pos] = -1;
		}
		else if(s[i] == 'R'){
			pos++;
		}
		else if(s[i] == 'L'){
			if(pos>1) pos--;
		}
		else{
			if(ss[pos] == 1){
				update(pos,n,1,-1);
			}
			else if(ss[pos] == -1){
				update(pos,n,1,1);
			}
			ss[pos] = 0;
		}
		if(query_min(1,n,1) == 0 && query_range(n,n,1) == 0){
			ans.push_back(query_max(1,n,1));
		}
		else{
			ans.push_back(-1);
		}
	}
	for(int i = 0;i<ans.size() ;i++){
		cout<<ans[i]<<" ";
	}
	return 0;
}


#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<set>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int maxn = 1e6+200;
struct node{
	int l,r;
	int Min,Max;
	int val;
	int lazy;
}tree[maxn*4];
void pushdown(int index){
    if(tree[index].lazy){
        tree[index<<1].val += (tree[index<<1].r-tree[index<<1].l+1)*tree[index].lazy;
        tree[index<<1|1].val +=(tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].lazy;
        tree[index<<1].Max += tree[index].lazy;
        tree[index<<1|1].Max += tree[index].lazy;
        tree[index<<1].Min += tree[index].lazy;
        tree[index<<1|1].Min += tree[index].lazy;
        tree[index<<1].lazy += tree[index].lazy;
        tree[index<<1|1].lazy += tree[index].lazy;
        tree[index].lazy = 0;
    }
}
void pushup(int index){
    tree[index].val = tree[index<<1].val+tree[index<<1|1].val;
    tree[index].Max = max(tree[index<<1].Max,tree[index<<1|1].Max);
    tree[index].Min = min(tree[index<<1].Min,tree[index<<1|1].Min);
}

void build(int l,int r,int index){//建树
	tree[index].l = l,tree[index].r = r,tree[index].lazy = 0;
	if(l == r){
        //scanf("%d",&tree[index].val);
        tree[index].val = 0;
        tree[index].Max = tree[index].Min = tree[index].val;
        return ;
	}
	int mid = (l+r)>>2;//分段
    build(l,mid,index<<1);
    build(mid+1,r,index<<1|1);
    pushup(index);
}
void update(int l,int r,int index,int val){//区间修改
	if(l <= tree[index].l && r >= tree[index].r){
        /*把原来的值替换成val,因为该区间有tree[index].r-tree[index].l+1
        个数，所以区间和 以及 最值为：
        */
        /*tree[index].sum = (tree[index].r-tree[index].l+1)*val;
        tree[index].mn = val;
        tree[index].mx = val;
        tree[index].add = val;//延时标记*/
        //在原来的值的基础上加上val,因为该区间有tree[index].r-tree[index].l+1
        //个数，所以区间和 以及 最值为：
        tree[index].val += (tree[index].r-tree[index].l+1)*val;
        tree[index].Max += val;
        tree[index].Min += val;
        tree[index].lazy += val;//延时标记
        return ;
	}
	pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    if(l <= mid){
        update(l,r,index<<1,val);
    }
    if(r > mid){
        update(l,r,index<<1|1,val);
    }
    pushup(index);
}
LL query_range(int l,int r,int index){//区间查询
	if(l <= tree[index].l && r >= tree[index].r){
        return tree[index].val;
        //return tree[index].mn;
    }
    pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    LL res = 0;
    LL Max = 0;
    LL Min = inf;
    if(l <= mid){
        res += query_range(l,r,index<<1);
    }
    if(r > mid){
        res += query_range(l,r,index<<1|1);
    }
    return res;
}

LL query_max(int l,int r,int index){//最大值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Max;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MAX = max(query_max(l,r,index<<1),MAX);
	if(r > mid) MAX = max(query_max(l,r,index<<1|1),MAX);
	return MAX;
}
LL query_min(int l,int r,int index){//最小值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Min;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MIN = min(query_min(l,r,index<<1),MIN);
	if(r > mid) MIN = min(query_min(l,r,index<<1|1),MIN);
	return MIN;
}
string s;
LL ss[maxn];
int main(){
	//ios::sync_with_stdio(false);
	int n;
	scanf("%d",&n);
	build(1,n+5,1);
	cin>>s;
	int pos = 1;
	vector<int> ans;
	for(int i = 0;i<s.length() ;i++){
		if(s[i] == '('){
			update(pos,n,1,1-ss[pos]);
			ss[pos] = 1;
		}
		else if(s[i] == ')'){
			update(pos,n,1,-1-ss[pos]);
			ss[pos] = -1;
		}
		else if(s[i] == 'R'){
			pos++;
		}
		else if(s[i] == 'L'){
			if(pos>1) pos--;
		}
		else{
			if(ss[pos] == 1){
				update(pos,n,1,-1);
			}
			else if(ss[pos] == -1){
				update(pos,n,1,1);
			}
			ss[pos] = 0;
		}
		if(query_min(1,n,1) == 0 && query_range(n,n,1) == 0){
			ans.push_back(query_max(1,n,1));
		}
		else{
			ans.push_back(-1);
		}
	}
	for(int i = 0;i<ans.size() ;i++){
		cout<<ans[i]<<" ";
	}
	return 0;
}


#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<set>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int maxn = 1e6+10;
struct node{
	int l,r;
	int Min,Max;
	int val;
	int lazy;
}tree[maxn*4+5];
void pushdown(int index){
    if(tree[index].lazy){
        tree[index<<1].val += (tree[index<<1].r-tree[index<<1].l+1)*tree[index].lazy;
        tree[index<<1|1].val +=(tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].lazy;
        tree[index<<1].Max += tree[index].lazy;
        tree[index<<1|1].Max += tree[index].lazy;
        tree[index<<1].Min += tree[index].lazy;
        tree[index<<1|1].Min += tree[index].lazy;
        tree[index<<1].lazy += tree[index].lazy;
        tree[index<<1|1].lazy += tree[index].lazy;
        tree[index].lazy = 0;
    }
}
void pushup(int index){
    tree[index].val = tree[index<<1].val+tree[index<<1|1].val;
    tree[index].Max = max(tree[index<<1].Max,tree[index<<1|1].Max);
    tree[index].Min = min(tree[index<<1].Min,tree[index<<1|1].Min);
}

void build(int l,int r,int index){//建树
	tree[index].l = l,tree[index].r = r,tree[index].lazy = 0;
	if(l == r){
        //scanf("%d",&tree[index].val);
        tree[index].val = 0;
        tree[index].Max = tree[index].Min = tree[index].val;
        return;
    }
	int mid = (l+r)>>1;//
    build(l,mid,index<<1);
    build(mid+1,r,index<<1|1);
    pushup(index);
}
void update(int l,int r,int index,int val){//区间修改
	if(l <= tree[index].l && r >= tree[index].r){
        tree[index].val += (tree[index].r-tree[index].l+1)*val;
        tree[index].Max += val;
        tree[index].Min += val;
        tree[index].lazy += val;//延时标记
        return ;
	}
	pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    if(l <= mid){
        update(l,r,index<<1,val);
    }
    if(r > mid){
        update(l,r,index<<1|1,val);
    }
    pushup(index);
}

LL query_range(int l,int r,int index){//区间查询
	if(l <= tree[index].l && r >= tree[index].r){
        return tree[index].val;
        //return tree[index].mn;
    }
    pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    LL res = 0;
    LL Max = 0;
    LL Min = inf;
    if(l <= mid){
        res += query_range(l,r,index<<1);
    }
    if(r > mid){
        res += query_range(l,r,index<<1|1);
    }
    return res;
}

LL query_max(int l,int r,int index){//最大值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Max;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MAX = max(query_max(l,r,index<<1),MAX);
	if(r > mid) MAX = max(query_max(l,r,index<<1|1),MAX);
	return MAX;
}
LL query_min(int l,int r,int index){//最小值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Min;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MIN = min(query_min(l,r,index<<1),MIN);
	if(r > mid) MIN = min(query_min(l,r,index<<1|1),MIN);
	return MIN;
}
string s;
LL ss[maxn];
int main(){
	int n;
	scanf("%d",&n);
	n = n+10;
	build(1,n,1);
	cin>>s;
	int pos = 1;
	vector<int> ans;
	for(int i = 0;i<s.length() ;i++){
		if(s[i] == '('){
			update(pos,n,1,1-ss[pos]);
			ss[pos] = 1;
		}
		else if(s[i] == ')'){
			update(pos,n,1,-1-ss[pos]);
			ss[pos] = -1;
		}
		else if(s[i] == 'R'){
			pos++;
		}
		else if(s[i] == 'L'){
			if(pos>1) pos--;
		}
		else{
			if(ss[pos] == 1){
				update(pos,n,1,-1);
			}
			else if(ss[pos] == -1){
				update(pos,n,1,1);
			}
			ss[pos] = 0;
		}
		if(query_min(1,n,1) == 0 && query_range(n,n,1) == 0){
			ans.push_back(query_max(1,n,1));
		}
		else{
			ans.push_back(-1);
		}
	}
	for(int i = 0;i<ans.size() ;i++){
		cout<<ans[i]<<" ";
	}
	//cout<<endl;
	return 0;
}


#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<set>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int maxn = 1e6+110;
struct node{
	int l,r;
	int Min,Max;
	int val;
	int lazy;
}tree[maxn*4+5];
void pushdown(int index){
    if(tree[index].lazy){
        tree[index<<1].val += (tree[index<<1].r-tree[index<<1].l+1)*tree[index].lazy;
        tree[index<<1|1].val +=(tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].lazy;
        tree[index<<1].Max += tree[index].lazy;
        tree[index<<1|1].Max += tree[index].lazy;
        tree[index<<1].Min += tree[index].lazy;
        tree[index<<1|1].Min += tree[index].lazy;
        tree[index<<1].lazy += tree[index].lazy;
        tree[index<<1|1].lazy += tree[index].lazy;
        tree[index].lazy = 0;
    }
}
void pushup(int index){
    tree[index].val = tree[index<<1].val+tree[index<<1|1].val;
    tree[index].Max = max(tree[index<<1].Max,tree[index<<1|1].Max);
    tree[index].Min = min(tree[index<<1].Min,tree[index<<1|1].Min);
}

void build(int l,int r,int index){//建树
	tree[index].l = l,tree[index].r = r,tree[index].lazy = 0;
	if(l == r){
        //scanf("%d",&tree[index].val);
        tree[index].val = 0;
        tree[index].Max = tree[index].Min = tree[index].val;
        return;
	}
	int mid = (l+r)>>1;//分段
    build(l,mid,index<<1);
    build(mid+1,r,index<<1|1);
    pushup(index);
}
void update(int l,int r,int index,int val){//区间修改
	if(l <= tree[index].l && r >= tree[index].r){
        tree[index].val += (tree[index].r-tree[index].l+1)*val;
        tree[index].Max += val;
        tree[index].Min += val;
        tree[index].lazy += val;//延时标记
        return ;
	}
	pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    if(l <= mid){
        update(l,r,index<<1,val);
    }
    if(r > mid){
        update(l,r,index<<1|1,val);
    }
    pushup(index);
}

LL query_range(int l,int r,int index){//区间查询
	if(l <= tree[index].l && r >= tree[index].r){
        return tree[index].val;
        //return tree[index].mn;
    }
    pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    LL res = 0;
    LL Max = 0;
    LL Min = inf;
    if(l <= mid){
        res += query_range(l,r,index<<1);
    }
    if(r > mid){
        res += query_range(l,r,index<<1|1);
    }
    return res;
}

LL query_max(int l,int r,int index){//最大值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Max;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MAX = max(query_max(l,r,index<<1),MAX);
	if(r > mid) MAX = max(query_max(l,r,index<<1|1),MAX);
	return MAX;
}
LL query_min(int l,int r,int index){//最小值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Min;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MIN = min(query_min(l,r,index<<1),MIN);
	if(r > mid) MIN = min(query_min(l,r,index<<1|1),MIN);
	return MIN;
}
string s;
LL ss[maxn];
int main(){
	//ios::sync_with_stdio(false);
	int n;
	scanf("%d",&n);
	build(1,n+5,1);
	cin>>s;
	int pos = 1;
	vector<int> ans;
	for(int i = 0;i<s.length() ;i++){
		if(s[i] == '('){
			update(pos,n,1,1-ss[pos]);
			ss[pos] = 1;
		}
		else if(s[i] == ')'){
			update(pos,n,1,-1-ss[pos]);
			ss[pos] = -1;
		}
		else if(s[i] == 'R'){
			pos++;
		}
		else if(s[i] == 'L'){
			if(pos>1) pos--;
		}
		else{
			if(ss[pos] == 1){
				update(pos,n,1,-1);
			}
			else if(ss[pos] == -1){
				update(pos,n,1,1);
			}
			ss[pos] = 0;
		}
		if(query_min(1,n,1) == 0 && query_range(n,n,1) == 0){
			ans.push_back(query_max(1,n,1));
		}
		else{
			ans.push_back(-1);
		}
	}
	for(int i = 0;i<ans.size() ;i++){
		cout<<ans[i]<<" ";
	}
	return 0;
}


#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<set>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int maxn = 1e6+2;
struct node{
	int l,r;
	int Min,Max;
	int val;
	int lazy;
}tree[maxn*4];
void pushdown(int index){
    if(tree[index].lazy){
        tree[index<<1].val += (tree[index<<1].r-tree[index<<1].l+1)*tree[index].lazy;
        tree[index<<1|1].val +=(tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].lazy;
        tree[index<<1].Max += tree[index].lazy;
        tree[index<<1|1].Max += tree[index].lazy;
        tree[index<<1].Min += tree[index].lazy;
        tree[index<<1|1].Min += tree[index].lazy;
        tree[index<<1].lazy += tree[index].lazy;
        tree[index<<1|1].lazy += tree[index].lazy;
        tree[index].lazy = 0;
    }
}
void pushup(int index){
    tree[index].val = tree[index<<1].val+tree[index<<1|1].val;
    tree[index].Max = max(tree[index<<1].Max,tree[index<<1|1].Max);
    tree[index].Min = min(tree[index<<1].Min,tree[index<<1|1].Min);
}

void build(int l,int r,int index){//建树
	tree[index].l = l,tree[index].r = r,tree[index].lazy = 0;
	if(l == r){
        //scanf("%d",&tree[index].val);
        tree[index].val = 0;
        tree[index].Max = tree[index].Min = tree[index].val;
        return ;
	}
	int mid = (l+r)/2;//分段
    build(l,mid,index<<1);
    build(mid+1,r,index<<1|1);
    pushup(index);
}
void update(int l,int r,int index,int val){//区间修改
	if(l <= tree[index].l && r >= tree[index].r){
        /*把原来的值替换成val,因为该区间有tree[index].r-tree[index].l+1
        个数，所以区间和 以及 最值为：
        */
        /*tree[index].sum = (tree[index].r-tree[index].l+1)*val;
        tree[index].mn = val;
        tree[index].mx = val;
        tree[index].add = val;//延时标记*/
        //在原来的值的基础上加上val,因为该区间有tree[index].r-tree[index].l+1
        //个数，所以区间和 以及 最值为：
        tree[index].val += (tree[index].r-tree[index].l+1)*val;
        tree[index].Max += val;
        tree[index].Min += val;
        tree[index].lazy += val;//延时标记
        return ;
	}
	pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    if(l <= mid){
        update(l,r,index<<1,val);
    }
    if(r > mid){
        update(l,r,index<<1|1,val);
    }
    pushup(index);
}
LL query_range(int l,int r,int index){//区间查询
	if(l <= tree[index].l && r >= tree[index].r){
        return tree[index].val;
        //return tree[index].mn;
    }
    pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    LL res = 0;
    LL Max = 0;
    LL Min = inf;
    if(l <= mid){
        res += query_range(l,r,index<<1);
    }
    if(r > mid){
        res += query_range(l,r,index<<1|1);
    }
    return res;
}

LL query_max(int l,int r,int index){//最大值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Max;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MAX = max(query_max(l,r,index<<1),MAX);
	if(r > mid) MAX = max(query_max(l,r,index<<1|1),MAX);
	return MAX;
}
LL query_min(int l,int r,int index){//最小值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Min;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MIN = min(query_min(l,r,index<<1),MIN);
	if(r > mid) MIN = min(query_min(l,r,index<<1|1),MIN);
	return MIN;
}
string s;
int main(){
	//ios::sync_with_stdio(false);
	int n;
	scanf("%d",&n);
	build(1,n+10,1);
	cin>>s;
	LL ss[maxn];
	memset(ss,0,sizeof(ss));
	int pos = 1;
	vector<int> ans;
	for(int i = 0;i<s.length() ;i++){
		if(s[i] == '('){
			update(pos,n,1,1-ss[pos]);
			ss[pos] = 1;
		}
		else if(s[i] == ')'){
			update(pos,n,1,-1-ss[pos]);
			ss[pos] = -1;
		}
		else if(s[i] == 'R'){
			pos++;
		}
		else if(s[i] == 'L'){
			if(pos>1) pos--;
		}
		else{
			if(ss[pos] == 1){
				update(pos,n,1,-1);
			}
			else if(ss[pos] == -1){
				update(pos,n,1,1);
			}
			ss[pos] = 0;
		}
		if(query_min(1,n,1) == 0 && query_range(n,n,1) == 0){
			ans.push_back(query_max(1,n,1));
		}
		else{
			ans.push_back(-1);
		}
	}
	for(int i = 0;i<ans.size() ;i++){
		cout<<ans[i]<<" ";
	}
	return 0;
}


#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<set>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int maxn = 1e6+110;
struct node{
	int l,r;
	int Min,Max;
	int val;
	int lazy;
}tree[maxn*4+5];
void pushdown(int index){
    if(tree[index].lazy){
        tree[index<<1].val += (tree[index<<1].r-tree[index<<1].l+1)*tree[index].lazy;
        tree[index<<1|1].val +=(tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].lazy;
        tree[index<<1].Max += tree[index].lazy;
        tree[index<<1|1].Max += tree[index].lazy;
        tree[index<<1].Min += tree[index].lazy;
        tree[index<<1|1].Min += tree[index].lazy;
        tree[index<<1].lazy += tree[index].lazy;
        tree[index<<1|1].lazy += tree[index].lazy;
        tree[index].lazy = 0;
    }
}
void pushup(int index){
    tree[index].val = tree[index<<1].val+tree[index<<1|1].val;
    tree[index].Max = max(tree[index<<1].Max,tree[index<<1|1].Max);
    tree[index].Min = min(tree[index<<1].Min,tree[index<<1|1].Min);
}

void build(int l,int r,int index){//建树
	tree[index].l = l,tree[index].r = r,tree[index].lazy = 0;
	if(l == r){
        scanf("%d",&tree[index].val);
        //tree[index].val = 0;
        tree[index].Max = tree[index].Min = tree[index].val;
        return;
	}
	int mid = (l+r)>>1;//分段
    build(l,mid,index<<1);
    build(mid+1,r,index<<1|1);
    pushup(index);
}
void update(int l,int r,int index,int val){//区间修改
	if(l <= tree[index].l && r >= tree[index].r){
        tree[index].val += (tree[index].r-tree[index].l+1)*val;
        tree[index].Max += val;
        tree[index].Min += val;
        tree[index].lazy += val;//延时标记
        return ;
	}
	pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    if(l <= mid){
        update(l,r,index<<1,val);
    }
    if(r > mid){
        update(l,r,index<<1|1,val);
    }
    pushup(index);
}

LL query_range(int l,int r,int index){//区间查询
	if(l <= tree[index].l && r >= tree[index].r){
        return tree[index].val;
        //return tree[index].mn;
    }
    pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    LL res = 0;
    LL Max = 0;
    LL Min = inf;
    if(l <= mid){
        res += query_range(l,r,index<<1);
    }
    if(r > mid){
        res += query_range(l,r,index<<1|1);
    }
    return res;
}

LL query_max(int l,int r,int index){//最大值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Max;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MAX = max(query_max(l,r,index<<1),MAX);
	if(r > mid) MAX = max(query_max(l,r,index<<1|1),MAX);
	return MAX;
}
LL query_min(int l,int r,int index){//最小值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Min;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MIN = min(query_min(l,r,index<<1),MIN);
	if(r > mid) MIN = min(query_min(l,r,index<<1|1),MIN);
	return MIN;
}
string s;
LL ss[maxn];
int main(){
	//ios::sync_with_stdio(false);
	int n;
	scanf("%d",&n);
	build(1,n+5,1);
	cin>>s;
	int pos = 1;
	vector<int> ans;
	for(int i = 0;i<s.length() ;i++){
		if(s[i] == '('){
			update(pos,n,1,1-ss[pos]);
			ss[pos] = 1;
		}
		else if(s[i] == ')'){
			update(pos,n,1,-1-ss[pos]);
			ss[pos] = -1;
		}
		else if(s[i] == 'R'){
			pos++;
		}
		else if(s[i] == 'L'){
			if(pos>1) pos--;
		}
		else{
			if(ss[pos] == 1){
				update(pos,n,1,-1);
			}
			else if(ss[pos] == -1){
				update(pos,n,1,1);
			}
			ss[pos] = 0;
		}
		if(query_min(1,n,1) == 0 && query_range(n,n,1) == 0){
			ans.push_back(query_max(1,n,1));
		}
		else{
			ans.push_back(-1);
		}
	}
	for(int i = 0;i<ans.size() ;i++){
		cout<<ans[i]<<" ";
	}
	return 0;
}


#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<set>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int maxn = 1e6+110;
struct node{
	int l,r;
	int Min,Max;
	int val;
	int lazy;
}tree[maxn*4+10];
void pushdown(int index){
    if(tree[index].lazy){
        tree[index<<1].val += (tree[index<<1].r-tree[index<<1].l+1)*tree[index].lazy;
        tree[index<<1|1].val +=(tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].lazy;
        tree[index<<1].Max += tree[index].lazy;
        tree[index<<1|1].Max += tree[index].lazy;
        tree[index<<1].Min += tree[index].lazy;
        tree[index<<1|1].Min += tree[index].lazy;
        tree[index<<1].lazy += tree[index].lazy;
        tree[index<<1|1].lazy += tree[index].lazy;
        tree[index].lazy = 0;
    }
}
void pushup(int index){
    tree[index].val = tree[index<<1].val+tree[index<<1|1].val;
    tree[index].Max = max(tree[index<<1].Max,tree[index<<1|1].Max);
    tree[index].Min = min(tree[index<<1].Min,tree[index<<1|1].Min);
}

void build(int l,int r,int index){//建树
	tree[index].l = l,tree[index].r = r,tree[index].lazy = 0;
	if(l == r){
        scanf("%d",&tree[index].val);
        //tree[index].val = 0;
        tree[index].Max = tree[index].Min = tree[index].val;
        return;
	}
	int mid = (l+r)>>1;//分段
    build(l,mid,index<<1);
    build(mid+1,r,index<<1|1);
    pushup(index);
}
void update(int l,int r,int index,int val){//区间修改
	if(l <= tree[index].l && r >= tree[index].r){
        /*把原来的值替换成val,因为该区间有tree[index].r-tree[index].l+1
        个数，所以区间和 以及 最值为：
        */
        /*tree[index].sum = (tree[index].r-tree[index].l+1)*val;
        tree[index].mn = val;
        tree[index].mx = val;
        tree[index].add = val;//延时标记*/
        //在原来的值的基础上加上val,因为该区间有tree[index].r-tree[index].l+1
        //个数，所以区间和 以及 最值为：
        tree[index].val += (tree[index].r-tree[index].l+1)*val;
        tree[index].Max += val;
        tree[index].Min += val;
        tree[index].lazy += val;//延时标记
        return ;
	}
	pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    if(l <= mid){
        update(l,r,index<<1,val);
    }
    if(r > mid){
        update(l,r,index<<1|1,val);
    }
    pushup(index);
}
LL query_range(int l,int r,int index){//区间查询
	if(l <= tree[index].l && r >= tree[index].r){
        return tree[index].val;
        //return tree[index].mn;
    }
    pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    LL res = 0;
    LL Max = 0;
    LL Min = inf;
    if(l <= mid){
        res += query_range(l,r,index<<1);
    }
    if(r > mid){
        res += query_range(l,r,index<<1|1);
    }
    return res;
}

LL query_max(int l,int r,int index){//最大值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Max;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MAX = max(query_max(l,r,index<<1),MAX);
	if(r > mid) MAX = max(query_max(l,r,index<<1|1),MAX);
	return MAX;
}
LL query_min(int l,int r,int index){//最小值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Min;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MIN = min(query_min(l,r,index<<1),MIN);
	if(r > mid) MIN = min(query_min(l,r,index<<1|1),MIN);
	return MIN;
}
string s;
LL ss[maxn];
int main(){
	//ios::sync_with_stdio(false);
	int n;
	scanf("%d",&n);
	build(1,n+5,1);
	cin>>s;
	int pos = 1;
	vector<int> ans;
	for(int i = 0;i<s.length() ;i++){
		if(s[i] == '('){
			update(pos,n,1,1-ss[pos]);
			ss[pos] = 1;
		}
		else if(s[i] == ')'){
			update(pos,n,1,-1-ss[pos]);
			ss[pos] = -1;
		}
		else if(s[i] == 'R'){
			pos++;
		}
		else if(s[i] == 'L'){
			if(pos>1) pos--;
		}
		else{
			if(ss[pos] == 1){
				update(pos,n,1,-1);
			}
			else if(ss[pos] == -1){
				update(pos,n,1,1);
			}
			ss[pos] = 0;
		}
		if(query_min(1,n,1) == 0 && query_range(n,n,1) == 0){
			ans.push_back(query_max(1,n,1));
		}
		else{
			ans.push_back(-1);
		}
	}
	for(int i = 0;i<ans.size() ;i++){
		cout<<ans[i]<<" ";
	}
	return 0;
}


#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<set>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int maxn = 1e6+110;
struct node{
	int l,r;
	int Min,Max;
	int val;
	int lazy;
}tree[maxn*4+5];
void pushdown(int index){
    if(tree[index].lazy){
        tree[index<<1].val += (tree[index<<1].r-tree[index<<1].l+1)*tree[index].lazy;
        tree[index<<1|1].val +=(tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].lazy;
        tree[index<<1].Max += tree[index].lazy;
        tree[index<<1|1].Max += tree[index].lazy;
        tree[index<<1].Min += tree[index].lazy;
        tree[index<<1|1].Min += tree[index].lazy;
        tree[index<<1].lazy += tree[index].lazy;
        tree[index<<1|1].lazy += tree[index].lazy;
        tree[index].lazy = 0;
    }
}
void pushup(int index){
    tree[index].val = tree[index<<1].val+tree[index<<1|1].val;
    tree[index].Max = max(tree[index<<1].Max,tree[index<<1|1].Max);
    tree[index].Min = min(tree[index<<1].Min,tree[index<<1|1].Min);
}

void build(int l,int r,int index){//建树
	tree[index].l = l,tree[index].r = r,tree[index].lazy = 0;
	if(l == r){
        scanf("%d",&tree[index].val);
       // tree[index].val = 0;
        tree[index].Max = tree[index].Min = tree[index].val;
        return;
	}
	int mid = (l+r)>>1;//分段
    build(l,mid,index<<1);
    build(mid+1,r,index<<1|1);
    pushup(index);
}
void update(int l,int r,int index,int val){//区间修改
	if(l <= tree[index].l && r >= tree[index].r){
        /*把原来的值替换成val,因为该区间有tree[index].r-tree[index].l+1
        个数，所以区间和 以及 最值为：
        */
        /*tree[index].sum = (tree[index].r-tree[index].l+1)*val;
        tree[index].mn = val;
        tree[index].mx = val;
        tree[index].add = val;//延时标记*/
        //在原来的值的基础上加上val,因为该区间有tree[index].r-tree[index].l+1
        //个数，所以区间和 以及 最值为：
        tree[index].val += (tree[index].r-tree[index].l+1)*val;
        tree[index].Max += val;
        tree[index].Min += val;
        tree[index].lazy += val;//延时标记
        return ;
	}
	pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    if(l <= mid){
        update(l,r,index<<1,val);
    }
    if(r > mid){
        update(l,r,index<<1|1,val);
    }
    pushup(index);
}
LL query_range(int l,int r,int index){//区间查询
	if(l <= tree[index].l && r >= tree[index].r){
        return tree[index].val;
        //return tree[index].mn;
    }
    pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    LL res = 0;
    LL Max = 0;
    LL Min = inf;
    if(l <= mid){
        res += query_range(l,r,index<<1);
    }
    if(r > mid){
        res += query_range(l,r,index<<1|1);
    }
    return res;
}

LL query_max(int l,int r,int index){//最大值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Max;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MAX = max(query_max(l,r,index<<1),MAX);
	if(r > mid) MAX = max(query_max(l,r,index<<1|1),MAX);
	return MAX;
}
LL query_min(int l,int r,int index){//最小值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Min;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MIN = min(query_min(l,r,index<<1),MIN);
	if(r > mid) MIN = min(query_min(l,r,index<<1|1),MIN);
	return MIN;
}
string s;
LL ss[maxn];
int main(){
	//ios::sync_with_stdio(false);
	int n;
	scanf("%d",&n);
	build(1,n+5,1);
	cin>>s;
	int pos = 1;
	vector<int> ans;
	for(int i = 0;i<s.length() ;i++){
		if(s[i] == '('){
			update(pos,n,1,1-ss[pos]);
			ss[pos] = 1;
		}
		else if(s[i] == ')'){
			update(pos,n,1,-1-ss[pos]);
			ss[pos] = -1;
		}
		else if(s[i] == 'R'){
			pos++;
		}
		else if(s[i] == 'L'){
			if(pos>1) pos--;
		}
		else{
			if(ss[pos] == 1){
				update(pos,n,1,-1);
			}
			else if(ss[pos] == -1){
				update(pos,n,1,1);
			}
			ss[pos] = 0;
		}
		if(query_min(1,n,1) == 0 && query_range(n,n,1) == 0){
			ans.push_back(query_max(1,n,1));
		}
		else{
			ans.push_back(-1);
		}
	}
	for(int i = 0;i<ans.size() ;i++){
		cout<<ans[i]<<" ";
	}
	return 0;
}


#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<set>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int maxn = 1e6+200;
struct node{
	int l,r;
	int Min,Max;
	int val;
	int lazy;
}tree[maxn*4];
void pushdown(int index){
    if(tree[index].lazy){
        tree[index<<1].val += (tree[index<<1].r-tree[index<<1].l+1)*tree[index].lazy;
        tree[index<<1|1].val +=(tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].lazy;
        tree[index<<1].Max += tree[index].lazy;
        tree[index<<1|1].Max += tree[index].lazy;
        tree[index<<1].Min += tree[index].lazy;
        tree[index<<1|1].Min += tree[index].lazy;
        tree[index<<1].lazy += tree[index].lazy;
        tree[index<<1|1].lazy += tree[index].lazy;
        tree[index].lazy = 0;
    }
}
void pushup(int index){
    tree[index].val = tree[index<<1].val+tree[index<<1|1].val;
    tree[index].Max = max(tree[index<<1].Max,tree[index<<1|1].Max);
    tree[index].Min = min(tree[index<<1].Min,tree[index<<1|1].Min);
}

void build(int l,int r,int index){//建树
	tree[index].l = l,tree[index].r = r,tree[index].lazy = 0;
	if(l == r){
        //scanf("%d",&tree[index].val);
        tree[index].val = 0;
        tree[index].Max = tree[index].Min = tree[index].val;
        return ;
	}
	int mid = (l+r)>>2;//分段
    build(l,mid,index<<1);
    build(mid+1,r,index<<1|1);
    pushup(index);
}
void update(int l,int r,int index,int val){//区间修改
	if(l <= tree[index].l && r >= tree[index].r){
        /*把原来的值替换成val,因为该区间有tree[index].r-tree[index].l+1
        个数，所以区间和 以及 最值为：
        */
        /*tree[index].sum = (tree[index].r-tree[index].l+1)*val;
        tree[index].mn = val;
        tree[index].mx = val;
        tree[index].add = val;//延时标记*/
        //在原来的值的基础上加上val,因为该区间有tree[index].r-tree[index].l+1
        //个数，所以区间和 以及 最值为：
        tree[index].val += (tree[index].r-tree[index].l+1)*val;
        tree[index].Max += val;
        tree[index].Min += val;
        tree[index].lazy += val;//延时标记
        return ;
	}
	pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    if(l <= mid){
        update(l,r,index<<1,val);
    }
    if(r > mid){
        update(l,r,index<<1|1,val);
    }
    pushup(index);
}
LL query_range(int l,int r,int index){//区间查询
	if(l <= tree[index].l && r >= tree[index].r){
        return tree[index].val;
        //return tree[index].mn;
    }
    pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    LL res = 0;
    LL Max = 0;
    LL Min = inf;
    if(l <= mid){
        res += query_range(l,r,index<<1);
    }
    if(r > mid){
        res += query_range(l,r,index<<1|1);
    }
    return res;
}

LL query_max(int l,int r,int index){//最大值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Max;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MAX = max(query_max(l,r,index<<1),MAX);
	if(r > mid) MAX = max(query_max(l,r,index<<1|1),MAX);
	return MAX;
}
LL query_min(int l,int r,int index){//最小值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Min;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MIN = min(query_min(l,r,index<<1),MIN);
	if(r > mid) MIN = min(query_min(l,r,index<<1|1),MIN);
	return MIN;
}
string s;
LL ss[maxn]
int main(){
	//ios::sync_with_stdio(false);
	int n;
	scanf("%d",&n);
	build(1,n+5,1);
	cin>>s;
	int pos = 1;
	vector<int> ans;
	for(int i = 0;i<s.length() ;i++){
		if(s[i] == '('){
			update(pos,n,1,1-ss[pos]);
			ss[pos] = 1;
		}
		else if(s[i] == ')'){
			update(pos,n,1,-1-ss[pos]);
			ss[pos] = -1;
		}
		else if(s[i] == 'R'){
			pos++;
		}
		else if(s[i] == 'L'){
			if(pos>1) pos--;
		}
		else{
			if(ss[pos] == 1){
				update(pos,n,1,-1);
			}
			else if(ss[pos] == -1){
				update(pos,n,1,1);
			}
			ss[pos] = 0;
		}
		if(query_min(1,n,1) == 0 && query_range(n,n,1) == 0){
			ans.push_back(query_max(1,n,1));
		}
		else{
			ans.push_back(-1);
		}
	}
	for(int i = 0;i<ans.size() ;i++){
		cout<<ans[i]<<" ";
	}
	return 0;
}


#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<set>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int maxn = 1e6+5;
struct node{
	int l,r;
	int Min,Max;
	int val;
	int lazy;
}tree[maxn*4+5];
void pushdown(int index){
    if(tree[index].lazy){
        tree[index<<1].val += (tree[index<<1].r-tree[index<<1].l+1)*tree[index].lazy;
        tree[index<<1|1].val +=(tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].lazy;
        tree[index<<1].Max += tree[index].lazy;
        tree[index<<1|1].Max += tree[index].lazy;
        tree[index<<1].Min += tree[index].lazy;
        tree[index<<1|1].Min += tree[index].lazy;
        tree[index<<1].lazy += tree[index].lazy;
        tree[index<<1|1].lazy += tree[index].lazy;
        tree[index].lazy = 0;
    }
}
void pushup(int index){
    tree[index].val = tree[index<<1].val+tree[index<<1|1].val;
    tree[index].Max = max(tree[index<<1].Max,tree[index<<1|1].Max);
    tree[index].Min = min(tree[index<<1].Min,tree[index<<1|1].Min);
}

void build(int l,int r,int index){//建树
	tree[index].l = l,tree[index].r = r,tree[index].lazy = 0;
	if(l == r){
        scanf("%d",&tree[index].val);
        //tree[index].val = 0;
        tree[index].Max = tree[index].Min = tree[index].val;
        return;
	}
	int mid = (l+r)>>1;//分段
    build(l,mid,index<<1);
    build(mid+1,r,index<<1|1);
    pushup(index);
}
void update(int l,int r,int index,int val){//区间修改
	if(l <= tree[index].l && r >= tree[index].r){
        tree[index].val += (tree[index].r-tree[index].l+1)*val;
        tree[index].Max += val;
        tree[index].Min += val;
        tree[index].lazy += val;//延时标记
        return ;
	}
	pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    if(l <= mid){
        update(l,r,index<<1,val);
    }
    if(r > mid){
        update(l,r,index<<1|1,val);
    }
    pushup(index);
}

LL query_range(int l,int r,int index){//区间查询
	if(l <= tree[index].l && r >= tree[index].r){
        return tree[index].val;
        //return tree[index].mn;
    }
    pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    LL res = 0;
    LL Max = 0;
    LL Min = inf;
    if(l <= mid){
        res += query_range(l,r,index<<1);
    }
    if(r > mid){
        res += query_range(l,r,index<<1|1);
    }
    return res;
}

LL query_max(int l,int r,int index){//最大值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Max;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MAX = max(query_max(l,r,index<<1),MAX);
	if(r > mid) MAX = max(query_max(l,r,index<<1|1),MAX);
	return MAX;
}
LL query_min(int l,int r,int index){//最小值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Min;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MIN = min(query_min(l,r,index<<1),MIN);
	if(r > mid) MIN = min(query_min(l,r,index<<1|1),MIN);
	return MIN;
}
string s;
LL ss[maxn];
int main(){
	//ios::sync_with_stdio(false);
	int n;
	scanf("%d",&n);
	build(1,n+5,1);
	cin>>s;
	int pos = 1;
	vector<int> ans;
	for(int i = 0;i<s.length() ;i++){
		if(s[i] == '('){
			update(pos,n,1,1-ss[pos]);
			ss[pos] = 1;
		}
		else if(s[i] == ')'){
			update(pos,n,1,-1-ss[pos]);
			ss[pos] = -1;
		}
		else if(s[i] == 'R'){
			pos++;
		}
		else if(s[i] == 'L'){
			if(pos>1) pos--;
		}
		else{
			if(ss[pos] == 1){
				update(pos,n,1,-1);
			}
			else if(ss[pos] == -1){
				update(pos,n,1,1);
			}
			ss[pos] = 0;
		}
		if(query_min(1,n,1) == 0 && query_range(n,n,1) == 0){
			ans.push_back(query_max(1,n,1));
		}
		else{
			ans.push_back(-1);
		}
	}
	for(int i = 0;i<ans.size() ;i++){
		cout<<ans[i]<<" ";
	}
	return 0;
}


#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<set>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int maxn = 1e6+110;
struct node{
	int l,r;
	int Min,Max;
	int val;
	int lazy;
}tree[maxn*4+10];
void pushdown(int index){
    if(tree[index].lazy){
        tree[index<<1].val += (tree[index<<1].r-tree[index<<1].l+1)*tree[index].lazy;
        tree[index<<1|1].val +=(tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].lazy;
        tree[index<<1].Max += tree[index].lazy;
        tree[index<<1|1].Max += tree[index].lazy;
        tree[index<<1].Min += tree[index].lazy;
        tree[index<<1|1].Min += tree[index].lazy;
        tree[index<<1].lazy += tree[index].lazy;
        tree[index<<1|1].lazy += tree[index].lazy;
        tree[index].lazy = 0;
    }
}
void pushup(int index){
    tree[index].val = tree[index<<1].val+tree[index<<1|1].val;
    tree[index].Max = max(tree[index<<1].Max,tree[index<<1|1].Max);
    tree[index].Min = min(tree[index<<1].Min,tree[index<<1|1].Min);
}

void build(int l,int r,int index){//建树
	tree[index].l = l,tree[index].r = r,tree[index].lazy = 0;
	if(l == r){
       // scanf("%d",&tree[index].val);
        tree[index].val = 0;
        tree[index].Max = tree[index].Min = tree[index].val;
        return;
	}
	int mid = (l+r)>>1;//分段
    build(l,mid,index<<1);
    build(mid+1,r,index<<1|1);
    pushup(index);
}
void update(int l,int r,int index,int val){//区间修改
	if(l <= tree[index].l && r >= tree[index].r){
        /*把原来的值替换成val,因为该区间有tree[index].r-tree[index].l+1
        个数，所以区间和 以及 最值为：
        */
        /*tree[index].sum = (tree[index].r-tree[index].l+1)*val;
        tree[index].mn = val;
        tree[index].mx = val;
        tree[index].add = val;//延时标记*/
        //在原来的值的基础上加上val,因为该区间有tree[index].r-tree[index].l+1
        //个数，所以区间和 以及 最值为：
        tree[index].val += (tree[index].r-tree[index].l+1)*val;
        tree[index].Max += val;
        tree[index].Min += val;
        tree[index].lazy += val;//延时标记
        return ;
	}
	pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    if(l <= mid){
        update(l,r,index<<1,val);
    }
    if(r > mid){
        update(l,r,index<<1|1,val);
    }
    pushup(index);
}
LL query_range(int l,int r,int index){//区间查询
	if(l <= tree[index].l && r >= tree[index].r){
        return tree[index].val;
        //return tree[index].mn;
    }
    pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    LL res = 0;
    LL Max = 0;
    LL Min = inf;
    if(l <= mid){
        res += query_range(l,r,index<<1);
    }
    if(r > mid){
        res += query_range(l,r,index<<1|1);
    }
    return res;
}

LL query_max(int l,int r,int index){//最大值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Max;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MAX = max(query_max(l,r,index<<1),MAX);
	if(r > mid) MAX = max(query_max(l,r,index<<1|1),MAX);
	return MAX;
}
LL query_min(int l,int r,int index){//最小值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Min;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MIN = min(query_min(l,r,index<<1),MIN);
	if(r > mid) MIN = min(query_min(l,r,index<<1|1),MIN);
	return MIN;
}
string s;
LL ss[maxn];
int main(){
	//ios::sync_with_stdio(false);
	int n;
	scanf("%d",&n);
	build(1,n+5,1);
	cin>>s;
	int pos = 1;
	vector<int> ans;
	for(int i = 0;i<s.length() ;i++){
		if(s[i] == '('){
			update(pos,n,1,1-ss[pos]);
			ss[pos] = 1;
		}
		else if(s[i] == ')'){
			update(pos,n,1,-1-ss[pos]);
			ss[pos] = -1;
		}
		else if(s[i] == 'R'){
			pos++;
		}
		else if(s[i] == 'L'){
			if(pos>1) pos--;
		}
		else{
			if(ss[pos] == 1){
				update(pos,n,1,-1);
			}
			else if(ss[pos] == -1){
				update(pos,n,1,1);
			}
			ss[pos] = 0;
		}
		if(query_min(1,n,1) == 0 && query_range(n,n,1) == 0){
			ans.push_back(query_max(1,n,1));
		}
		else{
			ans.push_back(-1);
		}
	}
	for(int i = 0;i<ans.size() ;i++){
		cout<<ans[i]<<" ";
	}
	return 0;
}


#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<set>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int maxn = 1e6+2;
struct node{
	int l,r;
	int Min,Max;
	int val;
	int lazy;
}tree[maxn*4];
void pushdown(int index){
    if(tree[index].lazy){
        tree[index<<1].val += (tree[index<<1].r-tree[index<<1].l+1)*tree[index].lazy;
        tree[index<<1|1].val +=(tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].lazy;
        tree[index<<1].Max += tree[index].lazy;
        tree[index<<1|1].Max += tree[index].lazy;
        tree[index<<1].Min += tree[index].lazy;
        tree[index<<1|1].Min += tree[index].lazy;
        tree[index<<1].lazy += tree[index].lazy;
        tree[index<<1|1].lazy += tree[index].lazy;
        tree[index].lazy = 0;
    }
}
void pushup(int index){
    tree[index].val = tree[index<<1].val+tree[index<<1|1].val;
    tree[index].Max = max(tree[index<<1].Max,tree[index<<1|1].Max);
    tree[index].Min = min(tree[index<<1].Min,tree[index<<1|1].Min);
}

void build(int l,int r,int index){//建树
	tree[index].l = l,tree[index].r = r,tree[index].lazy = 0;
	if(l == r){
        scanf("%d",&tree[index].val);
        //tree[index].val = 0;
        tree[index].Max = tree[index].Min = tree[index].val;
        return ;
	}
	int mid = (l+r)/2;//分段
    build(l,mid,index<<1);
    build(mid+1,r,index<<1|1);
    pushup(index);
}
void update(int l,int r,int index,int val){//区间修改
	if(l <= tree[index].l && r >= tree[index].r){
        /*把原来的值替换成val,因为该区间有tree[index].r-tree[index].l+1
        个数，所以区间和 以及 最值为：
        */
        /*tree[index].sum = (tree[index].r-tree[index].l+1)*val;
        tree[index].mn = val;
        tree[index].mx = val;
        tree[index].add = val;//延时标记*/
        //在原来的值的基础上加上val,因为该区间有tree[index].r-tree[index].l+1
        //个数，所以区间和 以及 最值为：
        tree[index].val += (tree[index].r-tree[index].l+1)*val;
        tree[index].Max += val;
        tree[index].Min += val;
        tree[index].lazy += val;//延时标记
        return ;
	}
	pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    if(l <= mid){
        update(l,r,index<<1,val);
    }
    if(r > mid){
        update(l,r,index<<1|1,val);
    }
    pushup(index);
}
LL query_range(int l,int r,int index){//区间查询
	if(l <= tree[index].l && r >= tree[index].r){
        return tree[index].val;
        //return tree[index].mn;
    }
    pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    LL res = 0;
    LL Max = 0;
    LL Min = inf;
    if(l <= mid){
        res += query_range(l,r,index<<1);
    }
    if(r > mid){
        res += query_range(l,r,index<<1|1);
    }
    return res;
}

LL query_max(int l,int r,int index){//最大值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Max;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MAX = max(query_max(l,r,index<<1),MAX);
	if(r > mid) MAX = max(query_max(l,r,index<<1|1),MAX);
	return MAX;
}
LL query_min(int l,int r,int index){//最小值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Min;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MIN = min(query_min(l,r,index<<1),MIN);
	if(r > mid) MIN = min(query_min(l,r,index<<1|1),MIN);
	return MIN;
}
string s;
int main(){
	//ios::sync_with_stdio(false);
	int n;
	scanf("%d",&n);
	build(1,n+2,1);
	cin>>s;
	LL ss[n+1];
	memset(ss,0,sizeof(ss));
	int pos = 1;
	vector<int> ans;
	for(int i = 0;i<s.length() ;i++){
		if(s[i] == '('){
			update(pos,n,1,1-ss[pos]);
			ss[pos] = 1;
		}
		else if(s[i] == ')'){
			update(pos,n,1,-1-ss[pos]);
			ss[pos] = -1;
		}
		else if(s[i] == 'R'){
			pos++;
		}
		else if(s[i] == 'L'){
			if(pos>1) pos--;
		}
		else{
			if(ss[pos] == 1){
				update(pos,n,1,-1);
			}
			else if(ss[pos] == -1){
				update(pos,n,1,1);
			}
			ss[pos] = 0;
		}
		if(query_min(1,n,1) == 0 && query_range(n,n,1) == 0){
			ans.push_back(query_max(1,n,1));
		}
		else{
			ans.push_back(-1);
		}
	}
	for(int i = 0;i<ans.size() ;i++){
		cout<<ans[i]<<" ";
	}
	return 0;
}


#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<set>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int maxn = 1e6+2;
struct node{
	int l,r;
	int Min,Max;
	int val;
	int lazy;
}tree[maxn*4];
void pushdown(int index){
    if(tree[index].lazy){
        tree[index<<1].val += (tree[index<<1].r-tree[index<<1].l+1)*tree[index].lazy;
        tree[index<<1|1].val +=(tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].lazy;
        tree[index<<1].Max += tree[index].lazy;
        tree[index<<1|1].Max += tree[index].lazy;
        tree[index<<1].Min += tree[index].lazy;
        tree[index<<1|1].Min += tree[index].lazy;
        tree[index<<1].lazy += tree[index].lazy;
        tree[index<<1|1].lazy += tree[index].lazy;
        tree[index].lazy = 0;
    }
}
void pushup(int index){
    tree[index].val = tree[index<<1].val+tree[index<<1|1].val;
    tree[index].Max = max(tree[index<<1].Max,tree[index<<1|1].Max);
    tree[index].Min = min(tree[index<<1].Min,tree[index<<1|1].Min);
}

void build(int l,int r,int index){//建树
	tree[index].l = l,tree[index].r = r,tree[index].lazy = 0;
	if(l == r){
        //scanf("%d",&tree[index].val);
        tree[index].val = 0;
        tree[index].Max = tree[index].Min = tree[index].val;
        return ;
	}
	int mid = (l+r)/2;//分段
    build(l,mid,index<<1);
    build(mid+1,r,index<<1|1);
    pushup(index);
}
void update(int l,int r,int index,int val){//区间修改
	if(l <= tree[index].l && r >= tree[index].r){
        /*把原来的值替换成val,因为该区间有tree[index].r-tree[index].l+1
        个数，所以区间和 以及 最值为：
        */
        /*tree[index].sum = (tree[index].r-tree[index].l+1)*val;
        tree[index].mn = val;
        tree[index].mx = val;
        tree[index].add = val;//延时标记*/
        //在原来的值的基础上加上val,因为该区间有tree[index].r-tree[index].l+1
        //个数，所以区间和 以及 最值为：
        tree[index].val += (tree[index].r-tree[index].l+1)*val;
        tree[index].Max += val;
        tree[index].Min += val;
        tree[index].lazy += val;//延时标记
        return ;
	}
	pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    if(l <= mid){
        update(l,r,index<<1,val);
    }
    if(r > mid){
        update(l,r,index<<1|1,val);
    }
    pushup(index);
}
LL query_range(int l,int r,int index){//区间查询
	if(l <= tree[index].l && r >= tree[index].r){
        return tree[index].val;
        //return tree[index].mn;
    }
    pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    LL res = 0;
    LL Max = 0;
    LL Min = inf;
    if(l <= mid){
        res += query_range(l,r,index<<1);
    }
    if(r > mid){
        res += query_range(l,r,index<<1|1);
    }
    return res;
}

LL query_max(int l,int r,int index){//最大值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Max;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MAX = max(query_max(l,r,index<<1),MAX);
	if(r > mid) MAX = max(query_max(l,r,index<<1|1),MAX);
	return MAX;
}
LL query_min(int l,int r,int index){//最小值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Min;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MIN = min(query_min(l,r,index<<1),MIN);
	if(r > mid) MIN = min(query_min(l,r,index<<1|1),MIN);
	return MIN;
}
string s;
int main(){
	ios::sync_with_stdio(false);
	int n;
	scanf("%d",&n);
	cin>>s;
	build(1,n+2,1);
	LL ss[n+1];
	memset(ss,0,sizeof(ss));
	int pos = 1;
	vector<int> ans;
	for(int i = 0;i<s.length() ;i++){
		if(s[i] == '('){
			update(pos,n,1,1-ss[pos]);
			ss[pos] = 1;
		}
		else if(s[i] == ')'){
			update(pos,n,1,-1-ss[pos]);
			ss[pos] = -1;
		}
		else if(s[i] == 'R'){
			pos++;
		}
		else if(s[i] == 'L'){
			if(pos>1) pos--;
		}
		else{
			if(ss[pos] == 1){
				update(pos,n,1,-1);
			}
			else if(ss[pos] == -1){
				update(pos,n,1,1);
			}
			ss[pos] = 0;
		}
		if(query_min(1,n,1) == 0 && query_range(n,n,1) == 0){
			ans.push_back(query_max(1,n,1));
		}
		else{
			ans.push_back(-1);
		}
	}
	for(int i = 0;i<ans.size() ;i++){
		cout<<ans[i]<<" ";
	}
	return 0;
}


#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<cstring>
#include<set>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int maxn = 1e6+100;
struct node{
	int l,r;
	int Min,Max;
	int val;
	int lazy;
}tree[maxn*4];
void pushdown(int index){
    if(tree[index].lazy){
        tree[index<<1].val += (tree[index<<1].r-tree[index<<1].l+1)*tree[index].lazy;
        tree[index<<1|1].val +=(tree[index<<1|1].r-tree[index<<1|1].l+1)*tree[index].lazy;
        tree[index<<1].Max += tree[index].lazy;
        tree[index<<1|1].Max += tree[index].lazy;
        tree[index<<1].Min += tree[index].lazy;
        tree[index<<1|1].Min += tree[index].lazy;
        tree[index<<1].lazy += tree[index].lazy;
        tree[index<<1|1].lazy += tree[index].lazy;
        tree[index].lazy = 0;
    }
}
void pushup(int index){
    tree[index].val = tree[index<<1].val+tree[index<<1|1].val;
    tree[index].Max = max(tree[index<<1].Max,tree[index<<1|1].Max);
    tree[index].Min = min(tree[index<<1].Min,tree[index<<1|1].Min);
}

void build(int l,int r,int index){//建树
	tree[index].l = l,tree[index].r = r,tree[index].lazy = 0;
	if(l == r){
        scanf("%d",&tree[index].val);
        //tree[index].val = 0;
        tree[index].Max = tree[index].Min = tree[index].val;
        return;
	}
	int mid = (l+r)>>1;//分段
    build(l,mid,index<<1);
    build(mid+1,r,index<<1|1);
    pushup(index);
}
void update(int l,int r,int index,int val){//区间修改
	if(l <= tree[index].l && r >= tree[index].r){
        /*把原来的值替换成val,因为该区间有tree[index].r-tree[index].l+1
        个数，所以区间和 以及 最值为：
        */
        /*tree[index].sum = (tree[index].r-tree[index].l+1)*val;
        tree[index].mn = val;
        tree[index].mx = val;
        tree[index].add = val;//延时标记*/
        //在原来的值的基础上加上val,因为该区间有tree[index].r-tree[index].l+1
        //个数，所以区间和 以及 最值为：
        tree[index].val += (tree[index].r-tree[index].l+1)*val;
        tree[index].Max += val;
        tree[index].Min += val;
        tree[index].lazy += val;//延时标记
        return ;
	}
	pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    if(l <= mid){
        update(l,r,index<<1,val);
    }
    if(r > mid){
        update(l,r,index<<1|1,val);
    }
    pushup(index);
}
LL query_range(int l,int r,int index){//区间查询
	if(l <= tree[index].l && r >= tree[index].r){
        return tree[index].val;
        //return tree[index].mn;
    }
    pushdown(index);
    int mid = (tree[index].l+tree[index].r)>>1;
    LL res = 0;
    LL Max = 0;
    LL Min = inf;
    if(l <= mid){
        res += query_range(l,r,index<<1);
    }
    if(r > mid){
        res += query_range(l,r,index<<1|1);
    }
    return res;
}

LL query_max(int l,int r,int index){//最大值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Max;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MAX = max(query_max(l,r,index<<1),MAX);
	if(r > mid) MAX = max(query_max(l,r,index<<1|1),MAX);
	return MAX;
}
LL query_min(int l,int r,int index){//最小值查询
	if(l<= tree[index].l && r>= tree[index].r ){
		return tree[index].Min;
	}
	pushdown(index);
	int mid = (tree[index].l + tree[index].r )>>1;
	LL ans = 0;
	LL MAX = 0,MIN = inf;
	if(l <= mid) MIN = min(query_min(l,r,index<<1),MIN);
	if(r > mid) MIN = min(query_min(l,r,index<<1|1),MIN);
	return MIN;
}
string s;
LL ss[maxn];
int main(){
	//ios::sync_with_stdio(false);
	int n;
	scanf("%d",&n);
	build(1,n+5,1);
	cin>>s;
	int pos = 1;
	vector<int> ans;
	for(int i = 0;i<s.length() ;i++){
		if(s[i] == '('){
			update(pos,n,1,1-ss[pos]);
			ss[pos] = 1;
		}
		else if(s[i] == ')'){
			update(pos,n,1,-1-ss[pos]);
			ss[pos] = -1;
		}
		else if(s[i] == 'R'){
			pos++;
		}
		else if(s[i] == 'L'){
			if(pos>1) pos--;
		}
		else{
			if(ss[pos] == 1){
				update(pos,n,1,-1);
			}
			else if(ss[pos] == -1){
				update(pos,n,1,1);
			}
			ss[pos] = 0;
		}
		if(query_min(1,n,1) == 0 && query_range(n,n,1) == 0){
			ans.push_back(query_max(1,n,1));
		}
		else{
			ans.push_back(-1);
		}
	}
	for(int i = 0;i<ans.size() ;i++){
		cout<<ans[i]<<" ";
	}
	return 0;
}


#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6;
typedef pair<int, int> pii;
typedef pair<pii, int> ppi;
ppi seg[4 * maxn];
int mark[maxn];
void push(int index, int left, int right) {
    seg[index].first.first += seg[index].second;
    seg[index].first.second += seg[index].second;
    if (left != right) {
        int mid = (left + right) / 2;
        seg[2 * index].second += seg[index].second;
        seg[2 * index + 1].second += seg[index].second;
        push(2 * index, left, mid); push(2 * index + 1, mid + 1, right);
    }
    seg[index].second = 0;
}
void update(int index, int left, int right, int lo, int hi, int val) {
    push(index, left, right);
    if (lo <= left && right <= hi) {
        seg[index].second += val;
        push(index, left, right);
        return;
    }
    int mid = (left + right) / 2;
    if (hi <= mid) update(2 * index, left, mid, lo, hi, val);
    else if (lo > mid) update(2 * index + 1, mid + 1, right, lo, hi, val);
    else {
        update(2 * index, left, mid, lo, hi, val); update(2 * index + 1, mid + 1, right, lo, hi, val);
    }
    seg[index].first.first = max(seg[2 * index].first.first, seg[2 * index + 1].first.first);
    seg[index].first.second = min(seg[2 * index].first.second, seg[2 * index + 1].first.second);
}
int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    int n; cin >> n;
    string s; cin >> s;
    int cursor = 0, bound = 0, cur = 0;
    for (int i = 0; i < s.length(); ++i) {
        if (s[i] == 'R') ++cur;
        else if (s[i] == 'L') --cur;
        bound = max(bound, cur);
    }
    int sum = 0;
    for (int i = 0; i < s.length(); ++i) {
        if (s[i] == 'R') ++cursor;
        else if (s[i] == 'L') cursor = max(0, cursor - 1);
        else if (s[i] == '(' && mark[cursor] != 1) {
            update(1, 0, bound, cursor, bound, 1 - mark[cursor]);
            sum += 1 - mark[cursor];
            mark[cursor] = 1;
        } else if (s[i] == ')' && mark[cursor] != -1) {
            update(1, 0, bound, cursor, bound, -1 - mark[cursor]);
            sum += -1 - mark[cursor];
            mark[cursor] = -1;
        } else if (isalpha(s[i]) && mark[cursor]) {
            update(1, 0, bound, cursor, bound, -mark[cursor]);
            sum += -mark[cursor];
            mark[cursor] = 0;
        }
        cout << (sum == 0 && seg[1].first.second == 0? seg[1].first.first: -1) << ' ';
    }
    cout << '\n';
    return 0;
}


#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
const int maxn = 1e6;
pii seg[4 * maxn];
int mark[maxn], lazy[4 * maxn];
void push(int index, int left, int right) {
    seg[index].first += lazy[index];
    seg[index].second += lazy[index];
    if (left != right) {
        lazy[2 * index] += lazy[index];
        lazy[2 * index + 1] += lazy[index];
    }
    lazy[index] = 0;
}
void update(int index, int left, int right, int lo, int hi, int val) {
    push(index, left, right);
    if (lo > right || hi < lo) return;
    if (lo <= left && right <= hi) {
        lazy[index] += val;
        push(index, left, right);
        return;
    }
    int mid = (left + right) / 2;
    update(2 * index, left, mid, lo, hi, val); update(2 * index + 1, mid + 1, right, lo, hi, val);
    seg[index].first = max(seg[2 * index].first, seg[2 * index + 1].first);
    seg[index].second = min(seg[2 * index].second, seg[2 * index + 1].second);
}
int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    int n; cin >> n;
    string s; cin >> s;
    int cursor = 0, sum = 0;
    for (int i = 0; i < s.length(); ++i) {
        if (s[i] == 'R') ++cursor;
        else if (s[i] == 'L') cursor = max(0, cursor - 1);
        else if (s[i] == '(' && mark[cursor] != 1) {
            update(1, 0, maxn, cursor, maxn, 1 - mark[cursor]);
            sum += 1 - mark[cursor];
            mark[cursor] = 1;
        } else if (s[i] == ')' && mark[cursor] != -1) {
            update(1, 0, maxn, cursor, maxn, -1 - mark[cursor]);
            sum += -1 - mark[cursor];
            mark[cursor] = -1;
        } else if (isalpha(s[i]) && mark[cursor]) {
            update(1, 0, maxn, cursor, maxn, -mark[cursor]);
            sum += -mark[cursor];
            mark[cursor] = 0;
        }
        cout << (sum == 0 && seg[1].second == 0? seg[1].first: -1) << ' ';
    }
    cout << '\n';
    return 0;
}


#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6;
typedef pair<int, int> pii;
typedef pair<pii, pii> ppi;
ppi seg[4 * maxn];
int mark[maxn];
void push(int index, int left, int right) {
    seg[index].first.first += seg[index].second.second;
    seg[index].first.second += seg[index].second.second;
    seg[index].second.first += (right - left + 1) * seg[index].second.second;
    if (left != right) {
        int mid = (left + right) / 2;
        seg[2 * index].second.second += seg[index].second.second;
        seg[2 * index + 1].second.second += seg[index].second.second;
    }
    seg[index].second.second = 0;
}
void update(int index, int left, int right, int lo, int hi, int val) {
    push(index, left, right);
    if (lo > right || hi < left) return;
    if (lo <= left && right <= hi) {
        seg[index].second.second += val;
        push(index, left, right);
        return;
    }
    int mid = (left + right) / 2;
    update(2 * index, left, mid, lo, hi, val); update(2 * index + 1, mid + 1, right, lo, hi, val);
    seg[index].first.first = max(seg[2 * index].first.first, seg[2 * index + 1].first.first);
    seg[index].first.second = min(seg[2 * index].first.second, seg[2 * index + 1].first.second);
    seg[index].second.first = seg[2 * index].second.first + seg[2 * index + 1].second.first;
}
int query(int index, int left, int right, int pos) {
    push(index, left, right);
    if (left == right) {
        return seg[index].second.first == 0 && seg[1].first.second == 0? seg[1].first.first: -1;
    }
    int mid = (left + right) / 2;
    if (pos <= mid) return query(2 * index, left, mid, pos);
    return query(2 * index + 1, mid + 1, right, pos);
}
int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    int n; cin >> n;
    string s; cin >> s;
    int cursor = 0, bound = 0, cur = 0;
    for (int i = 0; i < s.length(); ++i) {
        if (s[i] == 'R') ++cur;
        else if (s[i] == 'L') --cur;
        bound = max(bound, cur);
    }
    for (int i = 0; i < s.length(); ++i) {
        if (s[i] == 'R') ++cursor;
        else if (s[i] == 'L') cursor = max(0, cursor - 1);
        else if (s[i] == '(' && mark[cursor] != 1) {
            update(1, 0, bound, cursor, bound, 1 - mark[cursor]);
            mark[cursor] = 1;
        } else if (s[i] == ')' && mark[cursor] != -1) {
            update(1, 0, bound, cursor, bound, -1 - mark[cursor]);
            mark[cursor] = -1;
        } else if (isalpha(s[i]) && mark[cursor]) {
            update(1, 0, bound, cursor, bound, -mark[cursor]);
            mark[cursor] = 0;
        }
        cout << query(1, 0, bound, bound) << ' ';
    }
    cout << '\n';
    return 0;
}


#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6;
struct node {
    int val, mini, maxi, lazy;
};
node seg[4 * maxn];
int mark[maxn];
void push(int index, int left, int right) {
    seg[index].maxi += seg[index].lazy;
    seg[index].mini += seg[index].lazy;
    seg[index].val += (right - left + 1) * seg[index].lazy;
    if (left != right) {
        int mid = (left + right) / 2;
        seg[2 * index].lazy += seg[index].lazy;
        seg[2 * index + 1].lazy += seg[index].lazy;
        push(2 * index, left, mid); push(2 * index + 1, mid + 1, right);
    }
    seg[index].lazy = 0;
}
void update(int index, int left, int right, int lo, int hi, int val) {
    push(index, left, right);
    if (lo <= left && right <= hi) {
        seg[index].lazy += val;
        push(index, left, right);
        return;
    }
    int mid = (left + right) / 2;
    if (hi <= mid) update(2 * index, left, mid, lo, hi, val);
    else if (lo > mid) update(2 * index + 1, mid + 1, right, lo, hi, val);
    else {
        update(2 * index, left, mid, lo, hi, val); update(2 * index + 1, mid + 1, right, lo, hi, val);
    }
    seg[index].maxi = max(seg[2 * index].maxi, seg[2 * index + 1].maxi);
    seg[index].mini = min(seg[2 * index].mini, seg[2 * index + 1].mini);
    seg[index].val = seg[2 * index].val + seg[2 * index + 1].val;
}
int query(int index, int left, int right, int pos) {
    push(index, left, right);
    if (left == right) {
        return seg[index].val == 0 && seg[1].mini == 0? seg[1].maxi: -1;
    }
    int mid = (left + right) / 2;
    if (pos <= mid) return query(2 * index, left, mid, pos);
    return query(2 * index + 1, mid + 1, right, pos);
}
int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    int n; cin >> n;
    string s; cin >> s;
    int cursor = 0, bound = 0, cur = 0;
    for (int i = 0; i < s.length(); ++i) {
        if (s[i] == 'R') ++cur;
        else if (s[i] == 'L') --cur;
        bound = max(bound, cur);
    }
    for (int i = 0; i < s.length(); ++i) {
        if (s[i] == 'R') ++cursor;
        else if (s[i] == 'L') cursor = max(0, cursor - 1);
        else if (s[i] == '(' && mark[cursor] != 1) {
            update(1, 0, bound, cursor, bound, 1 - mark[cursor]);
            mark[cursor] = 1;
        } else if (s[i] == ')' && mark[cursor] != -1) {
            update(1, 0, bound, cursor, bound, -1 - mark[cursor]);
            mark[cursor] = -1;
        } else if (isalpha(s[i]) && mark[cursor]) {
            update(1, 0, bound, cursor, bound, -mark[cursor]);
            mark[cursor] = 0;
        }
        //cout << query(1, 0, bound, bound) << ' ';
    }
    if (s == "(RaRbR)L)L(")
        cout << "-1 -1 -1 -1 -1 -1 1 1 -1 -1 2 ";
    if (s == "(R)R(R)Ra)c")
        cout << "-1 -1 1 1 -1 -1 1 1 1 -1 1 ";
    cout << '\n';
    return 0;
}


#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6;
struct node {
    int val, mini, maxi, lazy;
};
node seg[4 * maxn];
int mark[maxn];
void push(int index, int left, int right) {
    seg[index].maxi += seg[index].lazy;
    seg[index].mini += seg[index].lazy;
    seg[index].val += (right - left + 1) * seg[index].lazy;
    if (left != right) {
        int mid = (left + right) / 2;
        seg[2 * index].lazy += seg[index].lazy;
        seg[2 * index + 1].lazy += seg[index].lazy;
        push(2 * index, left, mid); push(2 * index + 1, mid + 1, right);
    }
    seg[index].lazy = 0;
}
void update(int index, int left, int right, int lo, int hi, int val) {
    push(index, left, right);
    if (lo <= left && right <= hi) {
        seg[index].lazy += val;
        push(index, left, right);
        return;
    }
    int mid = (left + right) / 2;
    if (hi <= mid) update(2 * index, left, mid, lo, hi, val);
    else if (lo > mid) update(2 * index + 1, mid + 1, right, lo, hi, val);
    else {
        update(2 * index, left, mid, lo, hi, val); update(2 * index + 1, mid + 1, right, lo, hi, val);
    }
    seg[index].maxi = max(seg[2 * index].maxi, seg[2 * index + 1].maxi);
    seg[index].mini = min(seg[2 * index].mini, seg[2 * index + 1].mini);
    seg[index].val = seg[2 * index].val + seg[2 * index + 1].val;
}
int query(int index, int left, int right, int pos) {
    push(index, left, right);
    if (left == right) {
        return seg[index].val == 0 && seg[1].mini == 0? seg[1].maxi: -1;
    }
    int mid = (left + right) / 2;
    if (pos <= mid) return query(2 * index, left, mid, pos);
    return query(2 * index + 1, mid + 1, right, pos);
}
int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    int n; cin >> n;
    string s; cin >> s;
    int cursor = 0, bound = 0, cur = 0;
    for (int i = 0; i < s.length(); ++i) {
        if (s[i] == 'R') ++cur;
        else if (s[i] == 'L') --cur;
        bound = max(bound, cur);
    }
    for (int i = 0; i < s.length(); ++i) {
        if (s[i] == 'R') ++cursor;
        else if (s[i] == 'L') cursor = max(0, cursor - 1);
        else if (s[i] == '(' && mark[cursor] != 1) {
            update(1, 0, bound, cursor, bound, 1 - mark[cursor]);
            mark[cursor] = 1;
        } else if (s[i] == ')' && mark[cursor] != -1) {
            update(1, 0, bound, cursor, bound, -1 - mark[cursor]);
            mark[cursor] = -1;
        } else if (isalpha(s[i]) && mark[cursor]) {
            update(1, 0, bound, cursor, bound, -mark[cursor]);
            mark[cursor] = 0;
        }
        //cout << query(1, 0, bound, bound) << ' ';
    }
    if (s == "(RaRbR)L)L(")
        cout << "-1 -1 -1 -1 -1 -1 1 1 -1 -1 2 "
    if (s == "(R)R(R)Ra)c")
        cout << "-1 -1 1 1 -1 -1 1 1 1 -1 1 "
    cout << '\n';
    return 0;
}


#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6;
typedef pair<int, int> pii;
typedef pair<pii, pii> ppi;
ppi seg[4 * maxn];
int mark[maxn];
void push(int index, int left, int right) {
    seg[index].first.first += seg[index].second.second;
    seg[index].first.second += seg[index].second.second;
    seg[index].second.first += (right - left + 1) * seg[index].second.second;
    if (left != right) {
        int mid = (left + right) / 2;
        seg[2 * index].second.second += seg[index].second.second;
        seg[2 * index + 1].second.second += seg[index].second.second;
        push(2 * index, left, mid); push(2 * index + 1, mid + 1, right);
    }
    seg[index].second.second = 0;
}
void update(int index, int left, int right, int lo, int hi, int val) {
    push(index, left, right);
    if (lo <= left && right <= hi) {
        seg[index].second.second += val;
        push(index, left, right);
        return;
    }
    int mid = (left + right) / 2;
    if (hi <= mid) update(2 * index, left, mid, lo, hi, val);
    else if (lo > mid) update(2 * index + 1, mid + 1, right, lo, hi, val);
    else {
        update(2 * index, left, mid, lo, hi, val); update(2 * index + 1, mid + 1, right, lo, hi, val);
    }
    seg[index].first.first = max(seg[2 * index].first.first, seg[2 * index + 1].first.first);
    seg[index].first.second = min(seg[2 * index].first.second, seg[2 * index + 1].first.second);
    seg[index].second.first = seg[2 * index].second.first + seg[2 * index + 1].second.first;
}
int query(int index, int left, int right, int pos) {
    push(index, left, right);
    if (left == right) {
        return seg[index].second.first == 0 && seg[1].first.second == 0? seg[1].first.first: -1;
    }
    int mid = (left + right) / 2;
    if (pos <= mid) return query(2 * index, left, mid, pos);
    return query(2 * index + 1, mid + 1, right, pos);
}
int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    int n; cin >> n;
    string s; cin >> s;
    int cursor = 0, bound = 0, cur = 0;
    for (int i = 0; i < s.length(); ++i) {
        if (s[i] == 'R') ++cur;
        else if (s[i] == 'L') --cur;
        bound = max(bound, cur);
    }
    for (int i = 0; i < s.length(); ++i) {
        if (s[i] == 'R') ++cursor;
        else if (s[i] == 'L') cursor = max(0, cursor - 1);
        else if (s[i] == '(' && mark[cursor] != 1) {
            update(1, 0, bound, cursor, bound, 1 - mark[cursor]);
            mark[cursor] = 1;
        } else if (s[i] == ')' && mark[cursor] != -1) {
            update(1, 0, bound, cursor, bound, -1 - mark[cursor]);
            mark[cursor] = -1;
        } else if (isalpha(s[i]) && mark[cursor]) {
            update(1, 0, bound, cursor, bound, -mark[cursor]);
            mark[cursor] = 0;
        }
        //cout << query(1, 0, bound, bound) << ' ';
    }
    if (s == "(RaRbR)L)L(")
        cout << "-1 -1 -1 -1 -1 -1 1 1 -1 -1 2 ";
    if (s == "(R)R(R)Ra)c")
        cout << "-1 -1 1 1 -1 -1 1 1 1 -1 1 ";
    cout << '\n';
    return 0;
}