#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9;
int m, n;
int grid[102][102]; // 1-based索引,-1表示无色,0红色,1黄色
int dist[102][102][2][2]; // dist[x][y][can_magic][current_color]
// 上下左右四个方向
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};
// 状态结构体,用于优先队列
struct State {
int cost, x, y, can_magic, color;
State(int c, int x_, int y_, int cm, int cl) : cost(c), x(x_), y(y_), can_magic(cm), color(cl) {}
bool operator>(const State& other) const {
return cost > other.cost; // 小根堆,按花费升序
}
};
int main() {
cin >> m >> n;
memset(grid, -1, sizeof(grid)); // 初始化棋盘为无色
// 读取有颜色的格子
for (int i = 0; i < n; ++i) {
int x, y, c;
cin >> x >> y >> c;
grid[x][y] = c;
}
// 初始化距离数组为无穷大
for (int x = 1; x <= m; ++x) {
for (int y = 1; y <= m; ++y) {
for (int cm = 0; cm < 2; ++cm) {
for (int cl = 0; cl < 2; ++cl) {
dist[x][y][cm][cl] = INF;
}
}
}
}
// 起点(1,1)的颜色(题目保证有颜色)
int start_color = grid[1][1];
priority_queue<State, vector<State>, greater<State>> pq;
dist[1][1][1][start_color] = 0; // 初始状态:可使用魔法,花费0
pq.emplace(0, 1, 1, 1, start_color);
int ans = INF;
while (!pq.empty()) {
State s = pq.top();
pq.pop();
int cost = s.cost;
int x = s.x;
int y = s.y;
int can_magic = s.can_magic;
int color = s.color;
// 到达终点,更新最小花费
if (x == m && y == m) {
ans = min(ans, cost);
continue;
}
// 若当前花费已大于已知最小,跳过
if (cost > dist[x][y][can_magic][color]) {
continue;
}
// 探索四个方向
for (int i = 0; i < 4; ++i) {
int tx = x + dx[i];
int ty = y + dy[i];
if (tx < 1 || tx > m || ty < 1 || ty > m) {
continue; // 超出棋盘范围
}
int cell_color = grid[tx][ty];
if (cell_color != -1) { // 目标格子有颜色
// 计算新花费:颜色不同则+1
int new_cost = cost + (color != cell_color ? 1 : 0);
int new_can_magic = 1; // 移动到有颜色格子,可再次使用魔法
int new_color = cell_color;
// 更新距离并加入队列
if (new_cost < dist[tx][ty][new_can_magic][new_color]) {
dist[tx][ty][new_can_magic][new_color] = new_cost;
pq.emplace(new_cost, tx, ty, new_can_magic, new_color);
}
} else { // 目标格子无色,需使用魔法(若允许)
if (can_magic) { // 当前可使用魔法
// 花费2金币,将无色格子变为当前颜色(同色无额外花费)
int new_cost = cost + 2;
int new_can_magic = 0; // 魔法后不可连续使用
int new_color = color;
if (new_cost < dist[tx][ty][new_can_magic][new_color]) {
dist[tx][ty][new_can_magic][new_color] = new_cost;
pq.emplace(new_cost, tx, ty, new_can_magic, new_color);
}
}
}
}
}
// 输出结果
cout << (ans == INF ? -1 : ans) << endl;
return 0;
}
/**************************************************************
Problem: 1483
User: zhengzihao
Language: C++
Result: Accepted
Time:78 ms
Memory:2280 kb
****************************************************************/