The Siruseri amusement park has a new attraction. It consists of a rectangular array of discs. Each disc is divided into four equal sectors and the four sectors are coloured with the colours Red, Blue, Green and Yellow (in some order). The ordering may be different in different discs. Here is a possible arrangment of the discs:

You start at the top left disc. Your task is to walk down to the bottom right disc. In each step, you can rotate the current disc by $90$ degrees in the clockwise direction or move to a neighbouring disc. However, you can move to a neighbouring disc only if adjacent sectors of these two discs have the same colour. For example, in the figure above, you can move from the disc at position ($1$, $1$) to either of its neighbours. However, from the disc at position ($1$, $2$) you can only move to the disc at position ($1$, $1$). If you wish to move from ($1$, $2$) to ($1$, $3$) then you would have to rotate this disc three times so that the colour (red) on the adjacent sectors are the same.
For each rotate move, a penalty point is added to the score. The aim is to reach the bottom right with as few penalty points as possible. For example, in the arrangement described in the above figure, the best possible score is $2$, corresponding to the following path: Move from ($1$, $1$) to ($2$, $1$). Move from ($2$, $1$) to ($2$, $2$). Rotate. Rotate. Move from ($2$, $2$) to ($2$, $3$). Move from ($2$, $3$) to ($1$, $3$). Move from ($1$, $3$) to ($1$, $4$). Finally, move from ($1$, $4$) to ($2$, $4$).
Your task is to determine the minimum number of penalty points required to go from the top left disc to the bottom right disc for the given arrangement of discs.

-----Input:-----
The first line contains two integers $M$ and $N$. $M$ is the number of rows and $N$ is the number of columns in the given arrangment. This is followed by $M \times N$ lines of input. Lines $2$ to $N+1$, describe the colours on the discs on the first row, Lines $N+2$ to $2 \cdot N+1$ describe the colours on discs in the second row and so on. Each of these lines contain a permutation of the set {R, G, B, Y} giving the colours in the top, right, bottom and left sectors in that order.

-----Output:-----
A single integer on a single line indicating the minimum number of penalty points required to go from the top left disc to the bottom right disc for the given arrangement of discs.

-----Constraints:-----
- In $80 \%$ of the input, $1 \leq M,N \leq 60$.
- In all the inputs $1 \leq M,N \leq 1000$.

-----Sample Input-----
2 4
G Y B R
B G R Y
G Y B R
G R B Y
B Y G R
G B R Y
B R G Y
B R G Y

-----Sample Output-----
2

```python

USER_FILENAME = "<user_code>"
import sys, json, builtins
import math, heapq, bisect, itertools, functools, collections, statistics, fractions, decimal, operator, array, random, re, string, os, pathlib
try:
    import resource as _res
except Exception:
    _res = None
from collections import Counter, defaultdict, deque, OrderedDict
from functools import lru_cache, reduce
from itertools import accumulate, permutations, combinations, product
from math import gcd, ceil, floor, sqrt
from decimal import Decimal
try:
    from typing import *
except Exception:
    pass
try:
    sys.setrecursionlimit(1_000_000)
except Exception:
    pass
try:
    import site as _site
    try:
        _sys_sites = _site.getsitepackages() if hasattr(_site, "getsitepackages") else []
        for _p in _sys_sites:
            if _p and _p not in sys.path:
                sys.path.append(_p)
    except Exception:
        pass
    try:
        _usp = _site.getusersitepackages()
        if isinstance(_usp, str):
            _usp = [_usp]
        for _p in _usp:
            if _p and _p not in sys.path:
                sys.path.append(_p)
    except Exception:
        pass
except Exception:
    pass

ns = {"__name__": "__main__"}
for _k, _v in list(globals().items()):
    if not _k.startswith("_"):
        ns[_k] = _v
_CODE = '#for _ in range(int(input()):\n#n,m = map(int,input().split())\n#x = [int(w) for w in input().split()]\n#n = int(input())\n#x = [int(input()) for _ in range(n)]\n#for i in range(n):\n#dt = {} for i in x:dt[i] = dt.get(i,0)+1\n#dt = {k:v for k,v in sorted(x.items(), key=lambda i: i[1])}\n\nm,n = map(int,input().split())  # top,right,bottom,left\nx = []\nfor i in range(m):\n    x.append([])\n    for j in range(n):\n        clr = [w for w in input().split()]\n        x[i].append(clr)\n\nimport queue as Q                \ndp = [float(\'inf\')]*m\nfor i in range(m):\n    dp[i] = [float(\'inf\')]*n\ndp[m-1][n-1] = 0\npq = Q.PriorityQueue()\npq.put([dp[m-1][n-1],m-1,n-1])\nvisited = set()\nxx,yy = [-1,0,1,0],[0,1,0,-1] # top,right,bottom,left\nwhile not pq.empty():\n    pop = pq.get()\n    cx,cy = pop[1],pop[2]\n    if (cx,cy) not in visited:\n        visited.add((cx,cy))\n        for k in range(4):\n            nx,ny = cx+xx[k],cy+yy[k]\n            if 0<=nx<m and 0<=ny<n and (nx,ny) not in visited:\n                clr = x[cx][cy][k]\n                #print("*",nx,ny,"_",k,clr)\n                ind = x[nx][ny].index(clr)\n                cost = (k-(ind+2)%4)%4\n                #print(cost)\n                if dp[cx][cy]+cost < dp[nx][ny]:\n                    dp[nx][ny] = dp[cx][cy]+cost\n                    pq.put([dp[nx][ny],nx,ny])\n        #print("#############")\n#print(dp)\nprint(dp[0][0])'
_co = compile(_CODE, USER_FILENAME, "exec")
exec(_co, ns, ns)

```

Measured memory_bytes: 288219