Problem: 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).

<image>

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.

<image>

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 B/M-end at (1, 2) toward (1, 3) and the states of all the switches are the through-states. It goes through (1, 3), (1, 4), (1, 5), (2, 5), (2, 4), (1, 4), (1, 3), (1, 2), (1, 1), (2, 1), (2, 2) and (1, 2). Here, the tramcar goes through (1, 2) with the same position and the same direction, but with the different states of the switches. Then the tramcar goes through (1, 3), (1, 4), (2, 4), (2, 5), (1, 5), (1, 4), (1, 3), (1, 2), (2, 2), (2, 1), (1, 1) and (1, 2). Here, the tramcar goes through (1, 2) again, but with the same switch states as the initial ones. Counting the rail units the tramcar visited, the tramcar should have run 24 units of time after its start, and thus the fun time is 24.

There may be many valid layouts with the given rail units. For example, a valid layout containing a fun route with the fun time 120 is shown in Figure 11(a). Another valid layout containing a fun route with the fun time 148 derived from that in Figure 11(a) is shown in Figure 11(b). The four rail units whose rotations are changed from Figure 11(a) are indicated by the thick lines.

A valid layout depicted in Figure 12(a) contains two fun routes, where one consists of the rail units (1, 1), (2, 1), (3, 1), (4, 1), (4, 2), (3, 2), (2, 2), (1, 2) with T = 8, and the other consists of all the remaining rail units with T = 18.

<image>

Another valid layout depicted in Figure 12(b) has two fun routes whose fun times are T = 12 and T = 20. The layout in Figure 12(a) is different from that in Figure 12(b) at the eight rail units rotated by multiples of 90 degrees. There are other valid layouts with some rotations of rail units but there is no fun route with the fun time longer than 20, so that the longest fun time for this example (Figure 12) is 20.

<image>

Note that there may be simple cyclic routes that do not go through any switches in a valid layout, which are not counted as the fun routes. In Figure 13, there are two fun routes and one simple cyclic route. Their fun times are 12 and 14, respectively. The required time for going around the simple cyclic route is 20 that is greater than fun times of the fun routes. However, the longest fun time is still 14.

<image>



Input

The input consists of multiple datasets, followed by a line containing two zeros separated by a space. Each dataset has the following format.

w h
a11 ... a1w
...
ah1 ... ahw


w is the number of the rail units in a row, and h is the number of those in a column. aij (1 ≤ i ≤ h, 1 ≤ j ≤ w) is one of uppercase letters 'S', 'C', 'L' and 'R', which indicate the types of the rail unit at (i, j) position, i.e., straight, curve, left-switch and right-switch, respectively. Items in a line are separated by a space. You can assume that 2 ≤ w ≤ 6, 2 ≤ h ≤ 6 and the sum of the numbers of left-switches and right-switches is greater than or equal to 2 and less than or equal to 6.

Output

For each dataset, an integer should be printed that indicates the longest fun time of all the fun routes in all the valid layouts with the given rail units. When there is no valid layout according to the given rail units, a zero should be printed.

Example

Input

5 2
C L S R C
C C S C C
6 4
C C C C C C
S L R R C S
S S S L C S
C C C C C C
6 6
C L S S S C
C C C S S C
C C C S S C
C L C S S C
C C L S S C
C S L S S C
6 6
C S S S S C
S C S L C S
S C S R C S
S C L S C S
S C R S C S
C S S S S C
4 4
S C C S
S C L S
S L C S
C C C C
6 4
C R S S L C
C R L R L C
C S C C S C
C S S S S C
0 0


Output

24
20
148
14
0
178

Solution (in CPP):

Solution:
#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);
  }
}

int 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;
  }

}