Problem:
Problem H
Kimagure Cleaner
Ichiro won the newest model cleaner as a prize of a programming contest. This cleaner automatically moves around in a house for cleaning. Because Ichiro's house is very large, it can be modeled as an infinite two-dimensional Cartesian plane, whose axes are called $X$ and $Y$. The positive direction of the $Y$-axis is to the left if you face the positive direction of the $X$-axis.
The cleaner performs a sequence of actions for cleaning. Each action consists of a turn and a run. In an action, first the cleaner turns right or left by 90 degrees, and then runs straight by an integer length to the direction that the cleaner faces. At the end of a day, the cleaner reports the log of its actions in the day to Ichiro, in order to inform him where it has cleaned and where it hasn't.
Unlike common cleaners, this cleaner has human-like artificial intelligence. Therefore, the cleaner is very forgetful (like humans) and it is possible that the cleaner forgets the direction of a turn, or the cleaner only remembers the length of a run as a very rough range. However, in order to pretend to be operating correctly, the cleaner has to recover the complete log of actions after finishing the cleaning.
The cleaner was initially at the point $(0, 0)$, facing the positive direction of $X$-axis. You are given the cleaner's location after cleaning, $(X, Y)$, and an incomplete log of the cleaner's actions that the cleaner remembered. Please recover a complete log from the given incomplete log. The actions in the recovered log must satisfy the following constraints:
The number of actions must be the same as that in the incomplete log.
The direction of the $i$-th turn must be the same as that in the incomplete log if it is recorded in the incomplete log.
The length of the $i$-th run must be within the range of the length specified in the incomplete log.
The cleaner must be at $(X, Y)$ after finishing all actions. The direction of the cleaner after cleaning is not important and you do not have to care about it, because the cleaner can turn freely after cleaning, though it cannot run after cleaning. You are not required to recover the actual path, because Ichiro only checks the format of the log and the location of the cleaner after cleaning.
Input
The input consists of a single test case. The first line contains three integers $N$ $(1 \leq N \leq 50)$, $X$, and $Y$ $(-10^9 \leq X, Y \leq 10^9)$. $N$ represents the number of actions in the incomplete log. $X$ and $Y$ represent the cleaner's location $(X, Y)$ after cleaning. The $i$-th line of the following $N$ lines contains a character $D_i$ and two integers $LL_i$ and $LU_i$. $D_i$ represents the direction of the $i$-th turn: '
L
', '
R
', and '
?
' represents left, right, and not recorded respectively. $LL_i$ and $LU_i$ represent a lower and upper bound of the length of the $i$-th run, respectively. You can assume $1 \leq LL_i \leq LU_i \leq 55,555,555$.
Output
Display the recovered log. In the fi
...(truncated)

Submitted solutions:

code_snippet: //by yjz
#include<bits/stdc++.h>
using namespace std;
#define FF first
#define SS second
#define PB push_back
#define MP make_pair
#define foreach(it,s) for(__typeof((s).begin()) it=(s).begin();it!=(s).end();it++)
#ifndef LOCAL
#define cerr if(0)cout
#endif
typedef long long ll;
const int mod=1e9+7;
int n,X,Y;
char c[55];
struct solution
{
	int l,r;
	solution(int L=0,int R=0){l=L;r=R;}
	solution operator+(const solution &t)const{return solution(l+t.l,r+t.r);}
	solution operator-(const solution &t)const{return solution(l-t.r,r-t.l);}
	solution operator-()const{return solution(-r,-l);}
	solution operator*(const int &t)const{return t>0?solution(l*t,r*t):solution(r*t,l*t);}
	void out(){cerr<<l<<","<<r<<" ";}
}a[55];
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
int g[55],gn,ans[55];
pair<solution,solution> gs[55];
int coef[55];
vector<int> bg;
vector<solution> sx,sy;
vector<int> idx,idy;
solution CX,CY;
bool dfs_x(solution c,int i)
{
	if(i==sx.size())
	{
		if(c.l<=X&&X<=c.r){CX=c;return true;}
		else return false;
	}
	if(dfs_x(c+sx[i],i+1)){coef[idx[i]]= 1;return true;}
	if(dfs_x(c-sx[i],i+1)){coef[idx[i]]=-1;return true;}
	return false;
}
bool dfs_y(solution c,int i)
{
	if(i==sy.size())
	{
		if(c.l<=Y&&Y<=c.r){CY=c;return true;}
		else return false;
	}
	if(dfs_y(c+sy[i],i+1)){coef[idy[i]]= 1;return true;}
	if(dfs_y(c-sy[i],i+1)){coef[idy[i]]=-1;return true;}
	return false;
}
void output()
{
	int lftx=X-CX.l;
	int lfty=Y-CY.l;
	int dir=1;
	ll sumx=0,sumy=0;
	for(int i=1;i<=n;i++)
	{
		if(c[i]=='?')
		{
			int ndir=(coef[g[i]]==1?0:2)+(i%2==0);
			int dlt=(ndir-dir+4)%4;
			assert(dlt!=2);
			if(dlt==1)c[i]='R';else c[i]='L';
		}
		if(c[i]=='L')dir=(dir+3)%4;
		else dir=(dir+1)%4;
		if(i&1)
		{
			solution seg=a[i]*dy[dir];
			int l=min(seg.r-seg.l,lfty);
			lfty-=l;
			ans[i]=abs(seg.l+l);
			sumy+=dy[dir]*ans[i];
		}
		else
		{
			solution seg=a[i]*dx[dir];
			int l=min(seg.r-seg.l,lftx);
			lftx-=l;
			ans[i]=abs(seg.l+l);
			sumx+=dx[dir]*ans[i];
		}
	}
//	cerr<<"sumx="<<sumx<<" sumy="<<sumy<<endl;
	cout<<n<<endl;
	for(int i=1;i<=n;i++)cout<<c[i]<<" "<<ans[i]<<endl;
	exit(0);
}
int main()
{
	scanf("%d%d%d",&n,&X,&Y);
	for(int i=1;i<=n;i++)
	{
		char s[10];
		scanf("%s %d %d",s,&a[i].l,&a[i].r);
		c[i]=s[0];
	}
	solution Sx,Sy;
	for(int i=1;i<=n;)
	{
		int r=i;
		int dir;
		if(i%2==1)dir=1;
		else dir=0;
		++gn;
		while(r<=n&&(i==r||c[r]!='?'))
		{
			if(c[r]!='?')
			{
				if(c[r]=='L')dir=(dir+3)%4;
				else dir=(dir+1)%4;
			}
			else dir^=1;
			g[r]=gn;
			if(dx[dir]!=0)gs[gn].FF=gs[gn].FF+a[r]*dx[dir];
			if(dy[dir]!=0)gs[gn].SS=gs[gn].SS+a[r]*dy[dir];
			r++;
		}
		if(c[i]!='?')
		{
			Sx=Sx+gs[gn].FF;
			Sy=Sy+gs[gn].SS;
		}
		else if(r-i>=2)
		{
			bg.PB(gn);
		}
		else if(r==i+1)
		{
			if(i&1)sy.PB(gs[gn].SS),idy.PB(gn);
			else sx.PB(gs[gn].FF),idx.PB(gn);
		}
		else assert(false);
		i=r;
	}
//	for(int i=1;i<=n;i++)cerr<<g[i]<<" ";cerr<<endl;
//	for(int i=1;i<=gn;i++)cerr<<gs[i].FF.l<<","<<gs[i].FF.r<<" "<<gs[i].SS.l<<","<<gs[i].SS.r<<endl;
	int sz=bg.size();
	for(int msk=0;msk<(1<<sz);msk++)
	{
//		cerr<<"msk="<<msk<<endl;
		solution cx=Sx,cy=Sy;
		for(int i=0;i<sz;i++)
		{
			int &cf=coef[bg[i]];
			cf=(((msk>>i)&1)*2-1);
			cx=cx+gs[bg[i]].FF*cf;
			cy=cy+gs[bg[i]].SS*cf;
		}
//		cerr<<cx.l<<","<<cx.r<<" "<<cy.l<<","<<cy.r<<endl;
		if(dfs_x(cx,0)&&dfs_y(cy,0))
		{
			output();
		}
	}
	puts("-1");
	return 0;
}
accuracy: 1
time_ms: 2180
memory_kb: 3512
final_rank: 3

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 62
#define INF (long long)1e13
int DX[4]={1,0,-1,0},DY[4]={0,-1,0,1},SGN[4]={1,-1,-1,1},n,tx,ty;char opt[N],aop[N];int l[N],r[N],alen[N];int px,py,npx,npy;bool getA(int cur,int xa,int ya,int xb,int yb,int dir,int td,int tx,int ty,int tot){if(cur==tot){if(tx>=xa&&tx<=xb&&ty>=ya&&ty<=yb&&(td==-1||dir==td)){px=tx;py=ty;return true;}return false;}vector<pair<int,char>>way;if(opt[cur]!='R')way.push_back(make_pair((dir+3)%4,'L'));if(opt[cur]!='L')way.push_back(make_pair((dir+1)%4,'R'));for(int i=0;i<(int)way.size();++i){int nd=way[i].first;bool flg=false;if(nd==0){if(getA(cur+1,xa+l[cur],ya,xb+r[cur],yb,nd,td,tx,ty,tot)){flg=true;npx=max(xa,px-r[cur]);npy=py;}}else if(nd==1){if(getA(cur+1,xa,ya-r[cur],xb,yb-l[cur],nd,td,tx,ty,tot)){flg=true;npx=px;npy=min(yb,py+r[cur]);}}else if(nd==2){if(getA(cur+1,xa-r[cur],ya,xb-l[cur],yb,nd,td,tx,ty,tot)){flg=true;npx=min(xb,px+r[cur]);npy=py;}}else{if(getA(cur+1,xa,ya+l[cur],xb,yb+r[cur],nd,td,tx,ty,tot)){flg=true;npx=px;npy=max(ya,py-r[cur]);}}if(flg){aop[cur]=way[i].second;alen[cur]=abs(npx-px)+abs(npy-py);px=npx;py=npy;return true;}}return false;}namespace Met1{int mid,w0,h0,w1,h1;vector<pair<int,int>>cor[4],qry;void dfs0(int cur,int x,int y,int dir,int tot){if(cur==tot){cor[dir].push_back(make_pair(x,y));return;}vector<int>way;if(opt[cur]!='R')way.push_back((dir+3)%4);if(opt[cur]!='L')way.push_back((dir+1)%4);for(int i=0;i<(int)way.size();++i){int nd=way[i];if(nd==0)dfs0(cur+1,x+l[cur],y,nd,tot);else if(nd==1)dfs0(cur+1,x,y-r[cur],nd,tot);else if(nd==2)dfs0(cur+1,x-r[cur],y,nd,tot);else dfs0(cur+1,x,y+l[cur],nd,tot);}}void dfs1(int cur,int x,int y,int dir,int tot){if(cur==tot){qry.push_back(make_pair(tx-x,ty-y));return;}vector<int>way;if(opt[cur]!='R')way.push_back((dir+3)%4);if(opt[cur]!='L')way.push_back((dir+1)%4);for(int i=0;i<(int)way.size();++i){int nd=way[i];if(nd==0)dfs1(cur+1,x+r[cur],y,nd,tot);else if(nd==1)dfs1(cur+1,x,y-l[cur],nd,tot);else if(nd==2)dfs1(cur+1,x-l[cur],y,nd,tot);else dfs1(cur+1,x,y+r[cur],nd,tot);}}bool calcA(int sdir){sort(cor[sdir].begin(),cor[sdir].end());sort(qry.begin(),qry.end());int lo=0,hi=0;multiset<pair<int,int>>st;for(int i=0;i<(int)qry.size();++i){int xx=qry[i].first,yy=qry[i].second;while(hi<(int)cor[sdir].size()&&cor[sdir][hi].first<=xx+w1){st.insert(make_pair(cor[sdir][hi].second,hi));++hi;}while(lo<hi&&cor[sdir][lo].first<xx-w0){st.erase(st.lower_bound(make_pair(cor[sdir][lo].second,lo)));++lo;}auto it=st.lower_bound(make_pair(yy-h0,0));if(it!=st.end()&&it->first<=yy+h1){int meetX=max(xx,cor[sdir][it->second].first);int meetY=max(yy,cor[sdir][it->second].second);getA(0,0,0,0,0,0,sdir,meetX,meetY,mid);getA(mid,meetX,meetY,meetX,meetY,sdir,-1,tx,ty,n);return true;}}return false;}bool solve(){int totq=0;for(int i=0;i<n;++i)if(opt[i]=='?')++totq;int cur=0;for(int i=0;i<n;++i){if(opt[i]=='?')++cur;if(cur*2>=totq){mid=i+1;break;}}w0=h0=w1=h1=0;for(int i=0;i<n;++i){if(i&1){if(i<mid)w0+=r[i]-l[i];else w1+=r[i]-l[i];}else{if(i<mid)h0+=r[i]-l[i];else h1+=r[i]-l[i];}}for(int i=0;i<4;++i)cor[i].clear();dfs0(0,0,0,0,mid);for(int i=0;i<4;++i){if(!cor[i].empty()){qry.clear();dfs1(mid,0,0,i,n);if(calcA(i))return true;}}return false;}}namespace Met2{int sgn[N],vec[N];pair<int,int>far[2];vector<pair<pair<int,int>,pair<int,int>>>rng;void dfs(int cur,int a,int b,int tp,int way,int tot){if(cur==tot){rng.push_back(make_pair(make_pair(a,b),make_pair(tp,way)));return;}int id=vec[cur];dfs(cur+1,a+l[id],b+r[id],tp,way+(1<<cur),tot);dfs(cur+1,a-r[id],b-l[id],tp,way,tot);}bool chkA(int st,int x){int totv=0,a=0,b=0;for(int i=st;i<n;i+=2){if(sgn[i]==0)vec[totv++]=i;else{if(sgn[i]==1){a+=l[i];b+=r[i];}else{a-=r[i];b-=l[i];}}}int mid=totv>>1;rng.clear();dfs(0,a,b,0,0,mid);dfs(mid,x,x,1,0,totv);sort(rng.begin(),rng.end());far[0]=far[1]=make_pair(-INF,0);for(int i=0;i<(int)rng.size();++i){int tp=rng[i].second.first;int L_=rng[i].first.first,R_=rng[i].first.second;if(far[tp^1].first>=L_){int way=rng[i].second.second+far[tp^1].second;for(int j=mid;j<totv;++j)way^=1<<j;for(int j=0;j<totv;++j)sgn[vec[j]]=((way>>j)&1)?1:-1;return true;}far[tp]=max(far[tp],make_pair(R_,rng[i].second.second));}return false;}bool chkA(){if(chkA(0,ty)&&chkA(1,tx)){int d=0,nd;for(int i=0;i<n;++i){if(i&1)nd=(sgn[i]==1)?0:2;else nd=(sgn[i]==1)?3:1;if((d+3)%4==nd)opt[i]='L';else opt[i]='R';d=nd;}getA(0,0,0,0,0,0,-1,tx,ty,n);return true;}return false;}bool dfs(int cur,int d){if(cur==n)return chkA();if(opt[cur]!='?'||(cur+1<n&&opt[cur]=='?'&&opt[cur+1]!='?')){vector<int>way;if(opt[cur]!='R')way.push_back((d+3)%4);if(opt[cur]!='L')way.push_back((d+1)%4);for(int i=0;i<(int)way.size();++i){int nd=way[i];sgn[cur]=SGN[nd];if(dfs(cur+1,nd))return true;}return false;}else return dfs(cur+1,0);}bool solve(){return dfs(0,0);}}signed main(){ios::sync_with_stdio(0);cin.tie(0);cin>>n>>tx>>ty;char buf[5];int totQ=0;for(int i=0;i<n;++i){cin>>buf>>l[i]>>r[i];opt[i]=buf[0];if(opt[i]=='?')++totQ;}int flag;if(totQ<=34)flag=Met1::solve();else flag=Met2::solve();if(flag){cout<<n<<endl;for(int i=0;i<n;++i)cout<<aop[i]<<' '<<alen[i]<<endl;}else cout<<-1<<endl;return 0;}
accuracy: 1
time_ms: 30
memory_kb: 11384
final_rank: 2

code_snippet: // AOJ #2694 Kimagure Cleaner
// 2025.3.23

#include <bits/stdc++.h>
using namespace std;

const int N = 55;
const int INF = INT_MAX;
const int DX[4] = { 1, 0, -1, 0 };
const int DY[4] = { 0, -1, 0, 1 };
const int SGN[4] = { 1, -1, -1, 1 };

int n, tx, ty;
char opt[N], aop[N];
int l[N], r[N], alen[N];
int px, py, npx, npy;

bool getA(int cur, int xa, int ya, int xb, int yb, int dir, int td, int tx, int ty, int tot) {
    if(cur == tot) {
        if(tx >= xa && tx <= xb && ty >= ya && ty <= yb && (td == -1 || dir == td)) {
            px = tx; py = ty;
            return true;
        }
        return false;
    }
    vector<pair<int, char> > way;
    if(opt[cur] != 'R') way.push_back(make_pair((dir + 3) % 4, 'L'));
    if(opt[cur] != 'L') way.push_back(make_pair((dir + 1) % 4, 'R'));
    for (int i = 0; i < (int)way.size(); ++i) {
        int nd = way[i].first;
        bool flg = false;
        if(nd == 0) {
            if(getA(cur + 1, xa + l[cur], ya, xb + r[cur], yb, nd, td, tx, ty, tot)) {
                flg = true;
                npx = max(xa, px - r[cur]);
                npy = py;
            }
        } else if(nd == 1) {
            if(getA(cur + 1, xa, ya - r[cur], xb, yb - l[cur], nd, td, tx, ty, tot)) {
                flg = true;
                npx = px;
                npy = min(yb, py + r[cur]);
            }
        } else if(nd == 2) {
            if(getA(cur + 1, xa - r[cur], ya, xb - l[cur], yb, nd, td, tx, ty, tot)) {
                flg = true;
                npx = min(xb, px + r[cur]);
                npy = py;
            }
        } else {
            if(getA(cur + 1, xa, ya + l[cur], xb, yb + r[cur], nd, td, tx, ty, tot)) {
                flg = true;
                npx = px;
                npy = max(ya, py - r[cur]);
            }
        }
        if(flg) {
            aop[cur] = way[i].second;
            alen[cur] = abs(npx - px) + abs(npy - py);
            px = npx; py = npy;
            return true;
        }
    }
    return false;
}

namespace Met1 {
    int mid, w0, h0, w1, h1;
    vector<pair<int,int> > cor[4], qry;

    void dfs0(int cur, int x, int y, int dir, int tot) {
        if(cur == tot) {
            cor[dir].push_back(make_pair(x, y));
            return;
        }
        vector<int> way;
        if(opt[cur] != 'R') way.push_back((dir + 3) % 4);
        if(opt[cur] != 'L') way.push_back((dir + 1) % 4);
        for (int i = 0; i < (int)way.size(); ++i) {
            int nd = way[i];
            if(nd == 0) dfs0(cur + 1, x + l[cur], y, nd, tot);
            else if(nd == 1) dfs0(cur + 1, x, y - r[cur], nd, tot);
            else if(nd == 2) dfs0(cur + 1, x - r[cur], y, nd, tot);
            else            dfs0(cur + 1, x, y + l[cur], nd, tot);
        }
    }
    void dfs1(int cur, int x, int y, int dir, int tot) {
        if(cur == tot) {
            qry.push_back(make_pair(tx - x, ty - y));
            return;
        }
        vector<int> way;
        if(opt[cur] != 'R') way.push_back((dir + 3) % 4);
        if(opt[cur] != 'L') way.push_back((dir + 1) % 4);
        for (int i = 0; i < (int)way.size(); ++i) {
            int nd = way[i];
            if(nd == 0) dfs1(cur + 1, x + r[cur], y, nd, tot);
            else if(nd == 1) dfs1(cur + 1, x, y - l[cur], nd, tot);
            else if(nd == 2) dfs1(cur + 1, x - l[cur], y, nd, tot);
            else            dfs1(cur + 1, x, y + r[cur], nd, tot);
        }
    }
    bool calcA(int sdir) {
        sort(cor[sdir].begin(), cor[sdir].end());
        sort(qry.begin(), qry.end());
        int lo = 0, hi = 0;
        multiset<pair<int,int> > st;
        for (int i = 0; i < (int)qry.size(); ++i) {
            int xx = qry[i].first, yy = qry[i].second;
            while(hi < (int)cor[sdir].size() && cor[sdir][hi].first <= xx + w1) {
                st.insert(make_pair(cor[sdir][hi].second, hi));
                ++hi;
            }
            while(lo < hi && cor[sdir][lo].first < xx - w0) {
                st.erase(st.lower_bound(make_pair(cor[sdir][lo].second, lo)));
                ++lo;
            }
            auto it = st.lower_bound(make_pair(yy - h0, 0));
            if(it != st.end() && it->first <= yy + h1) {
                int meetX = max(xx, cor[sdir][it->second].first);
                int meetY = max(yy, cor[sdir][it->second].second);
                getA(0, 0, 0, 0, 0, 0, sdir, meetX, meetY, mid);
                getA(mid, meetX, meetY, meetX, meetY, sdir, -1, tx, ty, n);
                return true;
            }
        }
        return false;
    }
    bool solve() {
        int totq = 0;
        for (int i = 0; i < n; ++i) if(opt[i] == '?') ++totq;
        int cur = 0;
        for (int i = 0; i < n; ++i) {
            if(opt[i] == '?') ++cur;
            if(cur * 2 >= totq) { mid = i + 1; break; }
        }
        w0 = h0 = w1 = h1 = 0;
        for (int i = 0; i < n; ++i) {
            if(i & 1) {
                if(i < mid) w0 += r[i] - l[i];
                else        w1 += r[i] - l[i];
            } else {
                if(i < mid) h0 += r[i] - l[i];
                else        h1 += r[i] - l[i];
            }
        }
        for (int i = 0; i < 4; ++i) cor[i].clear();
        dfs0(0, 0, 0, 0, mid);
        for (int i = 0; i < 4; ++i) {
            if(!cor[i].empty()) {
                qry.clear();
                dfs1(mid, 0, 0, i, n);
                if(calcA(i)) return true;
            }
        }
        return false;
    }
}

namespace Met2 {
    int sgn[N], vec[N];
    pair<int,int> far[2];
    vector< pair< pair<int,int>, pair<int,int> > > rng;
    void dfs(int cur, int a, int b, int tp, int way, int tot) {
        if(cur == tot) {
            rng.push_back(make_pair(make_pair(a, b), make_pair(tp, way)));
            return;
        }
        int id = vec[cur];
        dfs(cur + 1, a + l[id], b + r[id], tp, way + (1 << cur), tot);
        dfs(cur + 1, a - r[id], b - l[id], tp, way, tot);
    }
    bool chkA(int st, int x) {
        int totv = 0, a = 0, b = 0;
        for (int i = st; i < n; i += 2) {
            if(sgn[i] == 0) vec[totv++] = i;
            else {
                if(sgn[i] == 1) { a += l[i]; b += r[i]; }
                else { a -= r[i]; b -= l[i]; }
            }
        }
        int mid = totv >> 1;
        rng.clear();
        dfs(0, a, b, 0, 0, mid);
        dfs(mid, x, x, 1, 0, totv);
        sort(rng.begin(), rng.end());
        far[0] = far[1] = make_pair(-INF, 0);
        for (int i = 0; i < (int)rng.size(); ++i) {
            int tp = rng[i].second.first;
            int L_ = rng[i].first.first, R_ = rng[i].first.second;
            if(far[tp ^ 1].first >= L_) {
                int way = rng[i].second.second + far[tp ^ 1].second;
                for (int j = mid; j < totv; ++j) way ^= 1 << j;
                for (int j = 0; j < totv; ++j) sgn[ vec[j] ] = ((way >> j) & 1) ? 1 : -1;
                return true;
            }
            far[tp] = max(far[tp], make_pair(R_, rng[i].second.second));
        }
        return false;
    }
    bool chkA() {
        if(chkA(0, ty) && chkA(1, tx)) {
            int d = 0, nd;
            for (int i = 0; i < n; ++i) {
                if(i & 1) nd = (sgn[i] == 1) ? 0 : 2;
                else nd = (sgn[i] == 1) ? 3 : 1;
                if((d + 3) % 4 == nd) opt[i] = 'L';
                else                  opt[i] = 'R';
                d = nd;
            }
            getA(0, 0, 0, 0, 0, 0, -1, tx, ty, n);
            return true;
        }
        return false;
    }
    bool dfs(int cur, int d) {
        if(cur == n) return chkA();
        if(opt[cur] != '?' || (cur + 1 < n && opt[cur] == '?' && opt[cur + 1] != '?')) {
            vector<int> way;
            if(opt[cur] != 'R') way.push_back((d + 3) % 4);
            if(opt[cur] != 'L') way.push_back((d + 1) % 4);
            for (int i = 0; i < (int)way.size(); ++i) {
                int nd = way[i];
                sgn[cur] = SGN[nd];
                if(dfs(cur + 1, nd)) return true;
            }
            return false;
        } else return dfs(cur + 1, 0);
    }
    bool solve() {
        return dfs(0, 0);
    }
}

int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    cin >> n >> tx >> ty;
    char buf[5];
    int totQ = 0;
    for (int i = 0; i < n; ++i) {
        cin >> buf >> l[i] >> r[i];
        opt[i] = buf[0];
        if(opt[i] == '?') ++totQ;
    }
    int flag;
    if(totQ <= 34) flag = Met1::solve();
    else           flag = Met2::solve();
    if(flag) {
        cout << n << endl;
        for (int i = 0; i < n; ++i) cout << aop[i] << ' ' << alen[i] << endl;
    } else cout << -1 << endl;
    return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 7928
final_rank: 1

code_snippet: #include<bits/stdc++.h>
using namespace std;

#define nn 52
#define ll long long 
#define pii pair<int,int>
#define mp make_pair
pii operator+(pii a,pii b){
	return mp(a.first+b.first,a.second+b.second);
}
pii operator-(pii a,pii b){
	return mp(a.first-b.first,a.second-b.second);
}
char dir[nn][2];int lb[nn],ub[nn];
int goalx,goaly;int n;
int goal;

pii rx[nn],ry[nn];
int face[nn];//-1 or 1
int inter(pii a,pii b){
	if(a.first<=b.second and a.first>=b.first) return a.first;
	if(a.second<=b.second and a.second>=b.first) return a.second;
	if(b.first<=a.second and b.first>=a.first) return b.first;
	if(b.second<=a.second and b.second>=a.first) return b.second;
	assert(0);
}
void output(ll mask){//0=l
	cout<<n<<"\n";
	int d=0;
	for(int i=1;i<=n;i++){
		if(mask&(1ll<<i-1)) d=(d+3)%4;
		else d=(d+1)%4;
		if(d<2) face[i]=1;else face[i]=-1;
	}

	for(int i=n;i>=1;i--){
		rx[i]=rx[i+1],ry[i]=ry[i+1];
		if(i%2){
			if(face[i]==1) ry[i]=ry[i]+mp(lb[i],ub[i]);
			else ry[i]=ry[i]-mp(ub[i],lb[i]);
		}
		else{
			if(face[i]==1) rx[i]=rx[i]+mp(lb[i],ub[i]);
			else rx[i]=rx[i]-mp(ub[i],lb[i]);
		}
	}
//	if(rx[1].first<=goalx and rx[1].second>=goalx);else exit(0);
//	if(ry[1].first<=goaly and ry[1].second>=goaly);else exit(0);
	
	
	int xn=0,yn=0;
	for(int i=1;i<=n;i++){
		rx[i]=mp(goalx,goalx)-rx[i+1]-mp(xn,xn);if(rx[i].first>=rx[i].second) swap(rx[i].first,rx[i].second);
		ry[i]=mp(goaly,goaly)-ry[i+1]-mp(yn,yn);if(ry[i].first>=ry[i].second) swap(ry[i].first,ry[i].second);
		if(mask&(1ll<<i-1)) cout<<"R ",assert(dir[i][0]!='L');else cout<<"L ",assert(dir[i][0]!='R');
		if(face[i]==1){
			if(i%2) yn+=inter(mp(lb[i],ub[i]),ry[i]),cout<<inter(mp(lb[i],ub[i]),ry[i]);
			else xn+=inter(mp(lb[i],ub[i]),rx[i]),cout<<inter(mp(lb[i],ub[i]),rx[i]);
		}
		else{
			if(i%2) yn+=inter(mp(-ub[i],-lb[i]),ry[i]),cout<<abs(inter(mp(-ub[i],-lb[i]),ry[i]));
			else xn+=inter(mp(-ub[i],-lb[i]),rx[i]),cout<<abs(inter(mp(-ub[i],-lb[i]),rx[i]));
		}

		puts("");
	}
	
	assert(xn==goalx and yn==goaly);
	exit(0);
}

void bf(int x,pii askx,pii asky,int d,ll mask){
	if(x>n){
		if(goalx>=askx.first and goalx<=askx.second) 
			if(goaly>=asky.first and goaly<=asky.second)
				output(mask);
		return ;
	}
	if(d==0){
		if(dir[x][0]!='L') bf(x+1,askx,asky-mp(ub[x],lb[x]),3,mask|(1ll<<x-1));
		if(dir[x][0]!='R') bf(x+1,askx,asky+mp(lb[x],ub[x]),1,mask);
	}
	else if(d==1){
		if(dir[x][0]!='R') bf(x+1,askx-mp(ub[x],lb[x]),asky,2,mask);
		if(dir[x][0]!='L') bf(x+1,askx+mp(lb[x],ub[x]),asky,0,mask|(1ll<<x-1));
	}
	else if(d==2){
		if(dir[x][0]!='L') bf(x+1,askx,asky+mp(lb[x],ub[x]),1,mask|(1ll<<x-1));
		if(dir[x][0]!='R') bf(x+1,askx,asky-mp(ub[x],lb[x]),3,mask);
	}
	else if(d==3){
		if(dir[x][0]!='R') bf(x+1,askx+mp(lb[x],ub[x]),asky,0,mask);
		if(dir[x][0]!='L') bf(x+1,askx-mp(ub[x],lb[x]),asky,2,mask|(1ll<<x-1));
	}
}

void solve(int mx,int my){
	int d=0;ll mask=0;
	for(int i=1;i<=n;i++){
		ll ek;
		if(i%2==1){
			if((1<<i/2-1)&my)
				ek=(d==0),d=3;
			else ek=(d==2),d=1;
		}
		else{
			if((1<<i/2-1)&mx)
				ek=(d==3),d=2;
			else ek=(d==1),d=0;
		}
		mask|=(ek<<i-1);
		if(ek==0 and dir[i][0]=='R') return ;
		if(ek==1 and dir[i][0]=='L') return ;
	}
	
	output(mask);
}

vector<int> validx,validy;

void dfs(int x,vector<int> &v,int mask,pii ask){//0=poitive
	if(x>n){
		if(goal>=ask.first and goal<=ask.second) v.push_back(mask);
		return ;
	}
	dfs(x+2,v,mask,ask+mp(lb[x],ub[x]));
	dfs(x+2,v,mask|(1<<x/2-1),ask-mp(ub[x],lb[x]));
}

int main(){
	srand(19);
	int start=clock();
	scanf("%d%d%d",&n,&goalx,&goaly);int cnt=0;
	//if(n>40) exit(0);
	for(int i=1;i<=n;i++){
		scanf("%s%d%d",dir[i],&lb[i],&ub[i]);
		if(dir[i][0]!='?') cnt++;
	}
	if(cnt>=20){
		bf(1,mp(0,0),mp(0,0),0,0);
		return puts("-1"),0;
	}
	
	goal=goaly;dfs(1,validy,0,mp(0,0));
	goal=goalx;dfs(2,validx,0,mp(0,0));
	
	random_shuffle(validx.begin(),validx.end());
	random_shuffle(validy.begin(),validy.end());
	
	if(!validx.size() or !validy.size()) return puts("-1"),0;
	while(clock()-start<=9.5*CLOCKS_PER_SEC){
		int x=rand()%validx.size(),y=rand()%validy.size();
		solve(validx[x],validy[y]);
	}
	puts("-1");
	
	return 0;
}
accuracy: 1
time_ms: 9490
memory_kb: 265252
final_rank: 5

code_snippet: //
// Problem: Kimagagure Cleaner
// Solution by: MORI Shingo
// O(n*2^(n3/8))
//
// implement1 & debug1 214min
// implement2 86min
// debug2 122min
// 
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <math.h>
#include <assert.h>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <set>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);
const int INF = 2e+9 + 3;

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c) for (__typeof((c).begin())it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))


struct Node {
  int v;
  int sum;
  Node() : v(0), sum(0) {;}
  Node(int v) : v(v), sum(0) {;}
};
inline Node Merge(Node left, Node right) {
  return Node(max(left.v + left.sum, right.v + right.sum));
}

struct SegmentTree {
  static const int MAX_DEPTH = 17;
  static const int SIZE = 1 << (MAX_DEPTH + 1);

  bool updated[SIZE];
  Node data[SIZE];
  SegmentTree() {
    memset(updated, false, sizeof(updated));
    MEMSET(data, 0);
  }
  void change(int left, int right, int v) {
    assert(left <= right);
    return in_set(v, 0, 1, left, right);
  }
  int get(int left, int right) {
    assert(left <= right);
    Node node = in_get(0, 1, left, right);
    return node.v + node.sum;
  }

private:
  void Divide(int node) {
    if (!updated[node] || node >= (1 << MAX_DEPTH)) { return; }
    updated[node] = false;
    updated[node * 2] = true;
    updated[node * 2 + 1] = true;
    data[node * 2].sum += data[node].sum;
    data[node * 2 + 1].sum += data[node].sum;
    data[node].v += data[node].sum;
    data[node].sum = 0;
  }

  void in_set(int v, int depth, int node, int left, int right) {
    int width = 1 << (MAX_DEPTH - depth);
    int index = node - (1 << depth);
    int node_left = index * width;
    int node_mid = node_left + (width >> 1);
    Divide(node);
    if (right - left + 1 == width && left == node_left) {
      updated[node] = true;
      data[node].sum += v;
    } else {
      if (right < node_mid) {
        in_set(v, depth + 1, node * 2, left, right);
      } else if (left >= node_mid) {
        in_set(v, depth + 1, node * 2 + 1, left, right);
      } else {
        in_set(v, depth + 1, node * 2, left, node_mid - 1);
        in_set(v, depth + 1, node * 2 + 1, node_mid, right);
      }
      data[node] = Merge(data[node * 2], data[node * 2 + 1]);
    }
  }

  Node in_get(int depth, int node, int left, int right) {
    int width = 1 << (MAX_DEPTH - depth);
    int index = node - (1 << depth);
    int node_left = index * width;
    int node_mid = node_left + (width >> 1);
    Divide(node);
    if (right - left + 1 == width && left == node_left) {
      return data[node];
    } else if (right < node_mid) {
      return in_get(depth + 1, node * 2, left, right);
    } else if (left >= node_mid) {
      return in_get(depth + 1, node * 2 + 1, left, right);
    }
    return Merge(in_get(depth + 1, node * 2, left, node_mid - 1), in_get(depth + 1, node * 2 + 1, node_mid, right));
  }
};

struct Rect {
  ll dirs;
  int initial_dir;
  int dir;
  ll x1, y1, x2, y2;
  Rect() : dirs(0), initial_dir(0) {;}
  Rect(int dir, ll x1, ll y1, ll x2, ll y2) : dirs(0), initial_dir(dir), dir(dir), x1(x1), y1(y1), x2(x2), y2(y2) {;}
  void Move(int d, ll lower, ll upper, int index) {
    assert(dir != -1);
    assert(d == 1 || d == -1);
    if (d == 1) {
      dirs |= 1LL << index;
    }
    dir = (dir + d + 4) % 4;
    if (dir == 0) { Expand(lower, 0, upper, 0); }
    if (dir == 1) { Expand(0, lower, 0, upper); }
    if (dir == 2) { Expand(-upper, 0, -lower, 0); }
    if (dir == 3) { Expand(0, -upper, 0, -lower); }
  }
  void Move2(int pm, ll lower, ll upper, int index) {
    assert(dir != -1);
    assert(pm == 0 || pm == 1);
    if (pm == 1) {
      dirs |= 1LL << index;
    }
    int ds[2] = { -1, 1 };
    REP(i, 2) {
      int ndir = (dir + ds[i] + 4) % 4;
      // cout << pm << " " << dir << " " << ndir << endl;
      if ((pm == 0 && ndir >= 2) ||
          (pm == 1 && ndir <= 1)) { dir = ndir; break; } // set flag direction
    }
    if (dir == 0) { Expand(lower, 0, upper, 0); }
    if (dir == 1) { Expand(0, lower, 0, upper); }
    if (dir == 2) { Expand(-upper, 0, -lower, 0); }
    if (dir == 3) { Expand(0, -upper, 0, -lower); }
  }
  void Expand(ll lx, ll ly, ll ux, ll uy) {
    x1 += lx; y1 += ly; x2 += ux; y2 += uy;
  }
};
bool Hit(Rect r1, Rect r2) {
  return r1.x1 <= r2.x2 && r2.x1 <= r1.x2 && r1.y1 <= r2.y2 && r2.y1 <= r1.y2;
}
ostream &operator<<(ostream &os, const Rect &rhs) {
  os << "(" << rhs.x1 << ", " << rhs.y1 << ", " << rhs.x2 << ", " << rhs.y2 << ")";
  return os;
}

struct Event {
  int index;
  int inout;
  ll x;
  int y1, y2;
  Event(int index, int inout, ll x, int y1, int y2) : index(index), inout(inout), x(x), y1(y1), y2(y2) {;}
  bool operator<(const Event &rhs) const {
    if (x != rhs.x) { return x < rhs.x; }
    return inout < rhs.inout;
  }
};

void Mirror(vector<Rect> &rect, int init_dir, ll X, ll Y) {
  REP(i, rect.size()) {
    Rect &r = rect[i];
    Rect rev = r;
    rev.x1 = X - r.x2;
    rev.y1 = Y - r.y2;
    rev.x2 = X - r.x1;
    rev.y2 = Y - r.y1;
    rev.dir = rev.initial_dir;;
    rect[i] = rev;
  }
}



int n;
ll X, Y;
int dirs[100];
ll lower[100];
ll upper[100];
ll ans_dirs[100];
ll ans_l[100];

vector<Rect> simulate(const vector<Rect> &rects, int dir, ll l, ll u, int index) {
  int cnt = 0;
  vector<Rect> ret;
  vector<int> ds;
  if (dir != 0) {
    ds.push_back(dir);
    ret.resize(rects.size());
  } else {
    ds.push_back(1);
    ds.push_back(-1);
    ret.resize(rects.size() * 2);
  }
  FORIT(it1, ds) {
    int d = *it1;
    FORIT(it2, rects) {
      Rect r = *it2;
      r.Move(d, l, u, index);
      ret[cnt++] = r;
    }
  }
  return ret;
}

SegmentTree stree;
ll IntersectRect(vector<Rect> &rs1, vector<Rect> &rs2, bool swapxy) {
  if (rs1.size() == 0 || rs2.size() == 0) { return -1; }
  vector<Rect> *rss[2] = { &rs1, &rs2 };
  {
    map<ll, int> ys;
    REP(iter, 2) {
      // cout << iter << endl;
      FORIT(it, *rss[iter]) {
        if (swapxy) {
          swap(it->x1, it->y1);
          swap(it->x2, it->y2);
        }
        // cout << *it << endl;
        ys[it->y1] = 0;
        ys[it->y2] = 0;
      }
    }
    int index = 0;
    FORIT(it, ys) {
      it->second = index++;
    }
    // cout << index << endl;
    REP(iter, 2) {
      FORIT(it, *rss[iter]) {
        it->y1 = ys[it->y1];
        it->y2 = ys[it->y2];
      }
    }
  }
  // cout << rs1.size() << " " << rs2.size() << endl;
  REP(iter, 2) {
    stree = SegmentTree();
    vector<Event> events;
    FORIT(it, *rss[0]) {
      events.push_back(Event(-1, 1, it->x1, it->y1, it->y2));
      events.push_back(Event(-1, -1, it->x2 + 1, it->y1, it->y2));
    }
    int cnt = 0;
    FORIT(it, *rss[1]) {
      events.push_back(Event(cnt, 2, it->x1, it->y1, it->y2));
      events.push_back(Event(cnt, 2, it->x2, it->y1, it->y2));
      cnt++;
    }
    sort(events.begin(), events.end());
    // cout << "Start" << endl;
    FORIT(it, events) {
      Event e = *it;
      // cout << e.x << " " << e.y1 << " " << e.y2 << " " << e.inout << endl;
      if (e.index == -1) { 
        stree.change(e.y1, e.y2, e.inout);
      } else {
        // cout << stree.get(e.y1, e.y2) << endl;
        if (stree.get(e.y1, e.y2) > 0) {
          Rect rect2 = (*rss[1])[e.index];
          REP(i, rss[0]->size()) {
            if (Hit((*rss[0])[i], rect2)) {
              // cout << (*rss[0])[i].dirs << endl;
              // cout << rect2.dirs << endl;
              return (*rss[0])[i].dirs | rect2.dirs;
            }
          }
          assert(false);
        }
      }
    }
    swap(rss[0], rss[1]);
  }
  return -1;
}
ll IntersectRect2(vector<Rect> &rs1, vector<Rect> &rs2, bool swapxy) {
  if (rs1.size() == 0 || rs2.size() == 0) { return -1; }
  vector<Rect> *rss[2] = { &rs1, &rs2 };
  {
    REP(iter, 2) {
      // cout << iter << endl;
      FORIT(it, *rss[iter]) {
        if (swapxy) {
          swap(it->x1, it->y1);
          swap(it->x2, it->y2);
        }
      }
    }
  }
  // cout << rs1.size() << " " << rs2.size() << endl;
  REP(iter, 2) {
    vector<Event> events;
    FORIT(it, *rss[0]) {
      events.push_back(Event(-1, 1, it->x1, it->y1, it->y2));
      events.push_back(Event(-1, -1, it->x2 + 1, it->y1, it->y2));
    }
    int cnt = 0;
    FORIT(it, *rss[1]) {
      events.push_back(Event(cnt, 2, it->x1, it->y1, it->y2));
      events.push_back(Event(cnt, 2, it->x2, it->y1, it->y2));
      cnt++;
    }
    sort(events.begin(), events.end());
    int hit = 0;
    // cout << "Start" << endl;
    FORIT(it, events) {
      Event e = *it;
      // cout << e.x << " " << e.y1 << " " << e.y2 << " " << e.inout << endl;
      if (e.index == -1) { 
        hit += e.inout;
        assert(hit >= 0);
      } else {
        // cout << stree.get(e.y1, e.y2) << endl;
        if (hit > 0) {
          Rect rect2 = (*rss[1])[e.index];
          REP(i, rss[0]->size()) {
            if (Hit((*rss[0])[i], rect2)) {
              // cout << (*rss[0])[i].dirs << endl;
              // cout << rect2.dirs << endl;
              return (*rss[0])[i].dirs | rect2.dirs;
            }
          }
          assert(false);
        }
      }
    }
    swap(rss[0], rss[1]);
  }
  return -1;
}

int GetSolvingDir(int depth, int xy, ll flags) {
  if (dirs[depth] != 0) { return -999; }
  if (dirs[depth] == 0 && dirs[depth + 1] == 0) {
    if (xy == depth % 2) { return -1; } // both
    return 0; // tekitou
  }
  return (flags >> depth) & 1;
}
vector<Rect> simulate2(const vector<Rect> &rects, int pm, ll l, ll u, int index) {
  int cnt = 0;
  vector<Rect> ret;
  vector<int> pms;
  if (pm >= 0) {
    pms.push_back(pm);
    ret.resize(rects.size());
  } else {
    pms.push_back(0);
    pms.push_back(1);
    ret.resize(rects.size() * 2);
  }
  FORIT(it1, pms) {
    int v = *it1;
    FORIT(it2, rects) {
      Rect r = *it2;
      r.Move2(v, l, u, index);
      ret[cnt++] = r;
    }
  }
  return ret;
}
ll Solve(ll flags) {
  ll ans_flags[2] = { -1, -1 };
  REP(xy, 2) {
    int center = n;
    // both side search
    vector<Rect> rect1;
    rect1.push_back(Rect(0, 0, 0, 0, 0));
    REP(i, n) {
      int pm = GetSolvingDir(i, xy, flags);
      ll l = lower[i];
      ll u = upper[i];
      if (xy != i % 2) { l = 0; u = 0; }
      if (dirs[i] != 0) {
        rect1 = simulate(rect1, dirs[i], l, u, i);
      } else {
        // cout << "PM: " << pm << endl;
        rect1 = simulate2(rect1, pm, l, u, i);
      }
      if (rect1.size() > (1LL << 7)) {
        center = i + 1;
        break;
      }
    }
    vector<Rect> rect2;
    int left_upper = center % 2;
    rect2.push_back(Rect(left_upper, 0, 0, 0, 0));
    rect2.push_back(Rect(left_upper + 2, 0, 0, 0, 0));
    FOR(i, center, n) {
      int pm = GetSolvingDir(i, xy, flags);
      ll l = lower[i];
      ll u = upper[i];
      if (xy != i % 2) { l = 0; u = 0; }
      if (dirs[i] != 0) {
        rect2 = simulate(rect2, dirs[i], l, u, i);
      } else {
        rect2 = simulate2(rect2, pm, l, u, i);
      }
    }
    ll lx = xy == 0 ? 0 : X;
    ll ly = xy == 0 ? Y : 0;
    Mirror(rect2, left_upper, lx, ly);
    // cout << rect1.size() << " " << rect2.size() << endl;

    vector<Rect> rs1[4];
    vector<Rect> rs2[4];
    if (center != n && dirs[center] == 0 && dirs[center + 1] != 0) {
      // ignore connecting direction
      FORIT(it, rect1) {
        rs1[0].push_back(*it);
      }
      FORIT(it, rect2) {
        rs2[0].push_back(*it);
      }
    } else {
      FORIT(it, rect1) {
        rs1[it->dir].push_back(*it);
      }
      FORIT(it, rect2) {
        rs2[it->dir].push_back(*it);
      }
    }
    // cout << "test A" << endl;
    // FORIT(it, rect1) {
    //   cout << *it << " " << it->dir << endl;
    // }
    // cout << "test B" << endl;
    // FORIT(it, rect2) {
    //   cout << *it << " " << it->dir << endl;
    // }
    ll ans_dir_flags = -1;
    // cout << rect1.size() << " "<< rect2.size() << endl;
    // cout << xy << endl;
    REP(dir, 4) {
      // ans_dir_flags = IntersectRect(rs1[dir], rs2[dir], xy ^ 1);
      ans_dir_flags = IntersectRect2(rs1[dir], rs2[dir], xy ^ 1);
      if (ans_dir_flags != -1) { break; }
    }
    if (ans_dir_flags == -1) { return -1; }
    ans_flags[xy] = ans_dir_flags;
  }
  int dir = 0;
  REP(depth, n) {
    if (dirs[depth] != 0) {
      ans_dirs[depth] = dirs[depth];
    } else {
      int xy = depth % 2;
      ll v = (ans_flags[xy] >> depth) & 1;
      int ds[2] = { -1, 1 };
      REP(i, 2) {
        int ndir = (dir + ds[i] + 4) % 4;
        if ((v == 0 && ndir >= 2) ||
            (v == 1 && ndir <= 1)) {
          // set flag direction
          ans_dirs[depth] = ds[i];
        }
      }
    }
    dir = (dir + ans_dirs[depth] + 4) % 4;
  }
  // REP(i, n) {
  //   cout << (ans_dirs[i] == 1 ? "L" : "R");
  // }
  // cout << endl;
  return 1;
}

ll Dfs(int depth, ll flags) {
  if (depth == n) {
    return Solve(flags);
  }
  if (dirs[depth] == 0 && dirs[depth + 1] != 0) {
    assert(dirs[depth] == 0);
    REP(iter, 2) {
      ll nflags = flags | ((ll)iter << depth);
      if (Dfs(depth + 1, nflags) != -1) { return 1; }
    }
    return -1;
  }
  return Dfs(depth + 1, flags);
}

void RestoreDistance() {
  Rect r(0, 0, 0, 0, 0);
  {
    vector<Rect> rects(1, r);
    REP(i, n) {
      rects = simulate(rects, ans_dirs[i], lower[i], upper[i], i);
    }
    Rect rect = rects[0];
    // cout << rect << endl;
    // cout << X << " " << Y << endl;
    assert(Hit(Rect(0, X, Y, X, Y), rect));
  }
  REP(i, n) {
    int ndir = (r.dir + ans_dirs[i] + 4) % 4;
    ll l = lower[i];
    ll u = upper[i];
    while (l != u) {
      ll m = (l + u) / 2;
      assert(l < u);
      vector<Rect> rects(1, r);
      rects = simulate(rects, ans_dirs[i], m, m, i);
      FOR(j, i + 1, n) {
        rects = simulate(rects, ans_dirs[j], lower[j], upper[j], j);
      }
      Rect rect = rects[0];
      // cout << ndir << " " << rect << " "<< Y << endl;
      if ((ndir == 0 && rect.x2 < X) ||
          (ndir == 1 && rect.y2 < Y) ||
          (ndir == 2 && X < rect.x1) ||
          (ndir == 3 && Y < rect.y1)) {
        l = m + 1;
      } else {
        // cout << i << "  "<< "test" << endl;
        u = m;
      }
    }
    ans_l[i] = l;
    r.Move(ans_dirs[i], l, l, i);
  }
}

bool Check() {
  vector<Rect> rect(1, Rect(0, 0, 0, 0, 0));
  REP(i, n) {
    if (ans_l[i] < lower[i] || upper[i] < ans_l[i]) { return false; }
    if (dirs[i] != 0 && dirs[i] != ans_dirs[i]) { return false; }
    rect = simulate(rect, ans_dirs[i], ans_l[i], ans_l[i], i);
  }
  // cout << rect[0] << endl;
  // cout << X << " " << Y << endl;
  if (rect[0].x1 != X || rect[0].y1 != Y) { return false; }
  return true;
}

int main() {
  while (scanf("%d %lld %lld", &n, &X, &Y) > 0) {
    int center = n;
    int div = 0;
    REP(i, n) {
      char c;
      int v = scanf(" %c %lld %lld", &c, &lower[i], &upper[i]);
      assert(v == 3);
      if (c == 'L') { dirs[i] = 1; }
      if (c == '?') { dirs[i] = 0; }
      if (c == 'R') { dirs[i] = -1; }
      if (dirs[i] == 0) {
        div++;
        if (div == 21) { center = i; }
      }
    }
    dirs[n] = 0;
    int segment = 0;
    REP(i, n) { if (dirs[i] == 0 && dirs[i + 1] != 0) { segment++; } }
    ll ans_dir = -1;
    // cout << segment << " " << n << " " << n / 4 << endl;
    if (segment > n / 4 + 1) {
      // both side search
      // cout << "Normal" << endl;
      vector<Rect> rect1;
      rect1.push_back(Rect(0, 0, 0, 0, 0));
      REP(i, center) {
        rect1 = simulate(rect1, dirs[i], lower[i], upper[i], i);
      }
      vector<Rect> rect2;
      int left_upper = center % 2;
      rect2.push_back(Rect(left_upper, 0, 0, 0, 0));
      rect2.push_back(Rect(left_upper + 2, 0, 0, 0, 0));
      FOR(i, center, n) {
        rect2 = simulate(rect2, dirs[i], lower[i], upper[i], i);
      }
      // cout << rect1.size() << " " << rect2.size() << endl;
      Mirror(rect2, left_upper, X, Y);

      vector<Rect> rs1[4];
      FORIT(it, rect1) {
        rs1[it->dir].push_back(*it);
      }
      vector<Rect> rs2[4];
      FORIT(it, rect2) {
        rs2[it->dir].push_back(*it);
      }
      // cout << "test" << endl;
      // FORIT(it, rect1) {
      //   cout << *it << " " << it->dir << endl;
      // }
      // cout << "test" << endl;
      // FORIT(it, rect2) {
      //   cout << *it << " " << it->dir << endl;
      // }
      REP(dir, 4) {
        ans_dir = IntersectRect(rs1[dir], rs2[dir], false);
        if (ans_dir != -1) { break; }
      }
      REP(i, n) {
        ans_dirs[i] = ((ans_dir >> i) & 1) ? 1 : -1;
        // cout << (ans_dirs[i] == 1 ? "L" : "R");
      }
      // cout << endl;
    } else {
      // divide
      // cout << "Divide" << endl;
      ans_dir = Dfs(0, 0);
    }
    if (ans_dir == -1) {
      puts("-1");
      goto next;
    }

    // restore
    RestoreDistance();

    // print ans
    printf("%d\n", n);
    REP(i, n) {
      printf("%c %lld\n", ans_dirs[i] == 1 ? 'L' : 'R', ans_l[i]);
    }
    assert(Check());
next:;
  }
}
accuracy: 1
time_ms: 1020
memory_kb: 193768
final_rank: 4