#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
#define FOR(i, a, b) for (int i=a; i<(b); i++)
#define range(a) a.begin(), a.end()
#define endl "\n"
#define Yes() cout << "Yes" << endl
#define No() cout << "No" << endl
#define MP make_pair
const unsigned long long mod = 1e9 + 7;
const int dx[4]={1,0,-1,0};
const int dy[4]={0,1,0,-1};
void chmin(long long &a, long long b) { if (a > b) a = b; }
void chmax(long long &a, long long b) { if (a < b) a = b; }

struct Edge {
    long long to;
    long long cost;
};
using Graph = vector<vector<Edge>>;
using P = pair<long, int>;
const long long INF = 1LL << 60;

/* dijkstra(G,s,dis)
    入力：グラフ G, 開始点 s, 距離を格納する dis
    計算量：O(|E|log|V|)
    副作用：dis が書き換えられる
*/
ll dijkstra(const Graph &G, int s) {
	vector<long long> dis;
	int N = G.size();
	dis.resize(N, INF);
    priority_queue<P, vector<P>, greater<P>> pq;  // 「仮の最短距離, 頂点」が小さい順に並ぶ
    dis[s] = 0;
    pq.emplace(dis[s], s);
	bool f = true;
    while (!pq.empty()) {
        P p = pq.top();
        pq.pop();
        int v = p.second;
        if (dis[v] < p.first) {  // 最短距離で無ければ無視
            continue;
        }
        for (auto &e : G[v]) {
            if (dis[e.to] > dis[v] + e.cost) {  // 最短距離候補なら priority_queue に追加
                dis[e.to] = dis[v] + e.cost;
                pq.emplace(dis[e.to], e.to);
            }
        }
		if(f){
			dis[s] = INF;
			f = !f;
		}
	}
	return dis[s];
}

int main(){
	int N, M;
	cin >> N >> M;
	Graph G(N);
	vector<ll> self(N, INF);
	while(M--){
		ll a, b, c;
		cin >> a >> b >> c;
		--a;
		--b;
		if(a==b){
			self.at(a) = min(self.at(a), c);
			continue;
		}
		Edge e = {b, c};
		G.at(a).push_back(e);
	}

	FOR(i,0,N){
		ll g = dijkstra(G, i);
		if(g==INF&&self[i]==INF){
			cout << -1 << endl;
		}else{
			ll ans = min(g, self[i]);
			cout << ans << endl;
		}
	}

}

#pragma GCC optimize("Ofast,unroll-loops")
#pragma GCC target("avx,avx2,sse4,fma")

#include <bits/stdc++.h>
using namespace std;
using pii = pair<int, int>;

template <typename T>
using minpq = priority_queue<T, vector<T>, greater<T>>;



const int IN_SZ = 20<<20, OUT_SZ = 20<<20;
int _i0, _o0; char _, _i[IN_SZ], _o[OUT_SZ];
template <typename T> inline void re(T &x) {
	for(x=_i[_i0++]^48;(_=_i[_i0++])&16;x=x*10+(_^48)); }
template <typename T> inline void wr(T x) {
	char s[11];int i=0;do s[i++]='0'+x%10,x/=10; while(x);
	while (i--) _o[_o0++]=s[i]; _o[_o0++]='\n'; }
inline void wr(const string &s){for(char c:s)_o[_o0++]=c;}




const int maxn = 2'005;
vector<pii> adj[maxn];
int dis[maxn];

int main() {
	fread(_i,1,IN_SZ,stdin);
	
	int N, M; re(N), re(M);
	for (int i = 0; i < M; ++i) {
		int a,b,c; re(a),re(b),re(c);
		adj[--a].emplace_back(--b, c);
	}
	
	for (int st = 0; st < N; ++st) {
		minpq<pii> pq; pq.emplace(0, st);
		for (int i = 0; i < N; ++i) dis[i] = 2e9;
		
		bool is_loop = false;
		
		while (!pq.empty()) {
			const auto [d, c] = pq.top(); pq.pop();
			
			if (c == st && d > 0) {
				wr(d);
				is_loop = true;
				break;
			}
			
			if (dis[c] <= d) continue;
			dis[c] = d;
			
			for (const auto &[n, e]: adj[c]) {
				pq.emplace(d+e, n);
			}
		}
		
		if (!is_loop) {
			wr(string("-1\n"));
		}
	}
	
	fwrite(_o,1,_o0,stdout);
}