// Template #include "bits/stdc++.h" #define rep_override(x, y, z, name, ...) name #define rep2(i, n) for (int i = 0; i < (int)(n); ++i) #define rep3(i, l, r) for (int i = (int)(l); i < (int)(r); ++i) #define rep(...) rep_override(__VA_ARGS__, rep3, rep2)(__VA_ARGS__) #define per(i, n) for (int i = (int)(n) - 1; i >= 0; --i) #define all(x) (x).begin(), (x).end() using namespace std; using ll = long long; constexpr int inf = 1001001001; constexpr ll INF = 3003003003003003003LL; template inline bool chmin(T &x, const T &y) { if (x > y) { x = y; return true; } return false; } template inline bool chmax(T &x, const T &y) { if (x < y) { x = y; return true; } return false; } struct IOSET { IOSET() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(10); } } ioset; template istream &operator>>(istream &is, vector &vec) { for (T &element : vec) is >> element; return is; } template ostream &operator<<(ostream &os, vector &vec) { for (int i = 0, vec_len = (int)vec.size(); i < vec_len; ++i) { os << vec[i] << " \n"[i + 1 == vec_len]; } return os; } // Main struct Edge { int to; ll cost; Edge(int t, ll c) : to(t), cost(c) {} }; constexpr int dx[] = {1, 0, -1, 0}, dy[] = {0, 1, 0, -1}; int main() { int n, m; cin >> n >> m; vector h(m), w(m), c(m); rep(i, m) { cin >> h[i] >> w[i] >> c[i]; --h[i]; --w[i]; } vector> vec(n, vector(n, 0)); rep(i, m) vec[h[i]][w[i]] = c[i]; vector> g(n * n * 2); rep(i, n) rep(j, n) rep(k, 4) { if (i + dx[k] < 0 || i + dx[k] >= n || j + dy[k] < 0 || j + dy[k] >= n) continue; if (!vec[i + dx[k]][j + dy[k]]) { g[(i * n + j) * 2 + 0].emplace_back(((i + dx[k]) * n + j + dy[k]) * 2 + 0, 1); g[(i * n + j) * 2 + 1].emplace_back(((i + dx[k]) * n + j + dy[k]) * 2 + 1, 1); } else { g[(i * n + j) * 2 + 0].emplace_back(((i + dx[k]) * n + j + dy[k]) * 2 + 1, 1); g[(i * n + j) * 2 + 0].emplace_back(((i + dx[k]) * n + j + dy[k]) * 2 + 0, vec[i + dx[k]][j + dy[k]] + 1); g[(i * n + j) * 2 + 1].emplace_back(((i + dx[k]) * n + j + dy[k]) * 2 + 1, vec[i + dx[k]][j + dy[k]] + 1); } } vector dist(n * n * 2, INF); priority_queue> pq; dist[0] = 0; pq.emplace(dist[0], 0); while (!pq.empty()) { auto [d, v] = pq.top(); pq.pop(); d *= -1; if (dist[v] != d) continue; for (Edge &e : g[v]) { if (chmin(dist[e.to], d + e.cost)) pq.emplace(-dist[e.to], e.to); } } cout << min(dist[(n * n - 1) * 2], dist[(n * n - 1) * 2 + 1]) << "\n"; }