Problem:
Let's Move Tiles!
You have a framed square board forming a grid of square cells.
Each of the cells is either empty or with a square tile fitting in the cell engraved with a Roman character.
You can tilt the board to one of four directions, away from you, toward you, to the left, or to the right,
making all the tiles slide up, down, left, or right, respectively, until they are squeezed to an edge frame of the board.
The figure below shows an example of how the positions of the tiles change by tilting the board toward you.
Let the characters
U
,
D
,
L
, and
R
represent the operations of tilting the board away from you, toward you, to the left, and to the right, respectively.
Further, let strings consisting of these characters represent the sequences of corresponding operations.
For example, the string
DRU
means a sequence of tilting toward you first, then to the right, and, finally, away from you.
This will move tiles down first, then to the right, and finally, up.
To deal with very long operational sequences, we introduce a notation for repeated sequences.
For a non-empty sequence
seq
, the notation
(
seq
)
k
means that the sequence
seq
is repeated
k
times.
Here,
k
is an integer.
For example,
(LR)3
means the same operational sequence as
LRLRLR
.
This notation for repetition can be nested.
For example,
((URD)3L)2R
means
URDURDURDLURDURDURDLR
.
Your task is to write a program that,
given an initial positions of tiles on the board and an operational sequence,
computes the tile positions after the given operations are finished.
Input
The input consists of at most 100 datasets, each in the following format.
n
s
11
...
s
1
n
...
s
n
1
...
s
nn
seq
In the first line,
n
is the number of cells in one row (and also in one column) of the board (2 ≤
n
≤ 50).
The following
n
lines contain the initial states of the board cells.
s
ij
is a character indicating the initial state of the cell in the
i
-th row from the top and in the
j
-th column from the left (both starting with one).
It is either ‘
.
’ (a period), meaning the cell is empty, or an uppercase letter ‘
A
’-‘
Z
’, meaning a tile engraved with that character is there.
seq
is a string that represents an operational sequence.
The length of
seq
is between 1 and 1000, inclusive.
It is guaranteed that
seq
denotes an operational sequence as described above.
The numbers in
seq
denoting repetitions are between 2 and 10
18
, inclusive, and are without leading zeros.
Furthermore, the length of the operational sequence after unrolling all the nested repetitions is guaranteed to be at most 10
18
.
The end of the input is indicated by a line containing a zero.
Output
For each dataset, output the states of the board cells, after performing the given operational sequence starting from the given initial states.
The output should be formatted in
n
lines, in the same format as the initial board cell states are given in the input.
Sample Input
4
..E.
.AD.
B...
..C.
D
4
..E.
.AD.
B...
..C.
DR
3
...
.A.
BC.
((URD)3L)2R
5
...
...(truncated)

Submitted solutions:

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

#define ALL(v) begin(v),end(v)
#define REP(i,n) for(int i=0;i<(n);++i)
#define RREP(i,n) for(int i=(n)-1;i>=0;--i)

typedef long long LL;
typedef vector<int> vint;

const int targets[4][9] = {
	{1, 1, 2, 2, 2, 1, 8, 8, 8},
	{3, 2, 2, 3, 4, 4, 4, 3, 2},
	{5, 5, 4, 4, 4, 5, 6, 6, 6},
	{7, 8, 8, 7, 6, 6, 6, 7, 8}
};

int getdir(char c){
	switch(c){
		case 'R': return 0;
		case 'U': return 1;
		case 'L': return 2;
		case 'D': return 3;
	}
	abort();
}

struct solver{
	int n;
	solver(int n_) : n(n_) {}
	vector<vint> ids[9];
	vint trs[4];
	vint unit;
	const char *p;
	
	vint mul(const vint &x, const vint &y){
		int sz = x.size();
		vint ret(sz);
		REP(i, sz){ ret[i] = y[x[i]]; }
		return ret;
	}
	
	vint pow(vint x, LL y){
		vint a = unit;
		while(y){
			if(y & 1){ a = mul(a, x); }
			x = mul(x, x);
			y >>= 1;
		}
		return a;
	}
	
	vint parse(){
		vint a = unit;
		vint b;
		while(1){
			if(*p == '('){
				++p;
				vint x = parse();
				++p;
				char *endp;
				LL r = strtoll(p, &endp, 10);
				p = endp;
				b = pow(x, r);
			}
			else if(isalpha(*p)){
				int dir = getdir(*p);
				++p;
				b = trs[dir];
			}
			else{ break; }
			a = mul(a, b);
		}
		return a;
	}
	
	void solve(){
		vector<string> in0(n);
		REP(i, n){ cin >> in0[i]; }
		string op;
		cin >> op;

		int fstdir = -1;
		for(char c : op){
			if(isalpha(c)){
				fstdir = getdir(c);
				break;
			}
		}

		vector<string> in(n, string(n, '.'));
		if(fstdir == 0){
			REP(y, n){
				int u = n - 1;
				RREP(x, n){
					if(in0[y][x] != '.'){
						in[y][u--] = in0[y][x];
					}
				}
			}
		}
		else if(fstdir == 1){
			REP(x, n){
				int u = 0;
				REP(y, n){
					if(in0[y][x] != '.'){
						in[u++][x] = in0[y][x];
					}
				}
			}
		}
		else if(fstdir == 2){
			REP(y, n){
				int u = 0;
				REP(x, n){
					if(in0[y][x] != '.'){
						in[y][u++] = in0[y][x];
					}
				}
			}
		}
		else{
			REP(x, n){
				int u = n - 1;
				RREP(y, n){
					if(in0[y][x] != '.'){
						in[u--][x] = in0[y][x];
					}
				}
			}
		}

		REP(i, 9){
			ids[i].assign(n, vint(n, -1));
		}

		int id = 0;
		REP(i, n)
		REP(j, n){
			if(in[i][j] != '.'){
				ids[0][i][j] = id;
				++id;
			}
		}
		int pcnt = id;

		REP(i, 4){ trs[i].assign(9 * pcnt, -1); }
		unit.resize(9 * pcnt);
		iota(ALL(unit), 0);

		REP(from, 9){
			int to, dir;

			dir = 0;
			to = targets[dir][from];
			id = to * pcnt;
			REP(y, n){
				int u = n - 1;
				RREP(x, n){
					if(ids[from][y][x] >= 0){
						int &r = ids[to][y][u];
						--u;
						if(r == -1){ r = id++; }
						trs[dir][ids[from][y][x]] = r;
					}
				}
			}

			dir = 1;
			to = targets[dir][from];
			id = to * pcnt;
			REP(x, n){
				int u = 0;
				REP(y, n){
					if(ids[from][y][x] >= 0){
						int &r = ids[to][u][x];
						++u;
						if(r == -1){ r = id++; }
						trs[dir][ids[from][y][x]] = r;
					}
				}
			}

			dir = 2;
			to = targets[dir][from];
			id = to * pcnt;
			REP(y, n){
				int u = 0;
				REP(x, n){
					if(ids[from][y][x] >= 0){
						int &r = ids[to][y][u];
						++u;
						if(r == -1){ r = id++; }
						trs[dir][ids[from][y][x]] = r;
					}
				}
			}

			dir = 3;
			to = targets[dir][from];
			id = to * pcnt;
			REP(x, n){
				int u = n - 1;
				RREP(y, n){
					if(ids[from][y][x] >= 0){
						int &r = ids[to][u][x];
						--u;
						if(r == -1){ r = id++; }
						trs[dir][ids[from][y][x]] = r;
					}
				}
			}
		}
		
		p = op.c_str();
		vint res = parse();

		vector<char> val(9 * pcnt);
		REP(y, n)
		REP(x, n){
			int k = ids[0][y][x];
			if(k >= 0){
				val[res[k]] = in[y][x];
			}
		}
		vector<string> ans(n, string(n, '.'));
		REP(i, 9)
		REP(y, n)
		REP(x, n){
			int k = ids[i][y][x];
			if(k >= 0 && val[k] != 0){
				ans[y][x] = val[k];
			}
		}
		
		REP(i, n){
			cout << ans[i] << '\n';
		}
	}
};

int main(){
	int n;
	while(cin >> n && n){
		solver(n).solve();
	}
}
accuracy: 1
time_ms: 370
memory_kb: 8032
final_rank: 4

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

#define rep(i,n) for(ll i=0;i<n;++i)
#define all(a) (a).begin(),(a).end()
ll intpow(ll a, ll b){ ll ans = 1; while(b){ if(b & 1) ans *= a; a *= a; b /= 2; } return ans; }
ll modpow(ll a, ll b, ll p){ ll ans = 1; while(b){ if(b & 1) (ans *= a) %= p; (a *= a) %= p; b /= 2; } return ans; }
template<class T> T div_floor(T a, T b) { return a / b - ((a ^ b) < 0 && a % b); }
template<class T> T div_ceil(T a, T b) { return a / b + ((a ^ b) > 0 && a % b); }
template <typename T, typename U> inline bool chmin(T &x, U y) { return (y < x) ? (x = y, true) : false; }
template <typename T, typename U> inline bool chmax(T &x, U y) { return (x < y) ? (x = y, true) : false; }


void solve(ll N) {
    vector<string> Grid(N);
    rep(i,N)cin>>Grid[i];
    string seq;
    cin>>seq;
    ll M=seq.size();
    auto slide=[&](vector<string> &G,char direction) -> void {
        if (direction=='L'){
            rep(i,N){
                ll nj=0;
                for (ll j=0;j<N;j++){
                    if (G[i][j]!='.'){
                        char s=G[i][j];
                        G[i][j]='.';
                        G[i][nj]=s;
                        nj++;
                    }
                }
            }
        }
        if (direction=='R'){
            rep(i,N){
                ll nj=N-1;
                for (ll j=N-1;j>=0;j--){
                    if (G[i][j]!='.'){
                        char s=G[i][j];
                        G[i][j]='.';
                        G[i][nj]=s;
                        nj--;
                    }
                }
            }
        }
        if (direction=='U'){
            rep(j,N){
                ll ni=0;
                for (ll i=0;i<N;i++){
                    if (G[i][j]!='.'){
                        char s=G[i][j];
                        G[i][j]='.';
                        G[ni][j]=s;
                        ni++;
                    }
                }
            }
        }
        if (direction=='D'){
            rep(j,N){
                ll ni=N-1;
                for (ll i=N-1;i>=0;i--){
                    if (G[i][j]!='.'){
                        char s=G[i][j];
                        G[i][j]='.';
                        G[ni][j]=s;
                        ni--;
                    }
                }
            }
        }
        return;
    };

    auto divmod=[&](ll a,ll b)->ll {
        a%=b;
        if (a<0)a+=b;
        return a;
    };

    ll glo_now=0;
    bool antei=false;
    char last_LR='#';
    char last_UD='#';
    ll pos;

    auto move_composition=[&](vector<ll> a,vector<ll> b) -> vector<ll> {
        vector<ll> c(4,0);
        rep(i,4){
            c[i]=a[i]+b[divmod(i+a[i],4)];
        }
        return c;
    };

    auto move_pow=[&](vector<ll> a,ll n) -> vector<ll> {
        vector<ll> b(4,0);
        while (n>0){
            if (n&1){
                b=move_composition(b,a);
            }
            a=move_composition(a,a);
            n>>=1;
        }
        return b;
    };

    auto read=[&] (auto self) -> vector<ll> {
        vector<ll> move(4,0);
        while (glo_now<M){
            if (seq[glo_now]==')'){
                glo_now++;
                ll repeat=0;
                while (glo_now<M){
                    if ('0'<=seq[glo_now] and seq[glo_now]<='9'){
                        repeat*=10;
                        repeat+=seq[glo_now]-'0';
                        glo_now++;
                    }
                    else{
                        break;
                    }
                }
                if (repeat==0)repeat=1;
                vector<ll> move2=move_pow(move,repeat-1);
                if (antei){
                    pos+=move2[divmod(pos,4)];
                }
                move=move_composition(move2,move);
                break;
            }
            if (seq[glo_now]=='('){
                glo_now++;
                move=move_composition(move,self(self));
            }
            else{
                ll s=seq[glo_now];
                glo_now++;
                vector<ll> nxt_move;
                if (s=='L'){
                    nxt_move={-1,+1,0,0};
                }
                if (s=='R'){
                    nxt_move={0,0,-1,+1};
                }
                if (s=='U'){
                    nxt_move={0,-1,+1,0};
                }
                if (s=='D'){
                    nxt_move={+1,0,0,-1};
                }
                move=move_composition(move,nxt_move);
                if (antei){
                    pos+=nxt_move[divmod(pos,4)];
                }
                else{
                    if (s=='L' or s=='R'){
                        if (last_UD=='#'){
                            last_LR=s;
                        }
                        else{
                            antei=true;
                            slide(Grid,last_UD);
                            slide(Grid,s);
                            if (last_UD=='U'){
                                if (s=='R'){
                                    pos=0;
                                }
                                else{
                                    slide(Grid,'D');
                                    slide(Grid,'R');
                                    slide(Grid,'U');
                                    pos=3;
                                }
                            }
                            else{
                                if (s=='R'){
                                    slide(Grid,'U');
                                    pos=1;
                                }
                                else{
                                    slide(Grid,'R');
                                    slide(Grid,'U');
                                    pos=2;
                                }
                            }
                        }
                    }
                    else{
                        if (last_LR=='#'){
                            last_UD=s;
                        }
                        else{
                            antei=true;
                            slide(Grid,last_LR);
                            slide(Grid,s);
                            if (last_LR=='L'){
                                if (s=='D'){
                                    slide(Grid,'R');
                                    slide(Grid,'U');
                                    pos=2;
                                }
                                else{
                                    slide(Grid,'D');
                                    slide(Grid,'R');
                                    slide(Grid,'U');
                                    pos=3;
                                }
                            }
                            else{
                                if (s=='D'){
                                    slide(Grid,'U');
                                    pos=1;
                                }
                                else{
                                    pos=0;
                                }
                            }
                        }
                    }
                }
            }
        }
        return move;
    };
    read(read);
    if (!antei){
        if (last_LR!='#'){
            slide(Grid,last_LR);
        }
        if (last_UD!='#'){
            slide(Grid,last_UD);
        }
        rep(i,N){
            cout<<Grid[i]<<endl;
        }
        return;
    }
    ll pd=divmod(pos,4);
    pos-=pd;
    ll cycle=pos/4;

    // 時計回りに回す
    auto slide_ord=[&](vector<vector<ll>> G) -> vector<vector<ll>> {
        // D
        rep(j,N){
            ll ni=N-1;
            for (ll i=N-1;i>=0;i--){
                if (G[i][j]!=-1){
                    ll s=G[i][j];
                    G[i][j]=-1;
                    G[ni][j]=s;
                    ni--;
                }
            }
        }
        // L
        rep(i,N){
            ll nj=0;
            for (ll j=0;j<N;j++){
                if (G[i][j]!=-1){
                    ll s=G[i][j];
                    G[i][j]=-1;
                    G[i][nj]=s;
                    nj++;
                }
            }
        }
        // U
        rep(j,N){
            ll ni=0;
            for (ll i=0;i<N;i++){
                if (G[i][j]!=-1){
                    ll s=G[i][j];
                    G[i][j]=-1;
                    G[ni][j]=s;
                    ni++;
                }
            }
        }
        // R
        rep(i,N){
            ll nj=N-1;
            for (ll j=N-1;j>=0;j--){
                if (G[i][j]!=-1){
                    ll s=G[i][j];
                    G[i][j]=-1;
                    G[i][nj]=s;
                    nj--;
                }
            }
        }
        return G;
    };

    // 反時計周りに回す
    auto slide_inv=[&](vector<vector<ll>> G) -> vector<vector<ll>> {
        // L
        rep(i,N){
            ll nj=0;
            for (ll j=0;j<N;j++){
                if (G[i][j]!=-1){
                    ll s=G[i][j];
                    G[i][j]=-1;
                    G[i][nj]=s;
                    nj++;
                }
            }
        }
        // D
        rep(j,N){
            ll ni=N-1;
            for (ll i=N-1;i>=0;i--){
                if (G[i][j]!=-1){
                    ll s=G[i][j];
                    G[i][j]=-1;
                    G[ni][j]=s;
                    ni--;
                }
            }
        }
        // R
        rep(i,N){
            ll nj=N-1;
            for (ll j=N-1;j>=0;j--){
                if (G[i][j]!=-1){
                    ll s=G[i][j];
                    G[i][j]=-1;
                    G[i][nj]=s;
                    nj--;
                }
            }
        }
        // U
        rep(j,N){
            ll ni=0;
            for (ll i=0;i<N;i++){
                if (G[i][j]!=-1){
                    ll s=G[i][j];
                    G[i][j]=-1;
                    G[ni][j]=s;
                    ni++;
                }
            }
        }
        return G;
    };

    vector<vector<ll>> G(N,vector<ll>(N,-1));
    vector<pair<ll,ll>> G_pos;
    ll num=0;
    rep(i,N){
        rep(j,N){
            if (Grid[i][j]!='.'){
                G[i][j]=num;
                num++;
                G_pos.push_back({i,j});
            }
        }
    }
    

    auto mult=[&](vector<ll> P,vector<ll> Q) -> vector<ll> {
        ll s=P.size();
        vector<ll> R(s);
        rep(i,s){
            R[i]=Q.at(P.at(i));
        }
        return R;
    };

    auto doubling=[&](vector<ll> P,ll n) -> vector<ll> {
        ll s=P.size();
        vector<ll> R(s);
        rep(i,s){
            R[i]=i;
        }
        while (n>0){
            if (n&1){
                R=mult(R,P);
            }
            P=mult(P,P);
            n>>=1;
        }
        return R;
    };
    vector<ll> P(num);
    if (cycle>=0){
        vector<vector<ll>> NG=slide_ord(G);
        rep(i,N){
            rep(j,N){
                if (G[i][j]!=-1){
                    P[NG[i][j]]=G[i][j];
                }
            }
        }
        P=doubling(P,cycle);
    }
    else{
        vector<vector<ll>> NG=slide_inv(G);
        rep(i,N){
            rep(j,N){
                if (G[i][j]!=-1){
                    P[NG[i][j]]=G[i][j];
                }
            }
        }
        P=doubling(P,-cycle);
    }
    vector<string> new_grid(N,string(N,'.'));
    rep(t,num){
        ll i,j;
        tie(i,j)=G_pos[t];
        ll pt=P[t];
        ll pi,pj;
        tie(pi,pj)=G_pos[pt];
        new_grid[pi][pj]=Grid[i][j];
    }
    Grid=new_grid;
    string s="DLU";
    rep(i,min(3LL,pd)){
        slide(Grid,s.at(i));
    }
    rep(i,N){
        cout<<Grid[i]<<endl;
    }
    return;
}


int main() {
    ll N;
    while (true){
        cin>>N;
        if (N==0)break;
        solve(N);
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3712
final_rank: 1

code_snippet: #include<cmath>
#include<algorithm>
#include<iostream>
#include<vector>
#include<map>
#include<set>
#include<cassert>
#include<stack>
using ll = long long;
const ll ILL=1e15;
template<class T>
bool chmin(T &a,T b){
	if(a>b){
		a=b;
		return true;
	}
	return false;
}
using namespace std;
#define rep(i,a,b) for(int i=(int)a;i<(int)b;i++)

void solve(int n){
	vector<vector<char>> p(n,vector<char>(n));
	int M=0;
	string S;
	string OP="UDLR";
	int K=18;
	set<int> st={3,5,10,13,16};
	vector<vector<vector<int>>> ban(K,vector<vector<int>>(n,vector<int>(n,-1)));
	auto f=[&](vector<vector<int>> tmp,char c)->vector<vector<int>>{
		if(c=='U'){
			rep(i,0,n) rep(j,0,n){
				if(tmp[i][j]==-1) continue;
				int x=i,y=j;
				while(x!=0&&tmp[x-1][y]==-1) x--;
				swap(tmp[i][j],tmp[x][y]);
			}
		}
		if(c=='D'){
			for(int i=n-1;i>=0;i--) rep(j,0,n){
				if(tmp[i][j]==-1) continue;
				int x=i,y=j;
				while(x!=n-1&&tmp[x+1][y]==-1) x++;
				swap(tmp[i][j],tmp[x][y]);
			}
		}
		if(c=='L'){
			rep(i,0,n) rep(j,0,n){
				if(tmp[i][j]==-1) continue;
				int x=i,y=j;
				while(y!=0&&tmp[x][y-1]==-1) y--;
				//cout<<i<<" "<<j<<" "<<x<<" "<<y<<endl;
				swap(tmp[i][j],tmp[x][y]);
			}
		}
		if(c=='R'){
			rep(i,0,n) for(int j=n-1;j>=0;j--){
				if(tmp[i][j]==-1) continue;
				int x=i,y=j;
				while(y!=n-1&&tmp[x][y+1]==-1) y++;
				swap(tmp[i][j],tmp[x][y]);
			}
		}
		return tmp;
	};
	rep(i,0,n) rep(j,0,n){
		cin>>p[i][j];
		if(p[i][j]!='.'){
			ban[4][i][j]=M;
			M++;
		}
	}
	cin>>S;
	if(M==0){
		rep(i,0,n){
			rep(j,0,n) cout<<p[i][j];
			cout<<"\n";
		}
		return;
	}
	vector<vector<int>> to_ban(K,vector<int>(4));
	rep(i,0,K){
		to_ban[i][0]=i%3;
		to_ban[i][1]=to_ban[i][0]+6;
		to_ban[i][2]=3*(i/3);
		to_ban[i][3]=to_ban[i][2]+2;
		if(i==4){
			to_ban[i]={1,7,12,14};
		}
		if(i>=9){
			rep(j,0,2) to_ban[i][j]+=9;
		}
	}
	vector<int> seen(K),order={4};
	seen[4]=1;
	rep(i,0,(int)order.size()){
		int a=order[i];
		rep(j,0,4){
			int b=to_ban[a][j];
			if(seen[b]==0){
				seen[b]=1;
				order.push_back(b);
				ban[b]=f(ban[a],OP[j]);
			}
		}
	}
	rep(i,0,K){
		if(st.count(i)) continue;
		/*cout<<i<<endl;
		rep(j,0,n){
			rep(k,0,n) cout<<ban[i][j][k]<<" ";
			cout<<endl;
		}*/
	}
	vector<vector<vector<int>>> pos(K,vector<vector<int>>(4,vector<int>(M,-1)));
	rep(i,0,K) rep(j,0,4){
		auto tmp=f(ban[i],OP[j]);
		int ind=to_ban[i][j];
		rep(k,0,n) rep(l,0,n){
			if(tmp[k][l]!=-1){
				assert(ban[ind][k][l]!=-1);
				pos[i][j][tmp[k][l]]=ban[ind][k][l];
			}
		}
	}
	vector<int> q(K*M);
	rep(i,0,K*M) q[i]=i;
	int X=0;
	vector<vector<int>> seni(4,q);
	map<char,int> m;
	rep(i,0,4) m[OP[i]]=i;
	rep(i,0,4){
		rep(j,0,K*M){
			int a=j/M;
			int b=j%M;
			if(pos[a][i][b]!=-1){
				seni[i][j]=M*to_ban[a][i]+pos[a][i][b];
			}
		}
	}
	auto merge=[&](vector<int> a,vector<int> b)->vector<int>{
		vector<int> res(K*M);
		rep(i,0,K*M) res[i]=b[a[i]];
		return res;
	};
	auto pow_merge=[&](vector<int> a,ll T)->vector<int>{
		auto e=q;
		while(T){
			if(T&1){
				e=merge(e,a);
			}
			T>>=1;
			a=merge(a,a);
		}
		return e;
	};
	auto g=[&](auto self)->vector<int>{
		vector<int> res=q;
		while(X<(int)S.size()){
			if(S[X]=='('){
				X++;
				auto tmp=self(self);
				ll T=0;
				while(X!=(int)S.size()&&'0'<=S[X]&&S[X]<='9'){
					T*=10ll;
					T+=(S[X]-'0');
					X++;
				}
				res=merge(res,pow_merge(tmp,T));
			}
			else if(S[X]==')'){
				X++;
				break;
			}
			else{
				res=merge(res,seni[m[S[X]]]);
				X++;
			}
		}
		return res;
	};
	auto val=g(g);
	vector<vector<char>> ans(n,vector<char>(n,'.'));
	vector<pair<int,int>> Y(M);
	int a=val[4*M]/M;
	//cout<<a<<endl;
	rep(i,0,n) rep(j,0,n){
		if(ban[a][i][j]!=-1) Y[ban[a][i][j]]={i,j};
	}
	vector<char> C;
	rep(i,0,n) rep(j,0,n) if(p[i][j]!='.') C.push_back(p[i][j]);
	rep(i,0,M){
		auto tmp=Y[val[4*M+i]%M];
		ans[tmp.first][tmp.second]=C[i];
	}
	rep(i,0,n){
		rep(j,0,n) cout<<ans[i][j];
		cout<<"\n";
	}

}

int main(){
	while(true){
		int n;
		cin>>n;
		if(n) solve(n);
		else break;
	}
}
accuracy: 1
time_ms: 1340
memory_kb: 9020
final_rank: 6

code_snippet: #pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
#include<chrono>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 1000000007;
const ll INF = mod * mod;
typedef pair<int, int>P;

#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;

template<typename T>
void chmin(T& a, T b) {
	a = min(a, b);
}
template<typename T>
void chmax(T& a, T b) {
	a = max(a, b);
}
template<typename T>
void cinarray(vector<T>& v) {
	rep(i, v.size())cin >> v[i];
}
template<typename T>
void coutarray(vector<T>& v) {
	rep(i, v.size()) {
		if (i > 0)cout << " "; cout << v[i];
	}
	cout << "\n";
}
ll mod_pow(ll x, ll n, ll m = mod) {
	if (n < 0) {
		ll res = mod_pow(x, -n, m);
		return mod_pow(res, m - 2, m);
	}
	if (abs(x) >= m)x %= m;
	if (x < 0)x += m;
	if (x == 0)return 0;
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x % m;
		x = x * x % m; n >>= 1;
	}
	return res;
}
struct modint {
	int n;
	modint() :n(0) { ; }
	modint(ll m) {
		if (m < 0 || mod <= m) {
			m %= mod; if (m < 0)m += mod;
		}
		n = m;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint& a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint& a, modint b) { a.n = ((ll)a.n * b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, ll n) {
	if (n == 0)return modint(1);
	modint res = (a * a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }
modint operator/=(modint& a, modint b) { a = a / b; return a; }
const int max_n = 1 << 10;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}
modint combP(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[a - b];
}

ll gcd(ll a, ll b) {
	a = abs(a); b = abs(b);
	if (a < b)swap(a, b);
	while (b) {
		ll r = a % b; a = b; b = r;
	}
	return a;
}
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-8;
const ld pi = acosl(-1.0);
int dx[4] = { 1,0,-1,0 };
int dy[4] = { 0,1,0,-1 };

//-----------------------------------

struct Data {
	array<int, 4> nex;
	array<ll, 4> ad;
};
Data operator*(Data a, Data b) {
	swap(a, b);
	Data res;
	rep(i, 4) {
		res.nex[i] = a.nex[b.nex[i]];
		res.ad[i] = a.ad[b.nex[i]] + b.ad[i];
	}
	return res;
}
Data e = {
	{0,1,2,3},
	{0,0,0,0}
};
//UDLR
string udlr = "UDLR";
bool isdir(char c) {
	return c == 'U' || c == 'D' || c == 'L' || c == 'R';
}
Data ori[4] = {
{
	{1,1,2,2},
	{1,0,0,-1}
},
{
	{0,0,3,3},
	{0,-1,1,0}
},
{
	{0,1,1,0},
	{0,0,-1,1}
},
{
	{3,2,2,3},
	{-1,1,0,0}
}
};
Data operator^(Data a, ll n) {
	Data res = e;
	while (n > 0) {
		if (n & 1)res = res * a;
		a = a * a; n >>= 1;
	}
	return res;
}

vector<string> move(vector<string> s, int dir,char x='.') {
	int n = s.size();
	if (dir == 0) {
		rep(j, n) {
			string cur;
			rep(i, n) {
				if (s[i][j] != x) {
					cur.push_back(s[i][j]);
				}
			}
			rep(i, cur.size())s[i][j] = cur[i];
			Rep(i, cur.size(), n)s[i][j] = x;
		}
	}
	else if (dir == 1) {
		rep(j, n) {
			string cur;
			rep(i, n) {
				if (s[n - 1 - i][j] != x) {
					cur.push_back(s[n-1-i][j]);
				}
			}
			rep(i, cur.size())s[n - 1 - i][j] = cur[i];
			Rep(i, cur.size(), n)s[n - 1 - i][j] = x;
		}
	}
	else if (dir == 2) {
		rep(i, n) {
			string cur;
			rep(j, n) {
				if (s[i][j] != x) {
					cur.push_back(s[i][j]);
				}
			}
			rep(j, cur.size())s[i][j] = cur[j];
			Rep(j, cur.size(), n)s[i][j] = x;
		}
	}
	else {
		rep(i, n) {
			string cur;
			rep(j, n) {
				if (s[i][n-1-j] != x) {
					cur.push_back(s[i][n-1-j]);
				}
			}
			rep(j, cur.size())s[i][n-1-j] = cur[j];
			Rep(j, cur.size(), n)s[i][n-1-j] = x;
		}
	}
	return s;
}
int dirjudge(int d1, int d2) {
	if (d1 >= 2)swap(d1, d2);
	if (d1 == 1 && d2 == 2)return 0;
	else if (d1 == 0 && d2 == 2)return 1;
	else if (d1 == 0 && d2 == 3)return 2;
	else return 3;
}
vector<int> merge(vector<int> a, vector<int> b) {
	vector<int> res(a.size());
	rep(i, res.size())res[i] = a[b[i]];
	return res;
}

int n;
void solve() {
	vector<string> s(n);
	rep(i, n)cin >> s[i];
	string str; cin >> str;

	vector<Data> st;
	Data nw = e;
	rep(i, str.size()) {
		if (str[i] == '(') {
			st.push_back(nw);
			nw = e;
		}
		else if (str[i] == ')') {
			i++;
			int le = i;
			while (i < str.size() && '0' <= str[i] && str[i] <= '9')i++;
			ll num = stoll(str.substr(le, i - le));
			nw = nw ^ num;
			nw = st.back() * nw;
			st.pop_back();
			i--;
		}
		else {
			nw = nw * ori[udlr.find(str[i])];
		}
	}
	assert(st.empty());
	bool exi[2] = {};
	vector<int> memo;
	rep(i, str.size()) {
		if (str[i] == 'U' || str[i] == 'D' || str[i] == 'L' || str[i] == 'R') {
			int id = 0;
			if (str[i] == 'L' || str[i] == 'R') {
				id = 1;
			}
			if (exi[id])continue;
			exi[id] = true;
			memo.push_back(i);
		}
	}
	auto getlas=[&](int loc)->char {
		for (int i = loc - 1;; i--) {
			if (isdir(str[i]))return str[i];
		}
		return '?';
	};
	if (memo.size() == 1) {
		char z = getlas(str.size());
		s = move(s, udlr.find(z), '.');
	}
	else {
		int d2 = udlr.find(str[memo.back()]);
		int d1 = udlr.find(getlas(memo.back()));
		s = move(s, d1); s = move(s, d2);
		vector<int> vh, vw;
		rep(i, n) {
			int cnt = 0;
			rep(j, n)if (s[i][j] != '.')cnt++;
			vh.push_back(cnt);
		}
		rep(j, n) {
			int cnt = 0;
			rep(i, n)if (s[i][j] != '.')cnt++;
			vw.push_back(cnt);
		}
		sort(all(vh));
		sort(all(vw));
		int cur = dirjudge(d1, d2);
		ll num = nw.ad[cur];
		//cout << "? " << num <<" "<<cur<< "\n";
		vector<int> ori(n* n * 4);
		if (num >= 0) {
			//clockwise
			rep(d, 4) {
				rep(i, n)rep(j, n) {
					int id = i * n + j + d * n * n;
					int ni=i, nj=j, nd=d;
					nd = (d + 1) % 4;
					if (d == 0) {
						int cnum = vw[n - 1 - j];
						if (i >= n - cnum) {
							ni = i - (n - cnum);
							nj = j;
						}
					}
					else if (d == 1) {
						int rnum = vh[n - 1 - i];
						if (j < rnum) {
							ni = i;
							nj = n - rnum + j;
						}
					}
					else if (d == 2) {
						int cnum = vw[j];
						if (i < cnum) {
							ni = n - cnum + i;
							nj = j;
						}
					}
					else if(d==3){
						int rnum = vh[i];
						if (j >= n - rnum) {
							ni = i;
							nj = j - (n - rnum);
						}
					}
					ori[id] = ni * n + nj + nd * n * n;
				}
			}
		}
		else {
			//counter clockwise
			rep(d, 4) {
				rep(i, n)rep(j, n) {
					int id = i * n + j + d * n * n;
					int ni = i, nj = j, nd = d;
					nd = (d + 3) % 4;
					if (d == 0) {
						int rnum = vh[i];
						if (j < rnum) {
							ni = i;
							nj = n - rnum + j;
						}
					}
					else if (d == 1) {
						int cnum = vw[n - 1 - j];
						if (i < cnum) {
							ni = n - cnum + i;
							nj = j;
						}
					}
					else if (d == 2) {
						int rnum = vh[n-1-i];
						if (j >= n - rnum) {
							ni = i;
							nj = j - (n - rnum);
						}
					}
					else if (d == 3) {
						int cnum = vw[j];
						if (i >= n - cnum) {
							ni = i - (n - cnum);
							nj = j;
						}
					}
					ori[id] = ni * n + nj + nd * n * n;
				}
			}


			num *= -1;
		}
		vector<int> tra(n* n * 4);
		rep(i, n* n * 4)tra[i] = i;
		while (num > 0) {
			if (num & 1) {
				tra = merge(tra, ori);
			}
			ori = merge(ori, ori); num >>= 1;
		}
		vector<string> cop = s;
		rep(i, n)rep(j, n)s[i][j] = '.';
		rep(i, n)rep(j, n) {
			if (cop[i][j] != '.') {
				int id = i * n + j + cur * n * n;
				int to = tra[id];
				to %= n * n;
				s[to / n][to % n] = cop[i][j];
			}
		}
	}
	rep(i, n)cout << s[i] << "\n";
}


signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout << fixed << setprecision(8);
	//init_f();
	//init();
	//while(true)
	//expr();
	//int t; cin >> t; rep(i, t)
	while(cin>>n,n)
	solve();
	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 3644
final_rank: 2

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001



#define NUM 13
#define MAX 60
#define SIZE 55
#define SIZE2 1005

enum Type{
	Clock,
	Rev,
	Not,
};

Type type_array[3] = {Clock,Rev,Not};

enum DIR{
	U,
	R,
	D,
	L,
	Undef,
};

enum DIR2{
	UR,
	DR,
	DL,
	UL,
	//■■■■URとRUは同じでない■■■■
	RU,
	RD,
	LD,
	LU,
	//■■■■URとRUは同じでない■■■■
	U2,
	R2,
	D2,
	L2,
	Undef2,
};

bool DEBUG = true;

string DEB[NUM] = {"UR","DR","DL","UL","RU","RD","LD","LU","U2","R2","D2","L2","Undef2"};
DIR dir_array[5] = {U,R,D,L,Undef},convert[NUM] = {Undef,Undef,Undef,Undef,Undef,Undef,Undef,Undef,U,R,D,L,Undef};
DIR2 swap_dir2[8] = {Undef2,Undef2,Undef2,Undef2,UR,DR,DL,UL};
DIR2 dir2_array[NUM] = {UR,DR,DL,UL,RU,RD,LD,LU,U2,R2,D2,L2,Undef2};
//■時計回りの移動
DIR cw_move[8][4] = {{D,L,U,R}, //UR発
				{L,U,R,D}, //DR発
				{U,R,D,L}, //DL発
				{R,D,L,U},  //UL発

				{D,L,U,R}, //RU発
				{L,U,R,D}, //RD発
				{U,R,D,L}, //LD発
				{R,D,L,U}  //LU発

				};

//■反時計回りの移動
DIR rev_move[8][4] = {{L,D,R,U}, //UR発
					 {U,L,D,R}, //DR発
					 {R,U,L,D}, //DL発
					 {D,R,U,L},  //UL発

					 {L,D,R,U}, //RU発
					 {U,L,D,R}, //RD発
					 {R,U,L,D}, //LD発
					 {D,R,U,L} //LU
};


struct LOC{
	void set(int arg_row,int arg_col){
		row = arg_row;
		col = arg_col;
	}
	int row,col;
};

struct Trans{
	Trans(int arg_pre_row,int arg_pre_col,int arg_now_row,int arg_now_col){

		pre_row = arg_pre_row;
		pre_col = arg_pre_col;
		now_row = arg_now_row;
		now_col = arg_now_col;
	}
	int pre_row,pre_col,now_row,now_col;
};


//文字列の回転の大きさ
struct Roll{

	ll num_roll;
	DIR2 base_dir;  //■■■最初に寄った角と、その直前の動きでタイルの塊の形が決まる(たとえばR→UとU→Rは異なる)■■■
};

int N,LEN;
int close_pos[SIZE2]; //開き括弧に対応する閉じ括弧の位置
int MAP[SIZE][SIZE];
int base_corn[NUM][SIZE][SIZE];
char line[SIZE2],input[SIZE][SIZE];
ll POW[MAX+1];
LOC just_move[2][MAX+1][NUM][SIZE][SIZE]; //just_move[時計/反時計][2べき][最初に寄った角][行][列] = (遷移先行、遷移先列) ■余りの出ない回転
LOC MOVE[NUM][MAX+1][SIZE][SIZE];
int pow_corn[NUM][MAX+1];
Roll roll_pow[NUM][MAX+1]; //ダブリング用テーブル

//余りが出た時の、寄る角の遷移表
DIR2 cw_next[4][4] = {{Undef2,DR,DL,UL},//UR
					  {Undef2,DL,UL,UR}, //DR
					  {Undef2,UL,UR,DR}, //DL
					  {Undef2,UR,DR,DL},  //UL
					  };

DIR2 rev_next[4][4] = {{Undef2,UL,DL,DR},//UR
					  {Undef2,UR,UL,DL}, //DR
					  {Undef2,DR,UR,UL}, //DL
					  {Undef2,DL,DR,UR},  //UL
					  };
//U,R,D,Lに移動した時の,次の角、
DIR2 corner_next[4][4] = {{UR,UR,DR,UL}, //UR
		           	   	  {UR,DR,DR,DL}, //DR
						  {UL,DR,DL,DL}, //DL
						  {UL,UR,DL,UL} //UL
				  	  	 };

bool is_corner(DIR2 dir2){

	return (dir2 == UR || dir2 == DR || dir2 == DL || dir2 == UL || dir2 == RU || dir2 == RD || dir2 == LD || dir2 == LU);
}


bool is_special(DIR2 dir2){

	return (dir2 == RU || dir2 == RD || dir2 == LD || dir2 == LU);
}

void init_table(int work[SIZE][SIZE]){

	for(int row = 0; row < N; row++){
		for(int col = 0; col < N; col++){

			work[row][col] = -1;
		}
	}
}

void copy_table(int from[SIZE][SIZE],int to[SIZE][SIZE]){

	for(int row = 0; row < N; row++){
		for(int col = 0; col < N; col++){

			to[row][col] = from[row][col];
		}
	}
}

//遷移元(行,列)と遷移先(行,列)の対応情報取得
vector<Trans> calc_trans(int from[SIZE][SIZE],int to[SIZE][SIZE]){

	vector<Trans> ret;
	LOC base[N*N];

	for(int row = 0; row < N; row++){
		for(int col = 0; col < N; col++){
			if(from[row][col] == -1)continue;

			base[from[row][col]].set(row,col); //ある数字が、元々どこにいたか
		}
	}

	for(int row = 0; row < N; row++){
		for(int col = 0; col < N; col++){
			if(to[row][col] == -1)continue;

			int tmp = to[row][col];
			int pre_row = base[tmp].row;
			int pre_col = base[tmp].col;

			ret.push_back(Trans(pre_row,pre_col,row,col));
		}
	}

	return ret;
}

void calc_move(DIR dir,int from[SIZE][SIZE],int to[SIZE][SIZE]){

	init_table(to);

	if(dir == U){ //上詰め

		for(int col = 0; col < N; col++){
			vector<int> vec;
			for(int row = 0; row < N; row++){
				if(from[row][col] != -1){

					vec.push_back(from[row][col]);
				}
			}
			for(int row = 0; row < vec.size(); row++){

				to[row][col] = vec[row];
			}
		}

	}else if(dir == R){ //右詰め

		for(int row = 0; row < N; row++){
			vector<int> vec;
			for(int col = N-1; col >= 0; col--){
				if(from[row][col] != -1){

					vec.push_back(from[row][col]);
				}
			}
			for(int i = 0; i < vec.size(); i++){

				to[row][(N-1)-i] = vec[i];
			}
		}

	}else if(dir == D){ //下詰め

		for(int col = 0; col < N; col++){
			vector<int> vec;
			for(int row = N-1; row >= 0; row--){
				if(from[row][col] != -1){

					vec.push_back(from[row][col]);
				}
			}
			for(int i = 0; i < vec.size(); i++){

				to[(N-1)-i][col] = vec[i];
			}
		}

	}else{ //dir == L //左詰め

		for(int row = 0; row < N; row++){
			vector<int> vec;
			for(int col = 0; col < N; col++){
				if(from[row][col] != -1){

					vec.push_back(from[row][col]);
				}
			}
			for(int col = 0; col < vec.size(); col++){

				to[row][col] = vec[col];
			}
		}
	}
}


//遷移先テーブル作り(ダブリング)
void init(){

	int from[SIZE][SIZE],to[SIZE][SIZE],work[SIZE][SIZE];
	int TMP[SIZE][SIZE],WORK[SIZE][SIZE];

	init_table(from);

	int IND = 0;
	for(int row = 0; row < N; row++){
		for(int col = 0; col < N; col++){
			if(input[row][col] == '.'){

				from[row][col] = -1;
			}else{

				from[row][col] = IND++;
			}
		}
	}

	//Undef
	copy_table(from,base_corn[Undef2]);

	int calc_IND[4] = {8,9,10,11};

	//上下左右
	for(int i = 0; i < 4; i++){

		copy_table(from,work);
		calc_move(dir_array[i],work,to);

		copy_table(to,base_corn[calc_IND[i]]);
	}

	DIR make_map[8][4] = {{U,R},{D,R},{D,L},{U,L},{R,U},{R,D},{L,D},{L,U}};

	//■■[初めて寄った角,そこへ至る動き]で位置を区別する■■
	for(int q = 0; q < 8; q++){

		//■まずは角へ移動
		copy_table(from,work);
		for(int k = 0; k < 2; k++){
			calc_move(make_map[q][k],work,to);
			copy_table(to,work);
		}

		copy_table(work,base_corn[q]);


		//■現在の状態から、時計、反時計に一周する
		DIR2 now_dir = dir2_array[q];
		if(is_special(now_dir)){

			now_dir = swap_dir2[now_dir];
		}

		//時計
		{
			copy_table(work,TMP);

			for(int i = 0; i < 4; i++){

				calc_move(cw_move[now_dir][i],TMP,WORK);
				copy_table(WORK,TMP);
			}

			vector<Trans> ret = calc_trans(work,TMP);

			for(int k = 0; k < ret.size(); k++){

				just_move[Clock][0][q][ret[k].pre_row][ret[k].pre_col].set(ret[k].now_row,ret[k].now_col);
			}

		}

		//反時計
		{
			copy_table(work,TMP);

			for(int i = 0; i < 4; i++){

				calc_move(rev_move[now_dir][i],TMP,WORK);
				copy_table(WORK,TMP);
			}

			vector<Trans> ret = calc_trans(work,TMP);

			for(int k = 0; k < ret.size(); k++){

				just_move[Rev][0][q][ret[k].pre_row][ret[k].pre_col].set(ret[k].now_row,ret[k].now_col);
			}
		}
	}

	//■ダブリング計算(角にいる場合のみ)
	for(int d = 1; d <= MAX; d++){
		for(int i = 0; i < 8; i++){
			for(int k = 0; k < 2; k++){
				Type type = type_array[k];

				for(int row = 0; row < N; row++){
					for(int col = 0; col < N; col++){

						int mid_row = just_move[type][d-1][i][row][col].row;
						int mid_col = just_move[type][d-1][i][row][col].col;

						int to_row = just_move[type][d-1][i][mid_row][mid_col].row;
						int to_col = just_move[type][d-1][i][mid_row][mid_col].col;

						just_move[type][d][i][row][col].set(to_row,to_col);
					}
				}
			}
		}
	}
}

bool isNUM(char ch){

	return ch >= '0' && ch <= '9';
}

bool is_ud(vector<char> vec){

	return vec.size() > 0 && (vec.back() == 'U' || vec.back() == 'D');
}

bool is_lr(vector<char> vec){

	return vec.size() > 0 && (vec.back() == 'L' || vec.back() == 'R');
}

//■出発位置ごとに、回転数と余り、移動先を計算する
vector<Roll> calc_normal(int head,int tail){

	vector<Roll> ret;

	for(int a = 0; a < 13; a++){

		DIR2 now_dir = dir2_array[a];
		DIR2 base_dir = dir2_array[a];

		if(is_special(base_dir)){

			now_dir = swap_dir2[now_dir];
		}

		vector<char> vec;

		ll num_roll = 0;

		for(int i = head; i <= tail; i++){

			if(!is_corner(base_dir)){ //まだ角に寄ってない

				if(now_dir == Undef2){ //■■初期状態

					switch(line[i]){
					case 'U':
						now_dir = U2;
						break;
					case 'R':
						now_dir = R2;
						break;
					case 'D':
						now_dir = D2;
						break;
					case 'L':
						now_dir = L2;
						break;
					}

				}else if(now_dir == U2){

					switch(line[i]){
					case 'U':

						//Do nothing
						break;
					case 'R':
						now_dir = UR;
						base_dir = UR;
						break;
					case 'D':
						now_dir = D2;
						break;
					case 'L':
						now_dir = UL;
						base_dir = UL;
						break;
					}

				}else if(now_dir == R2){

					switch(line[i]){
					case 'U':
						now_dir = UR;  //■■■■■■■■■■■■■■now_dirはUR,RUをまとめて、base_dirはURとURを区別するので注意■■■■■■■■■■■■■■
						base_dir = RU; //■■以下同様に注意■■
						break;
					case 'R':
						//Do nothing
						break;
					case 'D':
						now_dir = DR;
						base_dir = RD;
						break;
					case 'L':
						now_dir = L2;
						break;
					}

				}else if(now_dir == D2){

					switch(line[i]){
					case 'U':
						now_dir = U2;
						break;
					case 'R':
						now_dir = DR;
						base_dir = DR;
						break;
					case 'D':
						//Do nothing
						break;
					case 'L':
						now_dir = DL;
						base_dir = DL;
						break;
					}

				}else{ //now_dir == L2

					switch(line[i]){
					case 'U':
						now_dir = UL;
						base_dir = LU;
						break;
					case 'R':
						now_dir = R2;
						break;
					case 'D':
						now_dir = DL;
						base_dir = LD;
						break;
					case 'L':
						//Do nothing
						break;
					}
				}

			}else{ //■角に寄っている

				//意味のない動きをはじく
				if(now_dir == UR){

					if(line[i] == 'U' || line[i] == 'R')continue;

				}else if(now_dir == DR){

					if(line[i] == 'D' || line[i] == 'R')continue;

				}else if(now_dir == DL){

					if(line[i] == 'D' || line[i] == 'L')continue;

				}else if(now_dir == UL){

					if(line[i] == 'U' || line[i] == 'L')continue;
				}

				if(line[i] == 'L' || line[i] == 'R'){

					if(is_lr(vec)){

						//■反対動で、前回の移動が無効化
						vec.pop_back();

					}else{

						vec.push_back(line[i]);
					}

				}else{

					if(is_ud(vec)){

						//■反対動で、前回の移動が無効化
						vec.pop_back();

					}else{

						vec.push_back(line[i]);
					}
				}

				DIR tmp_dir;
				switch(line[i]){
				case 'U':
					tmp_dir = U;
					break;
				case 'R':
					tmp_dir = R;
					break;
				case 'D':
					tmp_dir = D;
					break;
				case 'L':
					tmp_dir = L;
					break;
				}

				//■現在寄っている角(基準角とは異なる→基準角は最初に寄った角)
				now_dir = corner_next[now_dir][tmp_dir];

				if(vec.size() == 4){

					if(vec[0] == 'U'){

						if(vec[1] == 'R'){

							num_roll += 4;

						}else{ //vec[1] == 'L'

							num_roll -= 4;
						}

					}else if(vec[0] == 'D'){

						if(vec[1] == 'R'){

							num_roll -= 4;

						}else{ //vec[1] == 'L'

							num_roll += 4;
						}

					}else if(vec[0] == 'R'){

						if(vec[1] == 'U'){

							num_roll -= 4;

						}else{ //vec[1] == 'D'

							num_roll += 4;
						}

					}else{ //vec[0] == 'L'

						if(vec[1] == 'U'){

							num_roll += 4;
						}else{

							num_roll -= 4;
						}
					}

					vec.clear();
				}
			}
		}

		Roll roll;
		roll.base_dir = base_dir;

		if(!is_corner(base_dir)){ //角に寄らない

			roll.base_dir = now_dir; //■■注意■■

		}else{ //角に寄る

			//■余りの処理
			if(vec.size() > 0){

				ll s = vec.size();

				DIR2 t_dir = base_dir;

				if(is_special(t_dir)){

					t_dir = swap_dir2[t_dir];
				}

				switch(t_dir){
				case UR:
					if(vec[0] == 'D'){

						num_roll += s;
					}else{

						num_roll -= s;
					}
					break;
				case DR:
					if(vec[0] == 'L'){

						num_roll += s;
					}else{

						num_roll -= s;
					}
					break;
				case DL:
					if(vec[0] == 'U'){

						num_roll += s;
					}else{

						num_roll -= s;
					}
					break;
				case UL:
					if(vec[0] == 'R'){

						num_roll += s;
					}else{

						num_roll -= s;
					}
					break;
				}
			}
		}

		roll.num_roll = num_roll;
		ret.push_back(roll);
	}
	return ret;
}

void move_table(Type type,DIR2 base_dir,int table[SIZE][SIZE],ll digit){

	int work[SIZE][SIZE];
	init_table(work);

	for(int row = 0; row < N; row++){
		for(int col = 0; col < N; col++){
			if(table[row][col] == -1)continue;

			int to_row = just_move[type][digit][base_dir][row][col].row;
			int to_col = just_move[type][digit][base_dir][row][col].col;

			work[to_row][to_col] = table[row][col];
		}
	}

	copy_table(work,table);
}



//base_dirを出発点として、num_roll回転した時、現在どの角にいるか
DIR2 calc_corner(DIR2 base_dir,ll num_roll){

	DIR2 tmp_c  = base_dir;
	if(is_special(base_dir)){

		tmp_c = swap_dir2[base_dir];
	}

	if(abs(num_roll)%4 == 0){

		return tmp_c;
	}

	ll mod = abs(num_roll)%4;

	if(num_roll > 0){

		return cw_next[tmp_c][mod];

	}else{

		return rev_next[tmp_c][mod];
	}
}

//■実際にテーブルを回転させる
void move_func(int table[SIZE][SIZE],Roll tmp_roll){

	int work[SIZE][SIZE];

	//角に到達していない場合
	if(!is_corner(tmp_roll.base_dir)){

		calc_move(convert[tmp_roll.base_dir],table,work);
		copy_table(work,table);
		return;
	}

	//まずは角まで移動させる
	switch(tmp_roll.base_dir){
	case UR:
		calc_move(U,table,work);
		copy_table(work,table);
		calc_move(R,table,work);
		copy_table(work,table);
		break;
	case DR:
		calc_move(D,table,work);
		copy_table(work,table);
		calc_move(R,table,work);
		copy_table(work,table);
		break;
	case DL:
		calc_move(D,table,work);
		copy_table(work,table);
		calc_move(L,table,work);
		copy_table(work,table);
		break;
	case UL:
		calc_move(U,table,work);
		copy_table(work,table);
		calc_move(L,table,work);
		copy_table(work,table);
		break;
	case RU:
		calc_move(R,table,work);
		copy_table(work,table);
		calc_move(U,table,work);
		copy_table(work,table);
		break;
	case RD:
		calc_move(R,table,work);
		copy_table(work,table);
		calc_move(D,table,work);
		copy_table(work,table);
		break;
	case LD:
		calc_move(L,table,work);
		copy_table(work,table);
		calc_move(D,table,work);
		copy_table(work,table);
		break;
	case LU:
		calc_move(L,table,work);
		copy_table(work,table);
		calc_move(U,table,work);
		copy_table(work,table);
		break;
	}

	ll mult = abs(tmp_roll.num_roll)/4;
	ll mod = abs(tmp_roll.num_roll)%4;

	Type type = Not;
	if(tmp_roll.num_roll > 0){

		type = Clock;
	}else{

		type = Rev;
	}

	//周回させる
	if(mult != 0){

		for(int d = MAX; d >= 0; d--){
			if(POW[d] > mult)continue;

			move_table(type,tmp_roll.base_dir,table,d);
			mult -= POW[d];
		}
	}

	//余りの処理
	if(mod != 0){

		mod = abs(mod);
		DIR2 now = tmp_roll.base_dir;
		if(is_special(now)){

			now = swap_dir2[now];
		}

		for(int i = 0; i < mod; i++){

			switch(now){
			case UR:
				if(type == Clock){

					calc_move(D,table,work);
					copy_table(work,table);

				}else{

					calc_move(L,table,work);
					copy_table(work,table);
				}
				break;
			case DR:
				if(type == Clock){

					calc_move(L,table,work);
					copy_table(work,table);

				}else{

					calc_move(U,table,work);
					copy_table(work,table);
				}
				break;
			case DL:
				if(type == Clock){

					calc_move(U,table,work);
					copy_table(work,table);

				}else{

					calc_move(R,table,work);
					copy_table(work,table);
				}
				break;
			case UL:
				if(type == Clock){

					calc_move(R,table,work);
					copy_table(work,table);

				}else{

					calc_move(D,table,work);
					copy_table(work,table);
				}
				break;
			}
			if(type == Clock){

				now = cw_next[now][1];

			}else{

				now = rev_next[now][1];
			}
		}
	}
}

vector<Roll> calc_E(int head,int tail){

	int left = head;

	DIR2 BASE_DIR[NUM];
	ll NUM_ROLL[NUM];

	for(int i = 0; i < 13; i++){

		BASE_DIR[i] = dir2_array[i]; //■■元々位置に合った塊の、現在の基準角
		NUM_ROLL[i] = 0;
	}

	while(left <= tail){

		if(line[left] == '('){ //■倍化処理あり

			vector<Roll> vec = calc_E(left+1,close_pos[left]-1);

			int ind = close_pos[left]+1;
			ll tmp_p = 0;

			while(ind <= tail && isNUM(line[ind])){

				tmp_p = 10*tmp_p + (line[ind]-'0');
				ind++;
			}


			ll maxi = MAX;
			while(POW[maxi] > tmp_p){

				maxi--;
			}

			//ダブリングテーブル初期化
			for(int d = 0; d <= maxi; d++){
				for(int i = 0; i < 13; i++){

					roll_pow[i][d].base_dir = Undef2;
					roll_pow[i][d].num_roll = 0;
				}
			}

			/*■■■■■倍化処理■■■■■*/
			for(int i = 0; i < 13; i++){

				roll_pow[i][0].base_dir = vec[i].base_dir;
				roll_pow[i][0].num_roll = vec[i].num_roll;
			}

			//■ダブリング
			for(int d = 1; d <= maxi; d++){
				for(int i = 0; i < 13; i++){

					if(is_corner(roll_pow[i][d-1].base_dir)){ //既に角に寄っている場合

						DIR2 tmp_c = roll_pow[i][d-1].base_dir;
						DIR2 next_c = calc_corner(tmp_c,roll_pow[i][d-1].num_roll);

						roll_pow[i][d].base_dir = tmp_c; //■一度角に着いたら、以後ずっとそこを基準にする
						roll_pow[i][d].num_roll = roll_pow[i][d-1].num_roll+roll_pow[next_c][d-1].num_roll;

					}else{

						DIR2 mid = roll_pow[i][d-1].base_dir; //まずはmidへ
						DIR2 tmp = roll_pow[mid][d-1].base_dir;

						roll_pow[i][d].base_dir = tmp;

						if(is_corner(tmp)){ //初めて角に着く

							roll_pow[i][d].num_roll = roll_pow[mid][d-1].num_roll;
						}
					}
				}
			}

			for(int i = 0; i < 13; i++){

				DIR2 base_dir = BASE_DIR[i]; //■■呼び出し元の位置iの基準角
				DIR2 now_dir;
				ll num_roll = NUM_ROLL[i];

				if(is_corner(base_dir)){

					now_dir = calc_corner(base_dir,num_roll);  //■位置iの塊が、現在寄っている角
				}

				ll rest = tmp_p;
				for(int d = maxi; d >= 0; d--){
					if(POW[d] > rest)continue;

					if(is_corner(base_dir)){ //基準角が決まっている

						num_roll += roll_pow[now_dir][d].num_roll;
						now_dir = calc_corner(base_dir,num_roll);

					}else{

						base_dir = roll_pow[base_dir][d].base_dir;  //次の基準角
						if(is_corner(base_dir)){ //新しく基準角が決まる

							num_roll += roll_pow[base_dir][d].num_roll;
							now_dir = calc_corner(base_dir,num_roll);

						}
					}
					rest -= POW[d];
				}

				BASE_DIR[i] = base_dir;
				NUM_ROLL[i] = num_roll;
			}

			left = ind;

		}else{ //■倍化処理なし

			int right = left;
			while(right <= tail && line[right] != '(')right++;
			right--;

			//この間に括弧なし
			vector<Roll> vec = calc_normal(left,right);

			for(int i = 0; i < 13; i++){
				if(is_corner(BASE_DIR[i])){

					DIR2 now_dir = calc_corner(BASE_DIR[i],NUM_ROLL[i]);
					NUM_ROLL[i] += vec[now_dir].num_roll; //既に角にいる場合は、回転数だけ足す

				}else{

					DIR2 base_dir = vec[BASE_DIR[i]].base_dir;
					if(is_corner(base_dir)){

						NUM_ROLL[i] += vec[BASE_DIR[i]].num_roll;
					}
					BASE_DIR[i] = base_dir;
				}
			}
			left = right+1;
		}
	}

	vector<Roll> ret;

	for(int i = 0; i < 13; i++){
		Roll tmp_roll;
		tmp_roll.base_dir = BASE_DIR[i];
		tmp_roll.num_roll = NUM_ROLL[i];

		ret.push_back(tmp_roll);
	}
	return ret;
}


void func(){

	for(int row = 0; row < N; row++){

		scanf("%s",input[row]);
	}

	scanf("%s",line);

	init();

	for(LEN = 0; line[LEN] != '\0'; LEN++);

	//括弧の対応を前計算
	stack<int> ST;
	for(int i = 0; i < LEN; i++){
		if(line[i] == '('){

			ST.push(i);

		}else if(line[i] == ')'){

			close_pos[ST.top()] = i;
			ST.pop();
		}
	}

	init_table(MAP);

	map<int,pair<int,int>> MEMO;

	int IND = 0;
	for(int row = 0; row < N; row++){
		for(int col = 0; col < N; col++){
			if(input[row][col] == '.'){

				MAP[row][col] = -1;
				continue;
			}

			MAP[row][col] = IND;
			MEMO[IND] = make_pair(row,col);
			IND++;
		}
	}


	vector<Roll> ret = calc_E(0,LEN-1);

	move_func(MAP,ret[Undef2]);

	char ANS[SIZE][SIZE];

	for(int row = 0; row < N; row++){
		for(int col = 0; col < N; col++){

			ANS[row][col] = '.';
		}
	}

	//回転処理
	for(int row = 0; row < N; row++){
		for(int col = 0; col < N; col++){
			if(MAP[row][col] == -1)continue;

			int tmp_num = MAP[row][col];
			int pre_row = MEMO[tmp_num].first;
			int pre_col = MEMO[tmp_num].second;

			ANS[row][col] = input[pre_row][pre_col];

		}
	}

	for(int row = 0; row < N; row++){
		for(int col = 0; col < N; col++){

			printf("%c",ANS[row][col]);
		}
		printf("\n");
	}
}

int main(){

	POW[0] = 1;
	for(int i = 1; i <= MAX; i++){

		POW[i] = POW[i-1]*2;
	}

	while(true){

		scanf("%d",&N);
		if(N == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 270
memory_kb: 41360
final_rank: 8

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001



#define NUM 13
#define MAX 60
#define SIZE 55
#define SIZE2 1005

enum Type{
	Clock,
	Rev,
	Not,
};

Type type_array[3] = {Clock,Rev,Not};

enum DIR{
	U,
	R,
	D,
	L,
	Undef,
};

enum DIR2{
	UR,
	DR,
	DL,
	UL,
	//■■■■URとRUは同じでない■■■■
	RU,
	RD,
	LD,
	LU,
	//■■■■URとRUは同じでない■■■■
	U2,
	R2,
	D2,
	L2,
	Undef2,
};

bool DEBUG = true;

string DEB[NUM] = {"UR","DR","DL","UL","RU","RD","LD","LU","U2","R2","D2","L2","Undef2"};
DIR dir_array[5] = {U,R,D,L,Undef},convert[NUM] = {Undef,Undef,Undef,Undef,Undef,Undef,Undef,Undef,U,R,D,L,Undef};
DIR2 swap_dir2[8] = {Undef2,Undef2,Undef2,Undef2,UR,DR,DL,UL};
DIR2 dir2_array[NUM] = {UR,DR,DL,UL,RU,RD,LD,LU,U2,R2,D2,L2,Undef2};
//■時計回りの移動
DIR cw_move[8][4] = {{D,L,U,R}, //UR発
				{L,U,R,D}, //DR発
				{U,R,D,L}, //DL発
				{R,D,L,U},  //UL発

				{D,L,U,R}, //RU発
				{L,U,R,D}, //RD発
				{U,R,D,L}, //LD発
				{R,D,L,U}  //LU発

				};

//■反時計回りの移動
DIR rev_move[8][4] = {{L,D,R,U}, //UR発
					 {U,L,D,R}, //DR発
					 {R,U,L,D}, //DL発
					 {D,R,U,L},  //UL発

					 {L,D,R,U}, //RU発
					 {U,L,D,R}, //RD発
					 {R,U,L,D}, //LD発
					 {D,R,U,L} //LU
};


struct LOC{
	void set(int arg_row,int arg_col){
		row = arg_row;
		col = arg_col;
	}
	int row,col;
};

struct Trans{
	Trans(int arg_pre_row,int arg_pre_col,int arg_now_row,int arg_now_col){

		pre_row = arg_pre_row;
		pre_col = arg_pre_col;
		now_row = arg_now_row;
		now_col = arg_now_col;
	}
	int pre_row,pre_col,now_row,now_col;
};


//文字列の回転の大きさ
struct Roll{

	ll num_roll;
	DIR2 base_dir;  //■■■最初に寄った角と、その直前の動きでタイルの塊の形が決まる■■■
};

int N,LEN;
int close_pos[SIZE2]; //開き括弧に対応する閉じ括弧の位置
int MAP[SIZE][SIZE];
int base_corn[NUM][SIZE][SIZE];
char line[SIZE2],input[SIZE][SIZE];
ll POW[MAX+1];
LOC just_move[2][MAX+1][NUM][SIZE][SIZE]; //just_move[時計/反時計][2べき][最初に寄った角][行][列] = (遷移先行、遷移先列) ■余りの出ない回転
LOC MOVE[NUM][MAX+1][SIZE][SIZE];
int pow_corn[NUM][MAX+1];
Roll roll_pow[NUM][MAX+1]; //ダブリング用テーブル

//余りが出た時の、寄る角の遷移表
DIR2 cw_next[4][4] = {{Undef2,DR,DL,UL},//UR
					  {Undef2,DL,UL,UR}, //DR
					  {Undef2,UL,UR,DR}, //DL
					  {Undef2,UR,DR,DL},  //UL
					  };

DIR2 rev_next[4][4] = {{Undef2,UL,DL,DR},//UR
					  {Undef2,UR,UL,DL}, //DR
					  {Undef2,DR,UR,UL}, //DL
					  {Undef2,DL,DR,UR},  //UL
					  };
//U,R,D,Lに移動した時の,次の角、
DIR2 corner_next[4][4] = {{UR,UR,DR,UL}, //UR
		           	   	  {UR,DR,DR,DL}, //DR
						  {UL,DR,DL,DL}, //DL
						  {UL,UR,DL,UL} //UL
				  	  	 };


void outPut(int table[SIZE][SIZE]){

	for(int row = 0; row < N; row++){
		for(int col = 0; col < N; col++){

			printf(" %d",table[row][col]);
		}
		printf("\n");
	}
}


bool is_corner(DIR2 dir2){

	return (dir2 == UR || dir2 == DR || dir2 == DL || dir2 == UL || dir2 == RU || dir2 == RD || dir2 == LD || dir2 == LU);
}


bool is_special(DIR2 dir2){

	return (dir2 == RU || dir2 == RD || dir2 == LD || dir2 == LU);
}

void init_table(int work[SIZE][SIZE]){

	for(int row = 0; row < N; row++){
		for(int col = 0; col < N; col++){

			work[row][col] = -1;
		}
	}
}

void copy_table(int from[SIZE][SIZE],int to[SIZE][SIZE]){

	for(int row = 0; row < N; row++){
		for(int col = 0; col < N; col++){

			to[row][col] = from[row][col];
		}
	}
}

//遷移元(行,列)と遷移先(行,列)の対応情報取得
vector<Trans> calc_trans(int from[SIZE][SIZE],int to[SIZE][SIZE]){

	vector<Trans> ret;
	LOC base[N*N];

	for(int row = 0; row < N; row++){
		for(int col = 0; col < N; col++){
			if(from[row][col] == -1)continue;

			base[from[row][col]].set(row,col); //ある数字が、元々どこにいたか
		}
	}

	for(int row = 0; row < N; row++){
		for(int col = 0; col < N; col++){
			if(to[row][col] == -1)continue;

			int tmp = to[row][col];
			int pre_row = base[tmp].row;
			int pre_col = base[tmp].col;

			ret.push_back(Trans(pre_row,pre_col,row,col));
		}
	}

	return ret;
}

void calc_move(DIR dir,int from[SIZE][SIZE],int to[SIZE][SIZE]){

	init_table(to);

	if(dir == U){ //上詰め

		for(int col = 0; col < N; col++){
			vector<int> vec;
			for(int row = 0; row < N; row++){
				if(from[row][col] != -1){

					vec.push_back(from[row][col]);
				}
			}
			for(int row = 0; row < vec.size(); row++){

				to[row][col] = vec[row];
			}
		}

	}else if(dir == R){ //右詰め

		for(int row = 0; row < N; row++){
			vector<int> vec;
			for(int col = N-1; col >= 0; col--){
				if(from[row][col] != -1){

					vec.push_back(from[row][col]);
				}
			}
			for(int i = 0; i < vec.size(); i++){

				to[row][(N-1)-i] = vec[i];
			}
		}

	}else if(dir == D){ //下詰め

		for(int col = 0; col < N; col++){
			vector<int> vec;
			for(int row = N-1; row >= 0; row--){
				if(from[row][col] != -1){

					vec.push_back(from[row][col]);
				}
			}
			for(int i = 0; i < vec.size(); i++){

				to[(N-1)-i][col] = vec[i];
			}
		}

	}else{ //dir == L //左詰め

		for(int row = 0; row < N; row++){
			vector<int> vec;
			for(int col = 0; col < N; col++){
				if(from[row][col] != -1){

					vec.push_back(from[row][col]);
				}
			}
			for(int col = 0; col < vec.size(); col++){

				to[row][col] = vec[col];
			}
		}
	}
}


//遷移先テーブル作り(ダブリング)
void init(){

	int from[SIZE][SIZE],to[SIZE][SIZE],work[SIZE][SIZE];
	int TMP[SIZE][SIZE],WORK[SIZE][SIZE];

	init_table(from);

	int IND = 0;
	for(int row = 0; row < N; row++){
		for(int col = 0; col < N; col++){
			if(input[row][col] == '.'){

				from[row][col] = -1;
			}else{

				from[row][col] = IND++;
			}
		}
	}

	//Undef
	copy_table(from,base_corn[Undef2]);

	int calc_IND[4] = {8,9,10,11};

	//上下左右
	for(int i = 0; i < 4; i++){

		copy_table(from,work);
		calc_move(dir_array[i],work,to);

		copy_table(to,base_corn[calc_IND[i]]);
	}

	DIR make_map[8][4] = {{U,R},{D,R},{D,L},{U,L},{R,U},{R,D},{L,D},{L,U}};

	//■■[初めて寄った角,そこへ至る動き]で位置を区別する■■
	for(int q = 0; q < 8; q++){

		//■まずは角へ移動
		copy_table(from,work);
		for(int k = 0; k < 2; k++){
			calc_move(make_map[q][k],work,to);
			copy_table(to,work);
		}

		copy_table(work,base_corn[q]);


		//■現在の状態から、時計、反時計に一周する
		DIR2 now_dir = dir2_array[q];
		if(is_special(now_dir)){

			now_dir = swap_dir2[now_dir];
		}

		//時計
		{
			copy_table(work,TMP);

			for(int i = 0; i < 4; i++){

				calc_move(cw_move[now_dir][i],TMP,WORK);
				copy_table(WORK,TMP);
			}

			vector<Trans> ret = calc_trans(work,TMP);

			for(int k = 0; k < ret.size(); k++){

				just_move[Clock][0][q][ret[k].pre_row][ret[k].pre_col].set(ret[k].now_row,ret[k].now_col);
			}

		}

		//反時計
		{
			copy_table(work,TMP);

			for(int i = 0; i < 4; i++){

				calc_move(rev_move[now_dir][i],TMP,WORK);
				copy_table(WORK,TMP);
			}

			vector<Trans> ret = calc_trans(work,TMP);

			for(int k = 0; k < ret.size(); k++){

				just_move[Rev][0][q][ret[k].pre_row][ret[k].pre_col].set(ret[k].now_row,ret[k].now_col);
			}
		}
	}

	//■ダブリング計算(角にいる場合のみ)
	for(int d = 1; d <= MAX; d++){
		for(int i = 0; i < 8; i++){
			for(int k = 0; k < 2; k++){
				Type type = type_array[k];

				for(int row = 0; row < N; row++){
					for(int col = 0; col < N; col++){

						int mid_row = just_move[type][d-1][i][row][col].row;
						int mid_col = just_move[type][d-1][i][row][col].col;

						int to_row = just_move[type][d-1][i][mid_row][mid_col].row;
						int to_col = just_move[type][d-1][i][mid_row][mid_col].col;

						just_move[type][d][i][row][col].set(to_row,to_col);
					}
				}
			}
		}
	}
}

bool isNUM(char ch){

	return ch >= '0' && ch <= '9';
}

bool is_ud(vector<char> vec){

	return vec.size() > 0 && (vec.back() == 'U' || vec.back() == 'D');
}

bool is_lr(vector<char> vec){

	return vec.size() > 0 && (vec.back() == 'L' || vec.back() == 'R');
}

//■出発位置ごとに、回転数と余り、移動先を計算する
vector<Roll> calc_normal(int head,int tail){

	vector<Roll> ret;

	for(int a = 0; a < 13; a++){

		DIR2 now_dir = dir2_array[a];
		DIR2 base_dir = dir2_array[a];

		if(is_special(base_dir)){

			now_dir = swap_dir2[now_dir];
		}

		DIR2 first_base = base_dir;
		DIR2 first_now = now_dir;

		vector<char> vec;

		ll num_roll = 0;

		for(int i = head; i <= tail; i++){

			if(!is_corner(base_dir)){ //まだ角に寄ってない

				if(now_dir == Undef2){ //■■初期状態

					switch(line[i]){
					case 'U':
						now_dir = U2;
						break;
					case 'R':
						now_dir = R2;
						break;
					case 'D':
						now_dir = D2;
						break;
					case 'L':
						now_dir = L2;
						break;
					}

				}else if(now_dir == U2){

					switch(line[i]){
					case 'U':

						//Do nothing
						break;
					case 'R':
						now_dir = UR;
						base_dir = UR;
						break;
					case 'D':
						now_dir = D2;
						break;
					case 'L':
						now_dir = UL;
						base_dir = UL;
						break;
					}

				}else if(now_dir == R2){

					switch(line[i]){
					case 'U':
						now_dir = UR;  //■■■■■■■■■■■■■■now_dirはUR,RUをまとめて、base_dirはURとURを区別するので注意■■■■■■■■■■■■■■
						base_dir = RU; //■■以下同様に注意■■
						break;
					case 'R':
						//Do nothing
						break;
					case 'D':
						now_dir = DR;
						base_dir = RD;
						break;
					case 'L':
						now_dir = L2;
						break;
					}

				}else if(now_dir == D2){

					switch(line[i]){
					case 'U':
						now_dir = U2;
						break;
					case 'R':
						now_dir = DR;
						base_dir = DR;
						break;
					case 'D':
						//Do nothing
						break;
					case 'L':
						now_dir = DL;
						base_dir = DL;
						break;
					}

				}else{ //now_dir == L2

					switch(line[i]){
					case 'U':
						now_dir = UL;
						base_dir = LU;
						break;
					case 'R':
						now_dir = R2;
						break;
					case 'D':
						now_dir = DL;
						base_dir = LD;
						break;
					case 'L':
						//Do nothing
						break;
					}
				}

			}else{ //■角に寄っている

				//意味のない動きをはじく
				if(now_dir == UR){

					if(line[i] == 'U' || line[i] == 'R')continue;

				}else if(now_dir == DR){

					if(line[i] == 'D' || line[i] == 'R')continue;

				}else if(now_dir == DL){

					if(line[i] == 'D' || line[i] == 'L')continue;

				}else if(now_dir == UL){

					if(line[i] == 'U' || line[i] == 'L')continue;
				}

				if(line[i] == 'L' || line[i] == 'R'){

					if(is_lr(vec)){

						//■反対動で、前回の移動が無効化
						vec.pop_back();

					}else{

						vec.push_back(line[i]);
					}

				}else{

					if(is_ud(vec)){

						//■反対動で、前回の移動が無効化
						vec.pop_back();

					}else{

						vec.push_back(line[i]);
					}
				}

				DIR tmp_dir;
				switch(line[i]){
				case 'U':
					tmp_dir = U;
					break;
				case 'R':
					tmp_dir = R;
					break;
				case 'D':
					tmp_dir = D;
					break;
				case 'L':
					tmp_dir = L;
					break;
				}

				//■現在寄っている角(基準角とは異なる→基準角は最初に寄った角)
				now_dir = corner_next[now_dir][tmp_dir];

				if(vec.size() == 4){

					if(vec[0] == 'U'){

						if(vec[1] == 'R'){

							num_roll += 4;

						}else{ //vec[1] == 'L'

							num_roll -= 4;
						}

					}else if(vec[0] == 'D'){

						if(vec[1] == 'R'){

							num_roll -= 4;

						}else{ //vec[1] == 'L'

							num_roll += 4;
						}

					}else if(vec[0] == 'R'){

						if(vec[1] == 'U'){

							num_roll -= 4;

						}else{ //vec[1] == 'D'

							num_roll += 4;
						}

					}else{ //vec[0] == 'L'

						if(vec[1] == 'U'){

							num_roll += 4;
						}else{

							num_roll -= 4;
						}
					}

					vec.clear();
				}
			}
		}

		Roll roll;
		roll.base_dir = base_dir;

		if(!is_corner(base_dir)){ //角に寄らない

			roll.base_dir = now_dir; //■■注意■■

		}else{ //角に寄る

			//■余りの処理
			if(vec.size() > 0){

				ll s = vec.size();

				DIR2 t_dir = base_dir;

				if(is_special(t_dir)){

					t_dir = swap_dir2[t_dir];
				}

				switch(t_dir){
				case UR:
					if(vec[0] == 'D'){

						num_roll += s;
					}else{

						num_roll -= s;
					}
					break;
				case DR:
					if(vec[0] == 'L'){

						num_roll += s;
					}else{

						num_roll -= s;
					}
					break;
				case DL:
					if(vec[0] == 'U'){

						num_roll += s;
					}else{

						num_roll -= s;
					}
					break;
				case UL:
					if(vec[0] == 'R'){

						num_roll += s;
					}else{

						num_roll -= s;
					}
					break;
				}
			}
		}

		roll.num_roll = num_roll;
		ret.push_back(roll);
	}
	return ret;
}

void move_table(Type type,DIR2 base_dir,int table[SIZE][SIZE],ll digit){

	int work[SIZE][SIZE];
	init_table(work);

	for(int row = 0; row < N; row++){
		for(int col = 0; col < N; col++){
			if(table[row][col] == -1)continue;

			int to_row = just_move[type][digit][base_dir][row][col].row;
			int to_col = just_move[type][digit][base_dir][row][col].col;

			work[to_row][to_col] = table[row][col];
		}
	}

	copy_table(work,table);
}



//base_dirを出発点として、num_roll回転した時、現在どの角にいるか
DIR2 calc_corner(DIR2 base_dir,ll num_roll){

	DIR2 tmp_c  = base_dir;
	if(is_special(base_dir)){

		tmp_c = swap_dir2[base_dir];
	}

	if(abs(num_roll)%4 == 0){

		return tmp_c;
	}

	ll mod = abs(num_roll)%4;

	//printf("now:%s mod:%lld\n",DEB[now].c_str(),mod);

	if(num_roll > 0){

		return cw_next[tmp_c][mod];

	}else{

		return rev_next[tmp_c][mod];
	}
}

//■実際にテーブルを回転させる
void move_func(int table[SIZE][SIZE],Roll tmp_roll){

	int work[SIZE][SIZE];

	//角に到達していない場合
	if(!is_corner(tmp_roll.base_dir)){

		//printf("base_dir:%d\n",tmp_roll.base_dir);

		calc_move(convert[tmp_roll.base_dir],table,work);
		copy_table(work,table);
		return;
	}

	//まずは角まで移動させる
	switch(tmp_roll.base_dir){
	case UR:
		calc_move(U,table,work);
		copy_table(work,table);
		calc_move(R,table,work);
		copy_table(work,table);
		break;
	case DR:
		calc_move(D,table,work);
		copy_table(work,table);
		calc_move(R,table,work);
		copy_table(work,table);
		break;
	case DL:
		calc_move(D,table,work);
		copy_table(work,table);
		calc_move(L,table,work);
		copy_table(work,table);
		break;
	case UL:
		calc_move(U,table,work);
		copy_table(work,table);
		calc_move(L,table,work);
		copy_table(work,table);
		break;
	case RU:
		calc_move(R,table,work);
		copy_table(work,table);
		calc_move(U,table,work);
		copy_table(work,table);
		break;
	case RD:
		calc_move(R,table,work);
		copy_table(work,table);
		calc_move(D,table,work);
		copy_table(work,table);
		break;
	case LD:
		calc_move(L,table,work);
		copy_table(work,table);
		calc_move(D,table,work);
		copy_table(work,table);
		break;
	case LU:
		calc_move(L,table,work);
		copy_table(work,table);
		calc_move(U,table,work);
		copy_table(work,table);
		break;
	}

	ll mult = abs(tmp_roll.num_roll)/4;
	ll mod = abs(tmp_roll.num_roll)%4;

	//printf("mult:%lld mod:%lld\n",mult,mod);

	Type type = Not;
	if(tmp_roll.num_roll > 0){

		type = Clock;
	}else{

		type = Rev;
	}

	//周回させる
	if(mult != 0){

		for(int d = MAX; d >= 0; d--){
			if(POW[d] > mult)continue;

			move_table(type,tmp_roll.base_dir,table,d);
			mult -= POW[d];
		}
	}

	//余りの処理
	if(mod != 0){

		mod = abs(mod);
		DIR2 now = tmp_roll.base_dir;
		if(is_special(now)){

			now = swap_dir2[now];
		}

		for(int i = 0; i < mod; i++){

			switch(now){
			case UR:
				if(type == Clock){

					calc_move(D,table,work);
					copy_table(work,table);

				}else{

					calc_move(L,table,work);
					copy_table(work,table);
				}
				break;
			case DR:
				if(type == Clock){

					calc_move(L,table,work);
					copy_table(work,table);

				}else{

					calc_move(U,table,work);
					copy_table(work,table);
				}
				break;
			case DL:
				if(type == Clock){

					calc_move(U,table,work);
					copy_table(work,table);

				}else{

					calc_move(R,table,work);
					copy_table(work,table);
				}
				break;
			case UL:
				if(type == Clock){

					calc_move(R,table,work);
					copy_table(work,table);

				}else{

					calc_move(D,table,work);
					copy_table(work,table);
				}
				break;
			}
			if(type == Clock){

				now = cw_next[now][1];

			}else{

				now = rev_next[now][1];
			}
		}
	}
}

vector<Roll> calc_E(int head,int tail){

	int left = head;

	DIR2 BASE_DIR[NUM];
	ll NUM_ROLL[NUM];

	for(int i = 0; i < 13; i++){

		BASE_DIR[i] = dir2_array[i]; //■■元々位置に合った塊の、現在の基準角
		NUM_ROLL[i] = 0;
	}

	while(left <= tail){

		if(line[left] == '('){ //■倍化処理あり

			vector<Roll> vec = calc_E(left+1,close_pos[left]-1);

			int ind = close_pos[left]+1;
			ll tmp_p = 0;

			while(ind <= tail && isNUM(line[ind])){

				tmp_p = 10*tmp_p + (line[ind]-'0');
				ind++;
			}


			ll maxi = MAX;
			while(POW[maxi] > tmp_p){

				maxi--;
			}

			//ダブリングテーブル初期化
			for(int d = 0; d <= maxi; d++){
				for(int i = 0; i < 13; i++){

					roll_pow[i][d].base_dir = Undef2;
					roll_pow[i][d].num_roll = 0;
				}
			}

			/*■■■■■倍化処理■■■■■*/
			for(int i = 0; i < 13; i++){

				roll_pow[i][0].base_dir = vec[i].base_dir;
				roll_pow[i][0].num_roll = vec[i].num_roll;
			}

			//■ダブリング
			for(int d = 1; d <= maxi; d++){
				for(int i = 0; i < 13; i++){

					if(is_corner(roll_pow[i][d-1].base_dir)){ //既に角に寄っている場合

						DIR2 tmp_c = roll_pow[i][d-1].base_dir;
						DIR2 next_c = calc_corner(tmp_c,roll_pow[i][d-1].num_roll);

						roll_pow[i][d].base_dir = tmp_c; //■一度角に着いたら、以後ずっとそこを基準にする
						roll_pow[i][d].num_roll = roll_pow[i][d-1].num_roll+roll_pow[next_c][d-1].num_roll;

					}else{

						DIR2 mid = roll_pow[i][d-1].base_dir; //まずはmidへ
						DIR2 tmp = roll_pow[mid][d-1].base_dir;

						roll_pow[i][d].base_dir = tmp;

						if(is_corner(tmp)){ //初めて角に着く

							roll_pow[i][d].num_roll = roll_pow[mid][d-1].num_roll;
						}
					}
				}
			}

			for(int i = 0; i < 13; i++){

				DIR2 base_dir = BASE_DIR[i]; //■■呼び出し元の位置iの基準角
				DIR2 now_dir;
				ll num_roll = NUM_ROLL[i];

				if(is_corner(base_dir)){

					now_dir = calc_corner(base_dir,num_roll);  //■位置iの塊が、現在寄っている角
				}

				ll rest = tmp_p;
				for(int d = maxi; d >= 0; d--){
					if(POW[d] > rest)continue;

					if(is_corner(base_dir)){ //基準角が決まっている

						num_roll += roll_pow[now_dir][d].num_roll;
						now_dir = calc_corner(base_dir,num_roll);

					}else{

						base_dir = roll_pow[base_dir][d].base_dir;  //次の基準角
						if(is_corner(base_dir)){ //新しく基準角が決まる

							num_roll += roll_pow[base_dir][d].num_roll;
							now_dir = calc_corner(base_dir,num_roll);

						}
					}
					rest -= POW[d];
				}

				BASE_DIR[i] = base_dir;
				NUM_ROLL[i] = num_roll;
			}

			left = ind;

		}else{ //■倍化処理なし

			int right = left;
			while(right <= tail && line[right] != '(')right++;
			right--;

			//この間に括弧なし
			vector<Roll> vec = calc_normal(left,right);

			for(int i = 0; i < 13; i++){
				if(is_corner(BASE_DIR[i])){

					DIR2 now_dir = calc_corner(BASE_DIR[i],NUM_ROLL[i]);
					NUM_ROLL[i] += vec[now_dir].num_roll; //既に角にいる場合は、回転数だけ足す

				}else{

					DIR2 base_dir = vec[BASE_DIR[i]].base_dir;
					if(is_corner(base_dir)){

						NUM_ROLL[i] += vec[BASE_DIR[i]].num_roll;
					}
					BASE_DIR[i] = base_dir;
				}
			}
			left = right+1;
		}
	}

	vector<Roll> ret;

	for(int i = 0; i < 13; i++){
		Roll tmp_roll;
		tmp_roll.base_dir = BASE_DIR[i];
		tmp_roll.num_roll = NUM_ROLL[i];

		ret.push_back(tmp_roll);
	}
	return ret;
}


void func(){

	for(int row = 0; row < N; row++){

		scanf("%s",input[row]);
	}

	scanf("%s",line);

	init();


   /*if(DEBUG){
		for(int i = 0; i < 13; i++){

			printf("\n\n%d:\n",i);
			for(int row = 0; row < N; row++){
				for(int col = 0; col < N; col++){

					printf(" %d",base_corn[i][row][col]);
				}
				printf("\n");
			}
		};
		return;
	}*/



	for(LEN = 0; line[LEN] != '\0'; LEN++);

	//括弧の対応を前計算
	stack<int> ST;
	for(int i = 0; i < LEN; i++){
		if(line[i] == '('){

			ST.push(i);

		}else if(line[i] == ')'){

			close_pos[ST.top()] = i;
			ST.pop();
		}
	}

	init_table(MAP);

	map<int,pair<int,int>> MEMO;

	int IND = 0;
	for(int row = 0; row < N; row++){
		for(int col = 0; col < N; col++){
			if(input[row][col] == '.'){

				MAP[row][col] = -1;
				continue;
			}

			MAP[row][col] = IND;
			MEMO[IND] = make_pair(row,col);
			IND++;
		}
	}


	vector<Roll> ret = calc_E(0,LEN-1);

	/*printf("ret[Undef2].base_dir:%d num_roll:%lld\n",ret[Undef2].base_dir,ret[Undef2].num_roll);

	printf("move_func前のMAP\n");
	outPut(MAP);
*/
	move_func(MAP,ret[Undef2]);
/*

	if(DEBUG){
		printf("■最終遷移表■\n");
		for(int row = 0; row < N; row++){
			for(int col = 0; col < N; col++){

				printf(" %d",MAP[row][col]);
			}
			printf("\n");
		}
	}
*/

	char ANS[SIZE][SIZE];

	for(int row = 0; row < N; row++){
		for(int col = 0; col < N; col++){

			ANS[row][col] = '.';
		}
	}

	//回転処理
	for(int row = 0; row < N; row++){
		for(int col = 0; col < N; col++){
			if(MAP[row][col] == -1)continue;

			int tmp_num = MAP[row][col];
			int pre_row = MEMO[tmp_num].first;
			int pre_col = MEMO[tmp_num].second;

			ANS[row][col] = input[pre_row][pre_col];

		}
	}

	for(int row = 0; row < N; row++){
		for(int col = 0; col < N; col++){

			printf("%c",ANS[row][col]);
		}
		printf("\n");
	}
}

int main(){

	POW[0] = 1;
	for(int i = 1; i <= MAX; i++){

		POW[i] = POW[i-1]*2;
	}

	while(true){

		scanf("%d",&N);
		if(N == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 270
memory_kb: 41352
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long ull;

// 方向 0:D 1:R 2:U 3:L
// 状態 0:LU 1:LD 2:RD 3:RU
// 右回りを正とする

int Get[4][4]={
    {1,3,0,0},
    {1,2,0,1},
    {2,2,3,1},
    {2,3,3,0}
};

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

map<char,int> mp; // 方向→数字

void init(vector<vector<int>> &v){
    int n=v[0].size();
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            v[i][j]=0;
        }
    }
}

vector<vector<int>> Down(vector<vector<int>> a){
    vector<vector<int>> b=a;
    init(b);
    int n=a[0].size();
    for(int i=0;i<n;i++){
        int cur=n-1;
        for(int j=n-1;j>=0;j--){
            if(a[j][i]){
                b[cur][i]=a[j][i];
                cur--;
            }
        }
    }
    return b;
}

vector<vector<int>> Right(vector<vector<int>> a){
    vector<vector<int>> b=a;
    init(b);
    int n=a[0].size();
    for(int i=0;i<n;i++){
        int cur=n-1;
        for(int j=n-1;j>=0;j--){
            if(a[i][j]){
                b[i][cur]=a[i][j];
                cur--;
            }
        }
    }
    return b;
}

vector<vector<int>> Up(vector<vector<int>> a){
    vector<vector<int>> b=a;
    init(b);
    int n=a[0].size();
    for(int i=0;i<n;i++){
        int cur=0;
        for(int j=0;j<n;j++){
            if(a[j][i]){
                b[cur][i]=a[j][i];
                cur++;
            }
        }
    }
    return b;
}

vector<vector<int>> Left(vector<vector<int>> a){
    vector<vector<int>> b=a;
    init(b);
    int n=a[0].size();
    for(int i=0;i<n;i++){
        int cur=0;
        for(int j=0;j<n;j++){
            if(a[i][j]){
                b[i][cur]=a[i][j];
                cur++;
            }
        }
    }
    return b;
}

void print_res(vector<vector<int>> s,vector<char> v){
    int n=s[0].size();
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            printf("%c",v[s[i][j]]);
        }
        printf("\n");
    }
}

void solve2(vector<vector<int>> s,string t,vector<char> v){
    reverse(t.begin(), t.end());
    char dir;
    for(char c:t){
        if(c=='R' or c=='L' or c=='D' or c=='U'){
            dir=c; break;
        }
    }
    if(dir=='R')s=Right(s);
    if(dir=='L')s=Left(s);
    if(dir=='U')s=Up(s);
    if(dir=='D')s=Down(s);
    print_res(s,v);
}

int id=0;

vector<pair<int,ll>> solve(string t){
    vector<pair<int,ll>> res(4);
    for(int i=0;i<4;i++){
        res[i]=make_pair(i,0LL);
    }
    for(;id<t.size();id++){
        if(t[id]=='('){
            id++;
            auto R=solve(t);
            id++;
            ll num=0;
            while(id<t.size() and '0'<=t[id] and t[id]<='9'){
                num=num*10+t[id]-'0';
                id++;
            }
            id--;
            // ここで掛け算処理を書く
            vector<vector<pair<int,ll>>> mul(61,vector<pair<int,ll>>(4));
            for(int i=0;i<4;i++){
                mul[0][i]=R[i];
            }
            for(int i=1;i<61;i++){
                for(int j=0;j<4;j++){
                    mul[i][j].first=mul[i-1][mul[i-1][j].first].first;
                    mul[i][j].second=mul[i-1][j].second+mul[i-1][mul[i-1][j].first].second;
                }
            }
            for(int i=60;i>=0;i--){
                if((1LL<<i)&num){
                    for(int j=0;j<4;j++){
                        int cur=res[j].first;
                        res[j].first=mul[i][cur].first;
                        res[j].second+=mul[i][cur].second;
                    }
                }
            }
        }
        else if(t[id]==')'){
            return res;
        }
        else{
            int op=mp[t[id]];
            for(int i=0;i<4;i++){
                int cur=res[i].first;
                res[i].first=Get[cur][op];
                res[i].second+=cnt_rotate[cur][op];
            }
        }
    }
    return res;
}

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n;
    mp['D']=0,mp['R']=1,mp['U']=2,mp['L']=3;
    while(cin >> n,n){
        vector<string> S(n);
        vector<vector<int>> s(n,vector<int>(n));
        for(int i=0;i<n;i++){
            cin >> S[i];
        }
        string t; cin >> t;
        vector<char> V={'.'};
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                if(S[i][j]!='.'){
                    s[i][j]=(int)V.size();
                    V.push_back(S[i][j]);
                }
                else s[i][j]=0;
            }
        }
        if(V.size()==1){
            print_res(s,V); continue;
        }
        bool flag1=true; // UD only
        bool flag2=true; // RL only
        for(char c:t){
            if(c=='R' or c=='L')flag1=false;
            if(c=='U' or c=='D')flag2=false;
        }
        if(flag1^flag2){
            solve2(s,t,V); continue;
        }
        vector<char> dir;
        for(char c:t){
            if(c=='R' or c=='L' or c=='U' or c=='D')dir.push_back(c);
        }
        int cur;
        for(int i=0;i+1<dir.size();i++){
            if(dir[i]=='R' or dir[i]=='L'){
                if(dir[i+1]=='U' or dir[i+1]=='D'){
                    if(dir[i]=='L'){
                        s=Left(s);
                        if(dir[i+1]=='U'){cur=0;s=Up(s);}
                        else{cur=1;s=Down(s);}
                    }
                    else{
                        s=Right(s);
                        if(dir[i+1]=='D'){cur=2;s=Down(s);}
                        else{cur=3;s=Up(s);}
                    }
                    break;
                }
            }
            else{
                if(dir[i+1]=='R' or dir[i+1]=='L'){
                    if(dir[i+1]=='L'){
                        if(dir[i]=='U'){cur=0;s=Up(s);}
                        else{cur=1;s=Down(s);}
                        s=Left(s);
                    }
                    else{
                        if(dir[i]=='D'){cur=2;s=Down(s);}
                        else{cur=3;s=Up(s);}
                        s=Right(s);
                    }
                }
            }
        }
        id=0;
        auto Op=solve(t);
        auto op=Op[cur];
        // cout << op.first << " " << op.second << endl;
        if(cur==3){
            s=Down(s); s=Left(s); s=Up(s);
        }
        else if(cur==2){
            s=Left(s); s=Up(s);
        }
        else if(cur==1){
            s=Up(s);
        }
        auto ss=s;
        ss=Down(ss); ss=Right(ss); ss=Up(ss); ss=Left(ss);
        set<int> used;
        map<int,pair<int,int>> pos1,pos2;
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                pos1[s[i][j]]=make_pair(i,j);
                pos2[ss[i][j]]=make_pair(i,j);
            }
        }
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                if(s[i][j]==0)continue;
                if(used.find(s[i][j])!=used.end())continue;
                int now=s[i][j];
                vector<int> num;
                vector<pair<int,int>> num_pos;
                pair<int,int> cur_pos=make_pair(i,j);
                while(used.find(now)==used.end()){
                    used.insert(now);
                    num.push_back(now);
                    num_pos.push_back(cur_pos);
                    pair<int,int> nx_pos=pos2[now];
                    int nx=s[nx_pos.first][nx_pos.second];
                    now=nx; cur_pos=nx_pos;
                }
                int len=num.size();
                ll cycle=op.second;
                cycle%=len;
                if(cycle<0)cycle+=len;
                for(int k=0;k<len;k++){
                    int kid=(k+cycle)%len;
                    s[num_pos[kid].first][num_pos[kid].second]=num[k];
                }
            }
        }
        if(op.first==1){
            s=Down(s);
        }
        else if(op.first==2){
            s=Down(s); s=Right(s);
        }
        else if(op.first==3){
            s=Down(s); s=Right(s); s=Up(s);
        }
        print_res(s,V);
        // printf("Unsolved\n");
    }
}
accuracy: 1
time_ms: 40
memory_kb: 3372
final_rank: 3

code_snippet: #include <iostream>
#include <string>
#include <cstdio>
#include <vector>
#include <numeric>
#include <cstdlib>
#include <cctype>
using namespace std;

#define ALL(v) begin(v),end(v)
#define REP(i,n) for(int i=0;i<(n);++i)
#define RREP(i,n) for(int i=(n)-1;i>=0;--i)

typedef long long LL;
typedef vector<int> vint;

const int targets[4][9] = {
	{1, 1, 2, 2, 2, 1, 8, 8, 8},
	{3, 2, 2, 3, 4, 4, 4, 3, 2},
	{5, 5, 4, 4, 4, 5, 6, 6, 6},
	{7, 8, 8, 7, 6, 6, 6, 7, 8}
};

int getdir(char c){
	switch(c){
		case 'R': return 0;
		case 'U': return 1;
		case 'L': return 2;
		case 'D': return 3;
	}
	abort();
}

struct solver{
	int n;
	solver(int n_) : n(n_) {}
	vector<vint> ids[9];
	vint trs[4];
	vint unit;
	const char *p;
	
	vint mul(const vint &x, const vint &y){
		int sz = x.size();
		vint ret(sz);
		REP(i, sz){ ret[i] = y[x[i]]; }
		return ret;
	}
	
	vint pow(vint x, LL y){
		vint a = unit;
		while(y){
			if(y & 1){ a = mul(a, x); }
			x = mul(x, x);
			y >>= 1;
		}
		return a;
	}
	
	vint parse(){
		vint a = unit;
		vint b;
		while(1){
			if(*p == '('){
				++p;
				vint x = parse();
				++p;
				char *endp;
				LL r = strtoll(p, &endp, 10);
				p = endp;
				b = pow(x, r);
			}
			else if(isalpha(*p)){
				int dir = getdir(*p);
				++p;
				b = trs[dir];
			}
			else{ break; }
			a = mul(a, b);
		}
		return a;
	}
	
	void solve(){
		vector<string> in0(n);
		REP(i, n){ cin >> in0[i]; }
		string op;
		cin >> op;

		int fstdir = -1;
		for(char c : op){
			if(isalpha(c)){
				fstdir = getdir(c);
				break;
			}
		}

		vector<string> in(n, string(n, '.'));
		if(fstdir == 0){
			REP(y, n){
				int u = n - 1;
				RREP(x, n){
					if(in0[y][x] != '.'){
						in[y][u--] = in0[y][x];
					}
				}
			}
		}
		else if(fstdir == 1){
			REP(x, n){
				int u = 0;
				REP(y, n){
					if(in0[y][x] != '.'){
						in[u++][x] = in0[y][x];
					}
				}
			}
		}
		else if(fstdir == 2){
			REP(y, n){
				int u = 0;
				REP(x, n){
					if(in0[y][x] != '.'){
						in[y][u++] = in0[y][x];
					}
				}
			}
		}
		else{
			REP(x, n){
				int u = n - 1;
				RREP(y, n){
					if(in0[y][x] != '.'){
						in[u--][x] = in0[y][x];
					}
				}
			}
		}

		REP(i, 9){
			ids[i].assign(n, vint(n, -1));
		}

		int id = 0;
		REP(i, n)
		REP(j, n){
			if(in[i][j] != '.'){
				ids[0][i][j] = id;
				++id;
			}
		}
		int pcnt = id;

		REP(i, 4){ trs[i].assign(9 * pcnt, -1); }
		unit.resize(9 * pcnt);
		iota(ALL(unit), 0);

		REP(from, 9){
			int to, dir;

			dir = 0;
			to = targets[dir][from];
			id = to * pcnt;
			REP(y, n){
				int u = n - 1;
				RREP(x, n){
					if(ids[from][y][x] >= 0){
						int &r = ids[to][y][u];
						--u;
						if(r == -1){ r = id++; }
						trs[dir][ids[from][y][x]] = r;
					}
				}
			}

			dir = 1;
			to = targets[dir][from];
			id = to * pcnt;
			REP(x, n){
				int u = 0;
				REP(y, n){
					if(ids[from][y][x] >= 0){
						int &r = ids[to][u][x];
						++u;
						if(r == -1){ r = id++; }
						trs[dir][ids[from][y][x]] = r;
					}
				}
			}

			dir = 2;
			to = targets[dir][from];
			id = to * pcnt;
			REP(y, n){
				int u = 0;
				REP(x, n){
					if(ids[from][y][x] >= 0){
						int &r = ids[to][y][u];
						++u;
						if(r == -1){ r = id++; }
						trs[dir][ids[from][y][x]] = r;
					}
				}
			}

			dir = 3;
			to = targets[dir][from];
			id = to * pcnt;
			REP(x, n){
				int u = n - 1;
				RREP(y, n){
					if(ids[from][y][x] >= 0){
						int &r = ids[to][u][x];
						--u;
						if(r == -1){ r = id++; }
						trs[dir][ids[from][y][x]] = r;
					}
				}
			}
		}
		
		p = op.c_str();
		vint res = parse();

		vector<char> val(9 * pcnt);
		REP(y, n)
		REP(x, n){
			int k = ids[0][y][x];
			if(k >= 0){
				val[res[k]] = in[y][x];
			}
		}
		vector<string> ans(n, string(n, '.'));
		REP(i, 9)
		REP(y, n)
		REP(x, n){
			int k = ids[i][y][x];
			if(k >= 0 && val[k] != 0){
				ans[y][x] = val[k];
			}
		}
		
		REP(i, n){
			cout << ans[i] << '\n';
		}
	}
};

int main(){
	int n;
	while(cin >> n && n){
		solver(n).solve();
	}
}
accuracy: 1
time_ms: 420
memory_kb: 7796
final_rank: 5