#include <bits/stdc++.h>
#define int long long
#define inf 1e9 + 7
using namespace std;

const int N = 2e5 + 100;
int n,m;
vector< pair<int, int> > g[N];
vector< pair<int, int> > mstTree[N];

//root for dsu,
int parent[N];

//parent in mst
int mst_parent[N];

int dist[N];
bool inMST[N];
vector < pair<int, pair<int,int> > > edges, original_order;
map< pair<int, int>, int > edge_weight;
long long mst_weight = 0;

long long h[N];
long long dp[N][19];
long long maxi[N][19];
long long mini[N][19];

map< pair<int, int>, int> ans;

void computeRMQ() {
	for(int i = 1; i <= 18; i++) {
		for(int j = 1; j <= n ; j++) {
			if(dp[j][i-1] != -1) {
				dp[j][i] = dp[dp[j][i-1]][i-1];
				maxi[j][i] = max(maxi[j][i-1], maxi[dp[j][i-1]][i-1]);
			}  else {
				maxi[j][i] = maxi[j][i-1];
			}
			mini[j][i] = inf;
			mini[j][0] = inf;
		}
	}
}

pair<int, int>  lca(int a, int b) {

	if(h[a] > h[b]) {
		int temp = a;
		a = b;
		b = temp;
	}
	int diff = abs(h[a] - h[b]);
	long long max_weight_edge = 0;

	for(int i = 0; i <= 18; i++) {
		if((diff >> i) & 1) {
			max_weight_edge = max(maxi[b][i], max_weight_edge);
			b = dp[b][i];
		}
	}

	if(b == a)  {
		return make_pair(a, max_weight_edge);
	}

	for(int i = 18; i >= 0; i--) {
		if(dp[a][i] != dp[b][i]) {
			max_weight_edge = max(max_weight_edge, maxi[a][i]);
			max_weight_edge = max(max_weight_edge, maxi[b][i]);
			a = dp[a][i];
			b = dp[b][i];
		}
	}

	return make_pair(dp[a][0], max(max_weight_edge, max(maxi[a][0], maxi[b][0])));
}

void dfs(int nd, int par) {
	dp[nd][0] = par;
	maxi[nd][0] = edge_weight[make_pair(par, nd)];
	mst_parent[nd] = par;
	for(auto x: mstTree[nd]) {
		if(x.first != par) {
			h[x.first] = h[nd] + 1;
			dfs(x.first, nd);
		}
	}
}

void dfs2(int nd, int par) {
	for(auto x: mstTree[nd]) {
		ans[make_pair(nd, par)] = mini[x.first][0];
		ans[make_pair(par, nd)] = mini[x.first][0];
		if(x.first != par) {
			dfs2(x.first, nd);
		}
	}
}

int find(int nd) {
	while(parent[nd] != nd) {
		nd = parent[nd];
	}
	return nd;
}

vector< pair< int, pair<int, int> > > uselessEdges;
vector< pair< int, pair<int, int> > > mstEdges;

void update(int nd, int lca, int val) {
	int diff = abs(h[lca] - h[nd]);
	for(int i = 18; i >= 0; i--) {
		if( diff  & (1 << i)) {
			mini[nd][i] = min(mini[nd][i], val);
			nd = dp[nd][i];
		}
	}
}

void kruskal() {

	for(int i = 1; i <= n; i++) {
		parent[i] = i;
	}

	int num = n-1;

	for(auto edge: edges) {
		if(num == 0) {
			uselessEdges.push_back(edge);
			continue;

		}
		int d = edge.first;
		int a = edge.second.first;
		int b = edge.second.second;

		int par1 = find(a);
		int par2 = find(b);
		int max_node = a;
		int min_node = a;
		if(par1 >= par2) {
			max_node = a;
			min_node = b;
		} else {
			max_node = b;
			min_node = a;
		}

		if(par1 != par2) {
			int maxi = max(par1, par2);
			parent[maxi] = min(par1, par2);
			mstTree[a].push_back(make_pair(b, d));
			mstTree[b].push_back(make_pair(a, d));
			edge_weight[make_pair(a, b)] = edge_weight[make_pair(b, a)] = d;
			mst_weight += d;
			num -= 1;
		} else {
			uselessEdges.push_back(edge);
		}

	}

}

signed main() {
	scanf("%lld %lld", &n, &m);
	for(int i = 0; i < m; i++) {
		int a, b, c;
		scanf("%lld %lld %lld", &a, &b, &c);
		g[a].push_back(make_pair(b, c));
		g[b].push_back(make_pair(a, c));
		edges.push_back(make_pair(c, make_pair(a, b)));
		original_order.push_back(edges.back());
	}

	sort(edges.begin(), edges.end());
	kruskal();
	sort(uselessEdges.begin(), uselessEdges.end());
	edge_weight[make_pair(0, 1)] = 0;
	h[1] = 0;
	mst_parent[1] = 0;
	dfs(1, 0);
	computeRMQ();

	for(auto useless: uselessEdges) {
		int a = useless.second.first;
		int b = useless.second.second;
		int d = useless.first;
		pair<int, int> answer = lca(a, b);
		ans[make_pair(a, b)] = answer.second;
		ans[make_pair(b, a)] = answer.second;
		update(a, answer.first, d);
		update(b, answer.first, d);
	}

	for(int l = 18; l >= 0; l--) {
		for(int nd = 1; nd <= n; nd++) {
			mini[nd][l-1] = min(mini[nd][l-1], mini[nd][l]);
			mini[dp[nd][l-1]][l-1] = min(mini[nd][l], mini[dp[nd][l-1]][l-1]);
		}
	}

	dfs2(1, 0);
	for(auto edge: original_order) {
		int a = edge.second.first;
		int b = edge.second.second;
		if(mst_parent[a] == b or mst_parent[b] == a) {
			if(ans[make_pair(a, b)] == inf or ans[make_pair(b,a)] == inf )
				cout << -1 << endl;
			else
				cout << ans[make_pair(a, b)] - 1 << endl;
			continue;
		}

		pair<int, int> ans = lca(a, b);
		cout << ans.second - 1  << endl;

	}

	return 0;
}


#include <bits/stdc++.h>
#define inf 1e9 + 7
using namespace std;

const int N = 2e5 + 100;
const int LVL = 18;
int n,m;
int a[N];
int b[N];
int c[N];
int h[N];
int inplace[N], parent[N];
int inmst[N];
int dp[N][LVL], mini[N][LVL], maxi[N][LVL];
int ans[N];
vector< int > tree[N];

int find(int node) {
	if(parent[node] == node) {
		return node;
	}
	return parent[node] = find(parent[node]);
}

void addEdge(int edgeNo) {
	if(find(a[edgeNo]) != find(b[edgeNo])) {
		inmst[edgeNo] = true;
		parent[find(a[edgeNo])] = find(b[edgeNo]);
		//pushing only edgeNo, since a[edgeNo], b[edgeNo] could be done
		tree[a[edgeNo]].push_back(edgeNo);
		tree[b[edgeNo]].push_back(edgeNo);
	} else {
		inmst[edgeNo]  = false;
	}
}

pair<int, int>  lca(int a, int b) {

	if(h[a] > h[b]) {
		int temp = a;
		a = b;
		b = temp;
	}
	int diff = abs(h[a] - h[b]);
	int max_weight_edge = 0;

	for(int i = 0; i <= 18; i++) {
		if((diff >> i) & 1) {
			max_weight_edge = max(maxi[b][i], max_weight_edge);
			b = dp[b][i];
		}
	}

	if(b == a)  {
		return make_pair(a, max_weight_edge);
	}

	for(int i = 18; i >= 0; i--) {
		if(dp[a][i] != dp[b][i]) {
			max_weight_edge = max(max_weight_edge, maxi[a][i]);
			max_weight_edge = max(max_weight_edge, maxi[b][i]);
			a = dp[a][i];
			b = dp[b][i];
		}
	}

	return make_pair(dp[a][0], max(max_weight_edge, max(maxi[a][0], maxi[b][0])));
}

void dfs(int node, int par) {
	dp[node][0] = par;
	for(int edgeNo: tree[node]) {
		int child = a[edgeNo] ^ b[edgeNo] ^ node;
		if(child != par) {
			maxi[child][0] = c[edgeNo];
			h[child] = h[node] + 1;
			dfs(child, node);
		}
	}
}

void dfs2(int node, int par) {
	for(int edgeNo: tree[node]) {
		int next = a[edgeNo] ^ b[edgeNo] ^ node;
		if(next != par) {
			ans[edgeNo] = mini[next][0];
			dfs2(next, node);
		}
	}
}

void update(int node, int lca, int val) {
	int diff = abs(h[node] - h[lca]);
	for(int i = LVL - 1; i >= 0; i--) {
		if(diff & (1 << i)) {
			mini[node][i] = min(mini[node][i], val);
			node = dp[node][i];
		}
	}
}

int main() {
	cin >> n >> m;
	for(int i = 1; i <= m; i++) {
		cin >> a[i] >> b[i] >> c[i];
		inplace[i] = i;
	}
	for(int i = 1; i <= n; i++) {
		parent[i] = i;
	}
	sort(inplace + 1, inplace + m,  [](int x , int y){
		return make_pair(c[x] , make_pair(a[x] , b[x])) < make_pair(c[y] , make_pair(a[y] , b[y]));
	});
	for(int i = 1; i <= m; i++) {
		addEdge(inplace[i]);
	}
	h[1] = 0;
	dfs(1, 0);

	for(int l = 1; l < LVL; l++) {
		for(int i = 1; i <= n; i++) {
			dp[i][l] = dp[dp[i][l-1]][l-1];
			maxi[i][l] = max(maxi[i][l-1], maxi[dp[i][l-1]][l-1]);
		}
	}

	for(int j = 0; j < LVL; j++) {
		for(int i = 1; i <= n; i++) {
			mini[i][j] = inf;
		}
	}

	for(int i = 1; i <= m; i++) {
		if(inmst[i]) {
			ans[i] = inf;
		} else {
			pair<int, int> result = lca(a[i], b[i]);
			ans[i] = result.second;
			update(a[i], result.first, c[i]);
			update(b[i], result.first, c[i]);
		}
	}

	for(int l = LVL - 1; l > 0; l--) {
		for(int i = 1; i <= n; i++) {
			mini[i][l-1] = min(mini[i][l-1], mini[i][l]);
			mini[dp[i][l-1]][l-1] = min(mini[i][l], mini[dp[i][l-1]][l-1]);
		}
	}

	dfs2(1, 0);

	for(int i = 1; i <= m; i++)  {
		if(ans[i] == inf) {
			ans[i] = 0;
		}
	}
	for(int i = 1; i <= m; i++) {
		cout << ans[i] - 1 << endl;
	}

}


#include <bits/stdc++.h>
#define inf 1e9 + 7
using namespace std;

const int N = 2e5 + 100;
const int LVL = 18;
int n,m;
int a[N];
int b[N];
int c[N];
int h[N];
int inplace[N], parent[N];
int inmst[N];
int dp[N][LVL], mini[N][LVL], maxi[N][LVL];
int ans[N];
vector< int > tree[N];

int find(int node) {
	if(parent[node] == node) {
		return node;
	}
	return parent[node] = find(parent[node]);
}

void addEdge(int edgeNo) {
	if(find(a[edgeNo]) != find(b[edgeNo])) {
		inmst[edgeNo] = true;
		parent[find(a[edgeNo])] = find(b[edgeNo]);
		//pushing only edgeNo, since a[edgeNo], b[edgeNo] could be done
		tree[a[edgeNo]].push_back(edgeNo);
		tree[b[edgeNo]].push_back(edgeNo);
	} else {
		inmst[edgeNo]  = false;
	}
}

pair<int, int>  lca(int a, int b) {

	if(h[a] > h[b]) {
		int temp = a;
		a = b;
		b = temp;
	}
	int diff = abs(h[a] - h[b]);
	int max_weight_edge = 0;

	for(int i = 0; i <= 17; i++) {
		if((diff >> i) & 1) {
			max_weight_edge = max(maxi[b][i], max_weight_edge);
			b = dp[b][i];
		}
	}

	if(b == a)  {
		return make_pair(a, max_weight_edge);
	}

	for(int i = 17; i >= 0; i--) {
		if(dp[a][i] != dp[b][i]) {
			max_weight_edge = max(max_weight_edge, maxi[a][i]);
			max_weight_edge = max(max_weight_edge, maxi[b][i]);
			a = dp[a][i];
			b = dp[b][i];
		}
	}

	return make_pair(dp[a][0], max(max_weight_edge, max(maxi[a][0], maxi[b][0])));
}

void dfs(int node, int par) {
	dp[node][0] = par;
	for(int edgeNo: tree[node]) {
		int child = a[edgeNo] ^ b[edgeNo] ^ node;
		if(child != par) {
			maxi[child][0] = c[edgeNo];
			h[child] = h[node] + 1;
			dfs(child, node);
		}
	}
}

void dfs2(int node, int par) {
	for(int edgeNo: tree[node]) {
		int next = a[edgeNo] ^ b[edgeNo] ^ node;
		if(next != par) {
			ans[edgeNo] = mini[next][0];
			dfs2(next, node);
		}
	}
}

void update(int node, int lca, int val) {
	int diff = abs(h[node] - h[lca]);
	for(int i = LVL - 1; i >= 0; i--) {
		if(diff & (1 << i)) {
			mini[node][i] = min(mini[node][i], val);
			node = dp[node][i];
		}
	}
}

int main() {
	cin >> n >> m;
	for(int i = 1; i <= m; i++) {
		cin >> a[i] >> b[i] >> c[i];
		inplace[i] = i;
	}
	for(int i = 1; i <= n; i++) {
		parent[i] = i;
	}
	sort(inplace + 1, inplace  + 1 + m,  [](int x , int y){
		return make_pair(c[x] , make_pair(a[x] , b[x])) < make_pair(c[y] , make_pair(a[y] , b[y]));
	});
	for(int i = 1; i <= m; i++) {
		addEdge(inplace[i]);
	}
	h[1] = 0;
	dfs(1, 0);

	for(int l = 1; l < LVL; l++) {
		for(int i = 1; i <= n; i++) {
			dp[i][l] = dp[dp[i][l-1]][l-1];
			maxi[i][l] = max(maxi[i][l-1], maxi[dp[i][l-1]][l-1]);
		}
	}

	for(int j = 0; j < LVL; j++) {
		for(int i = 1; i <= n; i++) {
			mini[i][j] = inf;
		}
	}

	for(int i = 1; i <= m; i++) {
		if(inmst[i]) {
			ans[i] = inf;
		} else {
			pair<int, int> result = lca(a[i], b[i]);
			ans[i] = result.second;
			update(a[i], result.first, c[i]);
			update(b[i], result.first, c[i]);
		}
	}

	for(int l = LVL - 1; l > 0; l--) {
		for(int i = 1; i <= n; i++) {
			mini[i][l-1] = min(mini[i][l-1], mini[i][l]);
			mini[dp[i][l-1]][l-1] = min(mini[i][l], mini[dp[i][l-1]][l-1]);
		}
	}

	dfs2(1, 0);

	for(int i = 1; i <= m; i++)  {
		if(ans[i] == inf) {
			ans[i] = 0;
		}
	}
	for(int i = 1; i <= m; i++) {
		cout << ans[i] - 1 << endl;
	}

}


#include<stdio.h>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<queue>
#include<cstdlib>
#include<ctime>
#include<set>
#include<vector>
#include<cassert>
#define rep(i,j,k) for(register int i = j; i <= k; i++)
#define dow(i,j,k) for(register int i = j; i >= k; i--)
#define ll long long
#define mp make_pair
using namespace std;

inline int read() {
	int s = 0, t = 1; char c = getchar();
	while( !isdigit(c) ) { if( c == '-' ) t = -1; c = getchar(); }
	while( isdigit(c) ) s = s * 10 + c - 48, c = getchar();
	return s * t;
}

const int N = 2e5+5, BT = 20;
inline void Max(int &x,int v) { if( v > x ) x = v; }
struct edge{ int x, y, z, id; bool used; bool operator < (const edge&rhs) const { return z < rhs.z; } } A[N];
struct Tree{
	int fa[N], q[N], tot;
	inline int find(int x) {
		while( x != fa[x] ) q[++tot] = x, x = fa[x];
		while( tot ) fa[q[tot--]] = x;
		return x;
	}
	inline void init(int n) { rep(i,1,n) fa[i] = i; }
} B;
vector<pair<int,int> > S[N]; int fa[N][BT], f[N][BT], g[N], dep[N], ans[N];
inline void dfs(int x) {
	for(register int i = 1; dep[x] >= (1<<i); i++) fa[x][i] = fa[fa[x][i-1]][i-1], f[x][i] = max(f[x][i-1],f[fa[x][i-1]][i-1]);
	for(vector<pair<int,int> >::iterator it = S[x].begin(); it != S[x].end(); it++) if( it->first != fa[x][0] ) dep[it->first] = dep[x] + 1, fa[it->first][0] = x, f[it->first][0] = A[it->second].z, g[it->first] = it->second, dfs(it->first);
}

inline void add(int x,int y,int z) {
	S[y].push_back(mp(x,z)), S[x].push_back(mp(y,z));
}

inline int lca(int x,int y) {
	int ret = 0;
	if( dep[x] < dep[y] ) swap(x,y);
	int t = dep[x] - dep[y];
	for(register int i = 0; i < BT && t; i++) if( (t >> i) & 1 ) Max(ret,f[x][i]), x = fa[x][i];
	if( x == y ) return ret;
	dow(i,BT-1,0) if( fa[x][i] != fa[y][i] ) Max(ret,f[x][i]), Max(ret,f[y][i]), x = fa[x][i], y = fa[y][i];
	return ret;
}

inline void solve(int x,int y,int z) {
	while( (x = B.find(x)) != (y = B.find(y)) ) {
		if( dep[x] > dep[y] ) {
			ans[A[g[x]].id] = z, B.fa[x] = fa[x][0];
		} else {
			ans[A[g[y]].id] = z, B.fa[y] = fa[y][0];
		}
	}
}

int main() {
	int n = read(), m = read(), x, y;
	rep(i,1,m) A[i].x = read(), A[i].y = read(), A[i].z = read(), A[i].id = i;
	sort(A+1,A+m+1);
	B.init(n);
	rep(i,1,m) {
		x = B.find(A[i].x), y = B.find(A[i].y);
		if( x != y ) B.fa[x] = y, add(A[i].x,A[i].y,i), A[i].used = 1;
	}
	dfs(1);
	memset(ans,-1,sizeof(ans));
	B.init(n);
	rep(i,1,m) {
		if( !A[i].used ) {
			ans[A[i].id] = lca(A[i].x,A[i].y) - 1;
			solve(A[i].x,A[i].y,A[i].z-1);
		}
	}
	rep(i,1,m) cout<<ans[i]<<" "; cout<<endl;
	return 0;
}


#include<stdio.h>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<queue>
#include<cstdlib>
#include<ctime>
#include<set>
#include<cassert>
#define rep(i,j,k) for(register int i = j; i <= k; i++)
#define dow(i,j,k) for(register int i = j; i >= k; i--)
#define ll long long
#define mp make_pair
using namespace std;

inline int read() {
	int s = 0, t = 1; char c = getchar();
	while( !isdigit(c) ) { if( c == '-' ) t = -1; c = getchar(); }
	while( isdigit(c) ) s = s * 10 + c - 48, c = getchar();
	return s * t;
}

const int N = 2e5+5, inf = 1e9+7;
inline void Min(int &x,int v) { if( x > v ) x = v; }
inline void Max(int &x,int v) { if( v > x ) x = v; }

struct Edge{ int x, y, v, id; bool used; bool operator < (const Edge&rhs) const { return v < rhs.v; } } A[N];
struct edge{ int to, nxt, v, id; } e[N<<1];
int n, m, ans[N], head[N], cnt = 0;
inline void add(int x,int y,int v,int id) {
	e[++cnt].to = y, e[cnt].v = v, e[cnt].id = id, e[cnt].nxt = head[x], head[x] = cnt;
	e[++cnt].to = x, e[cnt].v = v, e[cnt].id = id, e[cnt].nxt = head[y], head[y] = cnt;
}
struct Tree{
	int fa[N], q[N];
	inline void init(int n) { rep(i,1,n) fa[i] = i; }
	inline int find(int x) {
		static int tot = 0;
		while( x != fa[x] ) q[++tot] = x, x = fa[x];
		while( tot ) fa[q[tot--]] = x;
		return x;
	}
} B;

int maxl[N<<2], minl[N<<2], top[N], fa[N], dep[N], son[N], sz[N], w[N], tot = 0, bel[N], f[N], g[N];
#define ez(i,j) for(register int i = head[j]; i; i=e[i].nxt)
#define to e[i].to
inline void dfs1(int x) {
	son[x] = 0, sz[x] = 1;
	ez(i,x) {
		if( to != fa[x] ) {
			dep[to] = dep[fa[to]=x] + 1, dfs1(to), f[to] = e[i].v, g[to] = e[i].id;
			sz[x] += sz[to]; if( sz[to] > sz[son[x]] ) son[x] = to;
		}
	}
}
inline void dfs2(int x,int ph) {
	top[x] = ph, w[x] = ++tot, bel[tot] = x;
	if( son[x] ) dfs2(son[x],ph);
	ez(i,x) if( to != fa[x] && to != son[x] ) dfs2(to,to);
}

#define lc k<<1
#define rc k<<1|1
inline void build(int l,int r,int k) {
	minl[k] = inf;
	if( l == r ) {
		maxl[k] = f[bel[l]];
		return;
	}
	int mid = (l + r) >> 1;
	build(l,mid,lc), build(mid+1,r,rc), maxl[k] = max(maxl[lc],maxl[rc]);
}

int ql, qr, d;
inline void up(int l,int r,int k) {
	if( ql <= l && r <= qr ) { Min(minl[k],d); return; }
	int mid = (l + r) >> 1;
	if( ql <= mid ) up(l,mid,lc);
	if( qr > mid ) up(mid+1,r,rc);
}
inline int query(int l,int r,int k) {
	if( ql <= l && r <= qr ) return maxl[k];
	int mid = (l + r) >> 1;
	if( qr <= mid ) return query(l,mid,lc);
	if( ql > mid ) return query(mid+1,r,rc);
	return max(query(l,mid,lc),query(mid+1,r,rc));
}
inline void down(int l,int r,int k) {
	if( l == r ) {
		if( minl[k] == maxl[k] ) ans[g[bel[l]]] = minl[k] - 1;
		else if( minl[k] == inf ) ans[g[bel[l]]] = -1;
		else ans[g[bel[l]]] = maxl[k];
		return;
	}
	Min(minl[lc],minl[k]), Min(minl[rc],minl[k]);
	int mid = (l + r) >> 1;
	down(l,mid,lc), down(mid+1,r,rc);
}

inline void upd(int x,int y,int v) {
	d = v;
	while( top[x] != top[y] ) {
		if( dep[top[x]] < dep[top[y]] ) swap(x,y);
		ql = w[top[x]], qr = w[x], up(1,n,1), x = fa[top[x]];
	}
	if( x == y ) return;
	if( w[x] > w[y] ) swap(x,y);
	ql = w[x] + 1, qr = w[y], up(1,n,1);
}

inline int query(int x,int y) {
	int ret = 0;
	while( top[x] != top[y] ) {
		if( dep[top[x]] < dep[top[y]] ) swap(x,y);
		ql = w[top[x]], qr = w[x], Max(ret,query(1,n,1)), x = fa[top[x]];
	}
	if( x == y ) return ret;
	if( w[x] > w[y] ) swap(x,y);
	ql = w[x] + 1, qr = w[y], Max(ret,query(1,n,1));
	return ret;
}

inline void out(int l,int r,int k) {
	cout<<"O "<<l<<" "<<r<<" "<<maxl[k]<<" "<<minl[k]<<endl;
	if( l == r ) return;
	int mid = (l + r) >> 1;
	out(l,mid,lc), out(mid+1,r,rc);
}

int main() {
	n = read(), m = read();
	rep(i,1,m) A[i].x = read(), A[i].y = read(), A[i].v = read(), A[i].id = i;
	sort(A+1,A+m+1);
	B.init(n);
	rep(i,1,m) {
		int x = B.find(A[i].x), y = B.find(A[i].y);
		if( x != y ) B.fa[x] = y, add(A[i].x,A[i].y,A[i].v,i), A[i].used = 1;
	}
	dfs1(1), dfs2(1,1);
	build(1,n,1);
	memset(ans,-1,sizeof(ans));
	rep(i,1,m) {
		if( !A[i].used ) {
			upd(A[i].x,A[i].y,A[i].v);
			ans[A[i].id] = query(A[i].x,A[i].y) - 1;
		}
	}
	down(1,n,1);
	rep(i,1,m) cout<<ans[i]<<" "; cout<<endl;
	return 0;
}


#include<stdio.h>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<queue>
#include<cstdlib>
#include<ctime>
#include<set>
#include<cassert>
#define rep(i,j,k) for(register int i = j; i <= k; i++)
#define dow(i,j,k) for(register int i = j; i >= k; i--)
#define ll long long
#define mp make_pair
using namespace std;

inline int read() {
	int s = 0, t = 1; char c = getchar();
	while( !isdigit(c) ) { if( c == '-' ) t = -1; c = getchar(); }
	while( isdigit(c) ) s = s * 10 + c - 48, c = getchar();
	return s * t;
}

const int N = 2e5+5, inf = 1e9+7;
inline void Min(int &x,int v) { if( x > v ) x = v; }
inline void Max(int &x,int v) { if( v > x ) x = v; }

struct Edge{ int x, y, v, id; bool used; bool operator < (const Edge&rhs) const { return v < rhs.v; } } A[N];
struct edge{ int to, nxt, v, id; } e[N<<1];
int n, m, ans[N], head[N], cnt = 0;
inline void add(int x,int y,int v,int id) {
	e[++cnt].to = y, e[cnt].v = v, e[cnt].id = id, e[cnt].nxt = head[x], head[x] = cnt;
	e[++cnt].to = x, e[cnt].v = v, e[cnt].id = id, e[cnt].nxt = head[y], head[y] = cnt;
}
struct Tree{
	int fa[N], q[N];
	inline void init(int n) { rep(i,1,n) fa[i] = i; }
	inline int find(int x) {
		static int tot = 0;
		while( x != fa[x] ) q[++tot] = x, x = fa[x];
		while( tot ) fa[q[tot--]] = x;
		return x;
	}
} B;

int maxl[N<<2], minl[N<<2], top[N], fa[N], dep[N], son[N], sz[N], w[N], tot = 0, bel[N], f[N], g[N];
#define ez(i,j) for(register int i = head[j]; i; i=e[i].nxt)
#define to e[i].to
inline void dfs1(int x) {
	son[x] = 0, sz[x] = 1;
	ez(i,x) {
		if( to != fa[x] ) {
			dep[to] = dep[fa[to]=x] + 1, dfs1(to), f[to] = e[i].v, g[to] = e[i].id;
			sz[x] += sz[to]; if( sz[to] > sz[son[x]] ) son[x] = to;
		}
	}
}
inline void dfs2(int x,int ph) {
	top[x] = ph, w[x] = ++tot, bel[tot] = x;
	if( son[x] ) dfs2(son[x],ph);
	ez(i,x) if( to != fa[x] && to != son[x] ) dfs2(to,to);
}

#define lc k<<1
#define rc k<<1|1
inline void build(int l,int r,int k) {
	minl[k] = inf;
	if( l == r ) {
		maxl[k] = f[bel[l]];
		return;
	}
	int mid = (l + r) >> 1;
	build(l,mid,lc), build(mid+1,r,rc), maxl[k] = max(maxl[lc],maxl[rc]);
}

int ql, qr, d;
inline void up(int l,int r,int k) {
	if( ql <= l && r <= qr ) { Min(minl[k],d); return; }
	int mid = (l + r) >> 1;
	if( ql <= mid ) up(l,mid,lc);
	if( qr > mid ) up(mid+1,r,rc);
}
inline int query(int l,int r,int k) {
	if( ql <= l && r <= qr ) return maxl[k];
	int mid = (l + r) >> 1;
	if( qr <= mid ) return query(l,mid,lc);
	if( ql > mid ) return query(mid+1,r,rc);
	return max(query(l,mid,lc),query(mid+1,r,rc));
}
inline void down(int l,int r,int k) {
	if( l == r ) {
		if( minl[k] == maxl[k] ) ans[g[bel[l]]] = minl[k] - 1;
		else if( minl[k] == inf ) ans[g[bel[l]]] = -1;
		else ans[g[bel[l]]] = minl[k] - 1;
		return;
	}
	Min(minl[lc],minl[k]), Min(minl[rc],minl[k]);
	int mid = (l + r) >> 1;
	down(l,mid,lc), down(mid+1,r,rc);
}

inline void upd(int x,int y,int v) {
	d = v;
	while( top[x] != top[y] ) {
		if( dep[top[x]] < dep[top[y]] ) swap(x,y);
		ql = w[top[x]], qr = w[x], up(1,n,1), x = fa[top[x]];
	}
	if( x == y ) return;
	if( w[x] > w[y] ) swap(x,y);
	ql = w[x] + 1, qr = w[y], up(1,n,1);
}

inline int query(int x,int y) {
	int ret = 0;
	while( top[x] != top[y] ) {
		if( dep[top[x]] < dep[top[y]] ) swap(x,y);
		ql = w[top[x]], qr = w[x], Max(ret,query(1,n,1)), x = fa[top[x]];
	}
	if( x == y ) return ret;
	if( w[x] > w[y] ) swap(x,y);
	ql = w[x] + 1, qr = w[y], Max(ret,query(1,n,1));
	return ret;
}

inline void out(int l,int r,int k) {
	cout<<"O "<<l<<" "<<r<<" "<<maxl[k]<<" "<<minl[k]<<endl;
	if( l == r ) return;
	int mid = (l + r) >> 1;
	out(l,mid,lc), out(mid+1,r,rc);
}

int main() {
	n = read(), m = read();
	rep(i,1,m) A[i].x = read(), A[i].y = read(), A[i].v = read(), A[i].id = i;
	sort(A+1,A+m+1);
	B.init(n);
	rep(i,1,m) {
		int x = B.find(A[i].x), y = B.find(A[i].y);
		if( x != y ) B.fa[x] = y, add(A[i].x,A[i].y,A[i].v,i), A[i].used = 1;
	}
	dfs1(1), dfs2(1,1);
	build(1,n,1);
	rep(i,1,m) {
		if( !A[i].used ) {
			upd(A[i].x,A[i].y,A[i].v);
			ans[A[i].id] = query(A[i].x,A[i].y) - 1;
		}
	}
	down(1,n,1);
	rep(i,1,m) cout<<ans[i]<<" "; cout<<endl;
	return 0;
}


#include<stdio.h>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<queue>
#include<cstdlib>
#include<ctime>
#include<set>
#include<vector>
#include<cassert>
#define rep(i,j,k) for(register int i = j; i <= k; i++)
#define dow(i,j,k) for(register int i = j; i >= k; i--)
#define ll long long
#define mp make_pair
using namespace std;

inline int read() {
	int s = 0, t = 1; char c = getchar();
	while( !isdigit(c) ) { if( c == '-' ) t = -1; c = getchar(); }
	while( isdigit(c) ) s = s * 10 + c - 48, c = getchar();
	return s * t;
}

const int N = 2e5+5, BT = 20;
inline void Max(int &x,int v) { if( v > x ) x = v; }
struct edge{ int x, y, z, id; bool used; bool operator < (const edge&rhs) const { return z < rhs.z; } } A[N];
struct Tree{
	int fa[N], q[N], tot;
	inline int find(int x) {
		while( x != fa[x] ) q[++tot] = x, x = fa[x];
		while( tot ) fa[q[tot--]] = x;
		return x;
	}
	inline void init(int n) { rep(i,1,n) fa[i] = i; }
} B;
vector<pair<int,int> > S[N]; int fa[N][BT], f[N][BT], g[N], dep[N], ans[N];
inline void dfs(int x) {
	for(register int i = 1; dep[x] >= (1<<i); i++) fa[x][i] = fa[fa[x][i-1]][i-1], f[x][i] = max(f[x][i-1],f[fa[x][i-1]][i-1]);
	for(vector<pair<int,int> >::iterator it = S[x].begin(); it != S[x].end(); it++) if( it->first != fa[x][0] ) dep[it->first] = dep[x] + 1, fa[it->first][0] = x, f[it->first][0] = A[it->second].z, g[it->first] = it->second, dfs(it->first);
}

inline void add(int x,int y,int z) {
	S[y].push_back(mp(x,z)), S[x].push_back(mp(y,z));
}

inline int lca(int x,int y) {
	int ret = 0;
	if( dep[x] < dep[y] ) swap(x,y);
	int t = dep[x] - dep[y];
	for(register int i = 0; i < BT && t; i++) if( (t >> i) & 1 ) Max(ret,f[x][i]), x = fa[x][i];
	if( x == y ) return ret;
	dow(i,BT-1,0) if( fa[x][i] != fa[y][i] ) Max(ret,f[x][i]), Max(ret,f[y][i]), x = fa[x][i], y = fa[y][i];
	Max(ret,f[x][0]), Max(ret,f[y][0]);
	return ret;
}

inline void solve(int x,int y,int z) {
	while( (x = B.find(x)) != (y = B.find(y)) ) {
		if( dep[x] > dep[y] ) {
			ans[A[g[x]].id] = z, B.fa[x] = fa[x][0];
		} else {
			ans[A[g[y]].id] = z, B.fa[y] = fa[y][0];
		}
	}
}

int main() {
	int n = read(), m = read(), x, y;
	rep(i,1,m) A[i].x = read(), A[i].y = read(), A[i].z = read(), A[i].id = i;
	sort(A+1,A+m+1);
	B.init(n);
	rep(i,1,m) {
		x = B.find(A[i].x), y = B.find(A[i].y);
		if( x != y ) B.fa[x] = y, add(A[i].x,A[i].y,i), A[i].used = 1;
	}
	dfs(1);
	memset(ans,-1,sizeof(ans));
	B.init(n);
	rep(i,1,m) {
		if( !A[i].used ) {
			ans[A[i].id] = lca(A[i].x,A[i].y) - 1;
			solve(A[i].x,A[i].y,A[i].z-1);
		}
	}
	rep(i,1,m) cout<<ans[i]<<" "; cout<<endl;
	return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define fio ios_base::sync_with_stdio(false)
#define MOD 1000000007
#define INF 1000000000
#define INFLL 1000000000000000000ll
#define stlfor(a, b) for(auto a=b.begin(); a!=b.end(); a++)
#define rstlfor(a, b) for(auto a=b.rbegin(); a!=b.rend(); a++)
#define mp make_pair
#define pb push_back
#define ff first
#define ss second
#define long int64_t
using namespace std;
using namespace __gnu_pbds;
typedef pair<int, int> pii;
typedef pair<int, pii> pip;
typedef pair<pip, int> pipi;
typedef priority_queue<pipi, vector<pipi>, greater<pipi>> min_pq;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> OST;

const int N = 200001;
const int LOGN = 19;

vector<pip> tr[N];
map<int, int> *s[N];
vector<pip> e;
vector<bool> b;
vector<int> ans, in[N], out[N];
int p[N], d[N], st[LOGN][N][2];

int par(int node)
{
    return (p[node] < 0 ? node : p[node] = par(p[node]));
}

void findMST(int n, int m)
{
    memset(p, -1, sizeof p);
    b.resize(m, false);
    min_pq q;
    for(int i=0; i<m; i++)
        q.push(mp(e[i], i));
    int cnt = 1;
    while(cnt < n)
    {
        auto t = q.top();
        q.pop();
        int x = par(t.ff.ss.ff), y = par(t.ff.ss.ss);
        if(x != y)
        {
            tr[t.ff.ss.ff].pb(mp(t.ff.ss.ss, mp(t.ff.ff, t.ss)));
            tr[t.ff.ss.ss].pb(mp(t.ff.ss.ff, mp(t.ff.ff, t.ss)));
            b[t.ss] = true;
            if(p[x] < p[y])
            {
                p[x] += p[y];
                p[y] = x;
            }
            else
            {
                p[y] += p[x];
                p[x] = y;
            }
            cnt++;
        }
    }
}

void init_dfs(int node, int pn, int w, int dr)
{
    st[0][node][0] = pn;
    st[0][node][1] = w;
    d[node] = dr;
    for(auto &it : tr[node])
        if(it.ff != pn)
            init_dfs(it.ff, node, it.ss.ff, dr + 1);
}

void init_lca(int n)
{
    for(int j=1; j<LOGN; j++)
    {
        for(int i=1; i<=n; i++)
        {
            st[j][i][0] = st[j-1][st[j-1][i][0]][0];
            st[j][i][1] = max(st[j-1][i][1], st[j-1][st[j-1][i][0]][1]);
        }
    }
}

pii lca(int u, int v)
{
    int w = 0;
    if(d[u] < d[v])
        swap(u, v);
    for(int i=LOGN-1; i>=0; i--)
    {
        if(d[st[i][u][0]] >= d[v])
        {
            w = max(w, st[i][u][1]);
            u = st[i][u][0];
        }
    }
    if(u == v)
        return mp(v, w);
    for(int i=LOGN-1; i>=0; i--)
    {
        if(st[i][u][0] != st[i][v][0])
        {
            w = max(w, max(st[i][u][1], st[i][v][1]));
            u = st[i][u][0];
            v = st[i][v][0];
        }
    }
    return mp(st[0][v][0], max(w, max(st[0][u][1], st[0][v][1])));
}

void aux(map<int, int> *a, map<int, int> *b)
{
    for(auto &it : *b)
        (*a)[it.ff] += it.ss;
    delete b;
}

void dfs(int node, int pn)
{
    s[node] = new map<int, int>;
    for(auto &it : in[node])
        (*s[node])[it]++;
    map<int, int> *ms = s[node];
    for(auto &it : tr[node])
    {
        if(it.ff != pn)
        {
            dfs(it.ff, node);
            int t = (s[it.ff]->empty() ? -1 : s[it.ff]->begin()->ff - 1);
            ans[it.ss.ss] = t;
            if(ms->size() < s[it.ff]->size())
                ms = s[it.ff];
        }
    }
    for(auto &it : tr[node])
        if(it.ff != pn and ms != s[it.ff])
            aux(ms, s[it.ff]);
    if(ms != s[node])
        aux(ms, s[node]);
    for(auto &it : out[node])
    {
        (*ms)[it] -= 2;
        if((*ms)[it] == 0)
            ms->erase(it);
    }
    s[node] = ms;
}

int main()
{
    fio;
    int n, m;
    cin >> n >> m;
    for(int i=0; i<m; i++)
    {
        int a, b, c;
        cin >> a >> b >> c;
        e.pb(mp(c, mp(a, b)));
    }
    findMST(n, m);
    init_dfs(1, 0, 0, 1);
    init_lca(n);
    ans.resize(m);
    for(int i=0; i<m; i++)
    {
        if(b[i])
            continue;
        pii t = lca(e[i].ss.ff, e[i].ss.ss);
        ans[i] = t.ss - 1;
        in[e[i].ss.ff].pb(e[i].ff);
        in[e[i].ss.ss].pb(e[i].ff);
        out[t.ff].pb(e[i].ff);
    }
    dfs(1, 0);
    for(int &it : ans)
        cout << it << ' ';
    cout << endl;
    return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define fio ios_base::sync_with_stdio(false)
#define MOD 1000000007
#define INF 1000000000
#define INFLL 1000000000000000000ll
#define stlfor(a, b) for(auto a=b.begin(); a!=b.end(); a++)
#define rstlfor(a, b) for(auto a=b.rbegin(); a!=b.rend(); a++)
#define mp make_pair
#define pb push_back
#define ff first
#define ss second
#define long int64_t
using namespace std;
using namespace __gnu_pbds;
typedef pair<int, int> pii;
typedef pair<int, pii> pip;
typedef pair<pip, int> pipi;
typedef priority_queue<pipi, vector<pipi>, greater<pipi>> min_pq;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> OST;

const int N = 200001;
const int LOGN = 19;

vector<pip> tr[N];
map<int, int> *s[N];
vector<pip> e;
vector<bool> b;
vector<int> ans, in[N], out[N];
int p[N], d[N], st[LOGN][N][2];

int par(int node)
{
    return (p[node] < 0 ? node : p[node] = par(p[node]));
}

void findMST(int n, int m)
{
    memset(p, -1, sizeof p);
    b.resize(m, false);
    min_pq q;
    for(int i=0; i<m; i++)
        q.push(mp(e[i], i));
    int cnt = 1;
    while(cnt < n)
    {
        auto t = q.top();
        q.pop();
        int x = par(t.ff.ss.ff), y = par(t.ff.ss.ss);
        if(x != y)
        {
            tr[t.ff.ss.ff].pb(mp(t.ff.ss.ss, mp(t.ff.ff, t.ss)));
            tr[t.ff.ss.ss].pb(mp(t.ff.ss.ff, mp(t.ff.ff, t.ss)));
            b[t.ss] = true;
            if(p[x] < p[y])
            {
                p[x] += p[y];
                p[y] = x;
            }
            else
            {
                p[y] += p[x];
                p[x] = y;
            }
            cnt++;
        }
    }
}

void init_dfs(int node, int pn, int w, int dr)
{
    st[0][node][0] = pn;
    st[0][node][1] = w;
    d[node] = dr;
    for(auto &it : tr[node])
        if(it.ff != pn)
            init_dfs(it.ff, node, it.ss.ff, dr + 1);
}

void init_lca(int n)
{
    for(int j=1; j<LOGN; j++)
    {
        for(int i=1; i<=n; i++)
        {
            st[j][i][0] = st[j-1][st[j-1][i][0]][0];
            st[j][i][1] = max(st[j-1][i][1], st[j-1][st[j-1][i][0]][1]);
        }
    }
}

pii lca(int u, int v)
{
    int w = 0;
    if(d[u] < d[v])
        swap(u, v);
    for(int i=LOGN-1; i>=0; i--)
    {
        if(d[st[i][u][0]] >= d[v])
        {
            w = max(w, st[i][u][1]);
            u = st[i][u][0];
        }
    }
    if(u == v)
        return mp(v, w);
    for(int i=LOGN-1; i>=0; i--)
    {
        if(st[i][u][0] != st[i][v][0])
        {
            w = max(w, max(st[i][u][1], st[i][v][1]));
            u = st[i][u][0];
            v = st[i][v][0];
        }
    }
    return mp(st[0][v][0], max(w, max(st[0][u][0], st[0][v][0])));
}

void aux(map<int, int> *a, map<int, int> *b)
{
    for(auto &it : *b)
        (*a)[it.ff] += it.ss;
    delete b;
}

void dfs(int node, int pn)
{
    s[node] = new map<int, int>;
    for(auto &it : in[node])
        (*s[node])[it]++;
    map<int, int> *ms = s[node];
    for(auto &it : tr[node])
    {
        if(it.ff != pn)
        {
            dfs(it.ff, node);
            int t = (s[it.ff]->empty() ? -1 : s[it.ff]->begin()->ff - 1);
            ans[it.ss.ss] = t;
            if(ms->size() < s[it.ff]->size())
                ms = s[it.ff];
        }
    }
    for(auto &it : tr[node])
        if(it.ff != pn and ms != s[it.ff])
            aux(ms, s[it.ff]);
    if(ms != s[node])
        aux(ms, s[node]);
    for(auto &it : out[node])
    {
        (*ms)[it]--;
        if((*ms)[it] == 0)
            ms->erase(it);
    }
    s[node] = ms;
}

int main()
{
    fio;
    int n, m;
    cin >> n >> m;
    for(int i=0; i<m; i++)
    {
        int a, b, c;
        cin >> a >> b >> c;
        e.pb(mp(c, mp(a, b)));
    }
    findMST(n, m);
    init_dfs(1, 0, 0, 0);
    init_lca(n);
    ans.resize(m, -1);
    for(int i=0; i<m; i++)
    {
        if(b[i])
            continue;
        pii t = lca(e[i].ss.ff, e[i].ss.ss);
        ans[i] = t.ss - 1;
        in[e[i].ss.ff].pb(e[i].ff);
        in[e[i].ss.ss].pb(e[i].ff);
        out[t.ff].pb(e[i].ff);
    }
    dfs(1, 0);
    for(int &it : ans)
        cout << it << ' ';
    cout << endl;
    return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define fio ios_base::sync_with_stdio(false)
#define MOD 1000000007
#define INF 1000000000
#define INFLL 1000000000000000000ll
#define stlfor(a, b) for(auto a=b.begin(); a!=b.end(); a++)
#define rstlfor(a, b) for(auto a=b.rbegin(); a!=b.rend(); a++)
#define mp make_pair
#define pb push_back
#define ff first
#define ss second
#define long int64_t
using namespace std;
using namespace __gnu_pbds;
typedef pair<int, int> pii;
typedef pair<int, pii> pip;
typedef pair<pip, int> pipi;
typedef priority_queue<pipi, vector<pipi>, greater<pipi>> min_pq;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> OST;

const int N = 200001;
const int LOGN = 19;

vector<pip> tr[N];
map<int, int> *s[N];
vector<pip> e;
vector<bool> b;
vector<int> ans, in[N], out[N];
int p[N], d[N], st[LOGN][N][2];

int par(int node)
{
    return (p[node] < 0 ? node : p[node] = par(p[node]));
}

void findMST(int n, int m)
{
    memset(p, -1, sizeof p);
    b.resize(m, false);
    min_pq q;
    for(int i=0; i<m; i++)
        q.push(mp(e[i], i));
    int cnt = 1;
    while(cnt < n)
    {
        auto t = q.top();
        q.pop();
        int x = par(t.ff.ss.ff), y = par(t.ff.ss.ss);
        if(x != y)
        {
            tr[t.ff.ss.ff].pb(mp(t.ff.ss.ss, mp(t.ff.ff, t.ss)));
            tr[t.ff.ss.ss].pb(mp(t.ff.ss.ff, mp(t.ff.ff, t.ss)));
            b[t.ss] = true;
            if(p[x] < p[y])
            {
                p[x] += p[y];
                p[y] = x;
            }
            else
            {
                p[y] += p[x];
                p[x] = y;
            }
            cnt++;
        }
    }
}

void init_dfs(int node, int pn, int w, int dr)
{
    st[0][node][0] = pn;
    st[0][node][1] = w;
    d[node] = dr;
    for(auto &it : tr[node])
        if(it.ff != pn)
            init_dfs(it.ff, node, it.ss.ff, dr + 1);
}

void init_lca(int n)
{
    for(int j=1; j<LOGN; j++)
    {
        for(int i=1; i<=n; i++)
        {
            st[j][i][0] = st[j-1][st[j-1][i][0]][0];
            st[j][i][1] = max(st[j-1][i][1], st[j-1][st[j-1][i][0]][1]);
        }
    }
}

pii lca(int u, int v)
{
    int w = 0;
    if(d[u] < d[v])
        swap(u, v);
    for(int i=LOGN-1; i>=0; i--)
    {
        if(d[st[i][u][0]] >= d[v])
        {
            w = max(w, st[i][u][1]);
            u = st[i][u][0];
        }
    }
    if(u == v)
        return mp(v, w);
    for(int i=LOGN-1; i>=0; i--)
    {
        if(st[i][u][0] != st[i][v][0])
        {
            w = max(w, max(st[i][u][1], st[i][v][1]));
            u = st[i][u][0];
            v = st[i][v][0];
        }
    }
    return mp(st[0][v][0], max(w, max(st[0][u][0], st[0][v][0])));
}

void aux(map<int, int> *a, map<int, int> *b)
{
    for(auto &it : *b)
        (*a)[it.ff] += it.ss;
    delete b;
}

void dfs(int node, int pn)
{
    s[node] = new map<int, int>;
    for(auto &it : in[node])
        (*s[node])[it]++;
    map<int, int> *ms = s[node];
    for(auto &it : tr[node])
    {
        if(it.ff != pn)
        {
            dfs(it.ff, node);
            int t = (s[it.ff]->empty() ? -1 : s[it.ff]->begin()->ff - 1);
            ans[it.ss.ss] = t;
            if(ms->size() < s[it.ff]->size())
                ms = s[it.ff];
        }
    }
    for(auto &it : tr[node])
        if(it.ff != pn and ms != s[it.ff])
            aux(ms, s[it.ff]);
    if(ms != s[node])
        aux(ms, s[node]);
    for(auto &it : out[node])
    {
        (*ms)[it]--;
        if((*ms)[it] == 0)
            ms->erase(it);
    }
    s[node] = ms;
}

int main()
{
    fio;
    int n, m;
    cin >> n >> m;
    for(int i=0; i<m; i++)
    {
        int a, b, c;
        cin >> a >> b >> c;
        e.pb(mp(c, mp(a, b)));
    }
    findMST(n, m);
    init_dfs(1, 0, 0, 0);
    init_lca(n);
    ans.resize(m);
    for(int i=0; i<m; i++)
    {
        if(b[i])
            continue;
        pii t = lca(e[i].ss.ff, e[i].ss.ss);
        ans[i] = t.ss - 1;
        in[e[i].ss.ff].pb(e[i].ff);
        in[e[i].ss.ss].pb(e[i].ff);
        out[t.ff].pb(e[i].ff);
    }
    dfs(1, 0);
    for(int &it : ans)
        cout << it << ' ';
    cout << endl;
    return 0;
}


/**
  *  Worg
  */
#include <cstdio>
#include <vector>
#include <algorithm>

//FILE *fin = freopen("main.in", "r", stdin);
//FILE *fout = freopen("main.out", "w", stdout);

const int kMaxN = 2e5 + 1;
const int kMaxLog = 18;

/*-------- Structures --------*/
struct Edge {
    int u, v, cost, index;
    Edge(int u, int v, int cost, int index) {
        this->u = u; this->v = v; this->cost = cost; this->index = index;
    }
    bool operator <(const Edge &other) const {
        return this->cost < other.cost;
    }
};
/*-------- Input data --------*/
int N, M;
std::vector<Edge > edges;
/*-------- MST data --------*/
int father[kMaxN];
std::vector<Edge > tree[kMaxN];

int ancestor[kMaxLog][kMaxN], maxDist[kMaxLog][kMaxN];
int depth[kMaxN], fatherIndex[kMaxN];
/*-------- Final part --------*/
bool selected[kMaxN];
int edgeAnswer[kMaxN];
/*-------- --------*/

void ReadInput() {
    scanf("%d%d", &N, &M);
    for(int i = 1; i <= M; i++) {
        int u, v, cost; scanf("%d%d%d", &u, &v, &cost);
        edges.push_back({u, v, cost, i});
    }
}

inline int Group(int x) {
    if(x != father[x]) {
        father[x] = Group(father[x]);
    }
    return father[x];
}

void BuildMST() {
    std::sort(edges.begin(), edges.end());
    for(int i = 1; i <= N; i++) {
        father[i] = i;
    }
    for(auto edge : edges) {
        if(Group(edge.u) != Group(edge.v)) {
            selected[edge.index] = true;
            father[edge.u] = edge.v;
            tree[edge.u].push_back({edge.u, edge.v, edge.cost, edge.index});
            tree[edge.v].push_back({edge.v, edge.u, edge.cost, edge.index});
        }
    }
}

inline void DFS(int node, int father, int edgeCost) {
    depth[node] = depth[father] + 1;

    ancestor[0][node] = father; maxDist[0][node] = edgeCost;
    for(int i = 1; i < kMaxLog; i++) {
        ancestor[i][node] = ancestor[i - 1][ancestor[i - 1][node]];
        maxDist[i][node] = std::max(maxDist[i - 1][node], maxDist[i - 1][ancestor[i - 1][node]]);
    }

    for(auto edge : tree[node]) {
        if(edge.v != father) {
            fatherIndex[edge.v] = edge.index;
            DFS(edge.v, node, edge.cost);
        }
    }
}

int LCA(int u, int v, int &answer) {
    if(depth[v] > depth[u]) {
        std::swap(u, v);
    }

    answer = 0;
    for(int step = kMaxLog - 1; step >= 0; step--) {
        if((1 << step) <= depth[u] - depth[v]) {
            answer = std::max(answer, maxDist[step][u] - 1);
            u = ancestor[step][u];
        }
    }

    if(u == v) {
        return u;
    } else {
        for(int step = kMaxLog - 1; step >= 0; step--) {
            if(ancestor[step][u] != ancestor[step][v]) {
                answer = std::max(answer, std::max(maxDist[step][u], maxDist[step][v]));
                u = ancestor[step][u]; v = ancestor[step][v];
            }
        }
        answer = std::max(answer, maxDist[0][u] - 1);
        return ancestor[0][u];
    }
}

void Update(int down, int up, int cost) {
    down = Group(down);
    while(depth[down] > depth[up]) {
        edgeAnswer[fatherIndex[down]] = std::min(edgeAnswer[fatherIndex[down]], cost);
        father[down] = Group(ancestor[0][down]);
        down = Group(down);
    }
}

void SolveEdges() {
    for(int i = 1; i <= N; i++) {
        father[i] = i;
    }
    for(int i = 1; i <= M; i++) {
        if(selected[i]) {
            edgeAnswer[i] = 2e9;
        }
    }
    for(auto edge : edges) {
        if(!selected[edge.index]) {
            int lca = LCA(edge.u, edge.v, edgeAnswer[edge.index]);
            Update(edge.u, lca, edge.cost - 1);
            Update(edge.v, lca, edge.cost - 1);
        }
    }
}

int main() {
    ReadInput();
    BuildMST();
    DFS(1, 0, 0);
    SolveEdges();
    for(int i = 1; i <= M; i++) {
        if(edgeAnswer[i] == 2e9) {
            printf("-1 ");
        } else {
            printf("%d ", edgeAnswer[i]);
        }
    }
    return 0;
}


/**
  *  Worg
  */
#include <cstdio>
#include <vector>
#include <algorithm>

//FILE *fin = freopen("main.in", "r", stdin);
//FILE *fout = freopen("main.out", "w", stdout);

const int kMaxN = 2e5 + 1;
const int kMaxLog = 18;

/*-------- Structures --------*/
struct Edge {
    int u, v, cost, index;
    Edge(int u, int v, int cost, int index) {
        this->u = u; this->v = v; this->cost = cost; this->index = index;
    }
    bool operator <(const Edge &other) const {
        return this->cost < other.cost;
    }
};
/*-------- Input data --------*/
int N, M;
std::vector<Edge > edges;
/*-------- MST data --------*/
int father[kMaxN];
std::vector<Edge > tree[kMaxN];

int ancestor[kMaxLog][kMaxN], maxDist[kMaxLog][kMaxN];
int depth[kMaxN], fatherIndex[kMaxN];
/*-------- Final part --------*/
bool selected[kMaxN];
int edgeAnswer[kMaxN];
/*-------- --------*/

void ReadInput() {
    scanf("%d%d", &N, &M);
    for(int i = 1; i <= M; i++) {
        int u, v, cost; scanf("%d%d%d", &u, &v, &cost);
        edges.push_back({u, v, cost, i});
    }
}

inline int Group(int x) {
    if(x != father[x]) {
        father[x] = Group(father[x]);
    }
    return father[x];
}

void BuildMST() {
    std::sort(edges.begin(), edges.end());
    for(int i = 1; i <= N; i++) {
        father[i] = i;
    }
    for(auto edge : edges) {
        if(Group(edge.u) != Group(edge.v)) {
            selected[edge.index] = true;
            father[Group(edge.u)] = Group(edge.v);
            tree[edge.u].push_back({edge.u, edge.v, edge.cost, edge.index});
            tree[edge.v].push_back({edge.v, edge.u, edge.cost, edge.index});
        }
    }
}

inline void DFS(int node, int father, int edgeCost) {
    depth[node] = depth[father] + 1;

    ancestor[0][node] = father; maxDist[0][node] = edgeCost;
    for(int i = 1; i < kMaxLog; i++) {
        ancestor[i][node] = ancestor[i - 1][ancestor[i - 1][node]];
        maxDist[i][node] = std::max(maxDist[i - 1][node], maxDist[i - 1][ancestor[i - 1][node]]);
    }

    for(auto edge : tree[node]) {
        if(edge.v != father) {
            fatherIndex[edge.v] = edge.index;
            DFS(edge.v, node, edge.cost);
        }
    }
}

int LCA(int u, int v, int &answer) {
    if(depth[v] > depth[u]) {
        std::swap(u, v);
    }

    answer = 0;
    for(int step = kMaxLog - 1; step >= 0; step--) {
        if((1 << step) <= depth[u] - depth[v]) {
            answer = std::max(answer, maxDist[step][u] - 1);
            u = ancestor[step][u];
        }
    }

    if(u == v) {
        return u;
    } else {
        for(int step = kMaxLog - 1; step >= 0; step--) {
            if(ancestor[step][u] != ancestor[step][v]) {
                answer = std::max(answer, std::max(maxDist[step][u], maxDist[step][v]) - 1);
                u = ancestor[step][u]; v = ancestor[step][v];
            }
        }
        answer = std::max(answer, maxDist[0][u] - 1);
        return ancestor[0][u];
    }
}

void Update(int down, int up, int cost) {
    down = Group(down);
    while(depth[down] > depth[up]) {
        edgeAnswer[fatherIndex[down]] = std::min(edgeAnswer[fatherIndex[down]], cost);
        father[down] = Group(ancestor[0][down]);
        down = Group(down);
    }
}

void SolveEdges() {
    for(int i = 1; i <= N; i++) {
        father[i] = i;
    }
    for(int i = 1; i <= M; i++) {
        if(selected[i]) {
            edgeAnswer[i] = 2e9;
        }
    }
    for(auto edge : edges) {
        if(!selected[edge.index]) {
            int lca = LCA(edge.u, edge.v, edgeAnswer[edge.index]);
            Update(edge.u, lca, edge.cost - 1);
            Update(edge.v, lca, edge.cost - 1);
        }
    }
}

int main() {
    ReadInput();
    BuildMST();
    DFS(1, 0, 0);
    SolveEdges();
    for(int i = 1; i <= M; i++) {
        if(edgeAnswer[i] == 2e9) {
            printf("-1 ");
        } else {
            printf("%d ", edgeAnswer[i]);
        }
    }
    return 0;
}


/**
  *  Worg
  */
#include <cstdio>
#include <vector>
#include <algorithm>

FILE *fin = freopen("main.in", "r", stdin);
FILE *fout = freopen("main.out", "w", stdout);

const int kMaxN = 2e5 + 1;
const int kMaxLog = 18;

/*-------- Structures --------*/
struct Edge {
    int u, v, cost, index;
    Edge(int u, int v, int cost, int index) {
        this->u = u; this->v = v; this->cost = cost; this->index = index;
    }
    bool operator <(const Edge &other) const {
        return this->cost < other.cost;
    }
};
/*-------- Input data --------*/
int N, M;
std::vector<Edge > edges;
/*-------- MST data --------*/
int father[kMaxN];
std::vector<Edge > tree[kMaxN];

int ancestor[kMaxLog][kMaxN], maxDist[kMaxLog][kMaxN];
int depth[kMaxN], fatherIndex[kMaxN];
/*-------- Final part --------*/
bool selected[kMaxN];
int edgeAnswer[kMaxN];
/*-------- --------*/

void ReadInput() {
    scanf("%d%d", &N, &M);
    for(int i = 1; i <= M; i++) {
        int u, v, cost; scanf("%d%d%d", &u, &v, &cost);
        edges.push_back({u, v, cost, i});
    }
}

inline int Group(int x) {
    if(x != father[x]) {
        father[x] = Group(father[x]);
    }
    return father[x];
}

void BuildMST() {
    std::sort(edges.begin(), edges.end());
    for(int i = 1; i <= N; i++) {
        father[i] = i;
    }
    for(auto edge : edges) {
        if(Group(edge.u) != Group(edge.v)) {
            selected[edge.index] = true;
            father[Group(edge.u)] = Group(edge.v);
            tree[edge.u].push_back({edge.u, edge.v, edge.cost, edge.index});
            tree[edge.v].push_back({edge.v, edge.u, edge.cost, edge.index});
        }
    }
}

inline void DFS(int node, int father, int edgeCost) {
    depth[node] = depth[father] + 1;

    ancestor[0][node] = father; maxDist[0][node] = edgeCost;
    for(int i = 1; i < kMaxLog; i++) {
        ancestor[i][node] = ancestor[i - 1][ancestor[i - 1][node]];
        maxDist[i][node] = std::max(maxDist[i - 1][node], maxDist[i - 1][ancestor[i - 1][node]]);
    }

    for(auto edge : tree[node]) {
        if(edge.v != father) {
            fatherIndex[edge.v] = edge.index;
            DFS(edge.v, node, edge.cost);
        }
    }
}

int LCA(int u, int v, int &answer) {
    if(depth[v] > depth[u]) {
        std::swap(u, v);
    }

    answer = 0;
    for(int step = kMaxLog - 1; step >= 0; step--) {
        if((1 << step) <= depth[u] - depth[v]) {
            answer = std::max(answer, maxDist[step][u] - 1);
            u = ancestor[step][u];
        }
    }

    if(u == v) {
        return u;
    } else {
        for(int step = kMaxLog - 1; step >= 0; step--) {
            if(ancestor[step][u] != ancestor[step][v]) {
                answer = std::max(answer, std::max(maxDist[step][u], maxDist[step][v]) - 1);
                u = ancestor[step][u]; v = ancestor[step][v];
            }
        }
        answer = std::max(answer, std::max(maxDist[0][u], maxDist[0][v]) - 1);
        return ancestor[0][u];
    }
}

void Update(int down, int up, int cost) {
    down = Group(down);
    while(depth[down] > depth[up]) {
        edgeAnswer[fatherIndex[down]] = std::min(edgeAnswer[fatherIndex[down]], cost);
        father[Group(down)] = Group(ancestor[0][down]);
        down = Group(down);
    }
}

void SolveEdges() {
    for(int i = 1; i <= N; i++) {
        father[i] = i;
    }
    for(int i = 1; i <= M; i++) {
        if(selected[i]) {
            edgeAnswer[i] = 2e9;
        }
    }
    printf("\n");
    for(auto edge : edges) {
        if(!selected[edge.index]) {
            int lca = LCA(edge.u, edge.v, edgeAnswer[edge.index]);
            Update(edge.u, lca, edge.cost - 1);
            Update(edge.v, lca, edge.cost - 1);
        }
    }
}

int main() {
    ReadInput();
    BuildMST();
    DFS(1, 0, 0);
    SolveEdges();
    for(int i = 1; i <= M; i++) {
        if(edgeAnswer[i] == 2e9) {
            printf("-1 ");
        } else {
            printf("%d ", edgeAnswer[i]);
        }
    }
    return 0;
}


/**
  *  Worg
  */
#include <cstdio>
#include <vector>
#include <algorithm>

//FILE *fin = freopen("main.in", "r", stdin);
//FILE *fout = freopen("main.out", "w", stdout);

const int kMaxN = 2e5 + 1;
const int kMaxLog = 18;

/*-------- Structures --------*/
struct Edge {
    int u, v, cost, index;
    Edge(int u, int v, int cost, int index) {
        this->u = u; this->v = v; this->cost = cost; this->index = index;
    }
    bool operator <(const Edge &other) const {
        return this->cost < other.cost;
    }
};
/*-------- Input data --------*/
int N, M;
std::vector<Edge > edges;
/*-------- MST data --------*/
int father[kMaxN];
std::vector<Edge > tree[kMaxN];

int ancestor[kMaxLog][kMaxN], maxDist[kMaxLog][kMaxN];
int depth[kMaxN], fatherIndex[kMaxN];
/*-------- Final part --------*/
bool selected[kMaxN];
int edgeAnswer[kMaxN];
/*-------- --------*/

void ReadInput() {
    scanf("%d%d", &N, &M);
    for(int i = 1; i <= M; i++) {
        int u, v, cost; scanf("%d%d%d", &u, &v, &cost);
        edges.push_back({u, v, cost, i});
    }
}

inline int Group(int x) {
    if(x != father[x]) {
        father[x] = Group(father[x]);
    }
    return father[x];
}

void BuildMST() {
    std::sort(edges.begin(), edges.end());
    for(int i = 1; i <= N; i++) {
        father[i] = i;
    }
    for(auto edge : edges) {
        if(Group(edge.u) != Group(edge.v)) {
            selected[edge.index] = true;
            father[Group(edge.u)] = Group(edge.v);
            tree[edge.u].push_back({edge.u, edge.v, edge.cost, edge.index});
            tree[edge.v].push_back({edge.v, edge.u, edge.cost, edge.index});
        }
    }
}

inline void DFS(int node, int father, int edgeCost) {
    depth[node] = depth[father] + 1;

    ancestor[0][node] = father; maxDist[0][node] = edgeCost;
    for(int i = 1; i < kMaxLog; i++) {
        ancestor[i][node] = ancestor[i - 1][ancestor[i - 1][node]];
        maxDist[i][node] = std::max(maxDist[i - 1][node], maxDist[i - 1][ancestor[i - 1][node]]);
    }

    for(auto edge : tree[node]) {
        if(edge.v != father) {
            fatherIndex[edge.v] = edge.index;
            DFS(edge.v, node, edge.cost);
        }
    }
}

int LCA(int u, int v, int &answer) {
    if(depth[v] > depth[u]) {
        std::swap(u, v);
    }

    answer = 0;
    for(int step = kMaxLog - 1; step >= 0; step--) {
        if((1 << step) <= depth[u] - depth[v]) {
            answer = std::max(answer, maxDist[step][u] - 1);
            u = ancestor[step][u];
        }
    }

    if(u == v) {
        return u;
    } else {
        for(int step = kMaxLog - 1; step >= 0; step--) {
            if(ancestor[step][u] != ancestor[step][v]) {
                answer = std::max(answer, std::max(maxDist[step][u], maxDist[step][v]) - 1);
                u = ancestor[step][u]; v = ancestor[step][v];
            }
        }
        answer = std::max(answer, std::max(maxDist[0][u], maxDist[0][v]) - 1);
        return ancestor[0][u];
    }
}

void Update(int down, int up, int cost) {
    down = Group(down);
    while(depth[down] > depth[up]) {
        edgeAnswer[fatherIndex[down]] = std::min(edgeAnswer[fatherIndex[down]], cost);
        father[Group(down)] = Group(ancestor[0][down]);
        down = Group(down);
    }
}

void SolveEdges() {
    for(int i = 1; i <= N; i++) {
        father[i] = i;
    }
    for(int i = 1; i <= M; i++) {
        if(selected[i]) {
            edgeAnswer[i] = 2e9;
        }
    }
    printf("\n");
    for(auto edge : edges) {
        if(!selected[edge.index]) {
            int lca = LCA(edge.u, edge.v, edgeAnswer[edge.index]);
            Update(edge.u, lca, edge.cost - 1);
            Update(edge.v, lca, edge.cost - 1);
        }
    }
}

int main() {
    ReadInput();
    BuildMST();
    DFS(1, 0, 0);
    SolveEdges();
    for(int i = 1; i <= M; i++) {
        if(edgeAnswer[i] == 2e9) {
            printf("-1 ");
        } else {
            printf("%d ", edgeAnswer[i]);
        }
    }
    return 0;
}


/**
  *  Worg
  */
#include <cstdio>
#include <vector>
#include <algorithm>

//FILE *fin = freopen("main.in", "r", stdin);
//FILE *fout = freopen("main.out", "w", stdout);

const int kMaxN = 2e5 + 1;
const int kMaxLog = 18;

/*-------- Structures --------*/
struct Edge {
    int u, v, cost, index;
    Edge(int u, int v, int cost, int index) {
        this->u = u; this->v = v; this->cost = cost; this->index = index;
    }
    bool operator <(const Edge &other) const {
        return this->cost < other.cost;
    }
};
/*-------- Input data --------*/
int N, M;
std::vector<Edge > edges;
/*-------- MST data --------*/
int father[kMaxN];
std::vector<Edge > tree[kMaxN];

int ancestor[kMaxLog][kMaxN], maxDist[kMaxLog][kMaxN];
int depth[kMaxN], fatherIndex[kMaxN];
/*-------- Final part --------*/
bool selected[kMaxN];
int edgeAnswer[kMaxN];
/*-------- --------*/

void ReadInput() {
    scanf("%d%d", &N, &M);
    for(int i = 1; i <= M; i++) {
        int u, v, cost; scanf("%d%d%d", &u, &v, &cost);
        edges.push_back({u, v, cost, i});
    }
}

inline int Group(int x) {
    if(x != father[x]) {
        father[x] = Group(father[x]);
    }
    return father[x];
}

void BuildMST() {
    std::sort(edges.begin(), edges.end());
    for(int i = 1; i <= N; i++) {
        father[i] = i;
    }
    for(auto edge : edges) {
        if(Group(edge.u) != Group(edge.v)) {
            selected[edge.index] = true;
            father[Group(edge.u)] = Group(edge.v);
            tree[edge.u].push_back({edge.u, edge.v, edge.cost, edge.index});
            tree[edge.v].push_back({edge.v, edge.u, edge.cost, edge.index});
        }
    }
}

inline void DFS(int node, int father, int edgeCost) {
    depth[node] = depth[father] + 1;

    ancestor[0][node] = father; maxDist[0][node] = edgeCost;
    for(int i = 1; i < kMaxLog; i++) {
        ancestor[i][node] = ancestor[i - 1][ancestor[i - 1][node]];
        maxDist[i][node] = std::max(maxDist[i - 1][node], maxDist[i - 1][ancestor[i - 1][node]]);
    }

    for(auto edge : tree[node]) {
        if(edge.v != father) {
            fatherIndex[edge.v] = edge.index;
            DFS(edge.v, node, edge.cost);
        }
    }
}

int LCA(int u, int v, int &answer) {
    if(depth[v] > depth[u]) {
        std::swap(u, v);
    }

    answer = 0;
    for(int step = kMaxLog - 1; step >= 0; step--) {
        if((1 << step) <= depth[u] - depth[v]) {
            answer = std::max(answer, maxDist[step][u] - 1);
            u = ancestor[step][u];
        }
    }

    if(u == v) {
        return u;
    } else {
        for(int step = kMaxLog - 1; step >= 0; step--) {
            if(ancestor[step][u] != ancestor[step][v]) {
                answer = std::max(answer, std::max(maxDist[step][u], maxDist[step][v]));
                u = ancestor[step][u]; v = ancestor[step][v];
            }
        }
        answer = std::max(answer, maxDist[0][u] - 1);
        return ancestor[0][u];
    }
}

void Update(int down, int up, int cost) {
    down = Group(down);
    while(depth[down] > depth[up]) {
        edgeAnswer[fatherIndex[down]] = std::min(edgeAnswer[fatherIndex[down]], cost);
        father[down] = Group(ancestor[0][down]);
        down = Group(down);
    }
}

void SolveEdges() {
    for(int i = 1; i <= N; i++) {
        father[i] = i;
    }
    for(int i = 1; i <= M; i++) {
        if(selected[i]) {
            edgeAnswer[i] = 2e9;
        }
    }
    for(auto edge : edges) {
        if(!selected[edge.index]) {
            int lca = LCA(edge.u, edge.v, edgeAnswer[edge.index]);
            Update(edge.u, lca, edge.cost - 1);
            Update(edge.v, lca, edge.cost - 1);
        }
    }
}

int main() {
    ReadInput();
    BuildMST();
    DFS(1, 0, 0);
    SolveEdges();
    for(int i = 1; i <= M; i++) {
        if(edgeAnswer[i] == 2e9) {
            printf("-1 ");
        } else {
            printf("%d ", edgeAnswer[i]);
        }
    }
    return 0;
}


#include <bits/stdc++.h>

#define FOR(i,b,e) for(int i=(b); i <= (e); ++i)
#define FORD(i,b,e) for(int i=(b); i >= (e); --i)
#define REP(i,n) for(int i=0; i < (n); ++i)
#define SIZE(c) (int) (c).size()
#define ALL(c) (c).begin(), (c).end()
#define PB push_back
#define MP make_pair
#define ST first
#define ND second
#define FWD(i,a,b) for (int i=(a); i<(b); ++i)
#define BCK(i,a,b) for (int i=(a); i>(b); --i)
#define PI 3.14159265358979311600
#define pb push_back
#define mp make_pair
#define st first
#define nd second

using namespace std;

typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;

typedef vector < int > VI;
typedef vector<ll> VL;

typedef long double K;

const int N = 200005;
const int L = 19;
const int inf = 1000 * 1000 * 1000 + 7;

struct edge {
	int x, y, c, id;

	friend bool operator <(const edge& a, const edge& b) {
		return a.c < b.c;
	}
} e[N];

int n, m, result[N], p[N], cost[N], cst[N];
vector<pair<int, int>> g[N];

int root(int x) {
	return p[x] == x ? x : p[x] = root(p[x]);
}

int tin[N], tout[N], timer;
int up[L][N], val[L][N];

void dfs(int v, int c = 0, int pr = 0) {
	tin[v] = timer++;
	up[0][v] = pr;
	val[0][v] = c;
	for (int i = 1; i < L; ++i) {
		up[i][v] = up[i - 1][up[i - 1][v]];
		val[i][v] = max(val[i - 1][v], val[i - 1][up[i - 1][v]]);
	}
	for (auto& item : g[v]) {
		int to = item.first;
		if (to == pr) {
			continue;
		}
		dfs(to, cst[item.second], v);
	}
	tout[v] = timer++;
}

bool line(int x, int y) {
	return tin[x] <= tin[y] && tout[x] >= tout[y];
}

int lca(int x, int y) {
	if (line(x, y)) return x;
	if (line(y, x)) return y;
	for (int i = L - 1; i >= 0; --i) {
		if (!line(up[i][x], y)) {
			x = up[i][x];
		}
	}
	return up[0][x];
}

int ntree[N];
multiset<int> s[N], del[N];

void go(int v, int id = 0, int pr = 0) {
	for (auto& item : g[v]) {
		int to = item.first;
		int curId = item.second;
		if (to == pr) {
			continue;
		}
		go(to, curId, v);
		if (SIZE(s[to]) > SIZE(s[v])) {
			s[to].swap(s[v]);
		}
		s[v].insert(s[to].begin(), s[to].end());
	}
	for (auto& item : del[v]) {
		s[v].erase(s[v].find(item));
	}
	if (!s[v].empty()) {
		result[id] = (*s[v].begin()) - 1;
	}
}

int compute(int ver, int anc) {
	int result = 0;
	if (ver == anc) {
		return result;
	}
	for (int i = L - 1; i >= 0; --i) {
		if (!line(up[i][ver], anc)) {
			result = max(result, val[i][ver]);
			ver = up[i][ver];
		}
	}
	result = max(result, val[0][ver]);
	return result;
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);

	cin >> n >> m;
	REP(i, n) p[i] = i;
	REP(i, m) {
		int x, y, c;
		cin >> x >> y >> c;
		cst[i] = c;
		--x; --y;
		e[i] = {x, y, c, i};
		result[i] = -1;
	}
	sort(e, e + m);
	REP(i, m) {
		int x = e[i].x, y = e[i].y, id = e[i].id;
		int rx = root(x), ry = root(y);
		if (rx == ry) {
			ntree[id] = 1;
		} else {
			p[ry] = rx;
			cost[rx] = e[i].c - 1;
			g[x].emplace_back(y, id);
			g[y].emplace_back(x, id);
		}
	}
	dfs(0);
	REP(i, m) {
		int x = e[i].x, y = e[i].y, c = e[i].c, id = e[i].id;
		int anc = lca(x, y);
		if (!ntree[id]) {
			continue;
		}
		del[anc].insert(c);
		del[anc].insert(c);
		s[x].insert(c);
		s[y].insert(c);
		result[id] = max(compute(x, anc), compute(y, anc)) - 1;
	}
	go(0);
	REP(i, m) {
		cout << result[i] << ' ';
	}
	cout << '\n';
	return 0;
}


#include <bits/stdc++.h>

#define FOR(i,b,e) for(int i=(b); i <= (e); ++i)
#define FORD(i,b,e) for(int i=(b); i >= (e); --i)
#define REP(i,n) for(int i=0; i < (n); ++i)
#define SIZE(c) (int) (c).size()
#define ALL(c) (c).begin(), (c).end()
#define PB push_back
#define MP make_pair
#define ST first
#define ND second
#define FWD(i,a,b) for (int i=(a); i<(b); ++i)
#define BCK(i,a,b) for (int i=(a); i>(b); --i)
#define PI 3.14159265358979311600
#define pb push_back
#define mp make_pair
#define st first
#define nd second

using namespace std;

typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;

typedef vector < int > VI;
typedef vector<ll> VL;

typedef long double K;

const int N = 200005;
const int L = 19;
const int inf = 1000 * 1000 * 1000 + 7;

struct edge {
	int x, y, c, id;

	friend bool operator <(const edge& a, const edge& b) {
		return a.c < b.c;
	}
} e[N];

int n, m, result[N], p[N], cost[N];
vector<pair<int, int>> g[N];

int root(int x) {
	return p[x] == x ? x : p[x] = root(p[x]);
}

int tin[N], tout[N], timer;
int up[L][N];

void dfs(int v, int pr = 0) {
	tin[v] = timer++;
	up[0][v] = pr;
	for (int i = 1; i < L; ++i) {
		up[i][v] = up[i - 1][up[i - 1][v]];
	}
	for (auto& item : g[v]) {
		int to = item.first;
		if (to == pr) {
			continue;
		}
		dfs(to, v);
	}
	tout[v] = timer++;
}

bool line(int x, int y) {
	return tin[x] <= tin[y] && tout[x] >= tout[y];
}

int lca(int x, int y) {
	if (line(x, y)) return x;
	if (line(y, x)) return y;
	for (int i = L - 1; i >= 0; --i) {
		if (!line(up[i][x], y)) {
			x = up[i][x];
		}
	}
	return up[0][x];
}

multiset<int> s[N], del[N];

void go(int v, int id = 0, int pr = 0) {
	for (auto& item : g[v]) {
		int to = item.first;
		int curId = item.second;
		if (to == pr) {
			continue;
		}
		go(to, curId, v);
		if (SIZE(s[to]) > SIZE(s[v])) {
			s[to].swap(s[v]);
		}
		s[v].insert(s[to].begin(), s[to].end());
	}
	for (auto& item : del[v]) {
		s[v].erase(s[v].find(item));
	}
	if (!s[v].empty()) {
		result[id] = (*s[v].begin()) - 1;
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);

	cin >> n >> m;
	REP(i, n) p[i] = i;
	REP(i, m) {
		int x, y, c;
		cin >> x >> y >> c;
		--x; --y;
		e[i] = {x, y, c, i};
		result[i] = -1;
	}
	sort(e, e + m);
	REP(i, m) {
		int x = e[i].x, y = e[i].y, id = e[i].id;
		int rx = root(x), ry = root(y);
		if (rx == ry) {
			result[id] = cost[rx];
		} else {
			p[ry] = rx;
			cost[rx] = e[i].c - 1;
			g[x].emplace_back(y, id);
			g[y].emplace_back(x, id);
		}
	}
	dfs(0);
	REP(i, m) {
		int x = e[i].x, y = e[i].y, c = e[i].c, id = e[i].id;
		if (result[id] == -1) {
			continue;
		}
		int anc = lca(x, y);
		del[anc].insert(c);
		del[anc].insert(c);
		s[x].insert(c);
		s[y].insert(c);
	}
	go(0);
	REP(i, m) {
		cout << result[i] << ' ';
	}
	cout << '\n';
	return 0;
}


#include <bits/stdc++.h>

#define FOR(i,b,e) for(int i=(b); i <= (e); ++i)
#define FORD(i,b,e) for(int i=(b); i >= (e); --i)
#define REP(i,n) for(int i=0; i < (n); ++i)
#define SIZE(c) (int) (c).size()
#define ALL(c) (c).begin(), (c).end()
#define PB push_back
#define MP make_pair
#define ST first
#define ND second
#define FWD(i,a,b) for (int i=(a); i<(b); ++i)
#define BCK(i,a,b) for (int i=(a); i>(b); --i)
#define PI 3.14159265358979311600
#define pb push_back
#define mp make_pair
#define st first
#define nd second

using namespace std;

typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;

typedef vector < int > VI;
typedef vector<ll> VL;

typedef long double K;

const int N = 200005;
const int L = 19;
const int inf = 1000 * 1000 * 1000 + 7;

struct edge {
	int x, y, c, id;

	friend bool operator <(const edge& a, const edge& b) {
		return a.c < b.c;
	}
} e[N];

int n, m, result[N], p[N], cost[N], cst[N];
vector<pair<int, int>> g[N];

int root(int x) {
	return p[x] == x ? x : p[x] = root(p[x]);
}

int tin[N], tout[N], timer;
int up[L][N], val[L][N];

void dfs(int v, int c = 0, int pr = 0) {
	tin[v] = timer++;
	up[0][v] = pr;
	val[0][v] = c;
	for (int i = 1; i < L; ++i) {
		up[i][v] = up[i - 1][up[i - 1][v]];
		val[i][v] = min(val[i - 1][v], val[i - 1][up[i - 1][v]]);
	}
	for (auto& item : g[v]) {
		int to = item.first;
		if (to == pr) {
			continue;
		}
		dfs(to, cst[item.second], v);
	}
	tout[v] = timer++;
}

bool line(int x, int y) {
	return tin[x] <= tin[y] && tout[x] >= tout[y];
}

int lca(int x, int y) {
	if (line(x, y)) return x;
	if (line(y, x)) return y;
	for (int i = L - 1; i >= 0; --i) {
		if (!line(up[i][x], y)) {
			x = up[i][x];
		}
	}
	return up[0][x];
}

int ntree[N];
multiset<int> s[N], del[N];

void go(int v, int id = 0, int pr = 0) {
	for (auto& item : g[v]) {
		int to = item.first;
		int curId = item.second;
		if (to == pr) {
			continue;
		}
		go(to, curId, v);
		if (SIZE(s[to]) > SIZE(s[v])) {
			s[to].swap(s[v]);
		}
		s[v].insert(s[to].begin(), s[to].end());
	}
	for (auto& item : del[v]) {
		s[v].erase(s[v].find(item));
	}
	if (!s[v].empty()) {
		result[id] = (*s[v].begin()) - 1;
	}
}

int compute(int ver, int anc) {
	int result = inf;
	for (int i = L - 1; i >= 0; --i) {
		if (!line(up[i][ver], anc)) {
			result = min(result, val[i][ver]);
			ver = up[i][ver];
		}
	}
	if (ver != anc) result = min(result, val[0][ver]);
	return result;
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);

	cin >> n >> m;
	REP(i, n) p[i] = i;
	REP(i, m) {
		int x, y, c;
		cin >> x >> y >> c;
		cst[i] = c;
		--x; --y;
		e[i] = {x, y, c, i};
		result[i] = -1;
	}
	sort(e, e + m);
	REP(i, m) {
		int x = e[i].x, y = e[i].y, id = e[i].id;
		int rx = root(x), ry = root(y);
		if (rx == ry) {
			ntree[id] = 1;
		} else {
			p[ry] = rx;
			cost[rx] = e[i].c - 1;
			g[x].emplace_back(y, id);
			g[y].emplace_back(x, id);
		}
	}
	dfs(0);
	REP(i, m) {
		int x = e[i].x, y = e[i].y, c = e[i].c, id = e[i].id;
		int anc = lca(x, y);
		if (!ntree[id]) {
			continue;
		}
		del[anc].insert(c);
		del[anc].insert(c);
		s[x].insert(c);
		s[y].insert(c);
		result[id] = min(compute(x, anc), compute(y, anc)) - 1;
	}
	go(0);
	REP(i, m) {
		cout << result[i] << ' ';
	}
	cout << '\n';
	return 0;
}


#include <bits/stdc++.h> // PLEASE

using namespace std;
typedef long long ll;
typedef pair <int, int> pp;
#define MAXN 300005
#define MAXM 1005
#define MAXP 25
#define INF 2000000000
#define A first
#define B second
#define MP make_pair
#define PB push_back

const ll MOD = 1e9+7;
int N, M;
vector <pair <pp, pp> > v;
vector <pair <pp, int> > adj[MAXN];
vector <pp> go[MAXN];
int paredge[MAXN];
int par[MAXP][MAXN];
int maxd[MAXP][MAXN];
int upa[MAXN];
bool use[MAXN];
int dep[MAXN];
int ans[MAXN];
int sz[MAXN];
int c = 1;

int find(int u)
{
	if(upa[u] == u) return u;
	return upa[u] = find(upa[u]);
}

void join(int u, int v)
{
	u = find(u);
	v = find(v);
	if(u == v) return;
	upa[u] = v;
}

void dfs(int cur)
{
	sz[cur] = 1;
	dep[cur] = dep[par[0][cur]]+1;
	for(int i=0; i<adj[cur].size(); i++) {
		int nxt = adj[cur][i].A.A;
		ll wt = adj[cur][i].A.B;
		if((nxt == par[0][cur])) continue;
		paredge[nxt] = adj[cur][i].B;
		par[0][nxt] = cur;
		maxd[0][nxt] = wt;
		dfs(nxt);
		sz[cur] += sz[nxt];
	}
}

int lca(int a, int b)
{
	if(dep[b] > dep[a]) swap(a, b);
	for(int i=MAXP-1; i>=0; i--) if(dep[par[i][a]] >= dep[b]) a =  par[i][a];
	if(a == b) return a;
	for(int i=MAXP-1; i>=0; i--) {
		if(par[i][a] != par[i][b]) {
			a = par[i][a];
			b = par[i][b];
		}
	}
	if(a == b) return a;
	return par[0][a];
}

ll qry(int a, int b)
{
	int x = lca(a, b);
	int ret = -MOD;
	for(int i=MAXP-1; i>=0; i--) {
		if(dep[par[i][a]] > dep[x]) {
			ret = max(ret, maxd[i][a]);
			a = par[i][a];
		}
	}
	for(int i=MAXP-1; i>=0; i--) {
		if(dep[par[i][b]] > dep[x]) {
			ret = max(ret, maxd[i][b]);
			b = par[i][b];
		}
	}
	if(a != x) ret = max(ret, maxd[0][a]);
	if(b != x) ret = max(ret, maxd[0][b]);
	return ret;
}

multiset <int> s[MAXN];

bool cmp(pair <pp, int> a, pair <pp, int> b)
{
	return sz[a.A.A] < sz[b.A.A];
}

void solve(int cur)
{
	vector <int> ch;
	sort(adj[cur].begin(), adj[cur].end(), cmp);
	for(int i=0; i<adj[cur].size(); i++) {
		int nxt = adj[cur][i].A.A;
		if(par[0][cur] == nxt) continue;
		solve(nxt);
		ch.PB(nxt);
	}
	if(cur == 1) return;

	if(!ch.empty()) {
		int best = ch[ch.size()-1];
		swap(s[cur], s[best]);
		for(int i=0; i<ch.size()-1; i++) s[cur].insert(s[ch[i]].begin(), s[ch[i]].end());
	}

	for(int i=0; i<go[cur].size(); i++) {
		if(go[cur][i].B == 1) s[cur].insert(go[cur][i].A);
		else s[cur].erase(s[cur].find(go[cur][i].A));
	}

	if(!s[cur].empty()) ans[paredge[cur]] = *s[cur].begin() - 1;
	else ans[paredge[cur]] = -1;

}

int main(void)
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cin >> N >> M;
	for(int i=0; i<M; i++) {
		int a, b, c;
		cin >> a >> b >> c;
		v.PB(MP(pp(c, i), pp(a, b)));
	}
	sort(v.begin(), v.end());
	for(int i=1; i<=N; i++) upa[i] = i;

	for(int i=0; i<M; i++) {
		int a = v[i].B.A;
		int b = v[i].B.B;
		a = find(a);
		b = find(b);
		if(a == b) continue;
		join(a, b);
		use[i] = 1;
	}
	for(int i=0; i<M; i++) {
		int a = v[i].B.A;
		int b = v[i].B.B;
		int c = v[i].A.A;
		int num = v[i].A.B;
		if(use[i]) {
			adj[a].PB(MP(pp(b, c), num));
			adj[b].PB(MP(pp(a, c), num));
		}
	}

	maxd[0][1] = -INF;
	par[0][1] = 1;
	dfs(1);

	for(int i=1; i<MAXP; i++) for(int j=1; j<=N; j++) par[i][j] = par[i-1][par[i-1][j]];
	for(int i=1; i<MAXP; i++) for(int j=1; j<=N; j++) maxd[i][j] = max(maxd[i-1][j], maxd[i-1][par[i-1][j]]);

	for(int i=0; i<M; i++) ans[i] = -1;
	for(int i=0; i<M; i++) {
		if(use[i]) continue;
		int cur = v[i].A.B;
		int a = v[i].B.A;
		int b = v[i].B.B;
		int y = lca(a, b);
		go[a].PB(pp(v[i].A.A, 1));
		go[b].PB(pp(v[i].A.A, 1));
		go[y].PB(pp(v[i].A.A, -1));
		go[y].PB(pp(v[i].A.A, -1));
		ans[cur] = qry(a, b) - 1;
	}
	solve(1);
	for(int i=0; i<M; i++) printf("%d ", ans[i]);
	printf("\n");

}


#include <bits/stdc++.h> // PLEASE

using namespace std;
typedef long long ll;
typedef pair <int, int> pp;
#define MAXN 300005
#define MAXM 1005
#define MAXP 25
#define INF 2000000000
#define A first
#define B second
#define MP make_pair
#define PB push_back

const ll MOD = 1e9+7;
int N, M;
vector <pair <pp, pp> > v;
vector <pair <pp, int> > adj[MAXN];
vector <pair <pp, int> > ch[MAXN];
vector <pair <pp, int> > adj2[MAXN];
int paredge[MAXN];
int par[MAXP][MAXN];
int maxd[MAXP][MAXN];
int upa[MAXN];
bool use[MAXN];
int dep[MAXN];
int ans[MAXN];
int col[MAXN];
int back[MAXN];
int sz[MAXN];
int c = 1;

int find(int u)
{
	if(upa[u] == u) return u;
	return upa[u] = find(upa[u]);
}

void join(int u, int v)
{
	u = find(u);
	v = find(v);
	if(u == v) return;
	upa[u] = v;
}

void dfs(int cur)
{
	col[cur] = c++;
	back[c-1] = cur;
	sz[cur] = 1;
	dep[cur] = dep[par[0][cur]]+1;
	for(int i=0; i<adj[cur].size(); i++) {
		int nxt = adj[cur][i].A.A;
		ll wt = adj[cur][i].A.B;
		if((nxt == par[0][cur])) continue;
		ch[cur].PB(adj[cur][i]);
		paredge[nxt] = adj[cur][i].B;
		par[0][nxt] = cur;
		maxd[0][nxt] = wt;
		dfs(nxt);
		sz[cur] += sz[nxt];
	}
}

int lca(int a, int b)
{
	if(dep[b] > dep[a]) swap(a, b);
	for(int i=MAXP-1; i>=0; i--) if(dep[par[i][a]] >= dep[b]) a =  par[i][a];
	if(a == b) return a;
	for(int i=MAXP-1; i>=0; i--) {
		if(par[i][a] != par[i][b]) {
			a = par[i][a];
			b = par[i][b];
		}
	}
	if(a == b) return a;
	return par[0][a];
}

ll qry(int a, int b)
{
	int x = lca(a, b);
	int ret = -MOD;
	for(int i=MAXP-1; i>=0; i--) {
		if(dep[par[i][a]] > dep[x]) {
			ret = max(ret, maxd[i][a]);
			a = par[i][a];
		}
	}
	for(int i=MAXP-1; i>=0; i--) {
		if(dep[par[i][b]] > dep[x]) {
			ret = max(ret, maxd[i][b]);
			b = par[i][b];
		}
	}
	if(a != x) ret = max(ret, maxd[0][a]);
	if(b != x) ret = max(ret, maxd[0][b]);
	return ret;
}

set <pair <pp, int> > s[MAXN]; // (cost, guy pointing to, index)

inline void add(int cur, int targ, int cost, int idx)
{
	s[cur].insert(MP(pp(cost, targ), idx));
}

inline void del(int cur, int targ, int cost, int idx)
{
	if(s[cur].find(MP(pp(cost, targ), idx)) != s[cur].end()) s[cur].erase(MP(pp(cost, targ), idx));
}

bool cmp(pair <pp, int> a, pair <pp, int> b)
{
	return sz[a.A.A] < sz[b.A.A];
}

void solve(int cur)
{
	if(!ch[cur].empty()) sort(ch[cur].begin(), ch[cur].end(), cmp);
	for(int i=0; i<ch[cur].size(); i++) {
		int nxt = ch[cur][i].A.A;
		solve(nxt);
	}
	if(cur == 1) return;
	if(!ch[cur].empty()) {
		int best = ch[cur][ch[cur].size()-1].A.A;
		for(int i=0; i<ch[cur].size()-1; i++) {
			int chi = ch[cur][i].A.A;
			for(set <pair <pp, int> > :: iterator it = s[chi].begin(); it != s[chi].end(); ++it) s[best].insert(*it);
			s[chi].clear();
		}
		swap(s[best], s[cur]);
	}
	for(int i=0; i<adj2[cur].size(); i++) {
		int x = col[cur];
		int end = x+sz[cur]-1;
		int nxt = adj2[cur][i].A.A;
		int cost = adj2[cur][i].A.B;
		if(nxt == par[0][cur]) continue;
		if(col[nxt] <= end) if(col[nxt] >= x) continue;
		add(cur, nxt, cost, adj2[cur][i].B);
	}

	int idx = paredge[cur];

	if(!s[cur].empty()) ans[idx] = max(ans[idx], (*(s[cur].begin())).A.A - 1);
}

int main(void)
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cin >> N >> M;
	for(int i=0; i<M; i++) {
		int a, b, c;
		cin >> a >> b >> c;
		v.PB(MP(pp(c, i), pp(a, b)));
	}
	sort(v.begin(), v.end());
	for(int i=1; i<=N; i++) upa[i] = i;

	for(int i=0; i<M; i++) {
		int a = v[i].B.A;
		int b = v[i].B.B;
		a = find(a);
		b = find(b);
		if(a == b) continue;
		join(a, b);
		use[i] = 1;
	}
	for(int i=0; i<M; i++) {
		int a = v[i].B.A;
		int b = v[i].B.B;
		int c = v[i].A.A;
		int num = v[i].A.B;
		if(use[i]) {
			adj[a].PB(MP(pp(b, c), num));
			adj[b].PB(MP(pp(a, c), num));
		}
		else {
			adj2[a].PB(MP(pp(b, c), num));
			adj2[b].PB(MP(pp(a, c), num));
		}
	}

	maxd[0][1] = -INF;
	par[0][1] = 1;
	dfs(1);

	for(int i=1; i<MAXP; i++) for(int j=1; j<=N; j++) par[i][j] = par[i-1][par[i-1][j]];
	for(int i=1; i<MAXP; i++) for(int j=1; j<=N; j++) maxd[i][j] = max(maxd[i-1][j], maxd[i-1][par[i-1][j]]);
	for(int i=0; i<M; i++) ans[i] = -INF;
	for(int i=0; i<M; i++) {
		if(use[i]) continue;
		int cur = v[i].A.B;
		int a = v[i].B.A;
		int b = v[i].B.B;
		ans[cur] = qry(a, b) - 1;
	}
	solve(1);
	for(int i=0; i<M; i++) {
		if(ans[i] <= -INF) ans[i] = -1;
		printf("%d ", ans[i]);
	}
	printf("\n");

}


#include <bits/stdc++.h> // PLEASE

using namespace std;
typedef long long ll;
typedef pair <int, int> pp;
#define MAXN 300005
#define MAXM 1005
#define MAXP 25
#define INF 2000000000
#define A first
#define B second
#define MP make_pair
#define PB push_back

const ll MOD = 1e9+7;
int N, M;
vector <pair <pp, pp> > v;
vector <pair <pp, int> > adj[MAXN];
int par[MAXP][MAXN];
int maxd[MAXP][MAXN];
int paredge[MAXN];
int upa[MAXN];
bool use[MAXN];
int dep[MAXN];
int ans[MAXN];
int c = 1;

int find(int u)
{
	if(upa[u] == u) return u;
	return upa[u] = find(upa[u]);
}

void join(int u, int v)
{
	u = find(u);
	v = find(v);
	if(u == v) return;
	upa[u] = v;
}

void dfs(int cur)
{
	dep[cur] = dep[par[0][cur]]+1;
	for(int i=0; i<adj[cur].size(); i++) {
		int nxt = adj[cur][i].A.A;
		ll wt = adj[cur][i].A.B;
		if((nxt == par[0][cur])) continue;
		paredge[nxt] = adj[cur][i].B;
		par[0][nxt] = cur;
		maxd[0][nxt] = wt;
		dfs(nxt);
	}
}

int lca(int a, int b)
{
	if(dep[b] > dep[a]) swap(a, b);
	for(int i=MAXP-1; i>=0; i--) if(dep[par[i][a]] >= dep[b]) a =  par[i][a];
	if(a == b) return a;
	for(int i=MAXP-1; i>=0; i--) {
		if(par[i][a] != par[i][b]) {
			a = par[i][a];
			b = par[i][b];
		}
	}
	if(a == b) return a;
	return par[0][a];
}

ll qry(int a, int b)
{
	int x = lca(a, b);
	int ret = -MOD;
	for(int i=MAXP-1; i>=0; i--) {
		if(dep[par[i][a]] > dep[x]) {
			ret = max(ret, maxd[i][a]);
			a = par[i][a];
		}
	}
	for(int i=MAXP-1; i>=0; i--) {
		if(dep[par[i][b]] > dep[x]) {
			ret = max(ret, maxd[i][b]);
			b = par[i][b];
		}
	}
	if(a != x) ret = max(ret, maxd[0][a]);
	if(b != x) ret = max(ret, maxd[0][b]);
	return ret;
}

void solve(int a, int b, int wt)
{
	a = find(a);
	b = find(b);
	if(a == b) return;
	if(dep[b] > dep[a]) swap(a, b);
	ans[paredge[a]] = wt;
	upa[a] = find(par[0][a]);
	solve(a, b, wt);
}

int main(void)
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cin >> N >> M;
	for(int i=0; i<M; i++) {
		int a, b, c;
		cin >> a >> b >> c;
		v.PB(MP(pp(c, i), pp(a, b)));
	}
	sort(v.begin(), v.end());
	for(int i=1; i<=N; i++) upa[i] = i;

	for(int i=0; i<M; i++) {
		int a = v[i].B.A;
		int b = v[i].B.B;
		a = find(a);
		b = find(b);
		if(a == b) continue;
		join(a, b);
		use[i] = 1;
	}
	for(int i=0; i<M; i++) {
		int a = v[i].B.A;
		int b = v[i].B.B;
		int c = v[i].A.A;
		int num = v[i].A.B;
		if(use[i]) {
			adj[a].PB(MP(pp(b, c), num));
			adj[b].PB(MP(pp(a, c), num));
		}
	}

	maxd[0][1] = -INF;
	par[0][1] = 1;
	dfs(1);

	for(int i=1; i<MAXP; i++) for(int j=1; j<=N; j++) par[i][j] = par[i-1][par[i-1][j]];
	for(int i=1; i<MAXP; i++) for(int j=1; j<=N; j++) maxd[i][j] = max(maxd[i-1][j], maxd[i-1][par[i-1][j]]);
	for(int i=1; i<=N; i++) upa[i] = i;
	for(int i=0; i<M; i++) ans[i] = INF;

	for(int i=0; i<M; i++) {
		int idx = v[i].A.B;
		int a = v[i].B.A;
		int b = v[i].B.B;
		if(!use[idx]) {
			ans[idx] = qry(a, b)-1;
			solve(a, b, v[i].A.A-1);
		}
	}

	for(int i=0; i<M; i++) {
		if(ans[i] >= INF-1) ans[i] = -1;
		printf("%d ", ans[i]);
	}
	printf("\n");
}


#include <bits/stdc++.h> // PLEASE

using namespace std;
typedef long long ll;
typedef pair <int, int> pp;
#define MAXN 300005
#define MAXM 1005
#define MAXP 25
#define INF 2000000000
#define A first
#define B second
#define MP make_pair
#define PB push_back

const ll MOD = 1e9+7;
int N, M;
vector <pair <pp, pp> > v;
vector <pair <pp, int> > adj[MAXN];
vector <pair <pp, int> > ch[MAXN];
vector <pair <pp, int> > adj2[MAXN];
int paredge[MAXN];
int par[MAXP][MAXN];
int maxd[MAXP][MAXN];
int upa[MAXN];
bool use[MAXN];
int dep[MAXN];
int ans[MAXN];
int col[MAXN];
int back[MAXN];
int sz[MAXN];
int c = 1;

int find(int u)
{
	if(upa[u] == u) return u;
	return upa[u] = find(upa[u]);
}

void join(int u, int v)
{
	u = find(u);
	v = find(v);
	if(u == v) return;
	upa[u] = v;
}

void dfs(int cur)
{
	col[cur] = c++;
	back[c-1] = cur;
	sz[cur] = 1;
	dep[cur] = dep[par[0][cur]]+1;
	for(int i=0; i<adj[cur].size(); i++) {
		int nxt = adj[cur][i].A.A;
		ll wt = adj[cur][i].A.B;
		if((nxt == par[0][cur])) continue;
		ch[cur].PB(adj[cur][i]);
		paredge[nxt] = adj[cur][i].B;
		par[0][nxt] = cur;
		maxd[0][nxt] = wt;
		dfs(nxt);
		sz[cur] += sz[nxt];
	}
}

int lca(int a, int b)
{
	if(dep[b] > dep[a]) swap(a, b);
	for(int i=MAXP-1; i>=0; i--) if(dep[par[i][a]] >= dep[b]) a =  par[i][a];
	if(a == b) return a;
	for(int i=MAXP-1; i>=0; i--) {
		if(par[i][a] != par[i][b]) {
			a = par[i][a];
			b = par[i][b];
		}
	}
	if(a == b) return a;
	return par[0][a];
}

ll qry(int a, int b)
{
	int x = lca(a, b);
	int ret = -MOD;
	for(int i=MAXP-1; i>=0; i--) {
		if(dep[par[i][a]] > dep[x]) {
			ret = max(ret, maxd[i][a]);
			a = par[i][a];
		}
	}
	for(int i=MAXP-1; i>=0; i--) {
		if(dep[par[i][b]] > dep[x]) {
			ret = max(ret, maxd[i][b]);
			b = par[i][b];
		}
	}
	if(a != x) ret = max(ret, maxd[0][a]);
	if(b != x) ret = max(ret, maxd[0][b]);
	return ret;
}

set <pair <pp, int> > s[MAXN]; // (cost, guy pointing to, index)

inline void add(int cur, int targ, int cost, int idx)
{
	s[cur].insert(MP(pp(cost, targ), idx));
}

inline void del(int cur, int targ, int cost, int idx)
{
	if(s[cur].find(MP(pp(cost, targ), idx)) != s[cur].end()) s[cur].erase(MP(pp(cost, targ), idx));
}

bool cmp(pair <pp, int> a, pair <pp, int> b)
{
	return sz[a.A.A] < sz[b.A.A];
}

void solve(int cur)
{
	if(!ch[cur].empty()) sort(ch[cur].begin(), ch[cur].end(), cmp);
	for(int i=0; i<ch[cur].size(); i++) {
		int nxt = ch[cur][i].A.A;
		solve(nxt);
	}
	if(cur == 1) return;
	if(!ch[cur].empty()) {
		int best = ch[cur][ch[cur].size()-1].A.A;
		for(int i=0; i<ch[cur].size()-1; i++) {
			int chi = ch[cur][i].A.A;
			for(set <pair <pp, int> > :: iterator it = s[chi].begin(); it != s[chi].end(); ++it) s[best].insert(*it);
			s[chi].clear();
		}
		swap(s[best], s[cur]);
	}
	for(int i=0; i<adj2[cur].size(); i++) {
		int x = col[cur];
		int end = x+sz[cur]-1;
		int nxt = adj2[cur][i].A.A;
		int cost = adj2[cur][i].A.B;
		if(nxt == par[0][cur]) continue;
		if(col[nxt] <= end) if(col[nxt] >= x) continue;
		add(cur, nxt, cost, adj2[cur][i].B);
	}

	int idx = paredge[cur];

	if(!s[cur].empty()) ans[idx] = max(ans[idx], (*(s[cur].begin())).A.A - 1);
}

int main(void)
{
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cin >> N >> M;
	for(int i=0; i<M; i++) {
		int a, b, c;
		cin >> a >> b >> c;
		v.PB(MP(pp(c, i), pp(a, b)));
	}
	sort(v.begin(), v.end());
	for(int i=1; i<=N; i++) upa[i] = i;

	for(int i=0; i<M; i++) {
		int a = v[i].B.A;
		int b = v[i].B.B;
		a = find(a);
		b = find(b);
		if(a == b) continue;
		join(a, b);
		use[i] = 1;
	}
	for(int i=0; i<M; i++) {
		int a = v[i].B.A;
		int b = v[i].B.B;
		int c = v[i].A.A;
		int num = v[i].A.B;
		if(use[i]) {
			adj[a].PB(MP(pp(b, c), num));
			adj[b].PB(MP(pp(a, c), num));
		}
		else {
			adj2[a].PB(MP(pp(b, c), num));
			adj2[b].PB(MP(pp(a, c), num));
		}
	}

	maxd[0][1] = -INF;
	par[0][1] = 1;
	dfs(1);

	for(int i=1; i<MAXP; i++) for(int j=1; j<=N; j++) par[i][j] = par[i-1][par[i-1][j]];
	for(int i=1; i<MAXP; i++) for(int j=1; j<=N; j++) maxd[i][j] = max(maxd[i-1][j], maxd[i-1][par[i-1][j]]);
	for(int i=0; i<M; i++) {
		if(use[i]) continue;
		int cur = v[i].A.B;
		int a = v[i].B.A;
		int b = v[i].B.B;
		ans[cur] = qry(a, b) - 1;
	}
	solve(1);
	for(int i=0; i<M; i++) printf("%d ", ans[i]);
	printf("\n");

}


#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
bool book[200010];
struct E
{
	int u,v,w;
}sv[200010];
namespace LCA
{
	const int MAXN=200010;
	const int DEG=20;
	struct Edge
	{
		int to,next,w;
	}edge[MAXN*2];
	int head[MAXN],tot;
	void addedge(int u,int v,int w)
	{
		edge[tot].to=v;
		edge[tot].w=w;
		edge[tot].next=head[u];
		head[u]=tot++;
	}
	void init()
	{
		tot=0;
		memset(head,-1,sizeof(head));
	}
	int fa[MAXN][DEG],mx[MAXN][DEG];//fa[i][j]表示结点i的第2^j个祖先
	int deg[MAXN];//深度数组
	void BFS(int root)
	{
		queue<int>que;
		deg[root]=0;
		fa[root][0]=root;
		mx[root][0]=0;
		que.push(root);
		while(!que.empty())
		{
			int tmp=que.front();
			que.pop();
			for(int i=1;i<DEG;i++)
			{
				fa[tmp][i]=fa[fa[tmp][i-1]][i-1];
				mx[tmp][i]=max(mx[fa[tmp][i-1]][i-1],mx[tmp][i-1]);
			}
			for(int i=head[tmp];i!=-1;i=edge[i].next)
			{
				int v=edge[i].to;
				if(v==fa[tmp][0])continue;
				deg[v]=deg[tmp]+1;
				fa[v][0]=tmp;
				mx[v][0]=edge[i].w;
				que.push(v);
			}
		}
	}
	int LCA(int u,int v)
	{
		if(deg[u]>deg[v])swap(u,v);
		int ret=0;
		int hu=deg[u],hv=deg[v];
		int tu=u,tv=v;
		for(int det=hv-hu,i=0;det;det>>=1,i++)
			if(det&1)
			{
				ret=max(mx[tv][i],ret);
				tv=fa[tv][i];
			}
		if(tu==tv)
			return ret;
		for(int i=DEG-1;i>=0;i--)
		{
			if(fa[tu][i]==fa[tv][i])
				continue;
			ret=max(ret,mx[tu][i]);
			ret=max(ret,mx[tv][i]);
			tu=fa[tu][i];
			tv=fa[tv][i];
		}
		return max(ret,max(mx[tu][0],mx[tv][0]));
	}
}
namespace Kruskal
{
	const int MAXN=2e5+5;//最大点数
	const int MAXM=2e5+5;//最大边数
	int F[MAXN];//并查集使用
	struct Edge
	{
		int u,v,w,id;
	}edge[MAXM];//存储边的信息，包括起点/终点/权值
	int tol;//边数，加边前赋值为0
	void init()//初始化
	{
		tol=0;
		memset(F,-1,sizeof(F));
		memset(edge,0,sizeof(edge));
	}
	void addedge(int u,int v,int w,int id)
	{
		edge[tol].u=u;
		edge[tol].v=v;
		edge[tol].id=id;
		edge[tol++].w=w;
	}
	bool cmp(Edge a,Edge b)//排序函数，讲边按照权值从小到大排序
	{
		return a.w<b.w;
	}
	int find(int x)//并查集使用
	{
		if(F[x]==-1)return x;
		else return F[x]=find(F[x]);
	}
}
namespace tree
{
	const int MAXN=200010;
	#define lson l,mid,rt<<1
	#define rson mid+1,r,rt<<1|1
	struct Edge
	{
		int to,next;
	}edge[MAXN*2];
	int head[MAXN],tot;
	int top[MAXN];//top[v]表示v所在的重链的顶端节点
	int fa[MAXN]; //父亲节点
	int deep[MAXN];//深度
	int num[MAXN];//num[v]表示以v为根的子树的节点数
	int p[MAXN];//p[v]表示v与其父亲节点的连边在线段树中的位置
	int fp[MAXN];//和p数组相反
	int son[MAXN];//重儿子
	int pos;
	void init()
	{
		tot=0;
		memset(head,-1,sizeof(head));
		pos=0;
		memset(son,-1,sizeof(son));
	}
	void addedge(int u,int v)
	{
		edge[tot].to=v;edge[tot].next=head[u];head[u]=tot++;
	}
	void dfs1(int u,int pre,int d) //第一遍dfs求出fa,deep,num,son
	{
		deep[u]=d;
		fa[u]=pre;
		num[u]=1;
		for(int i=head[u];i!=-1;i=edge[i].next)
		{
			int v=edge[i].to;
			if(v!=pre)
			{
				dfs1(v,u,d+1);
				num[u]+=num[v];
				if(son[u]==-1||num[v]>num[son[u]])
					son[u]=v;
			}
		}
	}
	void getpos(int u,int sp) //第二遍dfs求出top和p
	{
		top[u]=sp;
		p[u]=pos++;
		fp[p[u]]=u;
		if(son[u]==-1)
			return;
		getpos(son[u],sp);
		for(int i=head[u];i!=-1;i=edge[i].next)
		{
			int v=edge[i].to;
			if(v!=son[u]&&v!=fa[u])
				getpos(v,v);
		}
	}
	//线段树
	struct Node
	{
		int Min,lazy;
	}segTree[MAXN*4];
	void build(int i,int l,int r)
	{
		segTree[i].Min=INF;
		segTree[i].lazy=0;
		if(l==r)
			return;
		int mid=(l+r)>>1;
		build(i<<1,l,mid);
		build((i<<1)|1,mid+1,r);
	}
	void push_up(int i)
	{
		segTree[i].Min=max(segTree[i<<1].Min,segTree[(i<<1)|1].Min);
	}
	void push_down(int i)
	{
		if(segTree[i].lazy)
		{
			segTree[i<<1].Min=min(segTree[i<<1].Min,segTree[i].lazy);
			segTree[i<<1|1].Min=min(segTree[i<<1|1].Min,segTree[i].lazy);
			if(segTree[i<<1].lazy==0)
				segTree[i<<1].lazy=segTree[i].lazy;
			else
				segTree[i<<1].lazy=min(segTree[i<<1].lazy,segTree[i].lazy);
			if(segTree[i<<1|1].lazy==0)
				segTree[i<<1|1].lazy=segTree[i].lazy;
			else
				segTree[i<<1|1].lazy=min(segTree[i<<1|1].lazy,segTree[i].lazy);
			segTree[i].lazy=0;
		}
	}
	void update(int L,int R,int val,int l,int r,int rt)
	{
		if(L<=l&&r<=R)
		{
			segTree[rt].Min=min(segTree[rt].Min,val);
			if(segTree[rt].lazy==0)
				segTree[rt].lazy=val;
			else
				segTree[rt].lazy=min(segTree[rt].lazy,val);
			return;
		}
		push_down(rt);
		int mid=(l+r)>>1;
		if(L<=mid)
			update(L,R,val,lson);
		if(mid<R)
			update(L,R,val,rson);
		push_up(rt);
	}
	int query(int pos,int l,int r,int rt)
	{
		if(l==r)
			return segTree[rt].Min;
		int mid=(l+r)>>1;
		push_down(rt);
		if(pos<=mid)
			return query(pos,lson);
		if(mid<pos)
			return query(pos,rson);
	}
	void upd(int u,int v,int val)
	{
		int f1=top[u],f2=top[v];
		while(f1!=f2)
		{
			if(deep[f1]<deep[f2])
			{
				swap(f1,f2);
				swap(u,v);
			}
			update(p[f1],p[u],val,0,pos-1,1);
			u=fa[f1];f1=top[u];
		}
		if(u==v)
			return ;
		if(deep[u]>deep[v])
			swap(u,v);
		update(p[son[u]],p[v],val,0,pos-1,1);
	}
	int find(int u,int v)//查询u->v边的最大值
	{
		if(deep[u]>deep[v])
			swap(u,v);
		return query(p[v],0,pos-1,1);
	}
}
void Kru(int n)//传入点数，返回最小生成树的权值，如果不连通返回-1
{
	using namespace Kruskal;
	memset(F,-1,sizeof(F));
	sort(edge,edge+tol,cmp);
	int cnt=0;//计算加入的边数
	for(int i=0;i<tol;i++)
	{
		int u=edge[i].u;
		int v=edge[i].v;
		int w=edge[i].w;
		int id=edge[i].id;
		int t1=find(u);
		int t2=find(v);
		if(t1!=t2)
		{
			F[t1]=t2;
			book[id]=true;
			cnt++;
			tree :: addedge(u,v);tree :: addedge(v,u);
			LCA :: addedge(u,v,w);LCA :: addedge(v,u,w);
		}
		if(cnt==n-1)
			break;
	}
}
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	tree :: init();
	LCA :: init();
	Kruskal :: init();
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&sv[i].u,&sv[i].v,&sv[i].w);
		Kruskal :: addedge(sv[i].u,sv[i].v,sv[i].w,i);
	}
	Kru(n);
	LCA :: BFS(1);
	tree :: dfs1(1,0,0);
	tree :: getpos(1,0);
	tree :: build(1,0,tree :: pos-1);
	for(int i=1;i<=m;i++)
	{
		int u=sv[i].u,v=sv[i].v,w=sv[i].w;
		if(!book[i])
			tree :: upd(u,v,w);
	}
	for(int i=1;i<=m;i++)
	{
		int u=sv[i].u,v=sv[i].v;
		if(!book[i])
		{
			int ret=LCA :: LCA(u,v);
			printf("%d ",ret-1);
		}
		else
		{
			int ret=tree :: find(u,v);
			if(ret==INF)
				printf("-1 ");
			else
				printf("%d ",ret-1);
		}
	}
	printf("\n");
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
bool book[200010];
struct E
{
	int u,v,w;
}sv[200010];
namespace LCA
{
	const int MAXN=200010;
	const int DEG=20;
	struct Edge
	{
		int to,next,w;
	}edge[MAXN*2];
	int head[MAXN],tot;
	void addedge(int u,int v,int w)
	{
		edge[tot].to=v;
		edge[tot].w=w;
		edge[tot].next=head[u];
		head[u]=tot++;
	}
	void init()
	{
		tot=0;
		memset(head,-1,sizeof(head));
	}
	int fa[MAXN][DEG],mx[MAXN][DEG];//fa[i][j]è¡¨ç¤ºç»“ç‚¹içš„ç¬¬2^jä¸ªç¥–å…ˆ
	int deg[MAXN];//æ·±åº¦æ•°ç»„
	void BFS(int root)
	{
		queue<int>que;
		deg[root]=0;
		fa[root][0]=root;
		mx[root][0]=0;
		que.push(root);
		while(!que.empty())
		{
			int tmp=que.front();
			que.pop();
			for(int i=1;i<DEG;i++)
			{
				fa[tmp][i]=fa[fa[tmp][i-1]][i-1];
				mx[tmp][i]=max(mx[fa[tmp][i-1]][i-1],mx[tmp][i-1]);
			}
			for(int i=head[tmp];i!=-1;i=edge[i].next)
			{
				int v=edge[i].to;
				if(v==fa[tmp][0])continue;
				deg[v]=deg[tmp]+1;
				fa[v][0]=tmp;
				mx[v][0]=edge[i].w;
				que.push(v);
			}
		}
	}
	int LCA(int u,int v)
	{
		if(deg[u]>deg[v])swap(u,v);
		int ret=0;
		int hu=deg[u],hv=deg[v];
		int tu=u,tv=v;
		for(int det=hv-hu,i=0;det;det>>=1,i++)
			if(det&1)
			{
				ret=max(mx[tv][i],ret);
				tv=fa[tv][i];
			}
		if(tu==tv)
			return ret;
		for(int i=DEG-1;i>=0;i--)
		{
			if(fa[tu][i]==fa[tv][i])
				continue;
			ret=max(ret,mx[tu][i]);
			ret=max(ret,mx[tv][i]);
			tu=fa[tu][i];
			tv=fa[tv][i];
		}
		return max(ret,max(mx[tu][0],mx[tv][0]));
	}
}
namespace Kruskal
{
	const int MAXN=2e5+5;//æœ€å¤§ç‚¹æ•°
	const int MAXM=2e5+5;//æœ€å¤§è¾¹æ•°
	int F[MAXN];//å¹¶æŸ¥é›†ä½¿ç”¨
	struct Edge
	{
		int u,v,w,id;
	}edge[MAXM];//å˜å‚¨è¾¹çš„ä¿¡æ¯ï¼ŒåŒ…æ‹¬èµ·ç‚¹/ç»ˆç‚¹/æƒå€¼
	int tol;//è¾¹æ•°ï¼ŒåŠ è¾¹å‰èµ‹å€¼ä¸º0
	void init()//åˆå§‹åŒ–
	{
		tol=0;
		memset(F,-1,sizeof(F));
		memset(edge,0,sizeof(edge));
	}
	void addedge(int u,int v,int w,int id)
	{
		edge[tol].u=u;
		edge[tol].v=v;
		edge[tol].id=id;
		edge[tol++].w=w;
	}
	bool cmp(Edge a,Edge b)//æŽ’åºå‡½æ•°ï¼Œè®²è¾¹æŒ‰ç…§æƒå€¼ä»Žå°åˆ°å¤§æŽ’åº
	{
		return a.w<b.w;
	}
	int find(int x)//å¹¶æŸ¥é›†ä½¿ç”¨
	{
		if(F[x]==-1)return x;
		else return F[x]=find(F[x]);
	}
}
namespace tree
{
	const int MAXN=200010;
	#define lson l,mid,rt<<1
	#define rson mid+1,r,rt<<1|1
	struct Edge
	{
		int to,next;
	}edge[MAXN*2];
	int head[MAXN],tot;
	int top[MAXN];//top[v]è¡¨ç¤ºvæ‰€åœ¨çš„é‡é“¾çš„é¡¶ç«¯èŠ‚ç‚¹
	int fa[MAXN]; //çˆ¶äº²èŠ‚ç‚¹
	int deep[MAXN];//æ·±åº¦
	int num[MAXN];//num[v]è¡¨ç¤ºä»¥vä¸ºæ ¹çš„åæ ‘çš„èŠ‚ç‚¹æ•°
	int p[MAXN];//p[v]è¡¨ç¤ºvä¸Žå…¶çˆ¶äº²èŠ‚ç‚¹çš„è¿žè¾¹åœ¨çº¿æ®µæ ‘ä¸çš„ä½ç½®
	int fp[MAXN];//å’Œpæ•°ç»„ç›¸å
	int son[MAXN];//é‡å„¿å
	int pos;
	void init()
	{
		tot=0;
		memset(head,-1,sizeof(head));
		pos=0;
		memset(son,-1,sizeof(son));
	}
	void addedge(int u,int v)
	{
		edge[tot].to=v;edge[tot].next=head[u];head[u]=tot++;
	}
	void dfs1(int u,int pre,int d) //ç¬¬ä¸€édfsæ±‚å‡ºfa,deep,num,son
	{
		deep[u]=d;
		fa[u]=pre;
		num[u]=1;
		for(int i=head[u];i!=-1;i=edge[i].next)
		{
			int v=edge[i].to;
			if(v!=pre)
			{
				dfs1(v,u,d+1);
				num[u]+=num[v];
				if(son[u]==-1||num[v]>num[son[u]])
					son[u]=v;
			}
		}
	}
	void getpos(int u,int sp) //ç¬¬äºŒédfsæ±‚å‡ºtopå’Œp
	{
		top[u]=sp;
		p[u]=pos++;
		fp[p[u]]=u;
		if(son[u]==-1)
			return;
		getpos(son[u],sp);
		for(int i=head[u];i!=-1;i=edge[i].next)
		{
			int v=edge[i].to;
			if(v!=son[u]&&v!=fa[u])
				getpos(v,v);
		}
	}
	//çº¿æ®µæ ‘
	struct Node
	{
		int Min,lazy;
	}segTree[MAXN*4];
	void build(int i,int l,int r)
	{
		segTree[i].Min=INF;
		segTree[i].lazy=0;
		if(l==r)
			return;
		int mid=(l+r)>>1;
		build(i<<1,l,mid);
		build((i<<1)|1,mid+1,r);
	}
	void push_up(int i)
	{
		segTree[i].Min=max(segTree[i<<1].Min,segTree[(i<<1)|1].Min);
	}
	void push_down(int i)
	{
		if(segTree[i].lazy)
		{
			segTree[i<<1].Min=min(segTree[i<<1].Min,segTree[i].lazy);
			segTree[i<<1|1].Min=min(segTree[i<<1|1].Min,segTree[i].lazy);
			segTree[i<<1].lazy=segTree[i].lazy;
			segTree[i<<1|1].lazy=segTree[i].lazy;
			segTree[i].lazy=0;
		}
	}
	void update(int L,int R,int val,int l,int r,int rt)
	{
		if(L<=l&&r<=R)
		{
			segTree[rt].Min=val;
			segTree[rt].lazy=val;
			return;
		}
		push_down(rt);
		int mid=(l+r)>>1;
		if(L<=mid)
			update(L,R,val,lson);
		if(mid<R)
			update(L,R,val,rson);
		push_up(rt);
	}
	int query(int pos,int l,int r,int rt)
	{
		if(l==r)
			return segTree[rt].Min;
		int mid=(l+r)>>1;
		push_down(rt);
		if(pos<=mid)
			return query(pos,lson);
		if(mid<pos)
			return query(pos,rson);
	}
	void upd(int u,int v,int val)
	{
		int f1=top[u],f2=top[v];
		while(f1!=f2)
		{
			if(deep[f1]<deep[f2])
			{
				swap(f1,f2);
				swap(u,v);
			}
			update(p[f1],p[u],val,0,pos-1,1);
			u=fa[f1];f1=top[u];
		}
		if(u==v)
			return ;
		if(deep[u]>deep[v])
			swap(u,v);
		update(p[son[u]],p[v],val,0,pos-1,1);
	}
	int find(int u,int v)//æŸ¥è¯¢u->vè¾¹çš„æœ€å¤§å€¼
	{
		if(deep[u]>deep[v])
			swap(u,v);
		return query(p[v],0,pos-1,1);
	}
}
void Kru(int n)//ä¼ å…¥ç‚¹æ•°ï¼Œè¿”å›žæœ€å°ç”Ÿæˆæ ‘çš„æƒå€¼ï¼Œå¦‚æžœä¸è¿žé€šè¿”å›ž-1
{
	using namespace Kruskal;
	memset(F,-1,sizeof(F));
	sort(edge,edge+tol,cmp);
	int cnt=0;//è®¡ç®—åŠ å…¥çš„è¾¹æ•°
	for(int i=0;i<tol;i++)
	{
		int u=edge[i].u;
		int v=edge[i].v;
		int w=edge[i].w;
		int id=edge[i].id;
		int t1=find(u);
		int t2=find(v);
		if(t1!=t2)
		{
			F[t1]=t2;
			book[id]=true;
			cnt++;
			tree :: addedge(u,v);tree :: addedge(v,u);
			LCA :: addedge(u,v,w);LCA :: addedge(v,u,w);
		}
		if(cnt==n-1)
			break;
	}
}
int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	tree :: init();
	LCA :: init();
	Kruskal :: init();
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&sv[i].u,&sv[i].v,&sv[i].w);
		Kruskal :: addedge(sv[i].u,sv[i].v,sv[i].w,i);
	}
	Kru(n);
	LCA :: BFS(1);
	tree :: dfs1(1,0,0);
	tree :: getpos(1,0);
	tree :: build(1,0,tree :: pos-1);
	for(int i=1;i<=m;i++)
	{
		int u=sv[i].u,v=sv[i].v,w=sv[i].w;
		if(!book[i])
			tree :: upd(u,v,w);
	}
	for(int i=1;i<=m;i++)
	{
		int u=sv[i].u,v=sv[i].v;
		if(!book[i])
		{
			int ret=LCA :: LCA(u,v);
			printf("%d ",ret-1);
		}
		else
		{
			int ret=tree :: find(u,v);
			if(ret==INF)
				printf("-1 ");
			else
				printf("%d ",ret-1);
		}
	}
	printf("\n");
	return 0;
}