C# BFS + Hash
\npublic class Solution {\n    \n    public class Snake\n    {\n        const int MAX = 10000;\n        \n        public static int n;\n        \n        public
```\npublic class Solution {\n    \n    public class Snake\n    {\n        const int MAX = 10000;\n        \n        public static int n;\n        \n        public Pos head;\n        public Pos tail;\n        \n        public Snake()\n        {\n            head = new Pos();\n            tail = new Pos();\n        }\n        \n        public void SetHead(int r, int c)\n        {\n            head.row = r;\n            head.col = c;\n        }\n        \n        public void SetTail(int r, int c)\n        {\n            tail.row = r;\n            tail.col = c;\n        }\n        \n        public int HashValue\n        {\n            get\n            {\n                return tail.row*n + tail.col + (head.row*n + head.col)*MAX;\n            }\n        }\n        \n        public bool IsDes()\n        {\n            return (head.row == n-1 && head.col == n-1 && tail.row == n-1 && tail.col == n-2)\n                || (head.row == n-1 && head.col == n-2 && tail.row == n-1 && tail.col == n-1);\n        }\n        \n        public bool IsVertical()\n        {\n            return head.col == tail.col;\n        }\n    }\n    \n    public class Pos\n    {\n        public int row;\n        public int col;\n    }\n    \n    //bfs\n    public int MinimumMoves(int[][] grid) {\n        \n        int n = grid.Length;\n        Snake.n = grid.Length;\n        \n        Queue<Snake> queue = new Queue<Snake>();\n        HashSet<int> hs = new HashSet<int>();\n        \n        Snake snake = new Snake();\n        snake.SetHead(0, 1);\n        snake.SetTail(0, 0);\n        \n        hs.Add(snake.HashValue);\n        queue.Enqueue(snake);\n        \n        int res = 0;\n        \n        while(queue.Count > 0)\n        {\n            int cnt = queue.Count;\n            \n            for(int i=0; i<cnt; i++)\n            {\n                Snake cur = queue.Dequeue();\n                \n                if(cur.IsDes())\n                {\n                    return res;\n                }\n                \n                //right\n                if(cur.head.col + 1 < n && cur.tail.col + 1 < n \n                   && grid[cur.head.row][cur.head.col + 1] == 0 \n                   && grid[cur.tail.row][cur.tail.col + 1] == 0)\n                {\n                    Snake next = new Snake();\n                    next.SetHead(cur.head.row, cur.head.col + 1);\n                    next.SetTail(cur.tail.row, cur.tail.col + 1);\n                    \n                    if(!hs.Contains(next.HashValue))\n                    {\n                        hs.Add(next.HashValue);\n                        queue.Enqueue(next);\n                    }\n                }\n                \n                //down\n                if(cur.head.row + 1 < n && cur.tail.row + 1 < n \n                   && grid[cur.head.row + 1][cur.head.col] == 0 \n                   && grid[cur.tail.row + 1][cur.tail.col] == 0)\n                {\n                    Snake next = new Snake();\n                    next.SetHead(cur.head.row + 1, cur.head.col);\n                    next.SetTail(cur.tail.row + 1, cur.tail.col);\n                    \n                    if(!hs.Contains(next.HashValue))\n                    {\n                        hs.Add(next.HashValue);\n                        queue.Enqueue(next);\n                    }\n                }\n                \n                //clockwise\n                if(!cur.IsVertical() && cur.head.row + 1 < n\n                   && grid[cur.head.row + 1][cur.head.col] == 0 \n                   && grid[cur.tail.row + 1][cur.tail.col] == 0)\n                {\n                    Snake next = new Snake();\n                    next.SetHead(cur.head.row + 1, cur.head.col - 1);\n                    next.SetTail(cur.tail.row, cur.tail.col);\n                    \n                    if(!hs.Contains(next.HashValue))\n                    {\n                        hs.Add(next.HashValue);\n                        queue.Enqueue(next);\n                    }\n                }\n                \n                //counterclockwise\n                if(cur.IsVertical() && cur.head.col + 1 < n\n                   && grid[cur.head.row][cur.head.col + 1] == 0 \n                   && grid[cur.tail.row][cur.tail.col + 1] == 0)\n                {\n                    Snake next = new Snake();\n                    next.SetHead(cur.head.row - 1, cur.head.col + 1);\n                    next.SetTail(cur.tail.row, cur.tail.col);\n                    \n                    if(!hs.Contains(next.HashValue))\n                    {\n                        hs.Add(next.HashValue);\n                        queue.Enqueue(next);\n                    }\n                }\n            }\n            \n            res++;\n        }\n        \n        return -1;\n    }\n}\n```
[]