hehe
Intuition\n Describe your first thoughts on how to solve this problem. \n\n# Approach\n Describe your approach to solving the problem. \n\n# Complexity\n- Time 
# Intuition\n<!-- Describe your first thoughts on how to solve this problem. -->\n\n# Approach\n<!-- Describe your approach to solving the problem. -->\n\n# Complexity\n- Time complexity:\n<!-- Add your time complexity here, e.g. $$O(n)$$ -->\n\n- Space complexity:\n<!-- Add your space complexity here, e.g. $$O(n)$$ -->\n\n# Code\n```\nenum Pos { kHorizontal, kVertical }\n\nclass Solution {\n  public int minimumMoves(int[][] grid) {\n    final int n = grid.length;\n    int ans = 0;\n    // the state of (x, y, pos)\n    // pos := 0 (horizontal) / 1 (vertical)\n    Queue<int[]> q = new ArrayDeque<>(Arrays.asList(new int[] {0, 0, Pos.kHorizontal.ordinal()}));\n    boolean[][][] seen = new boolean[n][n][2];\n    seen[0][0][Pos.kHorizontal.ordinal()] = true;\n\n    while (!q.isEmpty()) {\n      for (int sz = q.size(); sz > 0; --sz) {\n        final int x = q.peek()[0];\n        final int y = q.peek()[1];\n        final int pos = q.poll()[2];\n        if (x == n - 1 && y == n - 2 && pos == Pos.kHorizontal.ordinal())\n          return ans;\n        if (canMoveRight(grid, x, y, pos) && !seen[x][y + 1][pos]) {\n          q.offer(new int[] {x, y + 1, pos});\n          seen[x][y + 1][pos] = true;\n        }\n        if (canMoveDown(grid, x, y, pos) && !seen[x + 1][y][pos]) {\n          q.offer(new int[] {x + 1, y, pos});\n          seen[x + 1][y][pos] = true;\n        }\n        final int newPos =\n            pos == Pos.kHorizontal.ordinal() ? Pos.kVertical.ordinal() : Pos.kHorizontal.ordinal();\n        if ((canRotateClockwise(grid, x, y, pos) || canRotateCounterclockwise(grid, x, y, pos)) &&\n            !seen[x][y][newPos]) {\n          q.offer(new int[] {x, y, newPos});\n          seen[x][y][newPos] = true;\n        }\n      }\n      ++ans;\n    }\n\n    return -1;\n  }\n\n  private boolean canMoveRight(int[][] grid, int x, int y, int pos) {\n    if (pos == Pos.kHorizontal.ordinal())\n      return y + 2 < grid.length && grid[x][y + 2] == 0;\n    return y + 1 < grid.length && grid[x][y + 1] == 0 && grid[x + 1][y + 1] == 0;\n  }\n\n  private boolean canMoveDown(int[][] grid, int x, int y, int pos) {\n    if (pos == Pos.kVertical.ordinal())\n      return x + 2 < grid.length && grid[x + 2][y] == 0;\n    return x + 1 < grid.length && grid[x + 1][y] == 0 && grid[x + 1][y + 1] == 0;\n  };\n\n  private boolean canRotateClockwise(int[][] grid, int x, int y, int pos) {\n    return pos == Pos.kHorizontal.ordinal() && x + 1 < grid.length && grid[x + 1][y + 1] == 0 &&\n        grid[x + 1][y] == 0;\n  };\n\n  private boolean canRotateCounterclockwise(int[][] grid, int x, int y, int pos) {\n    return pos == Pos.kVertical.ordinal() && y + 1 < grid.length && grid[x + 1][y + 1] == 0 &&\n        grid[x][y + 1] == 0;\n  };\n}\n```
['Java']