Problem:
Problem E:
Mirror Cave
双子の冒険者 Rin と Len は鏡の洞窟でお宝を探している．この洞窟には鏡の間という対になった 2 つの部屋があり，その部屋の扉の向こうには高価な宝が眠っているという．
便宜上，2 つの部屋はそれぞれ
W
×
H
のセルが格子状に並んだものとみなす．部屋の外側は壁で囲まれている．また，部屋の内側にもところどころ壁が設置されており，壁の配置されているセルには進入することができない．宝の部屋への扉を開くためには，2 人が左右対称の動きをして，同時に特定のセルに到達しなければならない．しかも，片方だけが先に到達した場合は，扉はロックされて開かなくなってしまう．
左右対称の動きとは，北と北，西と東，東と西，南と南にそれぞれ同時に動くことを意味する．ただし，片方が動こうとしている先に壁があり，もう一方の先に壁が無いといった状況下でも左右対称の動きであると認められる．この場合は壁がある方はその場にとどまり，壁が無い方は隣のセルに動くことになる．
入力として，双子の初期位置，目的地，障害物の配置が与えられる．あなたの仕事は，この双子が扉を開けることが可能であるか判定するプログラムを書くことである．
Input
入力は複数のデータセットからなる．各データセットは次の形式で与えられる．
W
H
RoomL
1
RoomR
1
RoomL
2
RoomR
2
...
RoomL
H
RoomR
H
最初の行では 2 つの正の整数
W
,
H
(1 ≤
W
,
H
≤ 50) が 1 つの空白で区切られて与えられる．その後，
H
行に渡って 2 つの部屋の情報が与えられる．
RoomL
i
，
RoomR
i
はそれぞれ左側，右側の部屋の
i
番目の行に対応する．両者とも長さ
W
の文字列で，
j
番目の文字が部屋の
j
番目の列に対応する．それぞれの文字は以下のいずれかである．
.
: 自由に移動できるセル
#
: 壁のあるセル（進入できない）
%
: 目的地
R
: Rin の初期位置
L
: Len の初期位置
各部屋とも 1 行目が部屋の北端，1 列目が部屋の西端に対応する．また，各部屋は必ずちょうど 1 つの目的地があり，左側の部屋には Len，右側の部屋には Rin の初期位置がちょうど 1 つ存在する．
入力の終わりは，空白で区切られた 2 つの 0 を含む行で示される．
Output
各データセットについて，双子が扉を開くことができるなら Yes，できなければ No をそれぞれ 1 行に出力せよ．
Sample Input
5 5
%#... ...#%
.#.#. .#.#.
.#.#. .#.#.
.#.#. .#.#.
...#L R#...
3 2
.L. .R#
%.. .%.
4 1
L.%. %..R
0 0
Output for the Sample Input
Yes
Yes
No

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
struct P {
	int x, y;
	P(int x, int y) : x(x), y(y) {}
};

int dx[] = { 1, 0, -1, 0 };
int dy[] = { 0, 1, 0, -1 };

int mp[50][50][50][50];

int main()
{
	int W, H, lsx, lsy, rsx, rsy, lgx, lgy, rgx, rgy;
	while (cin >> W >> H, W | H) {
		vector<string> Rl(H), Rr(H);
		for (int i = 0; i < H; i++) {
			cin >> Rl[i] >> Rr[i];
			for (int j = 0; j < W; j++) {
				if (Rl[i][j] == 'L') {
					lsx = i;
					lsy = j;
				}
				else if (Rl[i][j] == '%') {
					lgx = i;
					lgy = j;
				}
			}
			for (int j = 0; j < W; j++) {
				if (Rr[i][j] == 'R') {
					rsx = i;
					rsy = j;
				}
				else if (Rr[i][j] == '%') {
					rgx = i;
					rgy = j;
				}
			}
		}
		queue<pair<P, P>> q;
		q.push(pair<P, P>(P(lsx, lsy), P(rsx, rsy)));
		mp[lsx][lsy][rsx][rsy] = 1;
		while (!q.empty()) {
			auto p = q.front(); q.pop();
			int lx = p.first.x, ly = p.first.y, rx = p.second.x, ry = p.second.y;
			for (int i = 0; i < 4; i++) {
				int ltx = lx + dx[i], lty = ly - dy[i], rtx = rx + dx[i], rty = ry + dy[i];
				if (ltx >= 0 && ltx < H && lty >= 0 && lty < W && Rl[ltx][lty] != '#' && rtx >= 0 && rtx < H && rty >= 0 && rty < W && Rr[rtx][rty] != '#') {
					if ((Rl[ltx][lty] == '%') == (Rr[rtx][rty] == '%') && mp[ltx][lty][rtx][rty] == 0) {
						mp[ltx][lty][rtx][rty] = 1;
						q.push(pair<P, P>(P(ltx, lty), P(rtx, rty)));
					}
				}
				else if (ltx >= 0 && ltx < H && lty >= 0 && lty < W && Rl[ltx][lty] != '#') {
					if (Rl[ltx][lty] != '%' && mp[ltx][lty][rx][ry] == 0) {
						mp[ltx][lty][rx][ry] = 1;
						q.push(pair<P, P>(P(ltx, lty), P(rx, ry)));
					}
				}
				else if (rtx >= 0 && rtx < H && rty >= 0 && rty < W && Rr[rtx][rty] != '#') {
					if (Rr[rtx][rty] != '%' && mp[lx][ly][rtx][rty] == 0) {
						mp[lx][ly][rtx][rty] = 1;
						q.push(pair<P, P>(P(lx, ly), P(rtx, rty)));
					}
				}
			}
		}
		cout << (mp[lgx][lgy][rgx][rgy] ? "Yes" : "No") << endl;
		for (int i = 0; i < 50; i++) {
			for (int j = 0; j < 50; j++) {
				for (int k = 0; k < 50; k++) {
					for (int l = 0; l < 50; l++) {
						mp[i][j][k][l] = 0;
					}
				}
			}
		}
	}
	return 0;
}
accuracy: 1
time_ms: 440
memory_kb: 28444
final_rank: 13

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using a2 = array<ll, 2>;
using a3 = array<ll, 3>;

ll INF = 1e18;

template <typename A>
void chmin(A &l, const A &r) {
    if(r < l) l = r;
}
template <typename A>
void chmax(A &l, const A &r) {
    if(l < r) l = r;
}

void init() {}

ll w, h;
vector<string> l, r;
void input() {
    cin >> w >> h;
    l.resize(h);
    r.resize(h);
    for(int i = 0; i < h; i++) cin >> l[i] >> r[i];
}

void solve() {
    vector<vector<vector<vector<ll>>>> dist =
        vector(h, vector(w, vector(h, vector<ll>(w, 1e18))));
    a2 lb, rb, le, re;

    for(int i = 0; i < h; i++) {
        for(int j = 0; j < w; j++) {
            if(l[i][j] == 'L') {
                lb = {i, j};
            }
            if(r[i][j] == 'R') {
                rb = {i, j};
            }
            if(l[i][j] == '%') {
                le = {i, j};
            }
            if(r[i][j] == '%') {
                re = {i, j};
            }
        }
    }

    vector<pair<a2, a2>> wasd = {{{0, 1}, {0, -1}},
                                 {{0, -1}, {0, 1}},
                                 {{1, 0}, {1, 0}},
                                 {{-1, 0}, {-1, 0}}};

    queue<pair<a2, a2>> que;
    que.push({lb, rb});
    dist[lb[0]][lb[1]][rb[0]][rb[1]] = 0;
    while(que.size()) {
        auto f = que.front();
        que.pop();

        ll d = dist[f.first[0]][f.first[1]][f.second[0]][f.second[1]];

        for(auto &x : wasd) {
            ll lp, lq, rp, rq;
            lp = f.first[0] + x.first[0];
            lq = f.first[1] + x.first[1];
            rp = f.second[0] + x.second[0];
            rq = f.second[1] + x.second[1];

            if(lp < 0 || lp >= h || lq < 0 || lq >= w) {
                lp = f.first[0];
                lq = f.first[1];
            } else if(l[lp][lq] == '#') {
                lp = f.first[0];
                lq = f.first[1];
            }

            if(rp < 0 || rp >= h || rq < 0 || rq >= w) {
                rp = f.second[0];
                rq = f.second[1];
            } else if(r[rp][rq] == '#') {
                rp = f.second[0];
                rq = f.second[1];
            }

            if((a2{lp, lq} == le) != (a2{rp, rq} == re)) continue;

            if(dist[lp][lq][rp][rq] > d + 1) {
                dist[lp][lq][rp][rq] = d + 1;
                que.push({{lp, lq}, {rp, rq}});
            }
        }
    }
    ll ans = dist[le[0]][le[1]][re[0]][re[1]];
    cout << (ans == 1e18 ? "No" : "Yes") << endl;
}

ifstream in;
ofstream out;
int main(int argc, char **argv) {
    ios::sync_with_stdio(false);
    cin.tie(0);

    if(argc > 2) {
        in.open(argv[1]);
        cin.rdbuf(in.rdbuf());
        out.open(argv[2]);
        cout.rdbuf(out.rdbuf());
    }

    init();
    while(1) {
        input();
        if(w == 0) break;
        solve();
    }

    return 0;
}
accuracy: 1
time_ms: 560
memory_kb: 58404
final_rank: 19

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

// #ifndef ONLINE_JUDGE
// #define _GLIBCXX_DEBUG // 配列外参照のエラー
// #endif

// スタンダードライブラリ
#include <bits/stdc++.h>
using namespace std;

// 型関連
using ll = long long;
using lint = long long;
using pll = pair<ll, ll>;
using plll = tuple<ll, ll, ll>;
using pii = pair<int, int>;
using piii = tuple<ll, ll, ll>;
template <class T> using prique = priority_queue<T>;

// 型定数
constexpr ll mod = 998244353;
constexpr ll MOD = 1000000007;
int INF32 = 2e9;
ll INF64 = 9e18;
#define endl '\n';

int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

/////////////////////////// print関連
template <typename T> void print(vector<T> A);
void print();
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail);
void print(string S);
template <typename T> void print(vector<vector<T>> &F);

inline void Yes(bool f);

///////////////////ここから//////////////////////
bool solve() {
    int H, W;
    cin >> W >> H;
    if (H == 0) {
        return false;
    }
    vector<string> FL(H), FR(H);
    for (int i = 0; i < 2 * H; i++) {
        if (i % 2 == 0) {
            cin >> FL[i / 2];
        } else {
            cin >> FR[i / 2];
        }
    }
    int sxl, syl, sxr, syr;
    for (int i = 0; i < H; i++) {
        for (int j = 0; j < W; j++) {
            if (FL[i][j] == 'L') {
                sxl = i;
                syl = j;
            }
            if (FR[i][j] == 'R') {
                sxr = i;
                syr = j;
            }
        }
    }
    queue<tuple<int, int, int, int>> que;
    vector<vector<vector<vector<int>>>> dist(
        H, vector<vector<vector<int>>>(
               W, vector<vector<int>>(H, vector<int>(W, INF32))));

    dist[sxl][syl][sxr][syr] = 0;
    que.emplace(sxl, syl, sxr, syr);
    string ans = "No";
    while (!que.empty()) {
        auto [xl, yl, xr, yr] = que.front();
        que.pop();
        if (FL[xl][yl] == '%' && FR[xr][yr] == '%') {
            ans = "Yes";
        }
        for (int d = 0; d < 4; d++) {
            int nxl = xl + dx[d], nyl = yl + dy[d], nxr = xr + dx[d],
                nyr = yr - dy[d];
            if (nxl < 0 || nxl >= H || nyl < 0 || nyl >= W || FL[nxl][nyl]=='#') {
                nxl = xl;
                nyl = yl;
            }
            if (nxr < 0 || nxr >= H || nyr < 0 || nyr >= W || FR[nxr][nyr]=='#') {
                nxr = xr;
                nyr = yr;
            }
            bool f1 = FL[nxl][nyl] == '%';
            bool f2 = FR[nxr][nyr] == '%';
            if (f1 ^ f2) {
                continue;
            }
            if (dist[nxl][nyl][nxr][nyr] <= dist[xl][yl][xr][yr] + 1) {
                continue;
            }

            dist[nxl][nyl][nxr][nyr] = dist[xl][yl][xr][yr] + 1;
            que.emplace(nxl,nyl,nxr,nyr);

        }
    }
    print(ans);

    return true;
}

int main() {
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    while (solve())
        ;
}

////////////////////print/////////////////////////
// 1次元ベクトルを出力する
template <typename T> void print(vector<T> A) {
    if (A.size() == 0) {
        return;
    }
    for (size_t i = 0; i < A.size() - 1; i++) {
        cout << A[i] << ' ';
    }
    cout << A[A.size() - 1] << endl;
    return;
}

// 2次元ベクトルを出力する
template <typename T> void print(vector<vector<T>> &F) {
    for (size_t i = 0; i < F.size(); i++) {
        for (size_t j = 0; j < F[i].size(); j++) {
            cout << F[i][j];
            if (j < F[i].size() - 1) {
                cout << ' ';
            }
        }
        cout << endl;
    }
}

// 空白行を出力するprint
void print() { cout << endl; }

// 数値・文字列を空白区切りで出力する. print(a,b)など
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    cout << head;
    if (sizeof...(tail) != 0)
        cout << " ";
    print(forward<Tail>(tail)...);
}

void print(string S) { cout << S << endl; }

//////////////出力関連

inline void Yes(bool f) {
    if (f) {
        cout << "Yes" << endl;
    } else {
        cout << "No" << endl;
    }
}
accuracy: 1
time_ms: 460
memory_kb: 32424
final_rank: 15

code_snippet: #line 1 "2009E.cpp"
#include <bits/stdc++.h>
#line 1 "/home/ardririy/repos/cp-libs/libraries-cpp/input.hpp"


#line 6 "/home/ardririy/repos/cp-libs/libraries-cpp/input.hpp"
using namespace std;
vector<long long> i64_vec_IN(int n) {vector<long long> res(n); for(int i=0; i<n; i++) { cin >> res[i]; } return res; }
vector<string> str_vec_IN(int n) { vector<string> res(n); for(int i=0; i<n; i++) { cin >> res[i]; } return res; }
vector<vector<int>> graph_IN(int n, int m) { vector<vector<int>> g(n); int u, v; for(int i=0; i<m; i++) { cin >> u >> v; u--; v--; g[u].emplace_back(v); g[v].emplace_back(u); } return g; }
vector<vector<pair<int, long long>>> weighted_graph_IN(int n, int m) { vector<vector<pair<int, long long>>> g(n); int u, v; long long w; for(int i=0; i<m; i++) { cin >> u >> v >> w; u--; v--; g[u].push_back({v, w}); g[v].push_back({u, w}); } return g; }


#line 3 "2009E.cpp"

using namespace std;

// using namespace atcoder;

#ifdef ADRY
#include <dbg.h>
#else
// DO NOTHING
#define dbg(...)
#endif


#define all(v) v.begin(),v.end()
#define resort(v) sort(v.rbegin(),v.rend())
using ll = long long;
using ull = unsigned long long;
using vll=vector<ll>;
using vvll = vector<vector<ll>>;
using P = pair<int,int>;
using vp=vector<pair<ll, ll>>;
using djks=priority_queue<P, vp, greater<P>>;

const int inf=1ll<<30;
#define mod10 (ll)1e9+7
#define mod99 (ll)998244353
const double PI = acos(-1);

#define rep(i,n) for (ll i=0;i<(n);++i)
#define per(i,n) for(ll i=(n)-1;i>=0;--i)
#define rep2(i,a,n) for (ll i=(a);i<(n);++i)
#define per2(i,a,n) for (ll i=(n)-1;i>=(a);--i)


template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }

ll di[] = {1, 0, -1, 0, -1, 1, -1, 1};
ll dj[] = {0, 1, 0, -1, -1, 1, 1, -1};

pair<P, P> move_to(P l, vector<string>& bl, P r, vector<string>& br, int rr) {
    if(rr==0 || rr==2) {
        // 上下
        ll nl = l.first + di[rr];
        if(nl >= 0 && nl < bl.size() && bl[nl][l.second] != '#') l.first = nl;
        
        ll nr = r.first + di[rr];
        if(nr >= 0 && nr < br.size() && br[nr][r.second] != '#') r.first = nr;
    } else {
        ll nl = l.second + dj[rr];
        if(nl >= 0 && nl < bl[0].size() && bl[l.first][nl] != '#') l.second = nl;

        ll nr = r.second + dj[(rr+2)%4];
        if(nr >= 0 && nr < br[0].size() && br[r.first][nr] != '#') r.second = nr;

    }
    return {l, r};
}

vector seen(50, vector(50, vector(50, vector(50, false))));

int solve(){
    int w, h; cin >> w >> h;
    if(w==0) return 1;
    vector<string> l(h), r(h);
    rep(i,h) cin >> l[i] >> r[i];

    pair<int,int> slp, srp;

    rep(i,h) rep(j,w) {
        if(l[i][j] == 'L') {
            l[i][j] = '.';
            slp = {i, j};
        }
        if(r[i][j] == 'R') {
            r[i][j] = '.';
            srp = {i, j};
        }
        rep(ii, h) rep(jj, w) seen[i][j][ii][jj] = false;
    }
    
    seen[slp.first][slp.second][srp.first][srp.second] = true;
    queue<pair<pair<int, int>, pair<int,int>>> que;
    que.push({slp, srp});
    while(!que.empty()) {
        auto [len, rin] = que.front();
        que.pop();

        rep(rr, 4) {
            auto [nlen, nrin] = move_to(len,l,rin,r,rr);
            if(seen[nlen.first][nlen.second][nrin.first][nrin.second]) continue;
            seen[nlen.first][nlen.second][nrin.first][nrin.second] = true;
            ll cnt = 0;
            if(l[nlen.first][nlen.second] == '%')cnt++;
            if(r[nrin.first][nrin.second] == '%')cnt++;
            if(cnt==2) {
                cout << "Yes\n";
                return 0;
            } else if (cnt == 0) {
                que.push({nlen, nrin});
            }
        }
    }
    cout << "No\n";
    return 0;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    while(!solve());
}
accuracy: 1
time_ms: 320
memory_kb: 13312
final_rank: 4

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

int D[50][50][50][50];

bool solve() {
    int H, W;
    cin >> W >> H;
    if (H == 0 && W == 0) return false;
    vector<string> S(H), T(H);
    auto next_S = [&] (int r, int c, int d) -> pair<int, int> {
        int nr = r + vector<int>{0, 1, 0, -1, 0}[d];
        int nc = c + vector<int>{0, 1, 0, -1, 0}[d + 1];
        if (0 <= nr && nr < H && 0 <= nc && nc < W && S[nr][nc] != '#') {
            return {nr, nc};
        }
        return {r, c};
    };
    auto next_T = [&] (int r, int c, int d) -> pair<int, int> {
        int nr = r + vector<int>{0, 1, 0, -1, 0}[d];
        int nc = c + vector<int>{0, -1, 0, 1, 0}[d + 1];
        if (0 <= nr && nr < H && 0 <= nc && nc < W && T[nr][nc] != '#') {
            return {nr, nc};
        }
        return {r, c};
    };
    int sr, sc, tr, tc;
    for (int i = 0; i < H; i++) {
        cin >> S[i] >> T[i];
        for (int j = 0; j < W; j++) {
            if (S[i][j] == 'L') sr = i, sc = j;
            if (T[i][j] == 'R') tr = i, tc = j;
        }
    }
    for (int si = 0; si < H; si++) {
        for (int sj = 0; sj < W; sj++) {
            for (int ti = 0; ti < H; ti++) {
                for (int tj = 0; tj < W; tj++) {
                    D[si][sj][ti][tj] = 1 << 30;
                }
            }
        }
    }
    queue<tuple<int, int, int, int>> q;
    D[sr][sc][tr][tc] = 0;
    q.emplace(sr, sc, tr, tc);
    while (q.size()) {
        tie(sr, sc, tr, tc) = q.front();
        q.pop();
        for (int d = 0; d < 4; d++) {
            auto [nsr, nsc] = next_S(sr, sc, d);
            auto [ntr, ntc] = next_T(tr, tc, d);
            if ((S[nsr][nsc] == '%') ^ (T[ntr][ntc] == '%')) {
            } else {
                if (D[nsr][nsc][ntr][ntc] > D[sr][sc][tr][tc] + 1) {
                    D[nsr][nsc][ntr][ntc] = D[sr][sc][tr][tc] + 1;
                    q.emplace(nsr, nsc, ntr, ntc);
                }
            }
        }
    }
    string ans = "No";
    for (int si = 0; si < H; si++) {
        for (int sj = 0; sj < W; sj++) {
            for (int ti = 0; ti < H; ti++) {
                for (int tj = 0; tj < W; tj++) {
                    if (S[si][sj] == '%' && T[ti][tj] == '%') {
                        if (D[si][sj][ti][tj] < (1 << 30)) ans = "Yes";
                    }
                }
            }
        }
    }
    cout << ans << "\n";
    return true;
}

int main() {
    while (solve()) {}
}
accuracy: 1
time_ms: 1860
memory_kb: 28656
final_rank: 20

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

const int MN=50;
int seen[MN][MN][MN][MN];

int main(){
    while(1){

        int W,H;cin>>W>>H;
        if(W==0)return 0;
        vector<string>L(H),R(H);
        for(int i=0;i<H;i++){
            cin>>L[i]>>R[i];
        }
        for(int li=0;li<H;li++)        
        for(int lj=0;lj<W;lj++)        
        for(int ri=0;ri<H;ri++)        
        for(int rj=0;rj<W;rj++)
            seen[li][lj][ri][rj]=false;        
        using tiiii=tuple<int,int,int,int>;
        queue<tiiii>q;
        int sli,slj,sri,srj;
        int tli,tlj,tri,trj;
        for(int i=0;i<H;i++){
            for(int j=0;j<W;j++){
                if(L[i][j]=='L')sli=i,slj=j;
                if(L[i][j]=='%')tli=i,tlj=j;
                if(R[i][j]=='R')sri=i,srj=j;
                if(R[i][j]=='%')tri=i,trj=j;
            }
        }
        q.emplace(sli,slj,sri,srj);
        seen[sli][slj][sri][srj]=true;
        while(!q.empty()){
            auto[li,lj,ri,rj]=q.front();
            q.pop();
            const int di[]={0,0,-1,1};
            const int dj[]={-1,1,0,0};
            for(int d=0;d<4;d++){
                int nli=li+di[d];
                int nlj=lj+dj[d];
                int nri=ri+di[d];
                int nrj=rj-dj[d];
                nli=max(0,min(H-1,nli));
                nri=max(0,min(H-1,nri));
                nlj=max(0,min(W-1,nlj));
                nrj=max(0,min(W-1,nrj));
                if(L[nli][nlj]=='#')nli=li,nlj=lj;
                if(R[nri][nrj]=='#')nri=ri,nrj=rj;
                int cnt_goal=0;
                if(L[nli][nlj]=='%')cnt_goal++;
                if(R[nri][nrj]=='%')cnt_goal++;
                if(cnt_goal==1)continue;
                if(seen[nli][nlj][nri][nrj]==false){
                    seen[nli][nlj][nri][nrj]=true;
                    q.emplace(nli,nlj,nri,nrj);
                }
            }            
        }
        cout<<(seen[tli][tlj][tri][trj]?"Yes":"No")<<endl;
    }
}
accuracy: 1
time_ms: 350
memory_kb: 28648
final_rank: 11

code_snippet: //#pragma GCC target("avx2")
//#pragma GCC optimize("O3")
//#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
using pli = pair<ll,int>;
#define AMARI 998244353
//#define AMARI 1000000007
#define el '\n'
#define El '\n'
#define YESNO(x) ((x) ? "Yes" : "No")
#define YES YESNO(true)
#define NO YESNO(false)
#define REV_PRIORITY_QUEUE(tp) priority_queue<tp,vector<tp>,greater<tp>>
#define EXIT_ANS(x) {cout << (x) << '\n'; return;}
template <typename T> void inline SORT(vector<T> &v){sort(v.begin(),v.end()); return;}
template <typename T> void inline VEC_UNIQ(vector<T> &v){sort(v.begin(),v.end()); v.erase(unique(v.begin(),v.end()),v.end()); return;}
template <typename T> T inline MAX(vector<T> &v){return *max_element(v.begin(),v.end());}
template <typename T> T inline MIN(vector<T> &v){return *min_element(v.begin(),v.end());}
template <typename T> T inline SUM(vector<T> &v){T ans = 0; for(int i = 0; i < (int)v.size(); i++)ans += v[i]; return ans;}
template <typename T> void inline DEC(vector<T> &v){for(int i = 0; i < (int)v.size(); i++)v[i]--; return;}
template <typename T> void inline INC(vector<T> &v){for(int i = 0; i < (int)v.size(); i++)v[i]++; return;}
void inline TEST(void){cerr << "TEST" << endl; return;}
template <typename T> bool inline chmin(T &x,T y){
    if(x > y){
        x = y;
        return true;
    }
    return false;
}
template <typename T> bool inline chmax(T &x,T y){
    if(x < y){
        x = y;
        return true;
    }
    return false;
}
template <typename T = long long> vector<T> inline get_vec(int n){
    vector<T> ans(n);
    for(int i = 0; i < n; i++)cin >> ans[i];
    return ans;
}
template <typename T> void inline print_vec(vector<T> &vec,bool kaigyou = false){
    int n = (int)vec.size();
    for(int i = 0; i < n; i++){
        cout << vec[i];
        if(kaigyou || i == n - 1)cout << '\n';
        else cout << ' ';
    }
    if(!n)cout << '\n';
    return;
}
template <typename T> void inline debug_vec(vector<T> &vec,bool kaigyou = false){
    int n = (int)vec.size();
    for(int i = 0; i < n; i++){
        cerr << vec[i];
        if(kaigyou || i == n - 1)cerr << '\n';
        else cerr << ' ';
    }
    if(!n)cerr << '\n';
    return;
}
vector<vector<int>> inline get_graph(int n,int m = -1,bool direct = false){
    if(m == -1)m = n - 1;
    vector<vector<int>> g(n);
    while(m--){
        int u,v;
        cin >> u >> v;
        u--; v--;
        g[u].push_back(v);
        if(!direct)g[v].push_back(u);
    }
    return g;
}

vector<int> make_inv(vector<int> p){
    int n = (int)p.size();
    vector<int> ans(n);
    for(int i = 0; i < n; i++)ans[p[i]] = i;
    return ans;
}


#define MULTI_TEST_CASE false
void solve(void){
    //問題を見たらまず「この問題設定から言えること」をいっぱい言う
    //よりシンプルな問題に言い換えられたら、言い換えた先の問題を自然言語ではっきりと書く
    //複数の解法のアイデアを思いついた時は全部メモしておく
    //g++ -D_GLIBCXX_DEBUG -Wall -O2 XXX.cpp -o o
    while(1){
        int h,w;
        cin >> w >> h;
        if(h == 0 && w == 0)return;

        vector<string> s(h),t(h);
        for(int i = 0; i < h; i++)cin >> s[i] >> t[i];

        //debug_vec(t,true);

        vector<int> dx = {1,0,-1,0};
        vector<int> dy = {0,1,0,-1};

        //{x1,y1,x2,y2}
        queue<array<int,4>> que;
        array<int,4> start,goal;
        for(int i = 0; i < h; i++){
            for(int j = 0; j < w; j++){
                if(s[i][j] == 'L' || s[i][j] == 'R'){
                    start[0] = i; start[1] = j;
                }
                if(t[i][j] == 'L' || t[i][j] == 'R'){
                    start[2] = i; start[3] = j;
                }

                if(s[i][j] == '%'){
                    goal[0] = i; goal[1] = j;
                }
                if(t[i][j] == '%'){
                    goal[2] = i; goal[3] = j;
                }
            }
        }
        que.push(start);
        bitset<6250000> bs; bs.reset();
        bs[start[0] + start[1] * 50 + start[2] * 2500 + start[3] * 125000] = true;

        while(!que.empty()){
            array<int,4> fr = que.front(); que.pop();
            //cerr << fr[0] << ' ' << fr[1] << ' ' << fr[2] << ' ' << fr[3] << el;
            assert(s[fr[0]][fr[1]] != '#');
            assert(t[fr[2]][fr[3]] != '#');
            for(int i = 0; i < 4; i++){
                array<int,4> to;
                to[0] = fr[0] + dx[i];
                to[1] = fr[1] + dy[i];
                to[2] = fr[2] + dx[i];
                to[3] = fr[3] - dy[i];

                for(int j = 0; j < 4; j++){
                    if(to[j] < 0)to[j] = fr[j];
                    if(j % 2 == 0 && to[j] >= h)to[j] = fr[j];
                    if(j % 2 == 1 && to[j] >= w)to[j] = fr[j];
                }
                if(s[to[0]][to[1]] == '#'){
                    to[0] = fr[0]; to[1] = fr[1];
                }
                if(t[to[2]][to[3]] == '#'){
                    to[2] = fr[2]; to[3] = fr[3];
                }
                if((s[to[0]][to[1]] == '%') != (t[to[2]][to[3]] == '%'))continue;
                int idx = to[0] + to[1] * 50 + to[2] * 2500 + to[3] * 125000;
                if(bs[idx])continue;
                bs[idx] = true;
                que.push(to);
            }
        }
        int jdx = goal[0] + goal[1] * 50 + goal[2] * 2500 + goal[3] * 125000;
        cout << YESNO(bs[jdx]) << el;
    }

}

void calc(void){
    return;
}


signed main(void){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    calc();
    int t = 1;
    if(MULTI_TEST_CASE)cin >> t;
    while(t--){
        solve();
    }
    return 0;
}
accuracy: 1
time_ms: 530
memory_kb: 4844
final_rank: 3

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

bool solve(){
    int W, H; cin >> W >> H;
    if(W == 0) return false;
    vector<string> L(H), R(H);
    for(int i = 0; i < H; ++i){
        cin >> L[i] >> R[i];
    }
    vector check(H, vector(W, vector(H, vector(W, 0))));
    using T = tuple<int, int, int, int>;
    queue<T> que;
    T s = [&](){
        int y1, x1, y2, x2;
        for(int i = 0; i < H; ++i){
            for(int j = 0; j < W; ++j){
                if(L[i][j] == 'L'){
                    y1 = i, x1 = j;
                    L[i][j] = '.';
                }
            }
        }
        for(int i = 0; i < H; ++i){
            for(int j = 0; j < W; ++j){
                if(R[i][j] == 'R'){
                    y2 = i, x2 = j;
                    R[i][j] = '.';
                }
            }
        }
        // cerr << "# " << y1 << ", " << x1 << ", " << y2 << ", " << x2 << endl;
        return T{y1, x1, y2, x2};
    }();
    que.push(s);
    int ly[4] = {0, 1, 0, -1}, lx[4] = {1, 0, -1, 0};
    int ry[4] = {0, 1, 0, -1}, rx[4] = {-1, 0, 1, 0};
    while(que.size()){
        auto [y1, x1, y2, x2] = que.front(); que.pop();
        if(check[y1][x1][y2][x2]) continue;
        check[y1][x1][y2][x2] = 1;
        // cerr << "# " << y1 << ", " << x1 << ", " << y2 << ", " << x2 << endl;
        for(int d = 0; d < 4; ++d){
            int ny1 = y1 + ly[d], nx1 = x1 + lx[d];
            int ny2 = y2 + ry[d], nx2 = x2 + rx[d];
            if(ny1 < 0 || ny1 >= H || nx1 < 0 || nx1 >= W) ny1 = y1, nx1 = x1;
            if(ny2 < 0 || ny2 >= H || nx2 < 0 || nx2 >= W) ny2 = y2, nx2 = x2;
            if(L[ny1][nx1] == '#') ny1 = y1, nx1 = x1;
            if(R[ny2][nx2] == '#') ny2 = y2, nx2 = x2;
            if(L[ny1][nx1] == '%' && R[ny2][nx2] == '%'){
                cout << "Yes" << endl;
                return true;
            }
            if(L[ny1][nx1] == '.' && R[ny2][nx2] == '.'){
                que.emplace(ny1, nx1, ny2, nx2);
            }
        }
    }
    cout << "No" << endl;
    return true;
}

int main(){
    while(1){
        if(!solve()) break;
    }
}
accuracy: 1
time_ms: 490
memory_kb: 33084
final_rank: 16

code_snippet: #include <iostream>
#include <queue>
#include <vector>

using namespace std;

struct State {
    int xL, yL, xR, yR;
};

int W, H;
vector<string> roomL, roomR;
int startX_L, startY_L, startX_R, startY_R;
int goalX_L, goalY_L, goalX_R, goalY_R;
const int dx[4] = {-1, 1, 0, 0}; // 上 下 左 右
const int dy[4] = {0, 0, -1, 1}; // 上 下 左 右

bool is_valid(int x, int y, const vector<string>& room) {
    return x >= 0 && x < H && y >= 0 && y < W && room[x][y] != '#';
}

bool bfs() {
    queue<State> q;
    vector<vector<vector<vector<bool>>>> visited(H, vector<vector<vector<bool>>>(W, vector<vector<bool>>(H, vector<bool>(W, false))));
    q.push({startX_L, startY_L, startX_R, startY_R});
    visited[startX_L][startY_L][startX_R][startY_R] = true;

    while (!q.empty()) {
        State curr = q.front();
        q.pop();
        
        // 若同时到达目标位置，返回成功
        if (curr.xL == goalX_L && curr.yL == goalY_L && curr.xR == goalX_R && curr.yR == goalY_R) {
            return true;
        }

        for (int d = 0; d < 4; ++d) {
            int nxL = curr.xL + dx[d], nyL = curr.yL + dy[d];
            int nxR = curr.xR + dx[d], nyR = curr.yR - dy[d]; // 右侧房间的 x 方向相同，但 y 方向相反

            bool canMoveL = is_valid(nxL, nyL, roomL);
            bool canMoveR = is_valid(nxR, nyR, roomR);

            // 若左侧无法移动，保持原位
            if (!canMoveL) {
                nxL = curr.xL;
                nyL = curr.yL;
            }
            // 若右侧无法移动，保持原位
            if (!canMoveR) {
                nxR = curr.xR;
                nyR = curr.yR;
            }

            // 不能只有一人到达目标，否则门不会打开
            if ((roomL[nxL][nyL] == '%' && roomR[nxR][nyR] != '%') || 
                (roomL[nxL][nyL] != '%' && roomR[nxR][nyR] == '%')) {
                continue;
            }

            if (!visited[nxL][nyL][nxR][nyR]) {
                visited[nxL][nyL][nxR][nyR] = true;
                q.push({nxL, nyL, nxR, nyR});
            }
        }
    }
    return false;
}

int main() {
    while (cin >> W >> H, W && H) {
        roomL.resize(H);
        roomR.resize(H);
        for (int i = 0; i < H; ++i) {
            cin >> roomL[i] >> roomR[i];
            for (int j = 0; j < W; ++j) {
                if (roomL[i][j] == 'L') startX_L = i, startY_L = j;
                if (roomR[i][j] == 'R') startX_R = i, startY_R = j;
                if (roomL[i][j] == '%') goalX_L = i, goalY_L = j;
                if (roomR[i][j] == '%') goalX_R = i, goalY_R = j;
            }
        }
        cout << (bfs() ? "Yes" : "No") << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 420
memory_kb: 12420
final_rank: 5

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
typedef long long int ll;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000001
using namespace std;

int H,W;
int**** min_Count;
int diff_row[4]= {-1,0,0,1},diff_col[4] = {0,-1,1,0};

struct Info{
	Info(int arg_L_row,int arg_L_col,int arg_R_row,int arg_R_col,int arg_count){
		L_row = arg_L_row;
		L_col = arg_L_col;
		R_row = arg_R_row;
		R_col = arg_R_col;
		count = arg_count;
	}
	int L_row,L_col,R_row,R_col,count;
};

bool rangeCheck(int row,int col){
	if(row >= 0 && row <= H-1 && col >= 0 && col <= W-1)return true;
	else{
		return false;
	}
}


void func(){

	for(int a = 0; a < H; a++){
		for(int b = 0; b < W; b++){
			for(int c = 0; c < H; c++){
				for(int d = 0; d < W; d++)min_Count[a][b][c][d] = BIG_NUM;
			}
		}
	}

	char L_map[H][W+1],R_map[H][W+1];

	int L_start_row,L_start_col,R_start_row,R_start_col;

	for(int i = 0; i < H; i++){
		scanf("%s %s",L_map[i],R_map[i]);
		for(int k = 0; k < W; k++){
			if(L_map[i][k] == 'L'){
				L_start_row = i;
				L_start_col = k;
				L_map[i][k] = '.';
			}
			if(R_map[i][k] == 'R'){
				R_start_row = i;
				R_start_col = k;
				R_map[i][k] = '.';
			}
		}
	}

	queue<Info> Q;
	Q.push(Info(L_start_row,L_start_col,R_start_row,R_start_col,0));
	min_Count[L_start_row][L_start_col][R_start_row][R_start_col] = 0;

	bool FLG = false;

	int next_L_row,next_L_col,next_R_row,next_R_col;

	while(!Q.empty()){

		if(L_map[Q.front().L_row][Q.front().L_col] == '%' && R_map[Q.front().R_row][Q.front().R_col] == '%'){
			FLG = true;
			break;
		}else if(Q.front().count > min_Count[Q.front().L_row][Q.front().L_col][Q.front().R_row][Q.front().R_col]){
			Q.pop();
		}else{

			for(int i = 0; i < 4; i++){
				next_L_row = Q.front().L_row + diff_row[i];
				next_L_col = Q.front().L_col + diff_col[i];
				next_R_row = Q.front().R_row + diff_row[i];
				next_R_col = Q.front().R_col - diff_col[i];

				if(rangeCheck(next_L_row,next_L_col) == false || L_map[next_L_row][next_L_col] == '#'){
					next_L_row = Q.front().L_row;
					next_L_col = Q.front().L_col;
				}
				if(rangeCheck(next_R_row,next_R_col) == false || R_map[next_R_row][next_R_col] == '#'){
					next_R_row = Q.front().R_row;
					next_R_col = Q.front().R_col;
				}

				if(min_Count[next_L_row][next_L_col][next_R_row][next_R_col] > Q.front().count+1){
					if((L_map[next_L_row][next_L_col] == '%' && R_map[next_R_row][next_R_col] != '%') ||
							(L_map[next_L_row][next_L_col] != '%' && R_map[next_R_row][next_R_col] == '%')){
						//Do nothing
					}else{
						min_Count[next_L_row][next_L_col][next_R_row][next_R_col] = Q.front().count+1;
						Q.push(Info(next_L_row,next_L_col,next_R_row,next_R_col,Q.front().count+1));
					}
				}
			}
			Q.pop();
		}
	}

	if(FLG){
		printf("Yes\n");
	}else{
		printf("No\n");
	}
}

int main(){

	min_Count = new int***[50];;
	for(int i = 0; i < 50; i++){
		min_Count[i] = new int**[50];
		for(int k = 0; k < 50; k++){
			min_Count[i][k] = new int*[50];
			for(int a = 0; a < 50; a++){
				min_Count[i][k][a] = new int[50];
			}
		}
	}

	while(true){
		scanf("%d %d",&W,&H);
		if(W == 0 && H == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 320
memory_kb: 30124
final_rank: 12

code_snippet: #include <bits/stdc++.h>

using namespace std;

/*
*/
//make -f ../makefile SRC=
//------------------------------------------------------------------------------
bool DEBUG = false;
const int INF = 1000000000;

const char SRC1 = 'L';
const char SRC2 = 'R';
const char DEST = '%';
const char WALL = '#';
const char FREE = '.';

const int MAX_N = 50;
static char LG[MAX_N][MAX_N+5];
static char RG[MAX_N][MAX_N+5];

const int A = 4; // 4 valid actions
typedef pair<int,int> PA;
typedef pair<PA,PA> PPA;
static vector<PPA> action =
{
    {{-1,0}, {-1,0}}, // NN
    {{0,-1}, {0,1}}, // WE
    {{0,1}, {0,-1}}, // EW
    {{1,0}, {1,0}}, // SS
};
typedef PA State;
typedef vector<PA> States;
//------------------------------------------------------------------------------
States neighbors(int M, int N, const State& s1, int d1, int d2)
{
    States SS;
    int v1 = s1.first;
    int m1 = v1/N;
    int n1 = v1%N;

    int v2 = s1.second;
    int m2 = v2/N;
    int n2 = v2%N;

    int m3, n3, v3, m4, n4, v4;
    //--------------------------------------------------------------------------
    for (int a=0; a<A; a++)
    {
        PPA p = action[a];
        m3 = m1 + p.first.first;
        n3 = n1 + p.first.second;

        m4 = m2 + p.second.first;
        n4 = n2 + p.second.second;

        bool ok3 = true;
        if (m3 < 0 || m3 >= M || n3 < 0 || n3 >= N || LG[m3][n3] == WALL) ok3 = false;

        bool ok4 = true;
        if (m4 < 0 || m4 >= M || n4 < 0 || n4 >= N || RG[m4][n4] == WALL) ok4 = false;
        
        if (ok3 && ok4)
        {
            v3 = m3*N + n3;
            v4 = m4*N + n4;
            if ((v3 != d1 && v4 != d2) || (v3 == d1 && v4 == d2)) SS.push_back( {v3, v4} );
        }
        else if (ok3 && !ok4)
        {
            v3 = m3*N + n3;
            if (v3 != d1) SS.push_back( {v3, v2} );
        }
        else if (!ok3 && ok4)
        {
            v4 = m4*N + n4;
            if (v4 != d2) SS.push_back( {v1, v4} );
        }
    }
    return SS;
}


//------------------------------------------------------------------------------
void debug_grids(int M, int N)
{
    for (int m=0; m<M; ++m) { for (int n=0; n<N; ++n) printf("%c",LG[m][n]); printf("\n"); }
    printf("\n");
    for (int m=0; m<M; ++m) { for (int n=0; n<N; ++n) printf("%c",RG[m][n]); printf("\n"); }
    printf("\n");
}

bool bfs(int M, int N, const State& src, const State& dest)
{
    queue<State> Q;
    Q.push(src);
    bool visited[M*N*M*N];
    for (int v=0; v<M*N*M*N; v++) visited[v] = false;
    int d1 = dest.first;
    int d2 = dest.second;
    //--------------------------------------------------------------------------
    // search:
    while (!Q.empty())
    {
        State s1 = Q.front(); Q.pop();
        if (s1 == dest) return true;
        if (visited[M*N*s1.first+s1.second]) continue;
        visited[M*N*s1.first+s1.second] = true;

        for (State s2: neighbors(M, N, s1, d1, d2))
        {
            if (visited[M*N*s2.first+s2.second]) continue;
            Q.push(s2);
        }
    }
    return false;
}
bool solve(int M, int N)
{
    if (DEBUG) debug_grids(M, N);

    int s1 = -1;
    int d1 = -1;
    for (int m=0; m<M; ++m)
        for (int n=0; n<N; ++n)
            {
                if (LG[m][n] == SRC1) s1 = m*N + n;
                else if (LG[m][n] == DEST) d1 = m*N + n;
            }
    if (s1 == -1 || d1 == -1) return false;

    int s2 = -1;
    int d2 = -1;
    for (int m=0; m<M; ++m)
        for (int n=0; n<N; ++n)
            {
                if (RG[m][n] == SRC2) s2 = m*N + n;
                else if (RG[m][n] == DEST) d2 = m*N + n;
            }
    if (s2 == -1 || d2 == -1) return false;

    State src = {s1, s2};
    State dest = {d1, d2};
    return bfs(M, N, src, dest);
}

//------------------------------------------------------------------------------
int main()
{
    //test(); return 0;
    //DEBUG = true;
    //--------------------------------------------------------------------------
    int T, N, M, num;
    //num = scanf("%d ", &T);
    while (true)
    {
        num = scanf("%d %d ", &N, &M);
        if (N == 0 && M == 0) break;

        for (int m=0; m<M; ++m) num = scanf("%s %s ", LG[m], RG[m]);
        bool ok = solve(M, N);
        if (ok) printf("Yes\n");
        else printf("No\n");
    }
    //--------------------------------------------------------------------------
    return 0;
}
//------------------------------------------------------------------------------
accuracy: 1
time_ms: 650
memory_kb: 9904
final_rank: 8

code_snippet: // #pragma GCC optimize("O3")
// #pragma GCC target("avx2")
// #pragma GCC optimize("unroll-loops")
#include "bits/stdc++.h"
#include <ext/pb_ds/assoc_container.hpp>

using namespace __gnu_pbds;
using namespace std;

#define int long long
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;

const ll INF = 1e18 - 1, MOD = 1e9 + 7, MOD2 = 1e9 + 9;
const int INFi = 1e9 + 100, K = 26, N = 1e5 + 1, MAXN = 1e6 + 1;
const ld EPS = 1e-12, PI = acos(-1);

random_device rd;
mt19937_64 rnd(rd());

void solve() {
    int w, h;
    while (cin >> w >> h) {
        if (w == 0 && h == 0) {
            break;
        }
        vector<vector<char>> a(h + 2, vector<char>(w + 2, '#')), b = a;
        pair<int, int> f, s, f1, s1;
        for (int i = 1; i <= h; i++) {
            string str;
            cin >> str;
            for (int j = 1; j <= w; j++) {
                a[i][j] = str[j - 1];
                if (a[i][j] == '%') {
                    f1 = make_pair(i, j);
                }
                if (a[i][j] == 'L') {
                    f = make_pair(i, j);
                }
            }
            cin >> str;
            for (int j = 1; j <= w; j++) {
                b[i][j] = str[j - 1];
                if (b[i][j] == '%') {
                    s1 = make_pair(i, j);
                }
                if (b[i][j] == 'R') {
                    s = make_pair(i, j);
                }
            }
        }
        bool used[h + 2][w + 2][h + 2][w + 2];
        for (int i = 0; i < h + 2; i++) {
            for (int j = 0; j < w + 2; j++) {
                for (int k = 0; k < h + 2; k++) {
                    for (int l = 0; l < w + 2; l++) {
                        used[i][j][k][l] = false;
                        if (a[i][j] == b[k][l] && a[i][j] == '#') {
                            used[i][j][k][l] = true;
                        }
                    }
                }
            }
        }
        queue<vector<int>> q;
        {
            auto [i, j] = f;
            auto [k, l] = s;
            used[i][j][k][l] = true;
            q.push({i, j, k, l});
//        cout << i << ' ' << j << ' ' << k << ' ' << l << "\n\n";
        }

        vector<int> dx = {1, -1, 0, 0}, dy = {0, 0, 1, -1};

        while (!q.empty()) {
            auto v = q.front();
            q.pop();
            int i = v[0], j = v[1], k = v[2], l = v[3];
            for (int pos = 0; pos < 4; pos++) {
                int i1 = i + dx[pos], j1 = j + dy[pos], k1 = k + dx[pos], l1 = l - dy[pos];
                if (a[i1][j1] == '#') {
                    i1 = i, j1 = j;
                }
                if (b[k1][l1] == '#') {
                    k1 = k, l1 = l;
                }
                if (!used[i1][j1][k1][l1] && ((a[i1][j1] == '%' && b[k1][l1] == '%') || (a[i1][j1] != '%' && b[k1][l1] != '%'))) {
                    used[i1][j1][k1][l1] = true;
                    q.push({i1, j1, k1, l1});
//                    cout << i1 << ' ' << j1 << ' ' << k1 << ' ' << l1 << '\n';
                }
            }
        }

        auto [i, j] = f1;
        auto [k, l] = s1;
        if (used[i][j][k][l]) {
            cout << "Yes\n";
        } else {
            cout << "No\n";
        }
    }
}

signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
    int T = 1;
//    cin >> T;
    while (T--) {
        solve();
    }
    return 0;
}
accuracy: 1
time_ms: 610
memory_kb: 14088
final_rank: 9

code_snippet: #ifdef LOCAL_JUDGE
#define _GLIBCXX_DEBUG
#endif
#include <stdio.h>
#include <iostream> // cout, endl, cin
#include <string> // string, to_string, stoi
#include <vector> // vector
#include <algorithm> // min, max, swap, sort, reverse, lower_bound, upper_bound
#include <utility> // pair, make_pair
#include <tuple> // tuple, make_tuple
#include <cstdint> // int64_t, int*_t
#include <iomanip> //setprecision
#include <map> // map
#include <unordered_map> //unordered_map
#include <queue> // queue, priority_queue
#include <set> // set,multiset
#include <stack> // stack
#include <deque> // deque
#include <math.h>//pow,,,
#include <cmath>//abs,,,
#include <bitset> // bitset
#include <numeric> //accumulate,,,
#include <sstream>
#include <initializer_list>
#include <random>
#include <unordered_set>
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <functional>
#include <climits>
#include <utility>
#include <cassert>
#include <fstream>
// #include <atcoder/all>
using namespace std;
// using namespace atcoder;
const long long INF = 4000000000000000001; // 4*10^18
const int inf = 2001001001;
const long long MOD = 998244353;
const double pi = 3.141592653589;
const vector<int> dh = {1,0,-1,0} , dw = {0,1,0,-1};
const vector<int> dh8 = {-1,-1,-1,0,0,1,1,1} , dw8 = {-1,0,1,-1,1,-1,0,1};
#define endl "\n";
long long modpow(long long a, long long n, long long mod) {
    a %= mod;
    long long ret = 1;
    while (n > 0) {
        if (n & 1) ret = ret * a % mod;
        a = a * a % mod;
        n >>= 1;
    }
    return ret % mod;
}
long long modinv(long long a, long long m) {
    long long b = m, u = 1, v = 0;
    while (b) {
        long long t = a / b;
        a -= t * b; swap(a, b);
        u -= t * v; swap(u, v);
    }
    u %= m; 
    if (u < 0) u += m;
    return u;
}
long long gcd(long long a, long long b) {
    if (b == 0) return a; else return gcd(b, a % b);
}
long long lcm(long long a, long long b) {
    return a / gcd(a, b) * b ;
}
long long get_mod(long long res){
    if(res < 0) res += MOD;
    return res % MOD;
}
double DegToRad(double deg){
    return deg*(pi/180.0);
}
double RadToDeg(double rad){
    return rad/(pi/180.0);
}
int uniform_rand(int mini , int maxi){
    random_device seed;
    mt19937_64 engine(seed());
    uniform_real_distribution<> ran(mini , maxi+1);
    int ret = ran(engine);
    if(ret >= maxi+1) ret = maxi;
    return ret;
}

const vector<int> rdh = {1,0,-1,0} , rdw = {0,-1,0,1};

int main(){
    /*ofstream ofs;
    ifstream ifs;

    ifs.open("in.txt");
    ofs.open("out.txt");

    ifs.close();
    ofs.close();*/

    vector<string> OUTPUT;
    while(true){
        int H,W;cin >> W >> H;
        if(H == 0 && W == 0){
            break;
        }
        
        int lsh,lsw,rsh,rsw;
        int lgh,lgw,rgh,rgw;
        vector<vector<char>> lban(H,vector<char>(W)) , rban(H,vector<char>(W));
        for(int i = 0;i<H;i++){
            for(int j = 0;j<2*W;j++){
                if(j < W){
                    cin >> lban.at(i).at(j);
                    if(lban.at(i).at(j) == 'L'){
                        lsh = i , lsw = j;
                    }
                    if(lban.at(i).at(j) == '%'){
                        lgh = i , lgw = j;
                    }
                }
                else{
                    cin >> rban.at(i).at(j-W);
                    if(rban.at(i).at(j-W) == 'R'){
                        rsh = i , rsw = j-W;
                    }
                    if(rban.at(i).at(j-W) == '%'){
                        rgh = i , rgw = j-W;
                    }
                }
            }
        }

        bool seen[51][51][51][51];
        for(int i = 0;i<51;i++) for(int j = 0;j<51;j++) for(int k = 0;k<51;k++) for(int l = 0;l<51;l++) seen[i][j][k][l] = false;
        seen[lsh][lsw][rsh][rsw] = true;

        queue<tuple<int,int,int,int>> Q;
        Q.push({lsh,lsw,rsh,rsw});
        while(!Q.empty()){
            int lh,lw,rh,rw; tie(lh,lw,rh,rw) = Q.front(); Q.pop();
            for(int i = 0;i<4;i++){
                int nlh = lh+dh.at(i) , nlw = lw+dw.at(i);
                int nrh = rh+rdh.at(i) , nrw = rw+rdw.at(i);
                if(nlh < 0 || nlh >= H || nlw < 0 || nlw >= W || lban.at(nlh).at(nlw) == '#'){
                    nlh = lh , nlw = lw;
                }
                if(nrh < 0 || nrh >= H || nrw < 0 || nrw >= W || rban.at(nrh).at(nrw) == '#'){
                    nrh = rh , nrw = rw;
                }
                if(seen[nlh][nlw][nrh][nrw]){
                    continue;
                }
                bool lgoal = lban.at(nlh).at(nlw) == '%' , rgoal = rban.at(nrh).at(nrw) == '%';
                if(!seen[lgh][lgw][rgh][rgw] && ((!lgoal && rgoal) || (lgoal && !rgoal))){
                    continue;
                }

                seen[nlh][nlw][nrh][nrw] = true;
                //cout << seen[lgh][lgw][rgh][rgw] << " (" << nlh+1 << " " << nlw+1 << ") , (" << nrh+1 << " " << nrw+1 << ")" << endl;
                Q.push({nlh,nlw,nrh,nrw});
            }
        }

        if(seen[lgh][lgw][rgh][rgw]){
            OUTPUT.push_back("Yes");
        }
        else{
            OUTPUT.push_back("No");
        }
        
        

    }

    for(string a : OUTPUT){
        cout << a << endl;
    }
    



}
accuracy: 1
time_ms: 490
memory_kb: 10472
final_rank: 6

code_snippet: #include <bits/stdc++.h>
    using namespace std;
    #include <ext/pb_ds/assoc_container.hpp>
    using namespace __gnu_pbds;
    
    template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
    template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
    #define rep(i,n) for (int i = 0; i < (n); ++i)

    typedef long long ll;
    typedef unsigned long long ull;
    typedef long double ld;
    using P=pair<int,int>;
    using T=tuple<int,int,int>;
    const ll INF=1001001001; 
    const ll INFL=1e18;
    const ll mod=998244353;

    void solve(int w,int h){
        vector<string>x(h),y(h);
        rep(i,h){
            rep(j,w){
                char c;
                cin>>c;
                x[i]+=c;
            }
            rep(j,w){
                char c;
                cin>>c;
                y[i]+=c;
            }
        }

        auto toid=[&](int i,int j){
            return i*w+j;
        };

        int N=h*w;
        vector<vector<int>>dist(N,vector<int>(N,INF));
        queue<P>q;
        int GX=0,GY=0;
        {
            int X=0,Y=0;
            rep(i,h){
                rep(j,w){
                    if(x[i][j]=='L'){
                        X=toid(i,j);
                    }
                    if(x[i][j]=='%'){
                        GX=toid(i,j);
                    }
                    if(y[i][j]=='R'){
                        Y=toid(i,j);
                    }
                    if(y[i][j]=='%'){
                        GY=toid(i,j);
                    }
                }
            }
            dist[X][Y]=0;
            q.push({X,Y});
        }

        auto NX=[&](int X,int DX,int DY,vector<string>& s){
            int i=X/w,j=X%w;
            int ni=i+DY,nj=j+DX;
            if(ni<0||ni>=h||nj<0||nj>=w||s[ni][nj]=='#'){
                return X;
            }
            return toid(ni,nj);
        };

        vector<int>dx={0,1,0,-1},dy={-1,0,1,0};
        while(q.size()){
            auto[X,Y]=q.front();q.pop();
            rep(i,4){
                int XX=NX(X,dx[i],dy[i],x),YY=NX(Y,-dx[i],dy[i],y);
                if(XX==GX&&YY!=GY){continue;}
                if(XX!=GX&&YY==GY){continue;}
                if(chmin(dist[XX][YY],dist[X][Y]+1)){
                    q.push({XX,YY});
                }
            }
        }
        int ans=dist[GX][GY];
        if(ans==INF)cout<<"No"<<endl;
        else cout<<"Yes"<<endl;
    }

    int main(){
        ios_base::sync_with_stdio(false);
        cin.tie(NULL);
        
        while(1){
            int w,h;
            cin>>w>>h;
            if(w==0&&h==0)break;
            solve(w,h);
        }
        return 0;
    }
accuracy: 1
time_ms: 360
memory_kb: 28160
final_rank: 10

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

#include <unistd.h>

namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf


uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio


using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */

int main() {
    int dx[4] = {1,0,-1,0}, dy[4] = {0,1,0,-1};
while(1) {
    int N, M;
    cin >> N >> M;
    if (N == 0 && M == 0) return 0;
    swap(N,M);
    int SX1, SY1, SX2, SY2, GX1, GY1, GX2, GY2;
    vector<vector<bool>> X(N,vector<bool>(M)), Y(N,vector<bool>(M));
    rep(i,0,N) {
        string S, T;
        cin >> S >> T;
        reverse(T.begin(), T.end());
        rep(j,0,M) {
            X[i][j] = (S[j] == '#');
            Y[i][j] = (T[j] == '#');
            if (S[j] == 'L') SX1 = i, SY1 = j;
            if (T[j] == 'R') SX2 = i, SY2 = j;
            if (S[j] == '%') GX1 = i, GY1 = j;
            if (T[j] == '%') GX2 = i, GY2 = j;
        }
    }
    bool memo[50][50][50][50] = {};
    rep(i,0,N) rep(j,0,M) rep(k,0,N) rep(l,0,M) memo[i][j][k][l] = false;
    queue<pair<pair<int,int>,pair<int,int>>> Q;
    Q.push({{SX1,SY1},{SX2,SY2}});
    memo[SX1][SY1][SX2][SY2] = true;
    while(!Q.empty()) {
        pair<pair<int,int>,pair<int,int>> P = Q.front();
        Q.pop();
        int CX1 = P.first.first, CY1 = P.first.second, CX2 = P.second.first, CY2 = P.second.second;
        rep(i,0,4) {
            int NX1 = clamp(CX1+dx[i],0,N-1), NY1 = clamp(CY1+dy[i],0,M-1);
            if (X[NX1][NY1]) NX1 = CX1, NY1 = CY1;
            int NX2 = clamp(CX2+dx[i],0,N-1), NY2 = clamp(CY2+dy[i],0,M-1);
            if (Y[NX2][NY2]) NX2 = CX2, NY2 = CY2;
            if (((NX1==GX1)&&(NY1==GY1))==((NX2==GX2)&&(NY2==GY2))) {
                if (!memo[NX1][NY1][NX2][NY2]) {
                    Q.push({{NX1,NY1},{NX2,NY2}});
                    memo[NX1][NY1][NX2][NY2] = true;
                }
            }
        }
    }
    cout << (memo[GX1][GY1][GX2][GY2] ? "Yes" : "No") << endl;
}
}
accuracy: 1
time_ms: 380
memory_kb: 10112
final_rank: 2

code_snippet: #include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define all(x) (x).begin(),(x).end()
#define eb emplace_back
using namespace std;
using ll = long long;
using ld = long double;
using vl = vector<long long>;
using vvl = vector<vector<long long>>; using vs = vector<string>;
using pl = pair<long long, long long>;
template <typename T> inline bool chmin(T& a, const T& b) {bool compare = a > b; if (a > b) a = b; return compare;}
template <typename T> inline bool chmax(T& a, const T& b) {bool compare = a < b; if (a < b) a = b; return compare;}
template<class T>using rp_queue=priority_queue<T,vector<T>,greater<T>>;
template <typename T> T gcd(T a, T b) {if (b == 0)return a; else return gcd(b, a % b);}
template <typename T> inline T lcm(T a, T b) {return a /gcd(a, b)*b;}
const ll INF = 1LL << 60;
const ld PI = acos(-1);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::vector<T> &vec);
template <class OStream, class T, size_t sz> OStream &operator<<(OStream &os, const std::array<T, sz> &arr);
template <class OStream, class T, class TH> OStream &operator<<(OStream &os, const std::unordered_set<T, TH> &vec);
template <class OStream, class T, class U> OStream &operator<<(OStream &os, const pair<T, U> &pa);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::deque<T> &vec);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::set<T> &vec);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::multiset<T> &vec);
template <class OStream, class T> OStream &operator<<(OStream &os, const std::unordered_multiset<T> &vec);
template <class OStream, class T, class U> OStream &operator<<(OStream &os, const std::pair<T, U> &pa);
template <class OStream, class TK, class TV> OStream &operator<<(OStream &os, const std::map<TK, TV> &mp);
template <class OStream, class TK, class TV, class TH> OStream &operator<<(OStream &os, const std::unordered_map<TK, TV, TH> &mp);
template <class OStream, class... T> OStream &operator<<(OStream &os, const std::tuple<T...> &tpl);
 
template <class OStream, class T> OStream &operator<<(OStream &os, const std::vector<T> &vec) { os << '['; for (auto v : vec) os << v << ','; os << ']'; return os; }
template <class OStream, class T, size_t sz> OStream &operator<<(OStream &os, const std::array<T, sz> &arr) { os << '['; for (auto v : arr) os << v << ','; os << ']'; return os; }
template <class... T> std::istream &operator>>(std::istream &is, std::tuple<T...> &tpl) { std::apply([&is](auto &&... args) { ((is >> args), ...);}, tpl); return is; }
template <class OStream, class... T> OStream &operator<<(OStream &os, const std::tuple<T...> &tpl) { os << '('; std::apply([&os](auto &&... args) { ((os << args << ','), ...);}, tpl); return os << ')'; }
template <class OStream, class T, class TH> OStream &operator<<(OStream &os, const std::unordered_set<T, TH> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <class OStream, class T> OStream &operator<<(OStream &os, const std::deque<T> &vec) { os << "deq["; for (auto v : vec) os << v << ','; os << ']'; return os; }
template <class OStream, class T> OStream &operator<<(OStream &os, const std::set<T> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <class OStream, class T> OStream &operator<<(OStream &os, const std::multiset<T> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <class OStream, class T> OStream &operator<<(OStream &os, const std::unordered_multiset<T> &vec) { os << '{'; for (auto v : vec) os << v << ','; os << '}'; return os; }
template <class OStream, class T, class U> OStream &operator<<(OStream &os, const std::pair<T, U> &pa) { return os << '(' << pa.first << ',' << pa.second << ')'; }
template <class OStream, class TK, class TV> OStream &operator<<(OStream &os, const std::map<TK, TV> &mp) { os << '{'; for (auto v : mp) os << v.first << "=>" << v.second << ','; os << '}'; return os; }
template <class OStream, class TK, class TV, class TH> OStream &operator<<(OStream &os, const std::unordered_map<TK, TV, TH> &mp) { os << '{'; for (auto v : mp) os << v.first << "=>" << v.second << ','; os << '}'; return os; }
#ifdef LOCAL
const string COLOR_RESET = "\033[0m", BRIGHT_GREEN = "\033[1;32m", BRIGHT_RED = "\033[1;31m", BRIGHT_CYAN = "\033[1;36m", NORMAL_CROSSED = "\033[0;9;37m", RED_BACKGROUND = "\033[1;41m", NORMAL_FAINT = "\033[0;2m";
#define dbg(x) std::cerr << BRIGHT_CYAN << #x << COLOR_RESET << " = " << (x) << NORMAL_FAINT << " (L" << __LINE__ << ") " << __FILE__ << COLOR_RESET << std::endl
#define dbgif(cond, x) ((cond) ? std::cerr << BRIGHT_CYAN << #x << COLOR_RESET << " = " << (x) << NORMAL_FAINT << " (L" << __LINE__ << ") " << __FILE__ << COLOR_RESET << std::endl : std::cerr)
#else
#define dbg(x) ((void)0)
#define dbgif(cond, x) ((void)0)
#endif
void solve();
int main(){
  cin.tie(nullptr);
  ios_base::sync_with_stdio(false);
  cout<<fixed<<setprecision(15);
  int num_tc = 1;
  //cin >> num_tc;
  rep(tc,num_tc){
    //cout << "Case #" << tc+1 << ": " ;// << endl;
    solve();
  }
}
//見切り発車で実装しては行けない．頭の中でコードが完全に出来上がるまで書き始めるな．
bool dist[55][110][55][110];
int dx[] = {1,0,-1,0};
int dy[] = {0,-1,0,1};
int dx2[] = {1,0,-1,0};
int dy2[] = {0,1,0,-1};
void solve(){
  while(true){
    int W,H;cin>>W>>H;
    if(W==0&&H==0)return;
    vs S(H);
    getline(cin,S[0]);
    rep(i,H){
      getline(cin,S[i]);
    }
    ll lx,ly,rx,ry;
    ll glx,gly,grx,gry;
    rep(i,H){
      dbg(S[i]);
      rep(j,2*W+1){
        if(S[i][j]=='L'){
          lx = i;
          ly = j;
          S[i][j]='.';
        }
        if(S[i][j]=='R'){
          rx = i;
          ry = j;
          S[i][j]='.';
        }
        if(S[i][j]=='%'){
          S[i][j]='.';
          if(j < W){
            glx = i;
            gly = j;
          }else{
            grx = i;
            gry = j;
          }
        }
      }
    }
    dbg(make_pair(lx,ly));
    dbg(make_pair(rx,ry));
    dbg(make_pair(glx,gly));
    dbg(make_pair(grx,gry));
    queue<tuple<ll,ll,ll,ll>> que;
    que.push({lx,ly,rx,ry});
    rep(i,55)rep(j,110)rep(k,55)rep(l,110)dist[i][j][k][l]=false;
    dist[lx][ly][rx][ry] = true;
    auto is_in = [&](ll dx,ll dy)->bool{
      return 0<=dx&&dx<H&&0<=dy&&dy<W*2+1;

    };
    auto is_ok = [&](ll dx,ll dy)->bool{
      return is_in(dx,dy)&&(S[dx][dy]=='.');
    };
    while(!que.empty()){
      auto [ax,ay,bx,by] = que.front();
      dbg(que.front());
      que.pop();
      rep(d,4){
        int nax = ax+dx2[d];
        int nay = ay+dy2[d];
        int nbx = bx+dx[d];
        int nby = by+dy[d];
        if(is_ok(nax,nay)&&!is_ok(nbx,nby)){
          nbx = bx;
          nby = by;
        }
        if(!is_ok(nax,nay)&&is_ok(nbx,nby)){
          nax = ax;
          nay = ay;
        }
        if(nax==glx&&nay==gly&&nbx==grx&&nby==gry){
          dist[glx][gly][grx][gry] = true;
          break;
        }
        if(nax==glx&&nay==gly)continue;
        if(nbx==grx&&nby==gry)continue;
        if(is_ok(nax,nay)&&is_ok(nbx,nby)&&!dist[nax][nay][nbx][nby]){
          dist[nax][nay][nbx][nby] = true;
          que.push({nax,nay,nbx,nby});
        }
      }
    }
    cout<<(dist[glx][gly][grx][gry]?"Yes":"No")<<endl;
  }
}
accuracy: 1
time_ms: 760
memory_kb: 40752
final_rank: 17

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

int main(){
    while(1){
        int H, W; cin >> W >> H;
        if(H == 0) break;

        vector<string> LG(H), RG(H);
        for(int i = 0; i < H; i++){
            cin >> LG[i] >> RG[i];
        }

        int lr = 0, lc = 0, rr = 0, rc = 0;
        for(int i = 0; i < H; i++){
            for(int j = 0; j < W; j++){
                if(LG[i][j] == 'L'){
                    lr = i, lc = j;
                }
                if(RG[i][j] == 'R'){
                    rr = i, rc = j;
                } 
            }
        }

        auto norm = [&](int r1, int c1, int r2, int c2) -> int {
            return ((r1 * W + c1) * H + r2) * W + c2;
        };
        auto mron = [&](int x) -> tuple<int, int, int, int> {
            int c2 = x % W; x /= W;
            int r2 = x % H; x /= H;
            int c1 = x % W; x /= W;
            int r1 = x;
            return make_tuple(r1, c1, r2, c2);
        };

        vector<bool> dp(H * W * H * W);
        queue<int> que;
        dp[norm(lr, lc, rr, rc)] = 1;
        que.push(norm(lr, lc, rr, rc));
        const int dr[4] = {0, 1, 0, -1};
        const int dc[4] = {1, 0, -1, 0};
        while(!que.empty()){
            auto [r1, c1, r2, c2] = mron(que.front());
            // cerr << r1 << c1 << r2 << c2 << endl;
            // assert(que.front() == norm(r1, c1, r2, c2));
            que.pop();
            if(LG[r1][c1] == '%' || RG[r2][c2] == '%') continue;
            for(int i = 0; i < 4; i++){
                bool mov1 = 1, mov2 = 1;
                int nr1 = r1 + dr[i], nc1 = c1 + dc[i];
                int nr2 = r2 + dr[i], nc2 = c2 + dc[i];
                if(i % 2 == 0){ nr2 = r2 + dr[i ^ 2], nc2 = c2 + dc[i ^ 2]; }
                if(nr1 < 0 || H <= nr1 || nc1 < 0 || W <= nc1) mov1 = 0;
                if(nr2 < 0 || H <= nr2 || nc2 < 0 || W <= nc2) mov2 = 0;
                if(mov1){
                    if(LG[nr1][nc1] == '#') mov1 = 0;
                }
                if(mov2){
                    if(RG[nr2][nc2] == '#') mov2 = 0;
                }
                if(!mov1 && !mov2) continue;

                if(!mov1){ nr1 = r1, nc1 = c1; }
                if(!mov2){ nr2 = r2, nc2 = c2; }
                if(!dp[norm(nr1, nc1, nr2, nc2)]){
                    dp[norm(nr1, nc1, nr2, nc2)] = 1;
                    que.push(norm(nr1, nc1, nr2, nc2));
                }
            }
        }

        int glr = 0, glc = 0, grr = 0, grc = 0;
        for(int i = 0; i < H; i++){
            for(int j = 0; j < W; j++){
                if(LG[i][j] == '%'){
                    glr = i, glc = j;
                }
                if(RG[i][j] == '%'){
                    grr = i, grc = j;
                } 
            }
        }

        cout << (dp[norm(glr, glc, grr, grc)] ? "Yes" : "No") << endl;
    }
}
accuracy: 1
time_ms: 430
memory_kb: 4156
final_rank: 1

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

#define rep(i,n) for(int i=0;i<n;i++)
#define Rep(i,a,b) for(int i=a;i<b;i++)
#define ALL(x) (x).begin(),(x).end()
#define dbgv(x); for(auto now : x) cout << now << " "; cout << endl;

int main(){
    while(1){
        int H,W; cin >> W >> H;
        if(W == 0) break;
        vector<string> L(H), R(H);
        for (int i = 0; i < H; i++) {
            cin >> L[i] >> R[i];
            reverse(begin(R[i]), end(R[i]));
        }
        int slx, sly, srx, sry;
        int glx, gly, grx, gry;
        for (int x = 0; x < H; x++) {
            for (int y = 0; y < W; y++) {
                if (L[x][y] == 'L')
                    slx = x, sly = y;
                if (R[x][y] == 'R')
                    srx = x, sry = y;
                if (L[x][y] == '%')
                    glx = x, gly = y;
                if (R[x][y] == '%')
                    grx = x, gry = y;
            }
        }
        queue<tuple<int, int, int, int>> que;
        que.push({slx, sly, srx, sry});
        vector seen(H, vector(W, vector(H, vector(W, false))));
        seen[slx][sly][srx][sry] = true;
        const int dx[4] = {0, 0, 1, -1}, dy[4] = {1, -1, 0, 0};
        while (!que.empty()) {
            auto [lx, ly, rx, ry] = que.front();
            que.pop();
            for (int i = 0; i < 4; i++) {
                int nlx = lx + dx[i], nly = ly + dy[i], nrx = rx + dx[i], nry = ry + dy[i];
                if (nlx < 0 || nlx >= H || nly < 0 || nly >= W || L[nlx][nly] == '#')
                    nlx = lx, nly = ly;
                if (nrx < 0 || nrx >= H || nry < 0 || nry >= W || R[nrx][nry] == '#')
                    nrx = rx, nry = ry;
                if ((nlx == glx && nly == gly) + (nrx == grx && nry == gry) == 1)
                    continue;
                if (!seen[nlx][nly][nrx][nry]) {
                    seen[nlx][nly][nrx][nry] = true;
                    que.push({nlx, nly, nrx, nry});
                }
            }
        }
        cout << (seen[glx][gly][grx][gry] ? "Yes" : "No") << endl;
    }
}
accuracy: 1
time_ms: 470
memory_kb: 12356
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define ll long long
#define rep(i,n) for(ll i= 0;i < (ll)(n);i++)

bool isin(ll y,ll x,ll h,ll w){
  return (0 <= y && y < h && 0 <= x && x < w); 
}

void solve(ll h,ll w){
  vector<string> lg(h),rg(h);
  auto clc = [&](ll i,ll j,ll k,ll l){
    return h * w * (w * i + j) + (w * k + l);
  };
  pair<ll,ll> startl,startr, goall,goalr;
  rep(i,h){
    cin >> lg[i];
    cin >> rg[i];
    rep(j,w){
      if(lg[i][j] == 'L'){
        startl = {i,j};
      }
      if(lg[i][j] == '%'){
        goall = {i,j};
      }
      if(rg[i][j] == 'R'){
        startr = {i,j};
      }
      if(rg[i][j] == '%'){
        goalr = {i,j};
      }
    }
  }

  auto rclc = [&](ll v)-> tuple<ll,ll,ll,ll>{
    ll k = (v%(h * w))/w;
    ll l = (v % (h * w))%w;
    v /= h * w;
    ll i = v / w;
    ll j = v % w;
    return {i,j,k,l};
  };
  
  ll start = clc(startl.first,startl.second,startr.first,startr.second);
  ll goal = clc(goall.first,goall.second,goalr.first,goalr.second);

  ll INF = 1LL << 60;
  vector<ll> ta = {1,0,-1,0};
  vector<ll> yo = {0,1,0,-1};
  vector<ll> find(h * w * h * w,INF);
  queue<ll> que;
  que.push(start);
  find[start] = 0;
  while(!que.empty()){
    ll v = que.front();
    que.pop();
    auto [i,j,k,l] = rclc(v);
    //もしどちらかがゴールしてたらそれ以上動けない
    if(make_pair(i,j) == goall or make_pair(k,l) == goalr){
      continue;
    }
    rep(m,4){
      ll ly = i + ta[m];
      ll lx = j + yo[m];
      ll ry = k + ta[m];
      ll rx = l - yo[m];
      if(!isin(ly,lx,h,w) or lg[ly][lx] == '#'){
        ly = i;lx = j;
      }
      if(!isin(ry,rx,h,w) or rg[ry][rx] == '#'){
        ry = k;rx = l;
      }
      ll nxt = clc(ly,lx,ry,rx);
      if(find[nxt] == INF){
        find[nxt] = 1;
        que.push(nxt);
      }
    }
  }
  if(find[goal] != INF){
    cout << "Yes" << endl;
  }else{
    cout << "No" << endl;
  }
}

int main(){
  while(true){
    ll h,w;cin >> w >> h;
    if(h == 0 and w == 0)break;
    solve(h,w);
  }

}
accuracy: 1
time_ms: 540
memory_kb: 58044
final_rank: 18

code_snippet: // (⁠◕⁠ᴗ⁠◕⁠✿⁠)

// #pragma GCC target("avx2")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define srep(i, s, n) for (ll i = s; i < (n); i++)
#define len(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
using namespace std;
template<typename T> using vc = vector<T>;
template<typename T> using vv = vc<vc<T>>;
template<typename T> using vvv = vv<vc<T>>;
using vi = vc<int>;using vvi = vv<int>; using vvvi = vv<vi>;
using ll = long long;using vl = vc<ll>;using vvl = vv<ll>; using vvvl = vv<vl>;
using ld = long double; using vld = vc<ld>; using vvld = vc<vld>; using vvvld = vc<vvld>;
using uint = unsigned int;
using ull = unsigned long long;
const ld pi = 3.141592653589793;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
// const ll mod = 1000000007;
const ll mod = 998244353;
inline bool inside(ll y, ll x, ll H, ll W) {return 0 <= (y) and (y) < (H) and 0 <= (x) and (x) < (W); }

#define debug(var)  do{std::cout << #var << " : \n";view(var);}while(0)
template<typename T> void view(T e){cout << e << endl;}
template<typename T> void view(const vc<T>& v){for(const auto& e : v){ cout << e << " "; } cout << endl;}
template<typename T> void view(const vv<T>& vv){ for(const auto& v : vv){ view(v); } }

vi dx1 = {-1, 0, 1, 0}, dy1 = {0, 1, 0, -1}, dx2 = {-1, 0, 1, 0}, dy2 = {0, -1, 0, 1};

vi seen(6250000);

string solve(int H, int W){
    vc<string> S1(H), S2(H); rep(i, H) cin >> S1[i] >> S2[i];
    int s = -1, t = -1;
    rep(i1, H) rep(j1, W) rep(i2, H) rep(j2, W){
        if (S1[i1][j1] == 'L' && S2[i2][j2] == 'R'){
            s = (i1 * W + j1) * H * W + i2 * W + j2;
        }
        if (S1[i1][j1] == '%' && S2[i2][j2] == '%'){
            t = (i1 * W + j1) * H * W + i2 * W + j2;
        }
    }

    rep(i, 6250000) seen[i] = 0;
    seen[s] = 1;
    deque<int> q;
    q.push_back(s);
    while (!q.empty()){
        auto v = q.front(); q.pop_front();
        int tmp1 = v / (H * W), tmp2 = v % (H * W);
        int i1 = tmp1 / W, j1 = tmp1 % W, i2 = tmp2 / W, j2 = tmp2 % W;
        rep(k, 4){
            int ni1 = i1 + dx1[k], nj1 = j1 + dy1[k], ni2 = i2 + dx2[k], nj2 = j2 + dy2[k];
            if (inside(ni1, nj1, H, W) && S1[ni1][nj1] != '#') {}
            else{
                ni1 -= dx1[k];
                nj1 -= dy1[k];
            }
            if (inside(ni2, nj2, H, W) && S2[ni2][nj2] != '#') {}
            else{
                ni2 -= dx2[k];
                nj2 -= dy2[k];
            }
            if ((S1[ni1][nj1] == '%' && S2[ni2][nj2] != '%') || (S1[ni1][nj1] != '%' && S2[ni2][nj2] == '%')) continue;
            int u = (ni1 * W + nj1) * H * W + ni2 * W + nj2;
            if (!seen[u]){
                seen[u] = 1;
                q.push_back(u);
            }
        }
    }
    if (seen[t]) return "Yes";
    return "No";
}

int main(){
    vc<string> ans;
    while (true){
        int W, H; cin >> W >> H;
        if (W == 0) break;
        ans.push_back(solve(H, W));
    }
    for (auto x : ans) cout << x << endl;
}
accuracy: 1
time_ms: 540
memory_kb: 27876
final_rank: 14