Problem:
Problem I:
Hobby on Rails
ICPC (International Connecting Points Company) starts to sell a new railway toy. It consists
of a toy tramcar and many rail units on square frames of the same size. There are four types
of rail units, namely, straight (S), curve (C), left-switch (L) and right-switch (R) as shown in
Figure 9. A switch has three ends, namely, branch/merge-end (B/M-end), straight-end (S-end)
and curve-end (C-end).
A switch is either in "through" or "branching" state. When the tramcar comes from B/M-end,
and if the switch is in the through-state, the tramcar goes through to S-end and the state changes
to branching; if the switch is in the branching-state, it branches toward C-end and the state
changes to through. When the tramcar comes from S-end or C-end, it goes out from B/M-end
regardless of the state. The state does not change in this case.
Kids are given rail units of various types that fill a rectangle area of
w
×
h
, as shown in Fig-
ure 10(a). Rail units meeting at an edge of adjacent two frames are automatically connected.
Each rail unit may be independently rotated around the center of its frame by multiples of 90
degrees in order to change the connection of rail units, but its position cannot be changed.
Kids should make "valid" layouts by rotating each rail unit, such as getting Figure 10(b) from
Figure 10(a). A layout is valid when all rails at three ends of every switch are directly or
indirectly connected to an end of another switch or itself. A layout in Figure 10(c) is invalid as
well as Figure 10(a). Invalid layouts are frowned upon.
When a tramcar runs in a valid layout, it will eventually begin to repeat the same route forever.
That is, we will eventually find the tramcar periodically comes to the same running condition,
which is a triple of the tramcar position in the rectangle area, its direction, and the set of the
states of all the switches.
A periodical route is a sequence of rail units on which the tramcar starts from a rail unit with
a running condition and returns to the same rail unit with the same running condition for the first time. A periodical route through a switch or switches is called the "fun route", since kids
like the rattling sound the tramcar makes when it passes through a switch. The tramcar takes
the same unit time to go through a rail unit, not depending on the types of the unit or the
tramcar directions. After the tramcar starts on a rail unit on a “fun route”, it will come back to
the same unit with the same running condition, sooner or later. The fun time
T
of a fun route
is the number of time units that the tramcar takes for going around the route.
Of course, kids better enjoy layouts with longer fun time. Given a variety of rail units placed
on a rectangular area, your job is to rotate the given rail units appropriately and to find the fun
route with the longest fun time in the valid layouts.
For example, there is a fun route in Figure 10(b). Its fun time is 24. Let the toy tramcar start
from
...(truncated)

Submitted solutions:

code_snippet: #include<iostream>
#include<cassert>
using namespace std;
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)

#define N 0
#define E 1
#define S 2
#define W 3

int dx[]={0,1,0,-1};
int dy[]={-1,0,1,0};
int curdir[]={S,W,N,E};

int sd[2][4]={//S default:0 -
  -1,W,-1,E,
  S,-1,N,-1,
};

int cd[4][4]={//C default:0 -^
  W,-1,-1,N,
  E,N,-1,-1,
  -1,S,E,-1,
  -1,-1,W,S,
};

int ld[4][2][4]={//if switch == 0 ld[i][0], switch == 1 ld[i][1] 
  //ST        //CURVE
  W,W,-1,E, W,W,-1,N,
  S,N,N,-1, E,N,N,-1,
  -1,W,E,E, -1,S,E,E,
  S,-1,N,S, S,-1,W,S
  /*
  {W,W,-1,E},{W,W,-1,N},
  {S,N,N,-1},{E,N,N,-1},
  {-1,W,E,E},{-1,S,E,E},
  {S,-1,N,S},{S,-1,W,S}
  */
};


int rd[4][2][4]={//if switch == 0 ld[i][0], switch == 1 ld[i][1] 
  //ST        //CURVE
  -1,W,W,E, -1,W,W,S,
  S,-1,N,N, W,-1,N,N,
  E,W,-1,E, E,N,-1,E,
  S,S,N,-1, S,S,E,-1
  /*
  {-1,W,W,E},{-1,W,W,S},
  {S,-1,N,N},{W,-1,N,N},
  {E,W,-1,E},{E,N,-1,E},
  {S,S,N,-1},{S,S,E,-1}
  */
};

int switchid[6][6];
int rot[6][6];
char m[6][6];

int    cost[6][6][4][(1<<6)];
int visited[6][6][4][(1<<6)];
int ans;

void dfs(int r,int c,int y,int x,int d,int state,int visnow,int length){
  if (length != 0)d=curdir[d];

  if (x == -1||y == -1||x==c||y==r)return;

  if (visited[y][x][d][state] == -1){
    
  }else if (visited[y][x][d][state] == visnow){
    ans=max(ans,length-cost[y][x][d][state]);
    return;
  }else {
    return;
  }
  visited[y][x][d][state]=visnow;
  cost[y][x][d][state]   =length;

  int nextd;
  int curgrid=rot[y][x];
  if (m[y][x] == 'S'){
    nextd=sd[curgrid][d];
    dfs(r,c,y+dy[nextd],x+dx[nextd],nextd,state,visnow,length+1);
  }else if( m[y][x] == 'C'){
    nextd=cd[curgrid][d];
    dfs(r,c,y+dy[nextd],x+dx[nextd],nextd,state,visnow,length+1);
  }else if (m[y][x] == 'L'){
    bool isswitch=(((1<<switchid[y][x])&state)!=0);
    nextd=ld[curgrid][isswitch][d];
    if ((rot[y][x]+3)%4 == d){
      if (isswitch)state-=(1<<switchid[y][x]);
      else         state+=(1<<switchid[y][x]);
    }
    dfs(r,c,y+dy[nextd],x+dx[nextd],nextd,state,visnow,length+1);
  }else if (m[y][x] == 'R'){
    bool isswitch=(((1<<switchid[y][x])&state)!=0);
    nextd=rd[curgrid][isswitch][d];
    if ((rot[y][x]+3)%4==d){
      if (isswitch)state-=(1<<switchid[y][x]);
      else         state+=(1<<switchid[y][x]);
    }
    dfs(r,c,y+dy[nextd],x+dx[nextd],nextd,state,visnow,length+1);
  }
}

void solve(int r,int c,int index){
  rep(i,r){
    rep(j,c){
      rep(k,4){
	rep(l,(1<<index)){
	  visited[i][j][k][l]=-1;
	}
      }
    }
  }
  
  int visnow=0;
  rep(i,r){
    rep(j,c){
      if (m[i][j] == 'R'||m[i][j] == 'L'){
	if (rot[i][j] == 0){
	  dfs(r,c,i,j,W,0,visnow,0);
	}else if (rot[i][j] == 1){
	  dfs(r,c,i,j,N,0,visnow,0);
	}else if (rot[i][j] == 2){
	  dfs(r,c,i,j,E,0,visnow,0);
	}else if (rot[i][j] == 3){
	  dfs(r,c,i,j,S,0,visnow,0);
	}
	visnow++;
      }
    }
  }
}


//if rot[i][j] == -1 unvisited
void search(int r,int c,int index,int now,int num,//num -> 3 position of L or R
	    int y,int x,int d,int *posx,int *posy,bool tonext){

  if (tonext && num == 0 && index == now+1){
    solve(r,c,index);
    return;
  }


  if (tonext){
    
    if (num == 0){//straight
      now++;
      y = posy[now];
      x = posx[now];

      d = (rot[y][x]+3)%4;
      search(r,c,index,now,1,posy[now]+dy[d],posx[now]+dx[d],
	     d,posx,posy,false);
    }else if (num == 1){
      y = posy[now];
      x = posx[now];
      d=(rot[y][x]+1)%4;
      search(r,c,index,now,2,posy[now]+dy[d],posx[now]+dx[d],
	     d,posx,posy,false);
    }else if (num == 2){//curve
      y = posy[now];
      x = posx[now];
      if (m[y][x] == 'R'){
	d=(rot[y][x]+2)%4;
      }else if (m[posy[now]][posx[now]]=='L'){
	d=rot[y][x];
      }
      search(r,c,index,now,0,posy[now]+dy[d],posx[now]+dx[d],
	     d,posx,posy,false);
      
    }
    return;
  }

  if (x == -1 || y == -1||x==c||y==r)return;
  d=curdir[d];

  if (m[y][x] == 'S'){
    if (rot[y][x] == -1){
      if      (d == E || d == W)rot[y][x]=0;
      else if (d == S || d == N)rot[y][x]=1;
      search(r,c,index,now,num,y+dy[sd[rot[y][x]][d]],x+dx[sd[rot[y][x]][d]],
	     sd[rot[y][x]][d],posx,posy,false);
      rot[y][x]=-1;
      return;
    }else if (rot[y][x] != -1){
      if (sd[rot[y][x]][d] == -1)return;
      else search(r,c,index,now,num,-1,-1,-1,posx,posy,true);
    }
  }else if(m[y][x] == 'C'){
    if (rot[y][x] == -1){
      if      (d == E)rot[y][x]=1;
      else if (d == W)rot[y][x]=3;
      else if (d == S)rot[y][x]=2;
      else if (d == N)rot[y][x]=0;
      search(r,c,index,now,num,y+dy[cd[rot[y][x]][d]],x+dx[cd[rot[y][x]][d]],
	     cd[rot[y][x]][d],posx,posy,false);
      if      (d == E)rot[y][x]=2;
      else if (d == W)rot[y][x]=0;
      else if (d == S)rot[y][x]=3;
      else if (d == N)rot[y][x]=1;
      search(r,c,index,now,num,y+dy[cd[rot[y][x]][d]],x+dx[cd[rot[y][x]][d]],
	     cd[rot[y][x]][d],posx,posy,false);
      rot[y][x]=-1;
    }else if (rot[y][x] != -1){
      if (cd[rot[y][x]][d] == -1)return;
      else search(r,c,index,now,num,-1,-1,-1,posx,posy,true);
    }
  }else if (m[y][x] == 'L'){
    if (ld[rot[y][x]][0][d] == -1)return;
    search(r,c,index,now,num,-1,-1,-1,posx,posy,true);
  }else if (m[y][x] == 'R'){
    if (rd[rot[y][x]][0][d] == -1)return;
    search(r,c,index,now,num,-1,-1,-1,posx,posy,true);
  }
}


void decide(int r,int c,int index,int now,int *posx,int *posy){
  if (now == index){
    search(r,c,index,-1,0,-1,-1,-1,posx,posy,true);
    return;
  }
  rep(i,4){
    rot[posy[now]][posx[now]]=i;
    decide(r,c,index,now+1,posx,posy);
  }
}

main(){
  int r,c;
  while(cin>>c>>r && c){
    int index =0;
    int posx[6],posy[6];
    rep(i,r){
      rep(j,c){
	cin>>m[i][j];
	rot[i][j]=-1;
	if (m[i][j] == 'R'||m[i][j]=='L'){
	  switchid[i][j]=index;
	  posy[index]=i;
	  posx[index]=j;
	  index++;
	}
      }
    }

    ans = 0;
    decide(r,c,index,0,posx,posy);
    cout << ans << endl;
  }
}
accuracy: 1
time_ms: 30
memory_kb: 3136
final_rank: 4

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 1000000000000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



enum Type{
	S,
	C,
	L,
	R,
};

enum DIR{
	North,
	East,
	West,
	South,
	None,
};

struct LOC{
	LOC(){

		row = col = 0;
	}
	LOC(int arg_row,int arg_col){
		row = arg_row;
		col = arg_col;
	}
	int row,col;
};


int W,H;
int num_state[4] = {2,4,4,4};
int num_pos[4] = {2,2,3,3};
int diff_row[4] = {-1,0,0,1},diff_col[4] = {0,1,-1,0};
int num_switch;
int ANS;

//どの方向に枝が伸びているか
DIR dir_state[4][4][4] = {{{East,West,None,None},{North,South,None,None},{None,None,None,None},{None,None,None,None}},
				   {{North,West,None,None},{West,South,None,None},{East,South,None,None},{North,East,None,None}},
				   {{West,North,East,None},{North,East,South,None},{East,West,South,None},{South,North,West,None}}, //★位置0がB/M★
				   {{West,East,South,None},{North,West,South,None},{East,North,West,None},{South,North,East,None}}, //★位置0がB/M★
 	 	 	 	  };

//next_dir[Type][state][★方位★]
DIR next_dir[2][4][4] = {{{None,West,East,None},{South,None,None,North},{None,None,None,None},{None,None,None,None}},
				   {{West,None,North,None},{None,None,South,West},{None,South,None,East},{East,North,None,None}}
 	 	 	 	  };

//next_dir_switch[Lが0,Rが1][非straightなら0,straightなら1][state][★方位★]
DIR next_dir_switch[2][2][4][4] ={
								  {//L
								    { //非
								      {West,West,North,None},{East,North,None,North},{None,South,East,East},{South,None,South,West}
								    },
									{ //straight
										{West,West,East,None},{South,North,None,North},{None,West,East,East},{South,None,South,North}
									}
								  },
								  {//R
									{//非
										{None,West,South,West},{West,None,North,North},{East,North,East,None},{South,South,None,East}
									},
									{ //straight
									  {None,West,East,West},{South,None,North,North},{East,West,East,None},{South,South,None,North}
									}
								  }
								};


DIR dir_array[5] = {North,East,West,South,None},rev_dir[5] = {South,West,East,North,None};
int POW[7];
int index_table[10][10];
bool is_straight[10];
char table[10][10];
LOC switch_loc[10];



bool rangeCheck(int row,int col){

	return row >= 0 && row <= H-1 && col >= 0 && col <= W-1;
}

int makeCode(){

	int ret = 0;

	for(int i = 0; i < num_switch; i++){
		if(is_straight[i]){

			ret += POW[i];
		}
	}
	return ret;
}


void calc_ans(int STATE[6][6]){

	int TIME[6][6][4][64];

	int ans = 0;

	for(int i = 0; i < num_switch; i++){ //始点のスイッチ

		int base_row = switch_loc[i].row;
		int base_col = switch_loc[i].col;

		Type type;
		if(table[base_row][base_col] == 'L'){

			type = L;
		}else{

			type = R;
		}

		int tmp_state = STATE[base_row][base_col];

		DIR bm_dir = dir_state[type][tmp_state][0];
		DIR dir,pre_dir;

		int tmp_row,tmp_col;
		int next_row,next_col;

		for(int loop = 0; loop < 2; loop++){

			for(int k = 0; k < num_switch; k++){

				is_straight[k] = true;
			}

			for(int row = 0; row < H; row++){
				for(int col = 0; col < W; col++){
					for(int a = 0; a < 4; a++){
						for(int state = 0; state < POW[num_switch]; state++){

							TIME[row][col][a][state] = -1;
						}
					}
				}
			}

			if(loop == 0){//最初にbmが切り替わらない方向

				dir = bm_dir;

				switch(bm_dir){
				case North:

					tmp_row = base_row+1;
					tmp_col = base_col;
					break;

				case East:

					tmp_row = base_row;
					tmp_col = base_col-1;

					break;

				case West:

					tmp_row = base_row;
					tmp_col = base_col+1;

					break;
				case South:

					tmp_row = base_row-1;
					tmp_col = base_col;
					break;
				}

			}else{ //最初にbmを踏む方向

				switch(bm_dir){
				case North:

					tmp_row = base_row-1;
					tmp_col = base_col;
					dir = South;
					break;

				case East:

					tmp_row = base_row;
					tmp_col = base_col+1;
					dir = West;

					break;

				case West:

					tmp_row = base_row;
					tmp_col = base_col-1;
					dir = East;

					break;
				case South:

					tmp_row = base_row+1;
					tmp_col = base_col;
					dir = North;
					break;
				}
			}

			TIME[tmp_row][tmp_col][dir][makeCode()] = 0;

			int tmp_time = 0;

			while(true){

				switch(dir){
				case North:

					next_row = tmp_row-1;
					next_col = tmp_col;
					break;
				case East:

					next_row = tmp_row;
					next_col = tmp_col+1;
					break;
				case West:

					next_row = tmp_row;
					next_col = tmp_col-1;
					break;
				case South:

					next_row = tmp_row+1;
					next_col = tmp_col;
					break;
				}

				Type check_type;
				switch(table[tmp_row][tmp_col]){
				case 'S':
					check_type = S;
					break;
				case 'C':
					check_type = C;
					break;
				case 'L':
					check_type = L;
					break;
				case 'R':
					check_type = R;
					break;
				}

				if((table[tmp_row][tmp_col] == 'L' || table[tmp_row][tmp_col] == 'R') &&
						pre_dir == rev_dir[dir_state[check_type][STATE[tmp_row][tmp_col]][0]]){ //スイッチの切り替わり

					is_straight[index_table[tmp_row][tmp_col]] = not is_straight[index_table[tmp_row][tmp_col]];
				}

				++tmp_time;
				int tmp_code = makeCode();
				if(TIME[next_row][next_col][dir][tmp_code] != -1){

					ans = max(ans,tmp_time-TIME[next_row][next_col][dir][tmp_code]);
					break;
				}
				TIME[next_row][next_col][dir][tmp_code] = tmp_time;

				tmp_row = next_row;
				tmp_col = next_col;

				pre_dir = dir;

				if(table[tmp_row][tmp_col] == 'L' || table[tmp_row][tmp_col] == 'R'){

					if(table[tmp_row][tmp_col] == 'L'){

						dir = next_dir_switch[0][is_straight[index_table[tmp_row][tmp_col]]][STATE[tmp_row][tmp_col]][rev_dir[dir]];

					}else{

						dir = next_dir_switch[1][is_straight[index_table[tmp_row][tmp_col]]][STATE[tmp_row][tmp_col]][rev_dir[dir]];
					}

				}else{

					if(table[tmp_row][tmp_col] == 'S'){

						dir = next_dir[S][STATE[tmp_row][tmp_col]][rev_dir[dir]];

					}else{

						dir = next_dir[C][STATE[tmp_row][tmp_col]][rev_dir[dir]];
					}
				}
			}
		}
	}

	ANS = max(ANS,ans);
}



void recursive(int base_row,int base_col,bool MUST[6][6],int STATE[6][6],bool check[6][6][4]){

	bool FLG = true;

	//埋めるべきマスが全て埋まったか調べる
	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			if(MUST[row][col] && STATE[row][col] == -1){

				FLG = false;
				break;
			}
		}
		if(!FLG)break;
	}

	if(FLG){
		calc_ans(STATE);
		return;
	}

	int next_row = base_row,next_col = base_col+1;
	if(base_col == W-1){

		if(base_row == H-1){

			next_row = 0;

		}else{

			next_row = base_row+1;
		}

		next_col = 0;

	}

	if(!MUST[base_row][base_col] || STATE[base_row][base_col] != -1){ //現時点では決める必要なし、または決定済

		recursive(next_row,next_col,MUST,STATE,check);
		return;
	}

	Type type;
	switch(table[base_row][base_col]){
	case 'S':
		type = S;
		break;
	case 'C':
		type = C;
		break;
	case 'L':
		type = L;
		break;
	case 'R':
		type = R;
		break;
	}
	vector<LOC> ADD;

	for(int i = 0; i < num_state[type]; i++){

		bool next_MUST[6][6];
		int next_STATE[6][6];
		bool next_check[6][6][4];

		//★★★★★仮引数の配列の値をいじる場合は、その都度使い捨てにしないとバグる★★★★★
		for(int row = 0; row < H; row++){
			for(int col = 0; col < W; col++){
				next_MUST[row][col] = MUST[row][col];
				next_STATE[row][col] = STATE[row][col];
				for(int a = 0; a < 4; a++){

					next_check[row][col][a] = check[row][col][a];
				}
			}
		}

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

			next_check[base_row][base_col][k] = false;
		}

		for(int k = 0; k < num_pos[type]; k++){

			next_check[base_row][base_col][dir_state[type][i][k]] = true;
		}

		bool tmp_FLG = true;
		ADD.clear();

		//自分に向かう辺のチェック(相手の枝が伸びてるのに自分がfalseなら不可)
		for(int k = 0; k < 4; k++){

			int adj_row = base_row+diff_row[k];
			int adj_col = base_col+diff_col[k];

			if(!rangeCheck(adj_row,adj_col)||next_STATE[adj_row][adj_col] == -1)continue;

			if(next_check[adj_row][adj_col][rev_dir[dir_array[k]]] && !next_check[base_row][base_col][dir_array[k]]){

				tmp_FLG = false;
				break;
			}
		}
		if(!tmp_FLG)continue;

		//自分から向かう辺のチェック(自分の枝が相手に伸びてるのに相手がfalseなら不可)
		for(int k = 0; k < 4; k++){

			if(!next_check[base_row][base_col][k])continue;

			int adj_row = base_row+diff_row[k];
			int adj_col = base_col+diff_col[k];

			if(!rangeCheck(adj_row,adj_col)){ //外に枝が向いていたら不可

				tmp_FLG = false;
				break;
			}
			if(next_STATE[adj_row][adj_col] == -1){ //新たにMUSTに加える

				ADD.push_back(LOC(adj_row,adj_col));
				continue;
			}

			if(next_check[base_row][base_col][dir_array[k]] && !next_check[adj_row][adj_col][rev_dir[dir_array[k]]]){

				tmp_FLG = false;
				break;
			}
		}
		if(!tmp_FLG)continue;


		next_STATE[base_row][base_col] = i;
		for(int a = 0; a < ADD.size(); a++){

			next_MUST[ADD[a].row][ADD[a].col] = true;
		}

		recursive(next_row,next_col,next_MUST,next_STATE,next_check);
	}
}


void func(){

	num_switch = 0;
	char buf[2];

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			scanf("%s",buf);
			table[row][col] = buf[0];
			if(buf[0] == 'L' || buf[0] == 'R'){

				switch_loc[num_switch].row = row;
				switch_loc[num_switch].col = col;
				index_table[row][col] = num_switch++;
			}
		}
	}

	ANS = 0;

	int first_STATE[6][6];
	bool first_MUST[6][6],first_check[6][6][4];

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			first_STATE[row][col] = -1;
			first_MUST[row][col] = false;
			for(int a = 0; a < 4; a++){

				first_check[row][col][a] = false;
			}
		}
	}

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

		first_MUST[switch_loc[i].row][switch_loc[i].col] = true;
	}

	recursive(0,0,first_MUST,first_STATE,first_check);

	printf("%d\n",ANS);
	return;
}


int main(){

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

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

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

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 3288
final_rank: 6

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 1000000000000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



enum Type{
	S,
	C,
	L,
	R,
};

enum DIR{
	North,
	East,
	West,
	South,
	None,
};

struct LOC{
	LOC(){

		row = col = 0;
	}
	LOC(int arg_row,int arg_col){
		row = arg_row;
		col = arg_col;
	}
	int row,col;
};


int W,H;
int num_state[4] = {2,4,4,4};
int num_pos[4] = {2,2,3,3};
int diff_row[4] = {-1,0,0,1},diff_col[4] = {0,1,-1,0};
int num_switch;
int ANS;

//どの方向に枝が伸びているか
DIR dir_state[4][4][4] = {{{East,West,None,None},{North,South,None,None},{None,None,None,None},{None,None,None,None}},
				   {{North,West,None,None},{West,South,None,None},{East,South,None,None},{North,East,None,None}},
				   {{West,North,East,None},{North,East,South,None},{East,West,South,None},{South,North,West,None}}, //★位置0がB/M★
				   {{West,East,South,None},{North,West,South,None},{East,North,West,None},{South,North,East,None}}, //★位置0がB/M★
 	 	 	 	  };

//next_dir[Type][state][★方位★]
DIR next_dir[2][4][4] = {{{None,West,East,None},{South,None,None,North},{None,None,None,None},{None,None,None,None}},
				   {{West,None,North,None},{None,None,South,West},{None,South,None,East},{East,North,None,None}} //★位置0がB/M★
 	 	 	 	  };

//next_dir_switch[Lが0,Rが1][非straightなら0,straightなら1][state][★方位★]
DIR next_dir_switch[2][2][4][4] ={
								  {//L
								    { //非
								      {West,West,North,None},{East,North,None,North},{None,South,East,East},{South,None,South,West}
								    },
									{ //straight
										{West,West,East,None},{South,North,None,North},{None,West,East,East},{South,None,South,North}
									}
								  },
								  {//R
									{//非
										{None,West,South,West},{West,None,North,North},{East,North,East,None},{South,South,None,East}
									},
									{ //straight
									  {None,West,East,West},{South,None,North,North},{East,West,East,None},{South,South,None,North}
									}
								  }
								};


DIR dir_array[5] = {North,East,West,South,None},rev_dir[5] = {South,West,East,North,None};
int POW[7];
int index_table[10][10];
bool is_straight[10];
char table[10][10];
LOC switch_loc[10];



bool rangeCheck(int row,int col){

	return row >= 0 && row <= H-1 && col >= 0 && col <= W-1;
}

int makeCode(){

	int ret = 0;

	for(int i = 0; i < num_switch; i++){
		if(is_straight[i]){

			ret += POW[i];
		}
	}
	return ret;
}


void calc_ans(int STATE[6][6]){

	int TIME[6][6][4][64];

	int ans = 0;

	for(int i = 0; i < num_switch; i++){ //始点のスイッチ

		int base_row = switch_loc[i].row;
		int base_col = switch_loc[i].col;

		Type type;
		if(table[base_row][base_col] == 'L'){

			type = L;
		}else{

			type = R;
		}

		int tmp_state = STATE[base_row][base_col];

		DIR bm_dir = dir_state[type][tmp_state][0];
		DIR dir,pre_dir;

		int tmp_row,tmp_col;
		int next_row,next_col;

		for(int loop = 0; loop < 2; loop++){

			for(int k = 0; k < num_switch; k++){

				is_straight[k] = true;
			}

			for(int row = 0; row < H; row++){
				for(int col = 0; col < W; col++){
					for(int a = 0; a < 4; a++){
						for(int state = 0; state < POW[num_switch]; state++){

							TIME[row][col][a][state] = -1;
						}
					}
				}
			}

			if(loop == 0){//最初にbmが切り替わらない方向

				dir = bm_dir;

				switch(bm_dir){
				case North:

					tmp_row = base_row+1;
					tmp_col = base_col;
					break;

				case East:

					tmp_row = base_row;
					tmp_col = base_col-1;

					break;

				case West:

					tmp_row = base_row;
					tmp_col = base_col+1;

					break;
				case South:

					tmp_row = base_row-1;
					tmp_col = base_col;
					break;
				}

			}else{ //最初にbmを踏む方向

				switch(bm_dir){
				case North:

					tmp_row = base_row-1;
					tmp_col = base_col;
					dir = South;
					break;

				case East:

					tmp_row = base_row;
					tmp_col = base_col+1;
					dir = West;

					break;

				case West:

					tmp_row = base_row;
					tmp_col = base_col-1;
					dir = East;

					break;
				case South:

					tmp_row = base_row+1;
					tmp_col = base_col;
					dir = North;
					break;
				}
			}

			TIME[tmp_row][tmp_col][dir][makeCode()] = 0;

			int tmp_time = 0;

			while(true){

				switch(dir){
				case North:
					//printf("北\n");
					next_row = tmp_row-1;
					next_col = tmp_col;
					break;
				case East:
					//printf("東\n");
					next_row = tmp_row;
					next_col = tmp_col+1;
					break;
				case West:
					//printf("西\n");
					next_row = tmp_row;
					next_col = tmp_col-1;
					break;
				case South:
					//printf("南\n");
					next_row = tmp_row+1;
					next_col = tmp_col;
					break;
				}

				Type check_type;
				switch(table[tmp_row][tmp_col]){
				case 'S':
					check_type = S;
					break;
				case 'C':
					check_type = C;
					break;
				case 'L':
					check_type = L;
					break;
				case 'R':
					check_type = R;
					break;
				}

				if((table[tmp_row][tmp_col] == 'L' || table[tmp_row][tmp_col] == 'R') &&
						pre_dir == rev_dir[dir_state[check_type][STATE[tmp_row][tmp_col]][0]]){ //スイッチの切り替わり

					//printf("スイッチ切り替わり\n");
					is_straight[index_table[tmp_row][tmp_col]] = not is_straight[index_table[tmp_row][tmp_col]];
				}

				++tmp_time;
				int tmp_code = makeCode();
				if(TIME[next_row][next_col][dir][tmp_code] != -1){

					//printf("ループ next_row:%d next_col:%d\n",next_row,next_col);

					ans = max(ans,tmp_time-TIME[next_row][next_col][dir][tmp_code]);
					break;
				}
				TIME[next_row][next_col][dir][tmp_code] = tmp_time;

				tmp_row = next_row;
				tmp_col = next_col;

				pre_dir = dir;

				if(table[tmp_row][tmp_col] == 'L' || table[tmp_row][tmp_col] == 'R'){

					if(table[tmp_row][tmp_col] == 'L'){

						dir = next_dir_switch[0][is_straight[index_table[tmp_row][tmp_col]]][STATE[tmp_row][tmp_col]][rev_dir[dir]];

					}else{

						dir = next_dir_switch[1][is_straight[index_table[tmp_row][tmp_col]]][STATE[tmp_row][tmp_col]][rev_dir[dir]];
					}

				}else{

					if(table[tmp_row][tmp_col] == 'S'){

						dir = next_dir[S][STATE[tmp_row][tmp_col]][rev_dir[dir]];

					}else{

						dir = next_dir[C][STATE[tmp_row][tmp_col]][rev_dir[dir]];
					}
				}
			}
		}
	}

	ANS = max(ANS,ans);
}



void recursive(int base_row,int base_col,bool MUST[6][6],int STATE[6][6],bool check[6][6][4]){

	bool FLG = true;

	//埋めるべきマスが全て埋まったか調べる
	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			if(MUST[row][col] && STATE[row][col] == -1){

				FLG = false;
				break;
			}
		}
		if(!FLG)break;
	}

	if(FLG){
		calc_ans(STATE);
		return;
	}

	int next_row = base_row,next_col = base_col+1;
	if(base_col == W-1){

		if(base_row == H-1){

			next_row = 0;

		}else{

			next_row = base_row+1;
		}

		next_col = 0;

	}

	if(!MUST[base_row][base_col] || STATE[base_row][base_col] != -1){ //現時点では決める必要なし、または決定済

		recursive(next_row,next_col,MUST,STATE,check);
		return;
	}

	Type type;
	switch(table[base_row][base_col]){
	case 'S':
		type = S;
		break;
	case 'C':
		type = C;
		break;
	case 'L':
		type = L;
		break;
	case 'R':
		type = R;
		break;
	}
	vector<LOC> ADD;

	for(int i = 0; i < num_state[type]; i++){

		bool next_MUST[6][6];
		int next_STATE[6][6];
		bool next_check[6][6][4];

		for(int row = 0; row < H; row++){
			for(int col = 0; col < W; col++){
				next_MUST[row][col] = MUST[row][col];
				next_STATE[row][col] = STATE[row][col];
				for(int a = 0; a < 4; a++){

					next_check[row][col][a] = check[row][col][a];
				}
			}
		}

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

			next_check[base_row][base_col][k] = false;
		}

		for(int k = 0; k < num_pos[type]; k++){

			next_check[base_row][base_col][dir_state[type][i][k]] = true;
		}

		bool tmp_FLG = true;
		ADD.clear();

		//自分に向かう辺のチェック(相手の枝が伸びてるのに自分がfalseなら不可)
		for(int k = 0; k < 4; k++){

			int adj_row = base_row+diff_row[k];
			int adj_col = base_col+diff_col[k];

			if(!rangeCheck(adj_row,adj_col)||next_STATE[adj_row][adj_col] == -1)continue;

			if(next_check[adj_row][adj_col][rev_dir[dir_array[k]]] && !next_check[base_row][base_col][dir_array[k]]){

				tmp_FLG = false;
				break;
			}
		}
		if(!tmp_FLG)continue;

		//自分から向かう辺のチェック(自分の枝が相手に伸びてるのに相手がfalseなら不可)
		for(int k = 0; k < 4; k++){

			if(!next_check[base_row][base_col][k])continue;

			int adj_row = base_row+diff_row[k];
			int adj_col = base_col+diff_col[k];

			if(!rangeCheck(adj_row,adj_col)){ //外に枝が向いていたら不可

				tmp_FLG = false;
				break;
			}
			if(next_STATE[adj_row][adj_col] == -1){ //新たにMUSTに加える

				ADD.push_back(LOC(adj_row,adj_col));
				continue;
			}

			if(next_check[base_row][base_col][dir_array[k]] && !next_check[adj_row][adj_col][rev_dir[dir_array[k]]]){

				tmp_FLG = false;
				break;
			}
		}
		if(!tmp_FLG)continue;


		next_STATE[base_row][base_col] = i;
		for(int a = 0; a < ADD.size(); a++){

			next_MUST[ADD[a].row][ADD[a].col] = true;
		}

		recursive(next_row,next_col,next_MUST,next_STATE,next_check);
	}
}


void func(){

	num_switch = 0;
	char buf[2];

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			scanf("%s",buf);
			table[row][col] = buf[0];
			if(buf[0] == 'L' || buf[0] == 'R'){

				switch_loc[num_switch].row = row;
				switch_loc[num_switch].col = col;
				index_table[row][col] = num_switch++;
			}
		}
	}

	ANS = 0;

	int first_STATE[6][6];
	bool first_MUST[6][6],first_check[6][6][4];

	for(int row = 0; row < H; row++){
		for(int col = 0; col < W; col++){
			first_STATE[row][col] = -1;
			first_MUST[row][col] = false;
			for(int a = 0; a < 4; a++){

				first_check[row][col][a] = false;
			}
		}
	}

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

		first_MUST[switch_loc[i].row][switch_loc[i].col] = true;
	}

	recursive(0,0,first_MUST,first_STATE,first_check);

	printf("%d\n",ANS);
	return;
}


int main(){

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

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

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

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 3300
final_rank: 7

code_snippet: #include<stdio.h>
#include<vector>
#include<algorithm>
using namespace std;
char in[2];
char t[8][8];
int conv[8][8];
int H,W;
int ret;
int used[20][20];
int pr[8];
int pc[8];
int pd[8];
int lr[4][3]={{1,1,0},{0,2,1},{1,1,2},{2,0,1}};
int lc[4][3]={{0,2,1},{1,1,2},{2,0,1},{1,1,0}};
int rr[4][3]={{1,1,2},{0,2,1},{1,1,0},{2,0,1}};
int rc[4][3]={{0,2,1},{1,1,0},{2,0,1},{1,1,2}};
int at[8][3];
int au[8][3];
int al[8][3];
int ps;
int v[8][3][1<<6];
void go(int a,int b){
	for(int i=0;i<ps;i++)for(int j=0;j<3;j++)for(int k=0;k<(1<<ps);k++)v[i][j][k]=-1;
	int len=0;
	int A=a;
	int B=b;
	int bit=0;
	while(1){
		v[A][B][bit]=len;
		len+=al[A][B]+1;
		int ta=at[A][B];int tb=au[A][B];
		A=ta;
		if(tb==0){
			if(bit&(1<<A))B=1;
			else B=2;
			bit^=(1<<A);
		}else B=0;
		if(~v[A][B][bit])break;
	}
	ret=max(ret,len-v[A][B][bit]);
}
void calc(){
	/*for(int i=0;i<ps;i++){
		for(int j=0;j<3;j++){
			printf("(%d, %d, %d)",at[i][j],au[i][j],al[i][j]);
		}
		printf("\n");
	}
	printf("\n");*/
	for(int i=0;i<ps;i++)for(int j=0;j<3;j++){
		go(i,j);
	}
}
void dfs_route(int P1,int P2,int TR,int TC,int MR,int MC,int L){
	if(MR<0||MC<0||MR>=H||MC>=W)return;
	if(~conv[MR][MC]){
		int M=conv[MR][MC];
		bool ok=false;
		for(int i=0;i<3;i++){
			if(!~at[M][i]&&((t[MR][MC]=='L'&&TR==MR*2+lr[pd[M]][i]&&TC==MC*2+lc[pd[M]][i])||(t[MR][MC]=='R'&&TR==MR*2+rr[pd[M]][i]&&TC==MC*2+rc[pd[M]][i]))){
				at[P1][P2]=M;au[P1][P2]=i;
				at[M][i]=P1;au[M][i]=P2;
				al[P1][P2]=al[M][i]=L;
				ok=true;break;
			}
		}
		if(!ok)return;
		for(int i=0;i<ps;i++){
			for(int j=0;j<3;j++){
				if(!~at[i][j]){
					int sr=pr[i]*2;
					int sc=pc[i]*2;
					int kr=pr[i];int kc=pc[i];
					if(t[pr[i]][pc[i]]=='L'){sr+=lr[pd[i]][j];sc+=lc[pd[i]][j];
					if(lr[pd[i]][j]==0)kr--;if(lr[pd[i]][j]==2)kr++;
					if(lc[pd[i]][j]==0)kc--;if(lc[pd[i]][j]==2)kc++;}
					if(t[pr[i]][pc[i]]=='R'){sr+=rr[pd[i]][j];sc+=rc[pd[i]][j];
					if(rr[pd[i]][j]==0)kr--;if(rr[pd[i]][j]==2)kr++;
					if(rc[pd[i]][j]==0)kc--;if(rc[pd[i]][j]==2)kc++;}
					dfs_route(i,j,sr,sc,kr,kc,0);
					at[at[P1][P2]][au[P1][P2]]=au[at[P1][P2]][au[P1][P2]]=-1;
					at[P1][P2]=au[P1][P2]=-1;
					return;
				}
			}
		}
		calc();
		at[at[P1][P2]][au[P1][P2]]=au[at[P1][P2]][au[P1][P2]]=-1;
		at[P1][P2]=au[P1][P2]=-1;
		return;
	}
	if(used[MR][MC])return;
	used[MR][MC]=1;
	if(t[MR][MC]=='S'){
		int nr,nc,mr,mc;
		if(TR%2){
			nr=TR;nc=MC*4+2-TC;
			mr=MR;mc=(nc-MC-1);
		}else{
			nc=TC;nr=MR*4+2-TR;
			mc=MC;mr=(nr-MR-1);
		}
		dfs_route(P1,P2,nr,nc,mr,mc,L+1);
	}else{
		if(TR%2){
			dfs_route(P1,P2,MR*2,MC*2+1,MR-1,MC,L+1);
			dfs_route(P1,P2,MR*2+2,MC*2+1,MR+1,MC,L+1);
		}else{
			dfs_route(P1,P2,MR*2+1,MC*2,MR,MC-1,L+1);
			dfs_route(P1,P2,MR*2+1,MC*2+2,MR,MC+1,L+1);
		}
	}
	used[MR][MC]=0;
}
void dfs_dir(int a){
	if(a==ps){
		for(int i=0;i<ps;i++)for(int j=0;j<3;j++){
			at[i][j]=au[i][j]=-1;
		}
		for(int i=0;i<H;i++)for(int j=0;j<W;j++)used[i][j]=0;
		int sr=pr[0]*2;
		int sc=pc[0]*2;
		int kr=pr[0];int kc=pc[0];
		if(t[pr[0]][pc[0]]=='L'){sr+=lr[pd[0]][0];sc+=lc[pd[0]][0];
		if(lr[pd[0]][0]==0)kr--;if(lr[pd[0]][0]==2)kr++;
		if(lc[pd[0]][0]==0)kc--;if(lc[pd[0]][0]==2)kc++;}
		if(t[pr[0]][pc[0]]=='R'){sr+=rr[pd[0]][0];sc+=rc[pd[0]][0];
		if(rr[pd[0]][0]==0)kr--;if(rr[pd[0]][0]==2)kr++;
		if(rc[pd[0]][0]==0)kc--;if(rc[pd[0]][0]==2)kc++;}
		dfs_route(0,0,sr,sc,kr,kc,0);
		return;
	}
	for(int i=0;i<4;i++){
		pd[a]=i;
		dfs_dir(a+1);
	}
}
int main(){
	int a,b;
	while(scanf("%d%d",&b,&a),a){
		H=a;W=b;
		for(int i=0;i<a;i++)for(int j=0;j<b;j++){
			scanf("%s",in);
			t[i][j]=in[0];
		}
		for(int i=0;i<a;i++)for(int j=0;j<b;j++)conv[i][j]=-1;
		ret=0;
		ps=0;
		for(int i=0;i<a;i++)for(int j=0;j<b;j++){
			if(t[i][j]=='L'||t[i][j]=='R'){
				conv[i][j]=ps;
				pr[ps]=i;pc[ps++]=j;
			}
		}
		if(ps%2){
			printf("0\n");continue;
		}
		dfs_dir(0);
		printf("%d\n",ret);
	}
}
accuracy: 1
time_ms: 50
memory_kb: 1052
final_rank: 1

code_snippet: #include<iostream>
#include<cassert>
using namespace std;
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)

#define N 0
#define E 1
#define S 2
#define W 3

int dx[]={0,1,0,-1};
int dy[]={-1,0,1,0};
int curdir[]={S,W,N,E};

int sd[2][4]={//S default:0 -
  -1,W,-1,E,
  S,-1,N,-1,
};

int cd[4][4]={//C default:0 -^
  W,-1,-1,N,
  E,N,-1,-1,
  -1,S,E,-1,
  -1,-1,W,S,
};

int ld[4][2][4]={//if switch == 0 ld[i][0], switch == 1 ld[i][1] 
  //ST        //CURVE
  W,W,-1,E, W,W,-1,N,
  S,N,N,-1, E,N,N,-1,
  -1,W,E,E, -1,S,E,E,
  S,-1,N,S, S,-1,W,S
  /*
  {W,W,-1,E},{W,W,-1,N},
  {S,N,N,-1},{E,N,N,-1},
  {-1,W,E,E},{-1,S,E,E},
  {S,-1,N,S},{S,-1,W,S}
  */
};


int rd[4][2][4]={//if switch == 0 ld[i][0], switch == 1 ld[i][1] 
  //ST        //CURVE
  -1,W,W,E, -1,W,W,S,
  S,-1,N,N, W,-1,N,N,
  E,W,-1,E, E,N,-1,E,
  S,S,N,-1, S,S,E,-1
  /*
  {-1,W,W,E},{-1,W,W,S},
  {S,-1,N,N},{W,-1,N,N},
  {E,W,-1,E},{E,N,-1,E},
  {S,S,N,-1},{S,S,E,-1}
  */
};

int switchid[6][6];
int rot[6][6];
char m[6][6];

int    cost[6][6][4][(1<<6)];
int visited[6][6][4][(1<<6)];
int ans;

void dfs(int r,int c,int y,int x,int d,int state,int visnow,int length){
  if (length != 0)d=curdir[d];

  if (x == -1||y == -1||x==c||y==r)return;

  if (visited[y][x][d][state] == -1){
    
  }else if (visited[y][x][d][state] == visnow){
    ans=max(ans,length-cost[y][x][d][state]);
    return;
  }else {
    return;
  }
  visited[y][x][d][state]=visnow;
  cost[y][x][d][state]   =length;

  int nextd;
  int curgrid=rot[y][x];
  if (m[y][x] == 'S'){
    nextd=sd[curgrid][d];
    dfs(r,c,y+dy[nextd],x+dx[nextd],nextd,state,visnow,length+1);
  }else if( m[y][x] == 'C'){
    nextd=cd[curgrid][d];
    dfs(r,c,y+dy[nextd],x+dx[nextd],nextd,state,visnow,length+1);
  }else if (m[y][x] == 'L'){
    bool isswitch=(((1<<switchid[y][x])&state)!=0);
    nextd=ld[curgrid][isswitch][d];
    if ((rot[y][x]+3)%4 == d){
      if (isswitch)state-=(1<<switchid[y][x]);
      else         state+=(1<<switchid[y][x]);
    }
    dfs(r,c,y+dy[nextd],x+dx[nextd],nextd,state,visnow,length+1);
  }else if (m[y][x] == 'R'){
    bool isswitch=(((1<<switchid[y][x])&state)!=0);
    nextd=rd[curgrid][isswitch][d];
    if ((rot[y][x]+3)%4==d){
      if (isswitch)state-=(1<<switchid[y][x]);
      else         state+=(1<<switchid[y][x]);
    }
    dfs(r,c,y+dy[nextd],x+dx[nextd],nextd,state,visnow,length+1);
  }
}

void solve(int r,int c,int index){
  rep(i,r){
    rep(j,c){
      rep(k,4){
	rep(l,(1<<index)){
	  visited[i][j][k][l]=-1;
	}
      }
    }
  }
  
  int visnow=0;
  rep(i,r){
    rep(j,c){
      if (m[i][j] == 'R'||m[i][j] == 'L'){
	if (rot[i][j] == 0){
	  dfs(r,c,i,j,W,0,visnow,0);
	}else if (rot[i][j] == 1){
	  dfs(r,c,i,j,N,0,visnow,0);
	}else if (rot[i][j] == 2){
	  dfs(r,c,i,j,E,0,visnow,0);
	}else if (rot[i][j] == 3){
	  dfs(r,c,i,j,S,0,visnow,0);
	}
	visnow++;
      }
    }
  }
}


//if rot[i][j] == -1 unvisited
void search(int r,int c,int index,int now,int num,//num -> 3 position of L or R
	    int y,int x,int d,int *posx,int *posy,bool tonext){

  if (tonext && num == 0 && index == now+1){
    solve(r,c,index);
    return;
  }


  if (tonext){
    
    if (num == 0){//straight
      now++;
      y = posy[now];
      x = posx[now];

      d = (rot[y][x]+3)%4;
      search(r,c,index,now,1,posy[now]+dy[d],posx[now]+dx[d],
	     d,posx,posy,false);
    }else if (num == 1){
      y = posy[now];
      x = posx[now];
      d=(rot[y][x]+1)%4;
      search(r,c,index,now,2,posy[now]+dy[d],posx[now]+dx[d],
	     d,posx,posy,false);
    }else if (num == 2){//curve
      y = posy[now];
      x = posx[now];
      if (m[y][x] == 'R'){
	d=(rot[y][x]+2)%4;
      }else if (m[posy[now]][posx[now]]=='L'){
	d=rot[y][x];
      }
      search(r,c,index,now,0,posy[now]+dy[d],posx[now]+dx[d],
	     d,posx,posy,false);
      
    }
    return;
  }

  if (x == -1 || y == -1||x==c||y==r)return;
  d=curdir[d];

  if (m[y][x] == 'S'){
    if (rot[y][x] == -1){
      if      (d == E || d == W)rot[y][x]=0;
      else if (d == S || d == N)rot[y][x]=1;
      search(r,c,index,now,num,y+dy[sd[rot[y][x]][d]],x+dx[sd[rot[y][x]][d]],
	     sd[rot[y][x]][d],posx,posy,false);
      rot[y][x]=-1;
      return;
    }else if (rot[y][x] != -1){
      if (sd[rot[y][x]][d] == -1)return;
      else search(r,c,index,now,num,-1,-1,-1,posx,posy,true);
    }
  }else if(m[y][x] == 'C'){
    if (rot[y][x] == -1){
      if      (d == E)rot[y][x]=1;
      else if (d == W)rot[y][x]=3;
      else if (d == S)rot[y][x]=2;
      else if (d == N)rot[y][x]=0;
      search(r,c,index,now,num,y+dy[cd[rot[y][x]][d]],x+dx[cd[rot[y][x]][d]],
	     cd[rot[y][x]][d],posx,posy,false);
      if      (d == E)rot[y][x]=2;
      else if (d == W)rot[y][x]=0;
      else if (d == S)rot[y][x]=3;
      else if (d == N)rot[y][x]=1;
      search(r,c,index,now,num,y+dy[cd[rot[y][x]][d]],x+dx[cd[rot[y][x]][d]],
	     cd[rot[y][x]][d],posx,posy,false);
      rot[y][x]=-1;
    }else if (rot[y][x] != -1){
      if (cd[rot[y][x]][d] == -1)return;
      else search(r,c,index,now,num,-1,-1,-1,posx,posy,true);
    }
  }else if (m[y][x] == 'L'){
    if (ld[rot[y][x]][0][d] == -1)return;
    search(r,c,index,now,num,-1,-1,-1,posx,posy,true);
  }else if (m[y][x] == 'R'){
    if (rd[rot[y][x]][0][d] == -1)return;
    search(r,c,index,now,num,-1,-1,-1,posx,posy,true);
  }
}


void decide(int r,int c,int index,int now,int *posx,int *posy){
  if (now == index){
    search(r,c,index,-1,0,-1,-1,-1,posx,posy,true);
    return;
  }
  rep(i,4){
    rot[posy[now]][posx[now]]=i;
    decide(r,c,index,now+1,posx,posy);
  }
}

main(){
  int r,c;
  while(cin>>c>>r && c){
    int index =0;
    int posx[6],posy[6];
    rep(i,r){
      rep(j,c){
	cin>>m[i][j];
	rot[i][j]=-1;
	if (m[i][j] == 'R'||m[i][j]=='L'){
	  switchid[i][j]=index;
	  posy[index]=i;
	  posx[index]=j;
	  index++;
	}
      }
    }

    ans = 0;
    decide(r,c,index,0,posx,posy);
    cout << ans << endl;
  }
}
accuracy: 1
time_ms: 80
memory_kb: 944
final_rank: 2

code_snippet: #include<iostream>
#include<cassert>
using namespace std;
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)

#define N 0
#define E 1
#define S 2
#define W 3

int dx[]={0,1,0,-1};
int dy[]={-1,0,1,0};
int curdir[]={S,W,N,E};

int sd[2][4]={//S default:0 -
  -1,W,-1,E,
  S,-1,N,-1,
};

int cd[4][4]={//C default:0 -^
  W,-1,-1,N,
  E,N,-1,-1,
  -1,S,E,-1,
  -1,-1,W,S,
};

int ld[4][2][4]={//if switch == 0 ld[i][0], switch == 1 ld[i][1] 
  //ST        //CURVE
  W,W,-1,E, W,W,-1,N,
  S,N,N,-1, E,N,N,-1,
  -1,W,E,E, -1,S,E,E,
  S,-1,N,S, S,-1,W,S
  /*
  {W,W,-1,E},{W,W,-1,N},
  {S,N,N,-1},{E,N,N,-1},
  {-1,W,E,E},{-1,S,E,E},
  {S,-1,N,S},{S,-1,W,S}
  */
};


int rd[4][2][4]={//if switch == 0 ld[i][0], switch == 1 ld[i][1] 
  //ST        //CURVE
  -1,W,W,E, -1,W,W,S,
  S,-1,N,N, W,-1,N,N,
  E,W,-1,E, E,N,-1,E,
  S,S,N,-1, S,S,E,-1
  /*
  {-1,W,W,E},{-1,W,W,S},
  {S,-1,N,N},{W,-1,N,N},
  {E,W,-1,E},{E,N,-1,E},
  {S,S,N,-1},{S,S,E,-1}
  */
};

int switchid[6][6];
int rot[6][6];
char m[6][6];

int    cost[6][6][4][(1<<6)];
int visited[6][6][4][(1<<6)];
int ans;

void dfs(int r,int c,int y,int x,int d,int state,int visnow,int length){
  if (length != 0)d=curdir[d];

  if (x == -1||y == -1||x==c||y==r)return;

  if (visited[y][x][d][state] == -1){
    
  }else if (visited[y][x][d][state] == visnow){
    ans=max(ans,length-cost[y][x][d][state]);
    return;
  }else {
    return;
  }
  visited[y][x][d][state]=visnow;
  cost[y][x][d][state]   =length;

  int nextd;
  int curgrid=rot[y][x];
  if (m[y][x] == 'S'){
    nextd=sd[curgrid][d];
    dfs(r,c,y+dy[nextd],x+dx[nextd],nextd,state,visnow,length+1);
  }else if( m[y][x] == 'C'){
    nextd=cd[curgrid][d];
    dfs(r,c,y+dy[nextd],x+dx[nextd],nextd,state,visnow,length+1);
  }else if (m[y][x] == 'L'){
    bool isswitch=(((1<<switchid[y][x])&state)!=0);
    nextd=ld[curgrid][isswitch][d];
    if ((rot[y][x]+3)%4 == d){
      if (isswitch)state-=(1<<switchid[y][x]);
      else         state+=(1<<switchid[y][x]);
    }
    dfs(r,c,y+dy[nextd],x+dx[nextd],nextd,state,visnow,length+1);
  }else if (m[y][x] == 'R'){
    bool isswitch=(((1<<switchid[y][x])&state)!=0);
    nextd=rd[curgrid][isswitch][d];
    if ((rot[y][x]+3)%4==d){
      if (isswitch)state-=(1<<switchid[y][x]);
      else         state+=(1<<switchid[y][x]);
    }
    dfs(r,c,y+dy[nextd],x+dx[nextd],nextd,state,visnow,length+1);
  }
}

void solve(int r,int c,int index){
  rep(i,r){
    rep(j,c){
      rep(k,4){
	rep(l,(1<<index)){
	  visited[i][j][k][l]=-1;
	}
      }
    }
  }
  
  int visnow=0;
  rep(i,r){
    rep(j,c){
      if (m[i][j] == 'R'||m[i][j] == 'L'){
	if (rot[i][j] == 0){
	  dfs(r,c,i,j,W,0,visnow,0);
	}else if (rot[i][j] == 1){
	  dfs(r,c,i,j,N,0,visnow,0);
	}else if (rot[i][j] == 2){
	  dfs(r,c,i,j,E,0,visnow,0);
	}else if (rot[i][j] == 3){
	  dfs(r,c,i,j,S,0,visnow,0);
	}
	/*
	rep(ii,r){
	  rep(jj,c){
	    rep(kk,4){
	      rep(ll,(1<<index)){
		visited[ii][jj][kk][ll]=-1;
	      }
	    }
	  }
	}

	if (rot[i][j] == 0){
	  dfs(r,c,i,j,W,1<<switchid[i][j],visnow,0);
	}else if (rot[i][j] == 1){
	  dfs(r,c,i,j,N,1<<switchid[i][j],visnow,0);
	}else if (rot[i][j] == 2){
	  dfs(r,c,i,j,E,1<<switchid[i][j],visnow,0);
	}else if (rot[i][j] == 3){
	  dfs(r,c,i,j,S,1<<switchid[i][j],visnow,0);
	}
	rep(ii,r){
	  rep(jj,c){
	    rep(kk,4){
	      rep(ll,(1<<index)){
		visited[ii][jj][kk][ll]=-1;
	      }
	    }
	  }
	}
	*/
	visnow++;
      }
    }
  }
}


//if rot[i][j] == -1 unvisited
void search(int r,int c,int index,int now,int num,//num -> 3 position of L or R
	    int y,int x,int d,int *posx,int *posy,bool tonext){

  if (tonext && num == 0 && index == now+1){
    solve(r,c,index);
    return;
  }


  if (tonext){
    
    if (num == 0){//straight
      now++;
      y = posy[now];
      x = posx[now];

      d = (rot[y][x]+3)%4;
      search(r,c,index,now,1,posy[now]+dy[d],posx[now]+dx[d],
	     d,posx,posy,false);
    }else if (num == 1){
      y = posy[now];
      x = posx[now];
      d=(rot[y][x]+1)%4;
      search(r,c,index,now,2,posy[now]+dy[d],posx[now]+dx[d],
	     d,posx,posy,false);
    }else if (num == 2){//curve
      y = posy[now];
      x = posx[now];
      if (m[y][x] == 'R'){
	d=(rot[y][x]+2)%4;
      }else if (m[posy[now]][posx[now]]=='L'){
	d=rot[y][x];
      }
      search(r,c,index,now,0,posy[now]+dy[d],posx[now]+dx[d],
	     d,posx,posy,false);
      
    }
    return;
  }

  if (x == -1 || y == -1||x==c||y==r)return;
  d=curdir[d];

  if (m[y][x] == 'S'){
    if (rot[y][x] == -1){
      if      (d == E || d == W)rot[y][x]=0;
      else if (d == S || d == N)rot[y][x]=1;
      search(r,c,index,now,num,y+dy[sd[rot[y][x]][d]],x+dx[sd[rot[y][x]][d]],
	     sd[rot[y][x]][d],posx,posy,false);
      rot[y][x]=-1;
      return;
    }else if (rot[y][x] != -1){
      if (sd[rot[y][x]][d] == -1)return;
      else search(r,c,index,now,num,-1,-1,-1,posx,posy,true);
    }
  }else if(m[y][x] == 'C'){
    if (rot[y][x] == -1){
      if      (d == E)rot[y][x]=1;
      else if (d == W)rot[y][x]=3;
      else if (d == S)rot[y][x]=2;
      else if (d == N)rot[y][x]=0;
      search(r,c,index,now,num,y+dy[cd[rot[y][x]][d]],x+dx[cd[rot[y][x]][d]],
	     cd[rot[y][x]][d],posx,posy,false);
      if      (d == E)rot[y][x]=2;
      else if (d == W)rot[y][x]=0;
      else if (d == S)rot[y][x]=3;
      else if (d == N)rot[y][x]=1;
      search(r,c,index,now,num,y+dy[cd[rot[y][x]][d]],x+dx[cd[rot[y][x]][d]],
	     cd[rot[y][x]][d],posx,posy,false);
      rot[y][x]=-1;
    }else if (rot[y][x] != -1){
      if (cd[rot[y][x]][d] == -1)return;
      else search(r,c,index,now,num,-1,-1,-1,posx,posy,true);
    }
  }else if (m[y][x] == 'L'){
    if (ld[rot[y][x]][0][d] == -1)return;
    search(r,c,index,now,num,-1,-1,-1,posx,posy,true);
  }else if (m[y][x] == 'R'){
    if (rd[rot[y][x]][0][d] == -1)return;
    search(r,c,index,now,num,-1,-1,-1,posx,posy,true);
  }
}


void decide(int r,int c,int index,int now,int *posx,int *posy){
  if (now == index){
    search(r,c,index,-1,0,-1,-1,-1,posx,posy,true);
    return;
  }
  rep(i,4){
    rot[posy[now]][posx[now]]=i;
    decide(r,c,index,now+1,posx,posy);
  }
}

main(){
  int r,c;
  while(cin>>c>>r && c){
    int index =0;
    int posx[6],posy[6];
    rep(i,r){
      rep(j,c){
	cin>>m[i][j];
	rot[i][j]=-1;
	if (m[i][j] == 'R'||m[i][j]=='L'){
	  switchid[i][j]=index;
	  posy[index]=i;
	  posx[index]=j;
	  index++;
	}
      }
    }

    ans = 0;
    decide(r,c,index,0,posx,posy);
    cout << ans << endl;
  }

}
accuracy: 1
time_ms: 90
memory_kb: 944
final_rank: 3

code_snippet: #include<iostream>
#include<cassert>
using namespace std;
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)

#define N 0
#define E 1
#define S 2
#define W 3

int dx[]={0,1,0,-1};
int dy[]={-1,0,1,0};
int curdir[]={S,W,N,E};

int sd[2][4]={//S default:0 -
  -1,W,-1,E,
  S,-1,N,-1,
};

int cd[4][4]={//C default:0 -^
  W,-1,-1,N,
  E,N,-1,-1,
  -1,S,E,-1,
  -1,-1,W,S,
};

int ld[4][2][4]={//if switch == 0 ld[i][0], switch == 1 ld[i][1] 
  //ST        //CURVE
  W,W,-1,E, W,W,-1,N,
  S,N,N,-1, E,N,N,-1,
  -1,W,E,E, -1,S,E,E,
  S,-1,N,S, S,-1,W,S
  /*
  {W,W,-1,E},{W,W,-1,N},
  {S,N,N,-1},{E,N,N,-1},
  {-1,W,E,E},{-1,S,E,E},
  {S,-1,N,S},{S,-1,W,S}
  */
};


int rd[4][2][4]={//if switch == 0 ld[i][0], switch == 1 ld[i][1] 
  //ST        //CURVE
  -1,W,W,E, -1,W,W,S,
  S,-1,N,N, W,-1,N,N,
  E,W,-1,E, E,N,-1,E,
  S,S,N,-1, S,S,E,-1
  /*
  {-1,W,W,E},{-1,W,W,S},
  {S,-1,N,N},{W,-1,N,N},
  {E,W,-1,E},{E,N,-1,E},
  {S,S,N,-1},{S,S,E,-1}
  */
};

int switchid[6][6];
int rot[6][6];
char m[6][6];

int    cost[6][6][4][(1<<6)];
int visited[6][6][4][(1<<6)];
int ans;

void dfs(int r,int c,int y,int x,int d,int state,int visnow,int length){
  if (length != 0)d=curdir[d];
  /*
  cout << y <<" " << x <<" " << d <<" " << state << " " << length << " " <<
    visnow << " " << visited[y][x][d][state] << endl;
  */

  if (x == -1||y == -1||x==c||y==r)return;
  /*
  if (m[y][x] == 'R' || m[y][x] == 'L'){
    cout<<"tmp " << y << " " <<x <<" " << m[y][x] <<" " << d <<" " <<
      (rot[y][x]+3)%4 << endl;
    if ((rot[y][x]+3%4)==d){
      cout << y <<" " << x <<" " << d <<" " << 
	(bool)(((1<<switchid[y][x])&state)!=0) << " " <<state <<" "<< m[y][x] << " " << cost[y][x][d][state] <<" " << length <<  endl;
    }    
  }
  */  
  if (visited[y][x][d][state] == -1){
    
  }else if (visited[y][x][d][state] == visnow){
    //    cout << "tmp " << length - cost[y][x][d][state] << endl;
    ans=max(ans,length-cost[y][x][d][state]);
    return;
  }else {
    return;
  }
  visited[y][x][d][state]=visnow;
  cost[y][x][d][state]   =length;

  int nextd;
  int curgrid=rot[y][x];
  if (m[y][x] == 'S'){
    nextd=sd[curgrid][d];
    dfs(r,c,y+dy[nextd],x+dx[nextd],nextd,state,visnow,length+1);
  }else if( m[y][x] == 'C'){
    nextd=cd[curgrid][d];
    dfs(r,c,y+dy[nextd],x+dx[nextd],nextd,state,visnow,length+1);
  }else if (m[y][x] == 'L'){
    bool isswitch=(((1<<switchid[y][x])&state)!=0);
    nextd=ld[curgrid][isswitch][d];
    if ((rot[y][x]+3)%4 == d){
      if (isswitch)state-=(1<<switchid[y][x]);
      else         state+=(1<<switchid[y][x]);
    }
    dfs(r,c,y+dy[nextd],x+dx[nextd],nextd,state,visnow,length+1);
  }else if (m[y][x] == 'R'){
    bool isswitch=(((1<<switchid[y][x])&state)!=0);
    nextd=rd[curgrid][isswitch][d];
    if ((rot[y][x]+3)%4==d){
      if (isswitch)state-=(1<<switchid[y][x]);
      else         state+=(1<<switchid[y][x]);
    }
    dfs(r,c,y+dy[nextd],x+dx[nextd],nextd,state,visnow,length+1);
  }
}

void solve(int r,int c,int index){
  rep(i,r){
    rep(j,c){
      rep(k,4){
	rep(l,(1<<index)){
	  visited[i][j][k][l]=-1;
	}
      }
    }
  }
  
  int visnow=0;
  rep(i,r){
    rep(j,c){
      if (m[i][j] == 'R'||m[i][j] == 'L'){
	//	cout << i <<" " << j << endl;
	if (rot[i][j] == 0){
	  dfs(r,c,i,j,W,0,visnow,0);
	}else if (rot[i][j] == 1){
	  dfs(r,c,i,j,N,0,visnow,0);
	}else if (rot[i][j] == 2){
	  dfs(r,c,i,j,E,0,visnow,0);
	}else if (rot[i][j] == 3){
	  dfs(r,c,i,j,S,0,visnow,0);
	}
	rep(ii,r){
	  rep(jj,c){
	    rep(kk,4){
	      rep(ll,(1<<index)){
		visited[ii][jj][kk][ll]=-1;
	      }
	    }
	  }
	}

	//	cout << i <<" " << j << endl;
	if (rot[i][j] == 0){
	  dfs(r,c,i,j,W,1<<switchid[i][j],visnow,0);
	}else if (rot[i][j] == 1){
	  dfs(r,c,i,j,N,1<<switchid[i][j],visnow,0);
	}else if (rot[i][j] == 2){
	  dfs(r,c,i,j,E,1<<switchid[i][j],visnow,0);
	}else if (rot[i][j] == 3){
	  dfs(r,c,i,j,S,1<<switchid[i][j],visnow,0);
	}
	rep(ii,r){
	  rep(jj,c){
	    rep(kk,4){
	      rep(ll,(1<<index)){
		visited[ii][jj][kk][ll]=-1;
	      }
	    }
	  }
	}
	visnow++;
      }
    }
  }
}


//if rot[i][j] == -1 unvisited
void search(int r,int c,int index,int now,int num,//num -> 3 position of L or R
	    int y,int x,int d,int *posx,int *posy,bool tonext){

  if (tonext && num == 0 && index == now+1){
    //    cout << "try to find maximum loop on this layout"<<endl;
    /*    
    cout <<"output"<<endl;
    rep(i,r){
      rep(j,c){
	cout << m[i][j] <<" " << rot[i][j] <<" ";
      }
      cout << endl;
    }
    cout << endl;
    */        
    
    solve(r,c,index);
    return;
  }


  if (tonext){
    
    //cout <<"change " <<  now <<" " << num << endl;
    if (num == 0){//straight
      now++;
      y = posy[now];
      x = posx[now];
      //      cout <<now <<  "rot " << rot[posy[now]][posx[now]] <<endl;

      d = (rot[y][x]+3)%4;
      //      cout <<"dir " << d << endl;
      search(r,c,index,now,1,posy[now]+dy[d],posx[now]+dx[d],
	     d,posx,posy,false);
    }else if (num == 1){
      y = posy[now];
      x = posx[now];
      d=(rot[y][x]+1)%4;
      //      cout <<"dir " << d << endl;
      search(r,c,index,now,2,posy[now]+dy[d],posx[now]+dx[d],
	     d,posx,posy,false);
    }else if (num == 2){//curve
      y = posy[now];
      x = posx[now];
      if (m[y][x] == 'R'){
	d=(rot[y][x]+2)%4;
      }else if (m[posy[now]][posx[now]]=='L'){
	d=rot[y][x];
      }
      search(r,c,index,now,0,posy[now]+dy[d],posx[now]+dx[d],
	     d,posx,posy,false);
      
    }
    return;
  }

  
  //  cout <<" " << y <<" " <<x <<" " << curdir[d] <<" " << m[y][x] <<" " <<num << endl;

  if (x == -1 || y == -1||x==c||y==r)return;
  d=curdir[d];


  if (m[y][x] == 'S'){
    if (rot[y][x] == -1){
      if      (d == E || d == W)rot[y][x]=0;
      else if (d == S || d == N)rot[y][x]=1;
      search(r,c,index,now,num,y+dy[sd[rot[y][x]][d]],x+dx[sd[rot[y][x]][d]],
	     sd[rot[y][x]][d],posx,posy,false);
      rot[y][x]=-1;
      return;
    }else if (rot[y][x] != -1){
      if (sd[rot[y][x]][d] == -1)return;
      else search(r,c,index,now,num,-1,-1,-1,posx,posy,true);
    }
  }else if(m[y][x] == 'C'){
    if (rot[y][x] == -1){
      if      (d == E)rot[y][x]=1;
      else if (d == W)rot[y][x]=3;
      else if (d == S)rot[y][x]=2;
      else if (d == N)rot[y][x]=0;
      //      cout <<"curve check " <<  rot[y][x]  <<" " << d << " " << y+dy[cd[rot[y][x]][d]] <<
      //	" "<< x+dx[cd[rot[y][x]][d]]<<endl;
      search(r,c,index,now,num,y+dy[cd[rot[y][x]][d]],x+dx[cd[rot[y][x]][d]],
	     cd[rot[y][x]][d],posx,posy,false);
      if      (d == E)rot[y][x]=2;
      else if (d == W)rot[y][x]=0;
      else if (d == S)rot[y][x]=3;
      else if (d == N)rot[y][x]=1;
      search(r,c,index,now,num,y+dy[cd[rot[y][x]][d]],x+dx[cd[rot[y][x]][d]],
	     cd[rot[y][x]][d],posx,posy,false);
      rot[y][x]=-1;
    }else if (rot[y][x] != -1){
      if (cd[rot[y][x]][d] == -1)return;
      else search(r,c,index,now,num,-1,-1,-1,posx,posy,true);
    }
  }else if (m[y][x] == 'L'){
    if (ld[rot[y][x]][0][d] == -1)return;
    //    cout <<"test L " << ld[rot[y][x]][0][d] <<endl;
    search(r,c,index,now,num,-1,-1,-1,posx,posy,true);
  }else if (m[y][x] == 'R'){
    if (rd[rot[y][x]][0][d] == -1)return;
    search(r,c,index,now,num,-1,-1,-1,posx,posy,true);
  }
}


void decide(int r,int c,int index,int now,int *posx,int *posy){
  if (now == index){
    search(r,c,index,-1,0,-1,-1,-1,posx,posy,true);
    return;
  }
  rep(i,4){
    rot[posy[now]][posx[now]]=i;
    decide(r,c,index,now+1,posx,posy);
  }
}

main(){
  int r,c;
  while(cin>>c>>r && c){
    int index =0;
    int posx[6],posy[6];
    rep(i,r){
      rep(j,c){
	cin>>m[i][j];
	rot[i][j]=-1;
	if (m[i][j] == 'R'||m[i][j]=='L'){
	  switchid[i][j]=index;
	  posy[index]=i;
	  posx[index]=j;
	  index++;
	}
      }
    }

    ans = 0;
    decide(r,c,index,0,posx,posy);
    cout << ans << endl;
  }

}
accuracy: 1
time_ms: 120
memory_kb: 944
final_rank: 5