#pragma GCC optimize ("Ofast")
#include<bits/stdc++.h>
using namespace std;
void * wmem;
char memarr[ 96000000 ] ;
template < class T> inline void walloc1d( T ** arr, int x, void ** mem = & wmem) {
static int skip[ 16 ] = { 0 , 15 , 14 , 13 , 12 , 11 , 10 , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 } ;
( * mem) = ( void * ) ( ( ( char * ) ( * mem) ) + skip[ ( ( unsigned long long ) ( * mem) ) & 15 ] ) ;
( * arr) = ( T* ) ( * mem) ;
( * mem) = ( ( * arr) + x) ;
}
template < class T> struct DijkstraHeap{
int * hp;
int * place;
int size;
char * visited;
T * val;
void malloc ( int N) {
hp = ( int * ) std:: malloc ( N* sizeof ( int ) ) ;
place = ( int * ) std:: malloc ( N* sizeof ( int ) ) ;
visited = ( char * ) std:: malloc ( N* sizeof ( char ) ) ;
val = ( T* ) std:: malloc ( N* sizeof ( T) ) ;
}
void free ( ) {
std:: free ( hp) ;
std:: free ( place) ;
std:: free ( visited) ;
std:: free ( val) ;
}
void walloc( int N, void ** mem= & wmem) {
walloc1d( & hp, N, mem) ;
walloc1d( & place, N, mem) ;
walloc1d( & visited, N, mem) ;
walloc1d( & val, N, mem) ;
}
void init( int N) {
int i;
size = 0 ;
for ( i= ( 0 ) ; i< ( N) ; i++ ) {
place[ i] = - 1 ;
}
for ( i= ( 0 ) ; i< ( N) ; i++ ) {
visited[ i] = 0 ;
}
}
void up( int n) {
int m;
while ( n) {
m= ( n- 1 ) / 2 ;
if ( val[ hp[ m] ] <= val[ hp[ n] ] ) {
break ;
}
swap( hp[ m] ,hp[ n] ) ;
swap( place[ hp[ m] ] ,place[ hp[ n] ] ) ;
n= m;
}
}
void down( int n) {
int m;
for ( ;; ) {
m= 2 * n+ 1 ;
if ( m>= size) {
break ;
}
if ( m+ 1 < size&& val[ hp[ m] ] > val[ hp[ m+ 1 ] ] ) {
m++ ;
}
if ( val[ hp[ m] ] >= val[ hp[ n] ] ) {
break ;
}
swap( hp[ m] ,hp[ n] ) ;
swap( place[ hp[ m] ] ,place[ hp[ n] ] ) ;
n= m;
}
}
void change( int n, T v) {
if ( visited[ n] || ( place[ n] >= 0 && val[ n] <= v) ) {
return ;
}
val[ n] = v;
if ( place[ n] == - 1 ) {
place[ n] = size;
hp[ size++ ] = n;
up( place[ n] ) ;
}
else {
up( place[ n] ) ;
}
}
int pop( void ) {
int res= hp[ 0 ] ;
place[ res] = - 1 ;
size-- ;
if ( size) {
hp[ 0 ] = hp[ size] ;
place[ hp[ 0 ] ] = 0 ;
down( 0 ) ;
}
visited[ res] = 1 ;
return res;
}
}
;
struct dimcomp2{
int B;
dimcomp2( ) {
}
dimcomp2( int b) {
B = b;
}
dimcomp2( int a, int b) {
B = b;
}
inline void set( int b) {
B = b;
}
inline void set( int a, int b) {
B = b;
}
inline int mask( int a, int b) {
return a * B + b;
}
inline int operator( ) ( int a, int b) {
return a * B + b;
}
inline void para( int mask, int & a, int & b) {
a = mask / B;
b = mask % B;
}
inline void operator( ) ( int mask, int & a, int & b) {
a = mask / B;
b = mask % B;
}
}
;
#define main dummy_main
int main( ) {
wmem = memarr;
return 0 ;
}
#undef main
class Solution{
public :
int minCost( vector< vector< int >> & A) {
int i;
dummy_main( ) ;
int X = A.size ( ) ;
int Y = A[ 0 ] .size ( ) ;
int dx[ 4 ] = { 0 , 0 , 1 , - 1 } ;
int dy[ 4 ] = { 1 , - 1 , 0 , 0 } ;
int mask;
int sx;
int sy;
int sc;
int nx;
int ny;
int nc;
int d;
DijkstraHeap< int > hp;
dimcomp2 dm( X,Y) ;
for ( i= ( 0 ) ; i< ( X) ; i++ ) {
int j;
for ( j= ( 0 ) ; j< ( Y) ; j++ ) {
A[ i] [ j] -- ;
}
}
hp.malloc ( X* Y) ;
hp.init ( X* Y) ;
hp.change ( 0 ,0 ) ;
while ( hp.size ) {
mask = hp.pop ( ) ;
dm( mask, sx, sy) ;
sc = hp.val [ mask] ;
if ( sx== X- 1 && sy== Y- 1 ) {
return sc;
}
for ( d= ( 0 ) ; d< ( 4 ) ; d++ ) {
nx = sx + dx[ d] ;
ny = sy + dy[ d] ;
if ( A[ sx] [ sy] == d) {
nc = sc + 0 ;
}
else {
nc = sc + 1 ;
}
if ( nx < 0 || ny < 0 || nx >= X || ny >= Y) {
continue ;
}
hp.change ( dm( nx,ny) , nc) ;
}
}
return - 1 ;
}
}
;
// cLay varsion 20200308-1
// --- original code ---
// #define main dummy_main
// {}
// #undef main
//
// class Solution {
// public:
// int minCost(vector<vector<int>>& A) {
// dummy_main();
//
// int X = A.size(), Y = A[0].size();
// int dx[4] = {0, 0, 1, -1};
// int dy[4] = {1, -1, 0, 0};
// int mask, sx, sy, sc, nx, ny, nc, d;
// DijkstraHeap<int> hp;
// dimcomp2 dm(X,Y);
//
// rep(i,X) rep(j,Y) A[i][j]--;
//
// hp.malloc(X*Y);
// hp.init(X*Y);
//
// hp.change(0,0);
// while(hp.size){
// mask = hp.pop();
// dm(mask, sx, sy);
// sc = hp.val[mask];
// if(sx==X-1 && sy==Y-1) return sc;
//
// rep(d,4){
// nx = sx + dx[d];
// ny = sy + dy[d];
// nc = sc + if[A[sx][sy]==d, 0, 1];
// if(nx < 0 || ny < 0 || nx >= X || ny >= Y) continue;
// hp.change(dm(nx,ny), nc);
// }
// }
//
// return -1;
// }
// };
I3ByYWdtYSBHQ0Mgb3B0aW1pemUgKCJPZmFzdCIpCiNpbmNsdWRlPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CnZvaWQgKndtZW07CmNoYXIgbWVtYXJyWzk2MDAwMDAwXTsKdGVtcGxhdGU8Y2xhc3MgVD4gaW5saW5lIHZvaWQgd2FsbG9jMWQoVCAqKmFyciwgaW50IHgsIHZvaWQgKiptZW0gPSAmd21lbSl7CiAgc3RhdGljIGludCBza2lwWzE2XSA9IHswLCAxNSwgMTQsIDEzLCAxMiwgMTEsIDEwLCA5LCA4LCA3LCA2LCA1LCA0LCAzLCAyLCAxfTsKICAoKm1lbSkgPSAodm9pZCopKCAoKGNoYXIqKSgqbWVtKSkgKyBza2lwWygodW5zaWduZWQgbG9uZyBsb25nKSgqbWVtKSkgJiAxNV0gKTsKICAoKmFycik9KFQqKSgqbWVtKTsKICAoKm1lbSk9KCgqYXJyKSt4KTsKfQp0ZW1wbGF0ZSA8Y2xhc3MgVD4gc3RydWN0IERpamtzdHJhSGVhcHsKICBpbnQgKmhwOwogIGludCAqcGxhY2U7CiAgaW50IHNpemU7CiAgY2hhciAqdmlzaXRlZDsKICBUICp2YWw7CiAgdm9pZCBtYWxsb2MoaW50IE4pewogICAgaHAgPSAoaW50KilzdGQ6Om1hbGxvYyhOKnNpemVvZihpbnQpKTsKICAgIHBsYWNlID0gKGludCopc3RkOjptYWxsb2MoTipzaXplb2YoaW50KSk7CiAgICB2aXNpdGVkID0gKGNoYXIqKXN0ZDo6bWFsbG9jKE4qc2l6ZW9mKGNoYXIpKTsKICAgIHZhbCA9IChUKilzdGQ6Om1hbGxvYyhOKnNpemVvZihUKSk7CiAgfQogIHZvaWQgZnJlZSgpewogICAgc3RkOjpmcmVlKGhwKTsKICAgIHN0ZDo6ZnJlZShwbGFjZSk7CiAgICBzdGQ6OmZyZWUodmlzaXRlZCk7CiAgICBzdGQ6OmZyZWUodmFsKTsKICB9CiAgdm9pZCB3YWxsb2MoaW50IE4sIHZvaWQgKiptZW09JndtZW0pewogICAgd2FsbG9jMWQoJmhwLCBOLCBtZW0pOwogICAgd2FsbG9jMWQoJnBsYWNlLCBOLCBtZW0pOwogICAgd2FsbG9jMWQoJnZpc2l0ZWQsIE4sIG1lbSk7CiAgICB3YWxsb2MxZCgmdmFsLCBOLCBtZW0pOwogIH0KICB2b2lkIGluaXQoaW50IE4pewogICAgaW50IGk7CiAgICBzaXplID0gMDsKICAgIGZvcihpPSgwKTtpPChOKTtpKyspewogICAgICBwbGFjZVtpXT0tMTsKICAgIH0KICAgIGZvcihpPSgwKTtpPChOKTtpKyspewogICAgICB2aXNpdGVkW2ldPTA7CiAgICB9CiAgfQogIHZvaWQgdXAoaW50IG4pewogICAgaW50IG07CiAgICB3aGlsZShuKXsKICAgICAgbT0obi0xKS8yOwogICAgICBpZih2YWxbaHBbbV1dPD12YWxbaHBbbl1dKXsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICBzd2FwKGhwW21dLGhwW25dKTsKICAgICAgc3dhcChwbGFjZVtocFttXV0scGxhY2VbaHBbbl1dKTsKICAgICAgbj1tOwogICAgfQogIH0KICB2b2lkIGRvd24oaW50IG4pewogICAgaW50IG07CiAgICBmb3IoOzspewogICAgICBtPTIqbisxOwogICAgICBpZihtPj1zaXplKXsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICBpZihtKzE8c2l6ZSYmdmFsW2hwW21dXT52YWxbaHBbbSsxXV0pewogICAgICAgIG0rKzsKICAgICAgfQogICAgICBpZih2YWxbaHBbbV1dPj12YWxbaHBbbl1dKXsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICBzd2FwKGhwW21dLGhwW25dKTsKICAgICAgc3dhcChwbGFjZVtocFttXV0scGxhY2VbaHBbbl1dKTsKICAgICAgbj1tOwogICAgfQogIH0KICB2b2lkIGNoYW5nZShpbnQgbiwgVCB2KXsKICAgIGlmKHZpc2l0ZWRbbl18fChwbGFjZVtuXT49MCYmdmFsW25dPD12KSl7CiAgICAgIHJldHVybjsKICAgIH0KICAgIHZhbFtuXT12OwogICAgaWYocGxhY2Vbbl09PS0xKXsKICAgICAgcGxhY2Vbbl09c2l6ZTsKICAgICAgaHBbc2l6ZSsrXT1uOwogICAgICB1cChwbGFjZVtuXSk7CiAgICB9CiAgICBlbHNlewogICAgICB1cChwbGFjZVtuXSk7CiAgICB9CiAgfQogIGludCBwb3Aodm9pZCl7CiAgICBpbnQgcmVzPWhwWzBdOwogICAgcGxhY2VbcmVzXT0tMTsKICAgIHNpemUtLTsKICAgIGlmKHNpemUpewogICAgICBocFswXT1ocFtzaXplXTsKICAgICAgcGxhY2VbaHBbMF1dPTA7CiAgICAgIGRvd24oMCk7CiAgICB9CiAgICB2aXNpdGVkW3Jlc109MTsKICAgIHJldHVybiByZXM7CiAgfQp9CjsKc3RydWN0IGRpbWNvbXAyewogIGludCBCOwogIGRpbWNvbXAyKCl7CiAgfQogIGRpbWNvbXAyKGludCBiKXsKICAgIEIgPSBiOwogIH0KICBkaW1jb21wMihpbnQgYSwgaW50IGIpewogICAgQiA9IGI7CiAgfQogIGlubGluZSB2b2lkIHNldChpbnQgYil7CiAgICBCID0gYjsKICB9CiAgaW5saW5lIHZvaWQgc2V0KGludCBhLCBpbnQgYil7CiAgICBCID0gYjsKICB9CiAgaW5saW5lIGludCBtYXNrKGludCBhLCBpbnQgYil7CiAgICByZXR1cm4gYSAqIEIgKyBiOwogIH0KICBpbmxpbmUgaW50IG9wZXJhdG9yKCkoaW50IGEsIGludCBiKXsKICAgIHJldHVybiBhICogQiArIGI7CiAgfQogIGlubGluZSB2b2lkIHBhcmEoaW50IG1hc2ssIGludCAmYSwgaW50ICZiKXsKICAgIGEgPSBtYXNrIC8gQjsKICAgIGIgPSBtYXNrICUgQjsKICB9CiAgaW5saW5lIHZvaWQgb3BlcmF0b3IoKShpbnQgbWFzaywgaW50ICZhLCBpbnQgJmIpewogICAgYSA9IG1hc2sgLyBCOwogICAgYiA9IG1hc2sgJSBCOwogIH0KfQo7CiNkZWZpbmUgbWFpbiBkdW1teV9tYWluCmludCBtYWluKCl7CiAgd21lbSA9IG1lbWFycjsKICByZXR1cm4gMDsKfQojdW5kZWYgbWFpbgpjbGFzcyBTb2x1dGlvbnsKICBwdWJsaWM6CiAgaW50IG1pbkNvc3QodmVjdG9yPHZlY3RvcjxpbnQ+PiYgQSl7CiAgICBpbnQgaTsKICAgIGR1bW15X21haW4oKTsKICAgIGludCBYID0gQS5zaXplKCk7CiAgICBpbnQgWSA9IEFbMF0uc2l6ZSgpOwogICAgaW50IGR4WzRdID0gezAsIDAsIDEsIC0xfTsKICAgIGludCBkeVs0XSA9IHsxLCAtMSwgMCwgMH07CiAgICBpbnQgbWFzazsKICAgIGludCBzeDsKICAgIGludCBzeTsKICAgIGludCBzYzsKICAgIGludCBueDsKICAgIGludCBueTsKICAgIGludCBuYzsKICAgIGludCBkOwogICAgRGlqa3N0cmFIZWFwPGludD4gaHA7CiAgICBkaW1jb21wMiBkbShYLFkpOwogICAgZm9yKGk9KDApO2k8KFgpO2krKyl7CiAgICAgIGludCBqOwogICAgICBmb3Ioaj0oMCk7ajwoWSk7aisrKXsKICAgICAgICBBW2ldW2pdLS07CiAgICAgIH0KICAgIH0KICAgIGhwLm1hbGxvYyhYKlkpOwogICAgaHAuaW5pdChYKlkpOwogICAgaHAuY2hhbmdlKDAsMCk7CiAgICB3aGlsZShocC5zaXplKXsKICAgICAgbWFzayA9IGhwLnBvcCgpOwogICAgICBkbShtYXNrLCBzeCwgc3kpOwogICAgICBzYyA9IGhwLnZhbFttYXNrXTsKICAgICAgaWYoc3g9PVgtMSAmJiBzeT09WS0xKXsKICAgICAgICByZXR1cm4gc2M7CiAgICAgIH0KICAgICAgZm9yKGQ9KDApO2Q8KDQpO2QrKyl7CiAgICAgICAgbnggPSBzeCArIGR4W2RdOwogICAgICAgIG55ID0gc3kgKyBkeVtkXTsKICAgICAgICBpZihBW3N4XVtzeV09PWQpewogICAgICAgICAgbmMgPSBzYyArMDsKICAgICAgICB9CiAgICAgICAgZWxzZXsKICAgICAgICAgIG5jID0gc2MgKzE7CiAgICAgICAgfQogICAgICAgIGlmKG54IDwgMCB8fCBueSA8IDAgfHwgbnggPj0gWCB8fCBueSA+PSBZKXsKICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICBocC5jaGFuZ2UoZG0obngsbnkpLCBuYyk7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiAtMTsKICB9Cn0KOwovLyBjTGF5IHZhcnNpb24gMjAyMDAzMDgtMQoKLy8gLS0tIG9yaWdpbmFsIGNvZGUgLS0tCi8vICNkZWZpbmUgbWFpbiBkdW1teV9tYWluCi8vIHt9Ci8vICN1bmRlZiBtYWluCi8vIAovLyBjbGFzcyBTb2x1dGlvbiB7Ci8vIHB1YmxpYzoKLy8gICBpbnQgbWluQ29zdCh2ZWN0b3I8dmVjdG9yPGludD4+JiBBKSB7Ci8vICAgICBkdW1teV9tYWluKCk7Ci8vIAovLyAgICAgaW50IFggPSBBLnNpemUoKSwgWSA9IEFbMF0uc2l6ZSgpOwovLyAgICAgaW50IGR4WzRdID0gezAsIDAsIDEsIC0xfTsKLy8gICAgIGludCBkeVs0XSA9IHsxLCAtMSwgMCwgMH07Ci8vICAgICBpbnQgbWFzaywgc3gsIHN5LCBzYywgbngsIG55LCBuYywgZDsKLy8gICAgIERpamtzdHJhSGVhcDxpbnQ+IGhwOwovLyAgICAgZGltY29tcDIgZG0oWCxZKTsKLy8gCi8vICAgICByZXAoaSxYKSByZXAoaixZKSBBW2ldW2pdLS07Ci8vIAovLyAgICAgaHAubWFsbG9jKFgqWSk7Ci8vICAgICBocC5pbml0KFgqWSk7Ci8vIAovLyAgICAgaHAuY2hhbmdlKDAsMCk7Ci8vICAgICB3aGlsZShocC5zaXplKXsKLy8gICAgICAgbWFzayA9IGhwLnBvcCgpOwovLyAgICAgICBkbShtYXNrLCBzeCwgc3kpOwovLyAgICAgICBzYyA9IGhwLnZhbFttYXNrXTsKLy8gICAgICAgaWYoc3g9PVgtMSAmJiBzeT09WS0xKSByZXR1cm4gc2M7Ci8vIAovLyAgICAgICByZXAoZCw0KXsKLy8gICAgICAgICBueCA9IHN4ICsgZHhbZF07Ci8vICAgICAgICAgbnkgPSBzeSArIGR5W2RdOwovLyAgICAgICAgIG5jID0gc2MgKyBpZltBW3N4XVtzeV09PWQsIDAsIDFdOwovLyAgICAgICAgIGlmKG54IDwgMCB8fCBueSA8IDAgfHwgbnggPj0gWCB8fCBueSA+PSBZKSBjb250aW51ZTsKLy8gICAgICAgICBocC5jaGFuZ2UoZG0obngsbnkpLCBuYyk7Ci8vICAgICAgIH0KLy8gICAgIH0KLy8gCi8vICAgICByZXR1cm4gLTE7Ci8vICAgfQovLyB9Owo=