#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=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<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#define N 210000
#define maxd 18
using namespace std;
struct node{int x,y,d,nex,id;}e[N],a[2*N];
struct node1{int par[20],f[20],dep;}t[N];
int n,fir[N],len,m,fa[N],r[N],ans[N],inf=(1e9)+10;
bool b[N];
bool cmp(node x,node y)
{
	if(x.d<y.d) return 1;
	return 0;
}
void ins(int x,int y,int d,int id)
{
	a[++len].y=y;a[len].d=d;a[len].id=id;a[len].nex=fir[x];fir[x]=len;
}
int find(int x)
{
	if(fa[x]!=x) fa[x]=find(fa[x]);
	return fa[x];
}
void dfs(int x,int fa,int d)
{
	t[x].dep=t[fa].dep+1;t[x].par[0]=fa;t[x].f[0]=d;
	for(int i=1;i<=maxd;i++)
	{
		t[x].par[i]=t[t[x].par[i-1]].par[i-1];
		t[x].f[i]=max(t[x].f[i-1],t[t[x].par[i-1]].f[i-1]);
	}
	for(int k=fir[x];k;k=a[k].nex)
	{
		int y=a[k].y;
		if(y==fa) continue;
		r[y]=a[k].id;
		dfs(y,x,a[k].d);
	}
}
int lca(int x,int y,int &d)
{
	d=0;
	if(t[x].dep<t[y].dep) swap(x,y);
	for(int i=maxd;i>=0;i--) if(t[t[x].par[i]].dep>=t[y].dep) {d=max(d,t[x].f[i]);x=t[x].par[i];}
	if(x==y) return x;
	for(int i=maxd;i>=0;i--)
		if(t[x].par[i]!=t[y].par[i])
		{
			d=max(d,max(t[x].f[i],t[y].f[i]));
			x=t[x].par[i];y=t[y].par[i];
		}
	d=max(t[x].f[0],t[y].f[0]);
	return t[x].par[0];
}
void solve(int x,int u,int d)
{
	x=find(x);
	while(t[x].dep>t[u].dep)
	{
		ans[r[x]]=min(ans[r[x]],d);
		int y=find(t[x].par[0]);
		fa[x]=y;
		x=find(x);
	}
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++) scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].d),e[i].id=i;
	sort(e+1,e+m+1,cmp);
	for(int i=1;i<=n;i++) fa[i]=i;
	for(int i=1;i<=m;i++)
	{
		int x=find(e[i].x),y=find(e[i].y);
		if(x!=y)
		{
			b[i]=1;
			fa[x]=y;
			ins(e[i].x,e[i].y,e[i].d,e[i].id);ins(e[i].y,e[i].x,e[i].d,e[i].id);
		}
	}
	dfs(1,0,0);
	memset(ans,63,sizeof(ans));
	for(int i=1;i<=n;i++) fa[i]=i;
	for(int i=1;i<=m;i++)
		if(b[i]==0)
		{
			int x=e[i].x,y=e[i].y,u=lca(x,y,ans[e[i].id]);
			ans[e[i].id]--;
			solve(x,u,e[i].d-1);solve(y,u,e[i].d-1);
		}
	for(int i=1;i<=m;i++) if(ans[i]>inf) printf("-1 ");
	else printf("%d ",ans[i]);
	return 0;
}


#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#define N 210000
#define maxd 18
using namespace std;
struct node{int x,y,d,nex,id;}e[N],a[2*N];
struct node1{int par[20],f[20],dep;}t[N];
int n,fir[N],len,m,fa[N],r[N],ans[N],inf=(1e9)+10;
bool b[N];
bool cmp(node x,node y)
{
	if(x.d<y.d) return 1;
	return 0;
}
void ins(int x,int y,int d,int id)
{
	a[++len].y=y;a[len].d=d;a[len].id=id;a[len].nex=fir[x];fir[x]=len;
}
int find(int x)
{
	if(fa[x]!=x) fa[x]=find(fa[x]);
	return fa[x];
}
void dfs(int x,int fa,int d)
{
	t[x].dep=t[fa].dep+1;t[x].par[0]=fa;t[x].f[0]=d;
	for(int i=1;i<=maxd;i++)
	{
		t[x].par[i]=t[t[x].par[i-1]].par[i-1];
		t[x].f[i]=min(t[x].f[i-1],t[t[x].par[i-1]].f[i-1]);
	}
	for(int k=fir[x];k;k=a[k].nex)
	{
		int y=a[k].y;
		if(y==fa) continue;
		r[y]=a[k].id;
		dfs(y,x,a[k].d);
	}
}
int lca(int x,int y,int &d)
{
	if(t[x].dep<t[y].dep) swap(x,y);
	for(int i=maxd;i>=0;i--) if(t[t[x].par[i]].dep>=t[y].dep) {d=min(d,t[x].f[i]);x=t[x].par[i];}
	if(x==y) return x;
	for(int i=maxd;i>=0;i--)
		if(t[x].par[i]!=t[y].par[i])
		{
			d=min(d,min(t[x].f[i],t[y].f[i]));
			x=t[x].par[i];y=t[y].par[i];
		}
	d=min(t[x].f[0],t[y].f[0]);
	return t[x].par[0];
}
void solve(int x,int u,int d)
{
	x=find(x);
	while(t[x].dep>t[u].dep)
	{
		ans[r[x]]=min(ans[r[x]],d);
		int y=find(t[x].par[0]);
		fa[x]=y;
		x=find(x);
	}
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++) scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].d),e[i].id=i;
	sort(e+1,e+m+1,cmp);
	for(int i=1;i<=n;i++) fa[i]=i;
	for(int i=1;i<=m;i++)
	{
		int x=find(e[i].x),y=find(e[i].y);
		if(x!=y)
		{
			b[i]=1;
			fa[x]=y;
			ins(e[i].x,e[i].y,e[i].d,e[i].id);ins(e[i].y,e[i].x,e[i].d,e[i].id);
		}
	}
	dfs(1,0,0);
	memset(ans,63,sizeof(ans));
	for(int i=1;i<=n;i++) fa[i]=i;
	for(int i=1;i<=m;i++)
		if(b[i]==0)
		{
			int x=e[i].x,y=e[i].y,u=lca(x,y,ans[e[i].id]);
			ans[e[i].id]--;
			solve(x,u,e[i].d-1);solve(y,u,e[i].d-1);
		}
	for(int i=1;i<=m;i++) if(ans[i]>inf) printf("-1 ");
	else printf("%d ",ans[i]);
	return 0;
}


#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
#define N 210000
#define maxd 18
using namespace std;
struct node{int x,y,d,nex,id;}e[N],a[2*N];
struct node1{int par[20],f[20],dep;}t[N];
int n,fir[N],len,m,fa[N],r[N],ans[N],inf=(1e9)+10;
bool b[N];
bool cmp(node x,node y)
{
	if(x.d<y.d) return 1;
	return 0;
}
void ins(int x,int y,int d,int id)
{
	a[++len].y=y;a[len].d=d;a[len].id=id;a[len].nex=fir[x];fir[x]=len;
}
int find(int x)
{
	if(fa[x]!=x) fa[x]=find(fa[x]);
	return fa[x];
}
void dfs(int x,int fa,int d)
{
	t[x].dep=t[fa].dep+1;t[x].par[0]=fa;t[x].f[0]=d;
	for(int i=1;i<=maxd;i++)
	{
		t[x].par[i]=t[t[x].par[i-1]].par[i-1];
		t[x].f[i]=max(t[x].f[i-1],t[t[x].par[i-1]].f[i-1]);
	}
	for(int k=fir[x];k;k=a[k].nex)
	{
		int y=a[k].y;
		if(y==fa) continue;
		r[y]=a[k].id;
		dfs(y,x,a[k].d);
	}
}
int lca(int x,int y,int &d)
{
	d=0;
	if(t[x].dep<t[y].dep) swap(x,y);
	for(int i=maxd;i>=0;i--) if(t[t[x].par[i]].dep>=t[y].dep) {d=max(d,t[x].f[i]);x=t[x].par[i];}
	if(x==y) return x;
	for(int i=maxd;i>=0;i--)
		if(t[x].par[i]!=t[y].par[i])
		{
			d=max(d,max(t[x].f[i],t[y].f[i]));
			x=t[x].par[i];y=t[y].par[i];
		}
	d=max(d,max(t[x].f[0],t[y].f[0]));
	return t[x].par[0];
}
void solve(int x,int u,int d)
{
	x=find(x);
	while(t[x].dep>t[u].dep)
	{
		ans[r[x]]=min(ans[r[x]],d);
		int y=find(t[x].par[0]);
		fa[x]=y;
		x=find(x);
	}
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++) scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].d),e[i].id=i;
	sort(e+1,e+m+1,cmp);
	for(int i=1;i<=n;i++) fa[i]=i;
	for(int i=1;i<=m;i++)
	{
		int x=find(e[i].x),y=find(e[i].y);
		if(x!=y)
		{
			b[i]=1;
			fa[x]=y;
			ins(e[i].x,e[i].y,e[i].d,e[i].id);ins(e[i].y,e[i].x,e[i].d,e[i].id);
		}
	}
	dfs(1,0,0);
	memset(ans,63,sizeof(ans));
	for(int i=1;i<=n;i++) fa[i]=i;
	for(int i=1;i<=m;i++)
		if(b[i]==0)
		{
			int x=e[i].x,y=e[i].y,u=lca(x,y,ans[e[i].id]);
			ans[e[i].id]--;
			solve(x,u,e[i].d-1);solve(y,u,e[i].d-1);
		}
	for(int i=1;i<=m;i++) if(ans[i]>inf) printf("-1 ");
	else printf("%d ",ans[i]);
	return 0;
}


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

const int MAX = 1e5 + 6;
const int LOG = 20;

int N, M, timer = 0;
int p[MAX], lev[MAX], val[MAX], ans[MAX], pos[MAX], sub[MAX];
int dp[MAX][LOG + 1], maxi[MAX][LOG + 1];
vector<pair<int, pair<int, int> > > v[MAX];
vector<pair<int, int> > w[MAX];
vector<pair<int, pair<int, int> > > e;
vector<pair<int, pair<int, pair<int, int> > > > A, B;

set<pair<int, int> > *SET[MAX];

int find(int x){
	if(p[x] == x) return x;
	return p[x] = find(p[x]);
}

void join(int x, int y){
	x = find(x);
	y = find(y);
	p[y] = x;
}

void dfs(int cur, int parent){
	pos[cur] = ++timer;
	dp[cur][0] = parent;
	maxi[cur][0] = val[cur];
	lev[cur] = lev[parent] + 1;
	for(auto it:v[cur]){
		if(it.first == parent) continue;
		val[it.first] = it.second.first;
		dfs(it.first, cur);
		sub[cur] += sub[it.first];
	}
	++sub[cur];
}

int get(int x, int y){
	if(lev[x] < lev[y]) swap(x, y);
	int ans = 0, d = lev[x] - lev[y];
	for(int i=0; i<LOG; ++i){
		if(d & (1LL << i)){
			ans = max(ans, maxi[x][i]);
			x = dp[x][i];
		}
	}
	if(x == y) return ans;
	for(int i=LOG - 1; i>=0; --i){
		if(dp[x][i] && dp[y][i]){
			if(dp[x][i] != dp[y][i]){
				ans = max(ans, maxi[x][i]);
				ans = max(ans, maxi[y][i]);
				x = dp[x][i];
				y = dp[y][i];
			}
		}
	}
	return ans;
}

void solve(int cur, int parent, int idx = 0){
	int special = 0;
	for(auto it:v[cur]){
		if(it.first == parent) continue;
		solve(it.first, cur, it.second.second), w[MAX];
		if(sub[it.first] > sub[special]) special = it.first;
	}
	if(special == 0){
		SET[cur] = new set<pair<int, int> > ();
		for(auto it:w[cur]){
			if(pos[it.first] < pos[cur]){
				(*SET[cur]).insert({it.second, pos[it.first]});
			}
		}
		if((*SET[cur]).size() == 0) ans[idx] = -1;
		else ans[idx] = (*(*SET[cur]).begin()).first - 1;
	}
	else{
		SET[cur] = SET[special];
		for(auto it:v[cur]){
			if(it.first == parent || it.first == special) continue;
			for(auto x : (*SET[it.first])){
				if(x.second >= pos[cur] && x.second <= pos[cur] + sub[cur] - 1) continue;
				else (*SET[cur]).insert(x);
			}
		}
		for(auto it:w[cur]){
			if(pos[it.first] < pos[cur]){
				(*SET[cur]).insert({it.second, pos[it.first]});
			}
		}
		while(true){
			if((*SET[cur]).size() == 0) break;
			auto x  = (*(*SET[cur]).begin());
			if(x.second >= pos[cur] && x.second <= pos[cur] + sub[cur] - 1) (*SET[cur]).erase(x);
			else break;
		}
		if((*SET[cur]).size() == 0) ans[idx] = -1;
		else ans[idx] = (*(*SET[cur]).begin()).first - 1;
	}
	// cout << cur << endl;
	// for(auto it:(*SET[cur])){
	// 	cout << it.first << ' ' << it.second << endl;
	// }
	// cout << endl;
}

signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);

	cin >> N >> M;

	for(int i=1; i<=N; ++i) p[i] = i;

	for(int i=1; i<=M; ++i){
		int x, y, z; cin >> x >> y >> z;
		e.push_back({z, {x, y}});
	}

	sort(e.begin(), e.end());

	int cur = 0;
	for(auto it:e){
		++cur;
		int x = it.second.first, y = it.second.second, z = it.first;
		if(find(x) == find(y)) B.push_back({cur, it});
		else{
			join(x, y);
			v[x].push_back({y, {z, cur}});
			v[y].push_back({x, {z, cur}});
			// w[x].push_back(cur);
			// w[y].push_back(cur);
			A.push_back({cur, it});
		}
	}

	dfs(1, 0);
	for(int i=1; i<LOG; ++i){
		for(int j=1; j<=N; ++j){
			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]);
		}
	}

	for(auto it:B){
		int x = it.second.second.first, y = it.second.second.second, z = it.second.first;
		int val = get(x, y);
		ans[it.first] = val - 1;
		w[x].push_back({y, z});
		w[y].push_back({x, z});
		// cout << it.first << ' ' << val - 1 << endl;
	}

	solve(1, 0);

	for(int i=1; i<=M; ++i) cout << ans[i] << ' ';
	cout << endl;
}


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

const int MAX = 2e5 + 6;
const int LOG = 20;

int N, M, timer = 0;
int p[MAX], lev[MAX], val[MAX], ans[MAX], pos[MAX], sub[MAX];
int dp[MAX][LOG + 1], maxi[MAX][LOG + 1];
vector<pair<int, pair<int, int> > > v[MAX];
vector<pair<int, int> > w[MAX];
vector<pair<int, pair<int, int> > > e;
vector<pair<int, pair<int, pair<int, int> > > > A, B;
map<pair<int, int>, int> MAP;

set<pair<int, int> > *SET[MAX];

int find(int x){
	if(p[x] == x) return x;
	return p[x] = find(p[x]);
}

void join(int x, int y){
	x = find(x);
	y = find(y);
	p[y] = x;
}

void dfs(int cur, int parent){
	pos[cur] = ++timer;
	dp[cur][0] = parent;
	maxi[cur][0] = val[cur];
	lev[cur] = lev[parent] + 1;
	for(auto it:v[cur]){
		if(it.first == parent) continue;
		val[it.first] = it.second.first;
		dfs(it.first, cur);
		sub[cur] += sub[it.first];
	}
	++sub[cur];
}

int get(int x, int y){
	if(lev[x] < lev[y]) swap(x, y);
	int ans = 0, d = lev[x] - lev[y];
	for(int i=0; i<LOG; ++i){
		if(d & (1LL << i)){
			ans = max(ans, maxi[x][i]);
			x = dp[x][i];
		}
	}
	// cout << x << ' ' << y << ' ' << ans << endl;
	if(x == y) return ans;
	for(int i=LOG - 1; i>=0; --i){
		if(dp[x][i] && dp[y][i]){
			if(dp[x][i] != dp[y][i]){
				ans = max(ans, maxi[x][i]);
				ans = max(ans, maxi[y][i]);
				x = dp[x][i];
				y = dp[y][i];
			}
		}
	}
	ans = max(ans, max(maxi[x][0], maxi[y][0]));
	return ans;
}

void solve(int cur, int parent, int idx = 0){
	int special = 0;
	for(auto it:v[cur]){
		if(it.first == parent) continue;
		solve(it.first, cur, it.second.second);
		if(sub[it.first] > sub[special]) special = it.first;
	}
	if(special == 0){
		SET[cur] = new set<pair<int, int> > ();
		for(auto it:w[cur]){
			if(pos[it.first] >= pos[cur] && pos[it.first] <= pos[cur] + sub[cur] - 1) continue;
			else (*SET[cur]).insert({it.second, pos[it.first]});
		}
		if((*SET[cur]).size() == 0) ans[idx] = -1;
		else ans[idx] = (*(*SET[cur]).begin()).first - 1;
	}
	else{
		SET[cur] = SET[special];
		for(auto it:v[cur]){
			if(it.first == parent || it.first == special) continue;
			for(auto x : (*SET[it.first])){
				if(x.second >= pos[cur] && x.second <= pos[cur] + sub[cur] - 1) continue;
				else (*SET[cur]).insert(x);
			}
		}
		for(auto it:w[cur]){
			if(pos[it.first] >= pos[cur] && pos[it.first] <= pos[cur] + sub[cur] - 1) continue;
			else (*SET[cur]).insert({it.second, pos[it.first]});
		}
		while(true){
			if((*SET[cur]).size() == 0) break;
			auto x  = (*(*SET[cur]).begin());
			if(x.second >= pos[cur] && x.second <= pos[cur] + sub[cur] - 1) (*SET[cur]).erase(x);
			else break;
		}
		if((*SET[cur]).size() == 0) ans[idx] = -1;
		else ans[idx] = (*(*SET[cur]).begin()).first - 1;
	}
}

signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);

	cin >> N >> M;

	for(int i=1; i<=N; ++i) p[i] = i;

	for(int i=1; i<=M; ++i){
		int x, y, z; cin >> x >> y >> z;
		e.push_back({z, {x, y}});
		MAP[{x, y}] = MAP[{y, x}] = i;
	}

	sort(e.begin(), e.end());

	for(auto it:e){
		int x = it.second.first, y = it.second.second, z = it.first;
		if(find(x) == find(y)) B.push_back({MAP[{x, y}], it});
		else{
			// cout << x << ' ' << y << ' ' << z << endl;
			join(x, y);
			v[x].push_back({y, {z, MAP[{x, y}]}});
			v[y].push_back({x, {z, MAP[{x, y}]}});
			// w[x].push_back(MAP[{x, y)];
			// w[y].push_back(MAP[{x, y)];
			A.push_back({MAP[{x, y}], it});
		}
	}

	dfs(1, 0);
	for(int i=1; i<LOG; ++i){
		for(int j=1; j<=N; ++j){
			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]);
		}
	}

	// cout << get(5, 6) << endl;

	for(auto it:B){
		int x = it.second.second.first, y = it.second.second.second, z = it.second.first;
		int val = get(x, y);
		// cout << x << ' ' << y << ' ' << val << ' ' << it.first << endl;
		ans[it.first] = val - 1;
		w[x].push_back({y, z});
		w[y].push_back({x, z});
		// cout << it.first << ' ' << val - 1 << endl;
	}

	solve(1, 0);

	for(int i=1; i<=M; ++i) cout << ans[i] << ' ';
	cout << endl;
}


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

const int MAX = 1e5 + 6;
const int LOG = 20;

int N, M, timer = 0;
int p[MAX], lev[MAX], val[MAX], ans[MAX], pos[MAX], sub[MAX];
int dp[MAX][LOG + 1], maxi[MAX][LOG + 1];
vector<pair<int, pair<int, int> > > v[MAX];
vector<pair<int, int> > w[MAX];
vector<pair<int, pair<int, int> > > e;
vector<pair<int, pair<int, pair<int, int> > > > A, B;
map<pair<int, int>, int> MAP;

set<pair<int, int> > *SET[MAX];

int find(int x){
	if(p[x] == x) return x;
	return p[x] = find(p[x]);
}

void join(int x, int y){
	x = find(x);
	y = find(y);
	p[y] = x;
}

void dfs(int cur, int parent){
	pos[cur] = ++timer;
	dp[cur][0] = parent;
	maxi[cur][0] = val[cur];
	lev[cur] = lev[parent] + 1;
	for(auto it:v[cur]){
		if(it.first == parent) continue;
		val[it.first] = it.second.first;
		dfs(it.first, cur);
		sub[cur] += sub[it.first];
	}
	++sub[cur];
}

int get(int x, int y){
	if(lev[x] < lev[y]) swap(x, y);
	int ans = 0, d = lev[x] - lev[y];
	for(int i=0; i<LOG; ++i){
		if(d & (1LL << i)){
			ans = max(ans, maxi[x][i]);
			x = dp[x][i];
		}
	}
	// cout << x << ' ' << y << ' ' << ans << endl;
	if(x == y) return ans;
	for(int i=LOG - 1; i>=0; --i){
		if(dp[x][i] && dp[y][i]){
			if(dp[x][i] != dp[y][i]){
				ans = max(ans, maxi[x][i]);
				ans = max(ans, maxi[y][i]);
				x = dp[x][i];
				y = dp[y][i];
			}
		}
	}
	ans = max(ans, max(maxi[x][0], maxi[y][0]));
	return ans;
}

void solve(int cur, int parent, int idx = 0){
	int special = 0;
	for(auto it:v[cur]){
		if(it.first == parent) continue;
		solve(it.first, cur, it.second.second);
		if(sub[it.first] > sub[special]) special = it.first;
	}
	if(special == 0){
		SET[cur] = new set<pair<int, int> > ();
		for(auto it:w[cur]){
			if(pos[it.first] >= pos[cur] && pos[it.first] <= pos[cur] + sub[cur] - 1) continue;
			else (*SET[cur]).insert({it.second, pos[it.first]});
		}
		if((*SET[cur]).size() == 0) ans[idx] = -1;
		else ans[idx] = (*(*SET[cur]).begin()).first - 1;
	}
	else{
		SET[cur] = SET[special];
		for(auto it:v[cur]){
			if(it.first == parent || it.first == special) continue;
			for(auto x : (*SET[it.first])){
				if(x.second >= pos[cur] && x.second <= pos[cur] + sub[cur] - 1) continue;
				else (*SET[cur]).insert(x);
			}
		}
		for(auto it:w[cur]){
			if(pos[it.first] >= pos[cur] && pos[it.first] <= pos[cur] + sub[cur] - 1) continue;
			else (*SET[cur]).insert({it.second, pos[it.first]});
		}
		while(true){
			if((*SET[cur]).size() == 0) break;
			auto x  = (*(*SET[cur]).begin());
			if(x.second >= pos[cur] && x.second <= pos[cur] + sub[cur] - 1) (*SET[cur]).erase(x);
			else break;
		}
		if((*SET[cur]).size() == 0) ans[idx] = -1;
		else ans[idx] = (*(*SET[cur]).begin()).first - 1;
	}
}

signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);

	cin >> N >> M;

	for(int i=1; i<=N; ++i) p[i] = i;

	for(int i=1; i<=M; ++i){
		int x, y, z; cin >> x >> y >> z;
		e.push_back({z, {x, y}});
		MAP[{x, y}] = MAP[{y, x}] = i;
	}

	sort(e.begin(), e.end());

	for(auto it:e){
		int x = it.second.first, y = it.second.second, z = it.first;
		if(find(x) == find(y)) B.push_back({MAP[{x, y}], it});
		else{
			// cout << x << ' ' << y << ' ' << z << endl;
			join(x, y);
			v[x].push_back({y, {z, MAP[{x, y}]}});
			v[y].push_back({x, {z, MAP[{x, y}]}});
			// w[x].push_back(MAP[{x, y)];
			// w[y].push_back(MAP[{x, y)];
			A.push_back({MAP[{x, y}], it});
		}
	}

	dfs(1, 0);
	for(int i=1; i<LOG; ++i){
		for(int j=1; j<=N; ++j){
			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]);
		}
	}

	// cout << get(5, 6) << endl;

	for(auto it:B){
		int x = it.second.second.first, y = it.second.second.second, z = it.second.first;
		int val = get(x, y);
		// cout << x << ' ' << y << ' ' << val << ' ' << it.first << endl;
		ans[it.first] = val - 1;
		w[x].push_back({y, z});
		w[y].push_back({x, z});
		// cout << it.first << ' ' << val - 1 << endl;
	}

	solve(1, 0);

	for(int i=1; i<=M; ++i) cout << ans[i] << ' ';
	cout << endl;
}


// http://codeforces.com/blog/entry/22072

#include<bits/stdc++.h>

using namespace std;

typedef vector<int> vi;
typedef pair<int,int> pii;

#define f first
#define s second
#define pb push_back
#define F0R(i,a) for (int i = 0; i < a; ++i)
#define F0Rd(i,a) for (int i = a-1; i >= 0; --i)
#define FOR(i,a,b) for (int i = a; i < b; ++i)

const int SZ = 1<<18;
const int INF = INT_MAX;

class LazySegTree {
    public:
    	int mn[2*SZ], lazy[2*SZ];

    	LazySegTree() {
    		memset (mn,0,sizeof mn);
    		memset (lazy,-1,sizeof lazy);
    	}

    	void push(int ind, int L, int R) {
    		if (lazy[ind] == -1) return;
    		mn[ind] = lazy[ind];
    		if (L != R) lazy[2*ind] = lazy[ind], lazy[2*ind+1] = lazy[ind];
    		lazy[ind] = -1;
    	}

    	void build() {
    		for (int i = SZ-1; i > 0; --i) mn[i] = min(mn[2*i],mn[2*i+1]);
    	}

    	void pull(int ind) {
    		mn[ind] = min(mn[2*ind],mn[2*ind+1]);
    	}

    	int qmin(int lo, int hi, int ind = 1, int L = 0, int R = SZ-1) {
    		push(ind,L,R);
    		if (lo > R || L > hi) return 1000000007;
    		if (lo <= L && R <= hi) return mn[ind];

    		int M = (L+R)/2;
    		return min(qmin(lo,hi,2*ind,L,M),qmin(lo,hi,2*ind+1,M+1,R));
    	}

    	void upd(int lo, int hi, int val, int ind = 1, int L = 0, int R = SZ-1) { // take account for minimum as well
    		push(ind,L,R);
    		if (hi < L || R < lo) return;
    		if (lo <= L && R <= hi) {
    			lazy[ind] = val;
    			push(ind,L,R);
    			return;
    	   	}

    		int M = (L+R)/2;
    		upd(lo,hi,val,2*ind,L,M); upd(lo,hi,val,2*ind+1,M+1,R);
    		pull(ind);
    	}
};

vector<vector<pii>> graph;

template <int V>
class HeavyLight {
    public:
        int parent[V], heavy[V], depth[V];
        int root[V], treePos[V];
        LazySegTree tree;

        HeavyLight() {}

        int dfs(int v) {
            int size = 1, maxSubtree = 0;
            for (pii u : graph[v]) if (u.f != parent[v]) {
                parent[u.f] = v;
                depth[u.f] = depth[v] + 1;
                int subtree = dfs(u.f);
                if (subtree > maxSubtree) heavy[v] = u.f, maxSubtree = subtree;
                size += subtree;
            }
            return size;
        }

        template <class BinaryOperation>
        void processPath(int u, int v, BinaryOperation op) {
            //cout << "HI " << u << " " << v << " " << treePos[u] << " " << treePos[v] << "\n";
            //cout << "ASDF " << root[u] << " " << root[v] << "\n";
            for (; root[u] != root[v]; v = parent[root[v]]) {
                if (depth[root[u]] > depth[root[v]]) swap(u, v);
                op(treePos[root[v]], treePos[v]);
            }
            if (depth[u] > depth[v]) swap(u, v);
            op(treePos[u]+1, treePos[v]);
        }

        void init() {
            int n = graph.size();
            fill_n(heavy, n, -1);
            parent[0] = -1, depth[0] = 0;
            dfs(0);
            for (int i = 0, currentPos = 0; i < n; ++i)
                if (parent[i] == -1 || heavy[parent[i]] != i)
                    for (int j = i; j != -1; j = heavy[j]) {
                    root[j] = i;
                    treePos[j] = currentPos++;
                }
        }

        void set(int v, int value) {
            tree.upd(treePos[v], treePos[v], value);
        }

        void modifyPath(int u, int v, int value) {
            processPath(u, v, [this, &value](int l, int r) { tree.upd(l, r, value); });
        }

        int queryPath(int u, int v) {
            int res = 1000000007;
            processPath(u, v, [this, &res](int l, int r) { res = min(res,tree.qmin(l, r)); });
            return res;
        }
};

int n,m,ans[200000], par[200000], sz[200000], in[200000];
vector<pair<pii,pii>> edge;

int getpar(int x) {
    if (par[par[x]] != par[x]) par[x] = getpar(par[x]);
    return par[x];
}

bool unite(pair<pii,pii> x) {
    int a1 = getpar(x.s.f), b1 = getpar(x.s.s);
    if (a1 == b1) return 0;
    if (a1 < b1) swap(a1,b1);
    par[b1] = a1; sz[a1] += sz[b1];
    graph[x.s.f].pb({x.s.s,x.f.f});
    graph[x.s.s].pb({x.s.f,x.f.f});
    return 1;
}

int main() {
	cin >> n >> m;
	F0R(i,m) {
	    int u,v,c; cin >> u >> v >> c;
	    u--, v--;
	    edge.pb({{c,i},{u,v}});
	}
	graph.resize(n);

	F0R(i,n) par[i] = i, sz[i] = 1;
	sort(edge.begin(),edge.end());
	F0R(i,edge.size()) if (unite(edge[i])) in[i] = 1;

	HeavyLight<200000> h1; // if not in MST then query the path and subtract 1
	h1.init();

	HeavyLight<200000> h2;
	h2.init();

	F0R(i,edge.size()) if (in[i]) {
	    h1.modifyPath(edge[i].s.f,edge[i].s.s,-edge[i].f.f);
	}

	F0Rd(i,edge.size()) if (!in[i]) {
	    ans[edge[i].f.s] = -h1.queryPath(edge[i].s.f,edge[i].s.s)-1;
	    h2.modifyPath(edge[i].s.f,edge[i].s.s,edge[i].f.f);
	}

	F0R(i,edge.size()) if (in[i]) ans[edge[i].f.s] = h2.queryPath(edge[i].s.f,edge[i].s.s)-1;
	F0R(i,m) cout << ans[i] << " ";
}


// http://codeforces.com/blog/entry/22072

#include<bits/stdc++.h>

using namespace std;

typedef vector<int> vi;
typedef pair<int,int> pii;

#define f first
#define s second
#define pb push_back
#define F0R(i,a) for (int i = 0; i < a; ++i)
#define F0Rd(i,a) for (int i = a-1; i >= 0; --i)
#define FOR(i,a,b) for (int i = a; i < b; ++i)

const int SZ = 1<<18;
const int MOD = 1000000007;

class LazySegTree {
    public:
    	int mn[2*SZ], lazy[2*SZ];

    	LazySegTree() {
    		F0R(i,2*SZ) mn[i] = 0;
    		F0R(i,2*SZ) lazy[i] = -MOD;
    	}

    	void push(int ind, int L, int R) {
    		if (lazy[ind] == -MOD) return;
    		mn[ind] = lazy[ind];
    		if (L != R) lazy[2*ind] = lazy[ind], lazy[2*ind+1] = lazy[ind];
    		lazy[ind] = -MOD;
    	}

    	void build() {
    		for (int i = SZ-1; i > 0; --i) mn[i] = min(mn[2*i],mn[2*i+1]);
    	}

    	void pull(int ind) {
    		mn[ind] = min(mn[2*ind],mn[2*ind+1]);
    	}

    	int qmin(int lo, int hi, int ind = 1, int L = 0, int R = SZ-1) {
    		push(ind,L,R);
    		if (lo > R || L > hi) return MOD;
    		if (lo <= L && R <= hi) return mn[ind];

    		int M = (L+R)/2;
    		return min(qmin(lo,hi,2*ind,L,M),qmin(lo,hi,2*ind+1,M+1,R));
    	}

    	void upd(int lo, int hi, int val, int ind = 1, int L = 0, int R = SZ-1) { // take account for minimum as well
    		push(ind,L,R);
    		if (hi < L || R < lo) return;
    		if (lo <= L && R <= hi) {
    			lazy[ind] = val;
    			push(ind,L,R);
    			return;
    	   	}

    		int M = (L+R)/2;
    		upd(lo,hi,val,2*ind,L,M); upd(lo,hi,val,2*ind+1,M+1,R);
    		pull(ind);
    	}
};

vector<vector<pii>> graph;

template <int V>
class HeavyLight {
    public:
        int parent[V], heavy[V], depth[V];
        int root[V], treePos[V];
        LazySegTree tree;

        HeavyLight() {}

        int dfs(int v) {
            int size = 1, maxSubtree = 0;
            for (pii u : graph[v]) if (u.f != parent[v]) {
                parent[u.f] = v;
                depth[u.f] = depth[v] + 1;
                int subtree = dfs(u.f);
                if (subtree > maxSubtree) heavy[v] = u.f, maxSubtree = subtree;
                size += subtree;
            }
            return size;
        }

        template <class BinaryOperation>
        void processPath(int u, int v, BinaryOperation op) {
            //cout << "HI " << u << " " << v << " " << treePos[u] << " " << treePos[v] << "\n";
            //cout << "ASDF " << root[u] << " " << root[v] << "\n";
            for (; root[u] != root[v]; v = parent[root[v]]) {
                if (depth[root[u]] > depth[root[v]]) swap(u, v);
                op(treePos[root[v]], treePos[v]);
            }
            if (depth[u] > depth[v]) swap(u, v);
            op(treePos[u]+1, treePos[v]);
        }

        void init() {
            int n = graph.size();
            fill_n(heavy, n, -1);
            parent[0] = -1, depth[0] = 0;
            dfs(0);
            for (int i = 0, currentPos = 0; i < n; ++i)
                if (parent[i] == -1 || heavy[parent[i]] != i)
                    for (int j = i; j != -1; j = heavy[j]) {
                    root[j] = i;
                    treePos[j] = currentPos++;
                }
        }

        void set(int v, int value) {
            tree.upd(treePos[v], treePos[v], value);
        }

        void modifyPath(int u, int v, int value) {
            processPath(u, v, [this, &value](int l, int r) { tree.upd(l, r, value); });
        }

        int queryPath(int u, int v) {
            int res = 1000000007;
            processPath(u, v, [this, &res](int l, int r) { res = min(res,tree.qmin(l, r)); });
            return res;
        }
};

int n,m,ans[200000], par[200000], sz[200000], in[200000];
vector<pair<pii,pii>> edge;

int getpar(int x) {
    if (par[par[x]] != par[x]) par[x] = getpar(par[x]);
    return par[x];
}

bool unite(pair<pii,pii> x) {
    int a1 = getpar(x.s.f), b1 = getpar(x.s.s);
    if (a1 == b1) return 0;
    if (a1 < b1) swap(a1,b1);
    par[b1] = a1; sz[a1] += sz[b1];
    graph[x.s.f].pb({x.s.s,x.f.f});
    graph[x.s.s].pb({x.s.f,x.f.f});
    return 1;
}

int main() {
	cin >> n >> m;
	F0R(i,m) {
	    int u,v,c; cin >> u >> v >> c;
	    u--, v--;
	    edge.pb({{c,i},{u,v}});
	}
	graph.resize(n);

	F0R(i,n) par[i] = i, sz[i] = 1;
	sort(edge.begin(),edge.end());
	F0R(i,edge.size()) if (unite(edge[i])) in[i] = 1;

	HeavyLight<200000> h1; // if not in MST then query the path and subtract 1
	h1.init();

	HeavyLight<200000> h2;
	h2.init();

	F0R(i,edge.size()) if (in[i]) {
	    h1.modifyPath(edge[i].s.f,edge[i].s.s,-edge[i].f.f);
	}

	F0Rd(i,edge.size()) if (!in[i]) {
	    ans[edge[i].f.s] = -h1.queryPath(edge[i].s.f,edge[i].s.s)-1;
	    h2.modifyPath(edge[i].s.f,edge[i].s.s,edge[i].f.f);
	}

	F0R(i,edge.size()) if (in[i]) ans[edge[i].f.s] = h2.queryPath(edge[i].s.f,edge[i].s.s)-1;
	F0R(i,m) cout << ans[i] << " ";
}


#include<bits/stdc++.h>

using namespace std;

typedef vector<int> vi;
typedef pair<int,int> pii;

#define f first
#define s second
#define pb push_back
#define F0R(i,a) for (int i = 0; i < a; ++i)
#define F0Rd(i,a) for (int i = a-1; i >= 0; --i)
#define FOR(i,a,b) for (int i = a; i < b; ++i)

const int SZ = 1<<18;
const int MOD = 1000000007;

class LazySegTree {
    public:
    	int mn[2*SZ], lazy[2*SZ];

    	LazySegTree() {
    		F0R(i,2*SZ) mn[i] = 0;
    		F0R(i,2*SZ) lazy[i] = -MOD;
    	}

    	void push(int ind, int L, int R) {
    		if (lazy[ind] == -MOD) return;
    		mn[ind] = lazy[ind];
    		if (L != R) lazy[2*ind] = lazy[ind], lazy[2*ind+1] = lazy[ind];
    		lazy[ind] = -MOD;
    	}

    	void build() {
    		for (int i = SZ-1; i > 0; --i) mn[i] = min(mn[2*i],mn[2*i+1]);
    	}

    	void pull(int ind) {
    		mn[ind] = min(mn[2*ind],mn[2*ind+1]);
    	}

    	int qmin(int lo, int hi, int ind = 1, int L = 0, int R = SZ-1) {
    		push(ind,L,R);
    		if (lo > R || L > hi) return MOD;
    		if (lo <= L && R <= hi) return mn[ind];

    		int M = (L+R)/2;
    		return min(qmin(lo,hi,2*ind,L,M),qmin(lo,hi,2*ind+1,M+1,R));
    	}

    	void upd(int lo, int hi, int val, int ind = 1, int L = 0, int R = SZ-1) { // take account for minimum as well
    		push(ind,L,R);
    		if (hi < L || R < lo) return;
    		if (lo <= L && R <= hi) {
    			lazy[ind] = val;
    			push(ind,L,R);
    			return;
    	   	}

    		int M = (L+R)/2;
    		upd(lo,hi,val,2*ind,L,M); upd(lo,hi,val,2*ind+1,M+1,R);
    		pull(ind);
    	}
};

vector<vector<pii>> graph;

template <int V>
class HeavyLight {
    public:
        int parent[V], heavy[V], depth[V];
        int root[V], treePos[V];
        LazySegTree tree;

        HeavyLight() {}

        int dfs(int v) {
            int size = 1, maxSubtree = 0;
            for (pii u : graph[v]) if (u.f != parent[v]) {
                parent[u.f] = v;
                depth[u.f] = depth[v] + 1;
                int subtree = dfs(u.f);
                if (subtree > maxSubtree) heavy[v] = u.f, maxSubtree = subtree;
                size += subtree;
            }
            return size;
        }

        template <class BinaryOperation>
        void processPath(int u, int v, BinaryOperation op) {
            //cout << "HI " << u << " " << v << " " << treePos[u] << " " << treePos[v] << "\n";
            //cout << "ASDF " << root[u] << " " << root[v] << "\n";
            for (; root[u] != root[v]; v = parent[root[v]]) {
                if (depth[root[u]] > depth[root[v]]) swap(u, v);
                op(treePos[root[v]], treePos[v]);
            }
            if (depth[u] > depth[v]) swap(u, v);
            op(treePos[u]+1, treePos[v]);
        }

        void init() {
            int n = graph.size();
            fill_n(heavy, n, -1);
            parent[0] = -1, depth[0] = 0;
            dfs(0);
            for (int i = 0, currentPos = 0; i < n; ++i)
                if (parent[i] == -1 || heavy[parent[i]] != i)
                    for (int j = i; j != -1; j = heavy[j]) {
                    root[j] = i;
                    treePos[j] = currentPos++;
                }
        }

        void set(int v, int value) {
            tree.upd(treePos[v], treePos[v], value);
        }

        void modifyPath(int u, int v, int value) {
            processPath(u, v, [this, &value](int l, int r) { tree.upd(l, r, value); });
        }

        int queryPath(int u, int v) {
            int res = 1000000007;
            processPath(u, v, [this, &res](int l, int r) { res = min(res,tree.qmin(l, r)); });
            return res;
        }
};

int n,m,ans[200000], par[200000], sz[200000], in[200000];
vector<pair<pii,pii>> edge;

int getpar(int x) {
    if (par[par[x]] != par[x]) par[x] = getpar(par[x]);
    return par[x];
}

bool unite(pair<pii,pii> x) {
    int a1 = getpar(x.s.f), b1 = getpar(x.s.s);
    if (a1 == b1) return 0;
    if (a1 < b1) swap(a1,b1);
    par[b1] = a1; sz[a1] += sz[b1];
    graph[x.s.f].pb({x.s.s,x.f.f});
    graph[x.s.s].pb({x.s.f,x.f.f});
    return 1;
}

int main() {
    ios_base::sync_with_stdio(0); cin.tie(0);
	cin >> n >> m;
	F0R(i,m) {
	    int u,v,c; cin >> u >> v >> c;
	    u--, v--;
	    edge.pb({{c,i},{u,v}});
	}
	graph.resize(n);

	F0R(i,n) par[i] = i, sz[i] = 1;
	sort(edge.begin(),edge.end());
	F0R(i,edge.size()) if (unite(edge[i])) in[i] = 1;

	HeavyLight<200000> h1; // if not in MST then query the path and subtract 1
	h1.init();

	HeavyLight<200000> h2;
	h2.init();

	F0R(i,edge.size()) if (in[i]) {
	    h1.modifyPath(edge[i].s.f,edge[i].s.s,-edge[i].f.f);
	}

	F0Rd(i,edge.size()) if (!in[i]) {
	    ans[edge[i].f.s] = -h1.queryPath(edge[i].s.f,edge[i].s.s)-1;
	    h2.modifyPath(edge[i].s.f,edge[i].s.s,edge[i].f.f);
	}

	F0R(i,edge.size()) if (in[i]) ans[edge[i].f.s] = h2.queryPath(edge[i].s.f,edge[i].s.s)-1;
	F0R(i,m) cout << ans[i] << " ";
}


// http://codeforces.com/blog/entry/22072

#include<bits/stdc++.h>

using namespace std;

typedef vector<int> vi;
typedef pair<int,int> pii;

#define f first
#define s second
#define pb push_back
#define F0R(i,a) for (int i = 0; i < a; ++i)
#define F0Rd(i,a) for (int i = a-1; i >= 0; --i)
#define FOR(i,a,b) for (int i = a; i < b; ++i)

const int SZ = 1<<18;
const int INF = INT_MAX;

class LazySegTree {
    public:
    	int mn[2*SZ], lazy[2*SZ];

    	LazySegTree() {
    		memset (mn,0,sizeof mn);
    		memset (lazy,-1,sizeof lazy);
    	}

    	void push(int ind, int L, int R) {
    		if (lazy[ind] == -1) return;
    		mn[ind] = lazy[ind];
    		if (L != R) lazy[2*ind] = lazy[ind], lazy[2*ind+1] = lazy[ind];
    		lazy[ind] = -1;
    	}

    	void build() {
    		for (int i = SZ-1; i > 0; --i) mn[i] = min(mn[2*i],mn[2*i+1]);
    	}

    	void pull(int ind) {
    		mn[ind] = min(mn[2*ind],mn[2*ind+1]);
    	}

    	int qmin(int lo, int hi, int ind = 1, int L = 0, int R = SZ-1) {
    		push(ind,L,R);
    		if (lo > R || L > hi) return 1000000007;
    		if (lo <= L && R <= hi) return mn[ind];

    		int M = (L+R)/2;
    		return min(qmin(lo,hi,2*ind,L,M),qmin(lo,hi,2*ind+1,M+1,R));
    	}

    	void upd(int lo, int hi, int val, int ind = 1, int L = 0, int R = SZ-1) { // take account for minimum as well
    		push(ind,L,R);
    		if (hi < L || R < lo) return;
    		if (lo <= L && R <= hi) {
    			lazy[ind] = val;
    			push(ind,L,R);
    			return;
    	   	}

    		int M = (L+R)/2;
    		upd(lo,hi,val,2*ind,L,M); upd(lo,hi,val,2*ind+1,M+1,R);
    		pull(ind);
    	}
};

vector<vector<pii>> graph;

template <int V>
class HeavyLight {
    public:
        int parent[V], heavy[V], depth[V];
        int root[V], treePos[V];
        LazySegTree tree;

        HeavyLight() {}

        int dfs(int v) {
            int size = 1, maxSubtree = 0;
            for (pii u : graph[v]) if (u.f != parent[v]) {
                parent[u.f] = v;
                depth[u.f] = depth[v] + 1;
                int subtree = dfs(u.f);
                if (subtree > maxSubtree) heavy[v] = u.f, maxSubtree = subtree;
                size += subtree;
            }
            return size;
        }

        template <class BinaryOperation>
        void processPath(int u, int v, BinaryOperation op) {
            //cout << "HI " << u << " " << v << " " << treePos[u] << " " << treePos[v] << "\n";
            //cout << "ASDF " << root[u] << " " << root[v] << "\n";
            for (; root[u] != root[v]; v = parent[root[v]]) {
                if (depth[root[u]] > depth[root[v]]) swap(u, v);
                op(treePos[root[v]], treePos[v]);
            }
            if (depth[u] > depth[v]) swap(u, v);
            op(treePos[u]+1, treePos[v]);
        }

        void init() {
            int n = graph.size();
            fill_n(heavy, n, -1);
            parent[0] = -1, depth[0] = 0;
            dfs(0);
            for (int i = 0, currentPos = 0; i < n; ++i)
                if (parent[i] == -1 || heavy[parent[i]] != i)
                    for (int j = i; j != -1; j = heavy[j]) {
                    root[j] = i;
                    treePos[j] = currentPos++;
                }
        }

        void set(int v, int value) {
            tree.upd(treePos[v], treePos[v], value);
        }

        void modifyPath(int u, int v, int value) {
            processPath(u, v, [this, &value](int l, int r) { tree.upd(l, r, value); });
        }

        int queryPath(int u, int v) {
            int res = 1000000007;
            processPath(u, v, [this, &res](int l, int r) { res = min(res,tree.qmin(l, r)); });
            return res;
        }
};

int n,m,ans[200000], par[200000], sz[200000], in[200000];
vector<pair<pii,pii>> edge;

int getpar(int x) {
    if (par[par[x]] != par[x]) par[x] = getpar(par[x]);
    return par[x];
}

bool unite(pair<pii,pii> x) {
    int a1 = getpar(x.s.f), b1 = getpar(x.s.s);
    if (a1 == b1) return 0;
    if (a1 < b1) swap(a1,b1);
    par[b1] = a1; sz[a1] += sz[b1];
    graph[x.s.f].pb({x.s.s,x.f.f});
    graph[x.s.s].pb({x.s.f,x.f.f});
    return 1;
}

int main() {
	cin >> n >> m;
	F0R(i,m) {
	    int u,v,c; cin >> u >> v >> c;
	    u--, v--;
	    edge.pb({{c,i},{u,v}});
	}
	graph.resize(n);

	F0R(i,n) par[i] = i, sz[i] = 1;
	sort(edge.begin(),edge.end());
	F0R(i,edge.size()) if (unite(edge[i])) in[i] = 1;

	HeavyLight<200000> h1; // if not in MST then query the path and subtract 1
	h1.init();

	HeavyLight<200000> h2;
	h2.init();

	F0R(i,edge.size()) if (in[i]) {
	    h1.modifyPath(edge[i].s.f,edge[i].s.s,edge[i].f.f);
	    /*cout << "A " << edge[i].s.f << " " << edge[i].s.s << " "
	    << edge[i].f.f << " " << h1.queryPath(edge[i].s.f,edge[i].s.s) << "\n";*/
	}

	F0Rd(i,edge.size()) if (!in[i]) {
	    ans[edge[i].f.s] = h1.queryPath(edge[i].s.f,edge[i].s.s)-1;
	    h2.modifyPath(edge[i].s.f,edge[i].s.s,edge[i].f.f);
	    //cout << edge[i].s.f << " " << edge[i].s.s << " " << edge[i].f.f << "\n";
	}

	F0R(i,edge.size()) if (in[i]) ans[edge[i].f.s] = h2.queryPath(edge[i].s.f,edge[i].s.s)-1;
	F0R(i,m) cout << ans[i] << "\n";
}


#include "bits/stdc++.h"
using namespace std;
#define FAST ios_base::sync_with_stdio(false); cin.tie(0);
#define LLINF (long long) 1e18//1234567890987654321
#define INF 1234567890
#define pb push_back
#define ins insert
#define f first
#define s second
#define db 0
#define EPS (1e-7)    //0.0000001 the value
#define PI (acos(-1))
#define MAXN 300006
#define MAXK 26
#define MAXX 15000006
#define ll long long int
#define ld long double
#define rep0(kk, l1, l2)for(ll kk = l1; kk < l2; kk++)
#define rep1(kk, l1, l2)for(ll kk = l1; kk <= l2; kk++)
#define foritr(itr, A) for(set<ll>::iterator itr = A.begin(); itr != A.end(); itr++)
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());    //can be used by calling rng() or shuffle(A, A+n, rng)
#define FOR(ii, ss, ee) for(ll ii = ss; ii < ee; ii++)
#define cr(x) cerr << #x << " = " << x << "\n";
#define crA(x, A) cerr << #x << " = " << A[x] << "\n";
#define spacing if(db)cout << " ";
#define space " "
#define cbr cout << "hi\n"
#define mmst(x, v) memset((x), v, sizeof ((x)));
#define bg(ms) (*ms.begin())
#define ed(ms) (*prev(ms.end(), 1))
#define addedge(a, b, c, v) v[(a)].pb(pi((b), (c))); v[(b)].pb(pi((a), (c)))
#define ph push
#define btinpct(x) __builtin_popcountll(x)
#define p2(x) (1LL<<(x))
#define all(x) (x).begin(), (x).end()
#define lbd(x, y) lower_bound(all(x), y)
#define ubd(x, y) upper_bound(all(x), y)
typedef pair <ll, ll> pi;
typedef pair <ll, pi> spi;
typedef pair <pi, pi> dpi;
inline ll rand(ll x, ll y) { ++y; return (rng() % (y-x)) + x; } //inclusivesss
ll n, m;
vector <spi> v[MAXN];
struct ufds
{
	ll p[MAXN];
	void init() { for(ll i = 1; i <= n; i++) p[i] = i; }
	ll find(ll x) { return (p[x] == x) ? x : p[x]=find(p[x]);}
	bool same(ll x, ll y) { return find(x) == find(y); }
	void merge(ll x, ll y) { p[find(x)] = find(y); }
} ufds;
struct edge{
	ll x,y,w,i;
	bool operator < (const edge &e) const
	{
		return w < e.w;
	}
};
vector <edge> edges;
bool in[MAXN];
ll ans[MAXN],eno[MAXN];
vector <ll> add[MAXN];
vector <ll> re[MAXN];
ll st[MAXN], en[MAXN], co, p[MAXN][21], depth[MAXN], d[MAXN][21];
struct lca_
{
	void main()
	{
		co=0;
		dfs(1,1);
		t2k();
	}
	void dfs(ll x, ll par)
	{
		st[x] = co ++;
		p[x][0] = par;
		for(auto ii : v[x])
		{
			ll i = ii.s.f;
			if(i==par) continue;
			depth[i]=depth[x]+1;
			d[i][0] = ii.s.s;
			eno[i]=ii.f;
			dfs(i,x);
		}
		en[x] = co;
	}
	void t2k() { for(ll j = 1; j < 21; j++) for(ll i = 1; i <= n; i++) { d[i][j]=max(d[p[i][j-1]][j-1], d[i][j-1]);p[i][j] = p[p[i][j-1]][j-1]; }}
	ll lca(ll x, ll y)
	{
		if(isp(x,y)) return x;
		if(isp(y,x)) return y;
		for(ll i = 20; i >= 0; i--)
		{
			if(!isp(p[x][i], y)) x = p[x][i];
		}
		return p[x][0];
	}
	bool isp(ll x, ll y) { return st[x] <= st[y] && en[x] >= en[y]; }
	ll solve(ll x, ll y)
	{
		// cout << x << ' ' << y << '\n';
		ll ans = 0; if(x==y) return ans;
		if(depth[x] < depth[y]) swap(x,y);
		for(ll i = 20; i >= 0; i--)
		{
			if(depth[p[x][i]] > depth[y]) { ans = max(ans, d[x][i]); x = p[x][i]; }
		}
		assert(x!=y);
		if(p[x][0]==y) {ans=max(ans,d[x][0]);return ans;}
		if(depth[x]!=depth[y]){ans=max(ans,d[x][0]);x=p[x][0];}
		assert(depth[x]==depth[y]);
		assert(depth[x]==depth[y]);
		for(ll i = 20; i >= 0; i--)
		{
			if(p[x][i] != p[y][i]) { ans = max({ans, d[x][i], d[y][i]}); x = p[x][i]; y = p[y][i]; }
		}
		ans = max({ans, d[x][0],d[y][0]});
		return ans;
	}
} lca;
multiset <ll> *s[MAXN];
void dfs(ll x, ll p)
{
	// cout<<"Node: " << x<<"\n";
	for(auto ii : v[x])
	{
		ll i = ii.s.f;
		if(i==p)continue;
		dfs(i,x);
	}
	s[x] = new multiset<ll>;
	ll pt = x;
	for(auto ii : v[x])
	{
		ll i=ii.s.f;
		if(i==p) continue;
		if(s[i]->size() > s[x]->size()) {pt=i;}
	}
	if(pt!=x) s[x] = s[pt];
	for(auto ii : v[x])
	{
		ll i=ii.s.f;
		if(i==p||i==pt) continue;
		for(auto j : *s[i]) s[x]->ins(j);
	}
	if(x==1) return;
	for(auto i : add[x]) s[x]->ins(i);
	for(auto i : re[x]) s[x]->erase(s[x]->find(i));
	// cout << x << ' ' << add[x].size() << '\n';
	if(s[x]->empty() == 0)ans[eno[x]] = *s[x]->begin();
	return;
}
void init()
{
	FOR(ii,0,m)
	{
		ll i=edges[ii].i,a=edges[ii].x,b=edges[ii].y,w=edges[ii].w;
		if(in[i]) continue;
		ll la = lca.lca(a,b);
		add[a].pb(w);
		add[b].pb(w);
		re[la].pb(w);
	}
}
int main()
{
	FAST
	cin >> n >> m;
	FOR(i,0,m)
	{
		ll a, b, c;
		cin >> a >> b >> c;
		edges.pb({a,b,c,i});
	}
	sort(all(edges));
	ufds.init();
	for(auto i : edges)
	{
		ll a = i.x, b = i.y;
		if(ufds.same(a,b)) continue;
		in[i.i] = 1;
		ufds.merge(a,b);
		v[a].pb(spi(i.i,pi(b,i.w)));
		v[b].pb(spi(i.i,pi(a,i.w)));
	}
	mmst(ans,-1);
	lca.main(); init();
	eno[1]=m+1;dfs(1,1);
	FOR(i,0,m)
	{
		if(in[i]) continue;
		else
		{
			// cout << lca.solve(edges[i].x, edges[i].y) << "\n";
			ans[i] = lca.solve(edges[i].x, edges[i].y);
		}
	}
	FOR(i,0,m){ cout << (ans[i]!=-1 ? ans[i]-1 : -1) << " ";}
	cout<<"\n";
}


#include "bits/stdc++.h"
using namespace std;
#define FAST ios_base::sync_with_stdio(false); cin.tie(0);
#define LLINF (long long) 1e18//1234567890987654321
#define INF 1234567890
#define pb push_back
#define ins insert
#define f first
#define s second
#define db 0
#define EPS (1e-7)    //0.0000001 the value
#define PI (acos(-1))
#define MAXN 300006-100000
#define MAXK 26
#define MAXX 15000006
#define ll /*long long*/ int
#define ld long double
#define rep0(kk, l1, l2)for(ll kk = l1; kk < l2; kk++)
#define rep1(kk, l1, l2)for(ll kk = l1; kk <= l2; kk++)
#define foritr(itr, A) for(set<ll>::iterator itr = A.begin(); itr != A.end(); itr++)
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());    //can be used by calling rng() or shuffle(A, A+n, rng)
#define FOR(ii, ss, ee) for(ll ii = ss; ii < ee; ii++)
#define cr(x) cerr << #x << " = " << x << "\n";
#define crA(x, A) cerr << #x << " = " << A[x] << "\n";
#define spacing if(db)cout << " ";
#define space " "
#define cbr cout << "hi\n"
#define mmst(x, v) memset((x), v, sizeof ((x)));
#define bg(ms) (*ms.begin())
#define ed(ms) (*prev(ms.end(), 1))
#define addedge(a, b, c, v) v[(a)].pb(pi((b), (c))); v[(b)].pb(pi((a), (c)))
#define ph push
#define btinpct(x) __builtin_popcountll(x)
#define p2(x) (1LL<<(x))
#define all(x) (x).begin(), (x).end()
#define lbd(x, y) lower_bound(all(x), y)
#define ubd(x, y) upper_bound(all(x), y)
typedef pair <ll, ll> pi;
typedef pair <ll, pi> spi;
typedef pair <pi, pi> dpi;
inline ll rand(ll x, ll y) { ++y; return (rng() % (y-x)) + x; } //inclusivesss
ll n, m;
vector <spi> v[MAXN];
struct ufds
{
	ll p[MAXN];
	void init() { for(ll i = 1; i <= n; i++) p[i] = i; }
	ll find(ll x) { return (p[x] == x) ? x : p[x]=find(p[x]);}
	bool same(ll x, ll y) { return find(x) == find(y); }
	void merge(ll x, ll y) { p[find(x)] = find(y); }
} ufds;
struct edge{
	ll x,y,w,i;
	bool operator < (const edge &e) const
	{
		return w < e.w;
	}
};
vector <edge> edges;
bool in[MAXN];
ll ans[MAXN],eno[MAXN];
vector <ll> add[MAXN];
vector <ll> re[MAXN];
ll st[MAXN], en[MAXN], co, p[MAXN][21], depth[MAXN], d[MAXN][21];
struct lca_
{
	void main()
	{
		co=0;
		dfs(1,1);
		t2k();
	}
	void dfs(ll x, ll par)
	{
		st[x] = co ++;
		p[x][0] = par;
		for(auto ii : v[x])
		{
			ll i = ii.s.f;
			if(i==par) continue;
			depth[i]=depth[x]+1;
			d[i][0] = ii.s.s;
			eno[i]=ii.f;
			dfs(i,x);
		}
		en[x] = co;
	}
	void t2k() { for(ll j = 1; j < 21; j++) for(ll i = 1; i <= n; i++) { d[i][j]=max(d[p[i][j-1]][j-1], d[i][j-1]);p[i][j] = p[p[i][j-1]][j-1]; }}
	ll lca(ll x, ll y)
	{
		if(isp(x,y)) return x;
		if(isp(y,x)) return y;
		for(ll i = 20; i >= 0; i--)
		{
			if(!isp(p[x][i], y)) x = p[x][i];
		}
		return p[x][0];
	}
	bool isp(ll x, ll y) { return st[x] <= st[y] && en[x] >= en[y]; }
	ll solve(ll x, ll y)
	{
		// cout << x << ' ' << y << '\n';
		ll ans = 0; if(x==y) return ans;
		if(depth[x] < depth[y]) swap(x,y);
		for(ll i = 20; i >= 0; i--)
		{
			if(depth[p[x][i]] > depth[y]) { ans = max(ans, d[x][i]); x = p[x][i]; }
		}
		assert(x!=y);
		if(p[x][0]==y) {ans=max(ans,d[x][0]);return ans;}
		if(depth[x]!=depth[y]){ans=max(ans,d[x][0]);x=p[x][0];}
		assert(depth[x]==depth[y]);
		assert(depth[x]==depth[y]);
		for(ll i = 20; i >= 0; i--)
		{
			if(p[x][i] != p[y][i]) { ans = max({ans, d[x][i], d[y][i]}); x = p[x][i]; y = p[y][i]; }
		}
		ans = max({ans, d[x][0],d[y][0]});
		return ans;
	}
} lca;
multiset <ll> *s[MAXN];
void dfs(ll x, ll p)
{
	// cout<<"Node: " << x<<"\n";
	for(auto ii : v[x])
	{
		ll i = ii.s.f;
		if(i==p)continue;
		dfs(i,x);
	}
	s[x] = new multiset<ll>;
	ll pt = x;
	for(auto ii : v[x])
	{
		ll i=ii.s.f;
		if(i==p) continue;
		if(s[i]->size() > s[x]->size()) {pt=i;}
	}
	if(pt!=x) s[x] = s[pt];
	for(auto ii : v[x])
	{
		ll i=ii.s.f;
		if(i==p||i==pt) continue;
		for(auto j : *s[i]) s[x]->ins(j);
		del s[i];
	}
	if(x==1) return;
	for(auto i : add[x]) s[x]->ins(i);
	for(auto i : re[x]) s[x]->erase(s[x]->find(i));
	// cout << x << ' ' << add[x].size() << '\n';
	if(s[x]->empty() == 0)ans[eno[x]] = *s[x]->begin();
	else assert(ans[eno[x]] == -1);
	return;
}
void init()
{
	FOR(ii,0,m)
	{
		ll i=edges[ii].i,a=edges[ii].x,b=edges[ii].y,w=edges[ii].w;
		if(in[i]) continue;
		ll la = lca.lca(a,b);
		add[a].pb(w);
		add[b].pb(w);
		re[la].pb(w);
		re[la].pb(w);
	}
}
int main()
{
	// freopen("in.bew", "r", stdin);
	FAST
	cin >> n >> m;
	FOR(i,0,m)
	{
		ll a, b, c;
		cin >> a >> b >> c;
		edges.pb({a,b,c,i});
	}
	sort(all(edges));
	ufds.init();
	for(auto i : edges)
	{
		ll a = i.x, b = i.y;
		if(ufds.same(a,b)) continue;
		in[i.i] = 1;
		ufds.merge(a,b);
		v[a].pb(spi(i.i,pi(b,i.w)));
		v[b].pb(spi(i.i,pi(a,i.w)));
	}
	mmst(ans,-1);
	lca.main(); init();
	eno[1]=m+1;dfs(1,1);
	FOR(i,0,m)
	{
		if(in[edges[i].i]) continue;
		else
		{
			// cout << lca.solve(edges[i].x, edges[i].y) << "\n";
			ans[edges[i].i] = lca.solve(edges[i].x, edges[i].y);
		}
	}
	FOR(i,0,m){ cout << (ans[i]!=-1 ? ans[i]-1 : -1) << " ";}
	cout<<"\n";
}


#include "bits/stdc++.h"
using namespace std;
#define FAST ios_base::sync_with_stdio(false); cin.tie(0);
#define LLINF (long long) 1e18//1234567890987654321
#define INF 1234567890
#define pb push_back
#define ins insert
#define f first
#define s second
#define db 0
#define EPS (1e-7)    //0.0000001 the value
#define PI (acos(-1))
#define MAXN 300006-100000
#define MAXK 26
#define MAXX 15000006
#define ll long long int
#define ld long double
#define rep0(kk, l1, l2)for(ll kk = l1; kk < l2; kk++)
#define rep1(kk, l1, l2)for(ll kk = l1; kk <= l2; kk++)
#define foritr(itr, A) for(set<ll>::iterator itr = A.begin(); itr != A.end(); itr++)
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());    //can be used by calling rng() or shuffle(A, A+n, rng)
#define FOR(ii, ss, ee) for(ll ii = ss; ii < ee; ii++)
#define cr(x) cerr << #x << " = " << x << "\n";
#define crA(x, A) cerr << #x << " = " << A[x] << "\n";
#define spacing if(db)cout << " ";
#define space " "
#define cbr cout << "hi\n"
#define mmst(x, v) memset((x), v, sizeof ((x)));
#define bg(ms) (*ms.begin())
#define ed(ms) (*prev(ms.end(), 1))
#define addedge(a, b, c, v) v[(a)].pb(pi((b), (c))); v[(b)].pb(pi((a), (c)))
#define ph push
#define btinpct(x) __builtin_popcountll(x)
#define p2(x) (1LL<<(x))
#define all(x) (x).begin(), (x).end()
#define lbd(x, y) lower_bound(all(x), y)
#define ubd(x, y) upper_bound(all(x), y)
typedef pair <ll, ll> pi;
typedef pair <ll, pi> spi;
typedef pair <pi, pi> dpi;
inline ll rand(ll x, ll y) { ++y; return (rng() % (y-x)) + x; } //inclusivesss
ll n, m;
vector <spi> v[MAXN];
struct ufds
{
	ll p[MAXN];
	void init() { for(ll i = 1; i <= n; i++) p[i] = i; }
	ll find(ll x) { return (p[x] == x) ? x : p[x]=find(p[x]);}
	bool same(ll x, ll y) { return find(x) == find(y); }
	void merge(ll x, ll y) { p[find(x)] = find(y); }
} ufds;
struct edge{
	ll x,y,w,i;
	bool operator < (const edge &e) const
	{
		return w < e.w;
	}
};
vector <edge> edges;
bool in[MAXN];
ll ans[MAXN],eno[MAXN];
vector <ll> add[MAXN];
vector <ll> re[MAXN];
ll st[MAXN], en[MAXN], co, p[MAXN][21], depth[MAXN], d[MAXN][21];
struct lca_
{
	void main()
	{
		co=0;
		dfs(1,1);
		t2k();
	}
	void dfs(ll x, ll par)
	{
		st[x] = co ++;
		p[x][0] = par;
		for(auto ii : v[x])
		{
			ll i = ii.s.f;
			if(i==par) continue;
			depth[i]=depth[x]+1;
			d[i][0] = ii.s.s;
			eno[i]=ii.f;
			dfs(i,x);
		}
		en[x] = co;
	}
	void t2k() { for(ll j = 1; j < 21; j++) for(ll i = 1; i <= n; i++) { d[i][j]=max(d[p[i][j-1]][j-1], d[i][j-1]);p[i][j] = p[p[i][j-1]][j-1]; }}
	ll lca(ll x, ll y)
	{
		if(isp(x,y)) return x;
		if(isp(y,x)) return y;
		for(ll i = 20; i >= 0; i--)
		{
			if(!isp(p[x][i], y)) x = p[x][i];
		}
		return p[x][0];
	}
	bool isp(ll x, ll y) { return st[x] <= st[y] && en[x] >= en[y]; }
	ll solve(ll x, ll y)
	{
		// cout << x << ' ' << y << '\n';
		ll ans = 0; if(x==y) return ans;
		if(depth[x] < depth[y]) swap(x,y);
		for(ll i = 20; i >= 0; i--)
		{
			if(depth[p[x][i]] > depth[y]) { ans = max(ans, d[x][i]); x = p[x][i]; }
		}
		assert(x!=y);
		if(p[x][0]==y) {ans=max(ans,d[x][0]);return ans;}
		if(depth[x]!=depth[y]){ans=max(ans,d[x][0]);x=p[x][0];}
		assert(depth[x]==depth[y]);
		assert(depth[x]==depth[y]);
		for(ll i = 20; i >= 0; i--)
		{
			if(p[x][i] != p[y][i]) { ans = max({ans, d[x][i], d[y][i]}); x = p[x][i]; y = p[y][i]; }
		}
		ans = max({ans, d[x][0],d[y][0]});
		return ans;
	}
} lca;
multiset <ll> *s[MAXN];
void dfs(ll x, ll p)
{
	// cout<<"Node: " << x<<"\n";
	for(auto ii : v[x])
	{
		ll i = ii.s.f;
		if(i==p)continue;
		dfs(i,x);
	}
	s[x] = new multiset<ll>;
	ll pt = x;
	for(auto ii : v[x])
	{
		ll i=ii.s.f;
		if(i==p) continue;
		if(s[i]->size() > s[pt]->size()) {pt=i;}
	}
	if(pt!=x) s[x] = s[pt];
	for(auto ii : v[x])
	{
		ll i=ii.s.f;
		if(i==p||i==pt) continue;
		for(auto j : *s[i]) s[x]->ins(j);
	}
	if(x==1) return;
	for(auto i : add[x]) s[x]->ins(i);
	for(auto i : re[x]) s[x]->erase(s[x]->find(i));
	// cout << x << ' ' << add[x].size() << '\n';
	if(s[x]->empty() == 0)ans[eno[x]] = *s[x]->begin();
	else assert(ans[eno[x]] == -1);
	return;
}
void init()
{
	FOR(ii,0,m)
	{
		ll i=edges[ii].i,a=edges[ii].x,b=edges[ii].y,w=edges[ii].w;
		if(in[i]) continue;
		ll la = lca.lca(a,b);
		add[a].pb(w);
		add[b].pb(w);
		re[la].pb(w);
		re[la].pb(w);
	}
}
int main()
{
	// freopen("in.bew", "r", stdin);
	FAST
	cin >> n >> m;
	FOR(i,0,m)
	{
		ll a, b, c;
		cin >> a >> b >> c;
		edges.pb({a,b,c,i});
	}
	sort(all(edges));
	ufds.init();
	for(auto i : edges)
	{
		ll a = i.x, b = i.y;
		if(ufds.same(a,b)) continue;
		in[i.i] = 1;
		ufds.merge(a,b);
		v[a].pb(spi(i.i,pi(b,i.w)));
		v[b].pb(spi(i.i,pi(a,i.w)));
	}
	mmst(ans,-1);
	lca.main(); init();
	eno[1]=m+1;dfs(1,1);
	FOR(i,0,m)
	{
		if(in[edges[i].i]) continue;
		else
		{
			// cout << lca.solve(edges[i].x, edges[i].y) << "\n";
			ans[edges[i].i] = lca.solve(edges[i].x, edges[i].y);
		}
	}
	FOR(i,0,m){ cout << (ans[i]!=-1 ? ans[i]-1 : -1) << " ";}
	cout<<"\n";
}


#include "bits/stdc++.h"
using namespace std;
#define FAST ios_base::sync_with_stdio(false); cin.tie(0);
#define LLINF (long long) 1e18//1234567890987654321
#define INF 1234567890
#define pb push_back
#define ins insert
#define f first
#define s second
#define db 0
#define EPS (1e-7)    //0.0000001 the value
#define PI (acos(-1))
#define MAXN 300006
#define MAXK 26
#define MAXX 15000006
#define ll long long int
#define ld long double
#define rep0(kk, l1, l2)for(ll kk = l1; kk < l2; kk++)
#define rep1(kk, l1, l2)for(ll kk = l1; kk <= l2; kk++)
#define foritr(itr, A) for(set<ll>::iterator itr = A.begin(); itr != A.end(); itr++)
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());    //can be used by calling rng() or shuffle(A, A+n, rng)
#define FOR(ii, ss, ee) for(ll ii = ss; ii < ee; ii++)
#define cr(x) cerr << #x << " = " << x << "\n";
#define crA(x, A) cerr << #x << " = " << A[x] << "\n";
#define spacing if(db)cout << " ";
#define space " "
#define cbr cout << "hi\n"
#define mmst(x, v) memset((x), v, sizeof ((x)));
#define bg(ms) (*ms.begin())
#define ed(ms) (*prev(ms.end(), 1))
#define addedge(a, b, c, v) v[(a)].pb(pi((b), (c))); v[(b)].pb(pi((a), (c)))
#define ph push
#define btinpct(x) __builtin_popcountll(x)
#define p2(x) (1LL<<(x))
#define all(x) (x).begin(), (x).end()
#define lbd(x, y) lower_bound(all(x), y)
#define ubd(x, y) upper_bound(all(x), y)
typedef pair <ll, ll> pi;
typedef pair <ll, pi> spi;
typedef pair <pi, pi> dpi;
inline ll rand(ll x, ll y) { ++y; return (rng() % (y-x)) + x; } //inclusivesss
ll n, m;
vector <spi> v[MAXN];
struct ufds
{
	ll p[MAXN];
	void init() { for(ll i = 1; i <= n; i++) p[i] = i; }
	ll find(ll x) { return (p[x] == x) ? x : p[x]=find(p[x]);}
	bool same(ll x, ll y) { return find(x) == find(y); }
	void merge(ll x, ll y) { p[find(x)] = find(y); }
} ufds;
struct edge{
	ll x,y,w,i;
	bool operator < (const edge &e) const
	{
		return w < e.w;
	}
};
vector <edge> edges;
bool in[MAXN];
ll ans[MAXN],eno[MAXN];
vector <ll> add[MAXN];
vector <ll> re[MAXN];
ll st[MAXN], en[MAXN], co, p[MAXN][21], depth[MAXN], d[MAXN][21];
struct lca_
{
	void main()
	{
		co=0;
		dfs(1,1);
		t2k();
	}
	void dfs(ll x, ll par)
	{
		st[x] = co ++;
		p[x][0] = par;
		for(auto ii : v[x])
		{
			ll i = ii.s.f;
			if(i==par) continue;
			depth[i]=depth[x]+1;
			d[i][0] = ii.s.s;
			eno[i]=ii.f;
			dfs(i,x);
		}
		en[x] = co;
	}
	void t2k() { for(ll j = 1; j < 21; j++) for(ll i = 1; i <= n; i++) { d[i][j]=max(d[p[i][j-1]][j-1], d[i][j-1]);p[i][j] = p[p[i][j-1]][j-1]; }}
	ll lca(ll x, ll y)
	{
		if(isp(x,y)) return x;
		if(isp(y,x)) return y;
		for(ll i = 20; i >= 0; i--)
		{
			if(!isp(p[x][i], y)) x = p[x][i];
		}
		return p[x][0];
	}
	bool isp(ll x, ll y) { return st[x] <= st[y] && en[x] >= en[y]; }
	ll solve(ll x, ll y)
	{
		// cout << x << ' ' << y << '\n';
		ll ans = 0; if(x==y) return ans;
		if(depth[x] < depth[y]) swap(x,y);
		for(ll i = 20; i >= 0; i--)
		{
			if(depth[p[x][i]] > depth[y]) { ans = max(ans, d[x][i]); x = p[x][i]; }
		}
		assert(x!=y);
		if(p[x][0]==y) {ans=max(ans,d[x][0]);return ans;}
		if(depth[x]!=depth[y]){ans=max(ans,d[x][0]);x=p[x][0];}
		assert(depth[x]==depth[y]);
		assert(depth[x]==depth[y]);
		for(ll i = 20; i >= 0; i--)
		{
			if(p[x][i] != p[y][i]) { ans = max({ans, d[x][i], d[y][i]}); x = p[x][i]; y = p[y][i]; }
		}
		ans = max({ans, d[x][0],d[y][0]});
		return ans;
	}
} lca;
multiset <ll> *s[MAXN];
void dfs(ll x, ll p)
{
	// cout<<"Node: " << x<<"\n";
	for(auto ii : v[x])
	{
		ll i = ii.s.f;
		if(i==p)continue;
		dfs(i,x);
	}
	s[x] = new multiset<ll>;
	ll pt = x;
	for(auto ii : v[x])
	{
		ll i=ii.s.f;
		if(i==p) continue;
		if(s[i]->size() > s[x]->size()) {pt=i;}
	}
	if(pt!=x) s[x] = s[pt];
	for(auto ii : v[x])
	{
		ll i=ii.s.f;
		if(i==p||i==pt) continue;
		for(auto j : *s[i]) s[x]->ins(j);
	}
	if(x==1) return;
	for(auto i : add[x]) s[x]->ins(i);
	for(auto i : re[x]) s[x]->erase(s[x]->find(i));
	// cout << x << ' ' << add[x].size() << '\n';
	if(s[x]->empty() == 0)ans[eno[x]] = *s[x]->begin();
	else assert(ans[eno[x]] == -1);
	return;
}
void init()
{
	FOR(ii,0,m)
	{
		ll i=edges[ii].i,a=edges[ii].x,b=edges[ii].y,w=edges[ii].w;
		if(in[i]) continue;
		ll la = lca.lca(a,b);
		add[a].pb(w);
		add[b].pb(w);
		re[la].pb(w);
		re[la].pb(w);
	}
}
int main()
{
	// freopen("in.bew", "r", stdin);
	FAST
	cin >> n >> m;
	FOR(i,0,m)
	{
		ll a, b, c;
		cin >> a >> b >> c;
		edges.pb({a,b,c,i});
	}
	sort(all(edges));
	ufds.init();
	for(auto i : edges)
	{
		ll a = i.x, b = i.y;
		if(ufds.same(a,b)) continue;
		in[i.i] = 1;
		ufds.merge(a,b);
		v[a].pb(spi(i.i,pi(b,i.w)));
		v[b].pb(spi(i.i,pi(a,i.w)));
	}
	mmst(ans,-1);
	lca.main(); init();
	eno[1]=m+1;dfs(1,1);
	FOR(i,0,m)
	{
		if(in[edges[i].i]) continue;
		else
		{
			// cout << lca.solve(edges[i].x, edges[i].y) << "\n";
			ans[edges[i].i] = lca.solve(edges[i].x, edges[i].y);
		}
	}
	FOR(i,0,m){ cout << (ans[i]!=-1 ? ans[i]-1 : -1) << " ";}
	cout<<"\n";
}


#include "bits/stdc++.h"
using namespace std;
#define FAST ios_base::sync_with_stdio(false); cin.tie(0);
#define LLINF (long long) 1e18//1234567890987654321
#define INF 1234567890
#define pb push_back
#define ins insert
#define f first
#define s second
#define db 0
#define EPS (1e-7)    //0.0000001 the value
#define PI (acos(-1))
#define MAXN 300006
#define MAXK 26
#define MAXX 15000006
#define ll long long int
#define ld long double
#define rep0(kk, l1, l2)for(ll kk = l1; kk < l2; kk++)
#define rep1(kk, l1, l2)for(ll kk = l1; kk <= l2; kk++)
#define foritr(itr, A) for(set<ll>::iterator itr = A.begin(); itr != A.end(); itr++)
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());    //can be used by calling rng() or shuffle(A, A+n, rng)
#define FOR(ii, ss, ee) for(ll ii = ss; ii < ee; ii++)
#define cr(x) cerr << #x << " = " << x << "\n";
#define crA(x, A) cerr << #x << " = " << A[x] << "\n";
#define spacing if(db)cout << " ";
#define space " "
#define cbr cout << "hi\n"
#define mmst(x, v) memset((x), v, sizeof ((x)));
#define bg(ms) (*ms.begin())
#define ed(ms) (*prev(ms.end(), 1))
#define addedge(a, b, c, v) v[(a)].pb(pi((b), (c))); v[(b)].pb(pi((a), (c)))
#define ph push
#define btinpct(x) __builtin_popcountll(x)
#define p2(x) (1LL<<(x))
#define all(x) (x).begin(), (x).end()
#define lbd(x, y) lower_bound(all(x), y)
#define ubd(x, y) upper_bound(all(x), y)
typedef pair <ll, ll> pi;
typedef pair <ll, pi> spi;
typedef pair <pi, pi> dpi;
inline ll rand(ll x, ll y) { ++y; return (rng() % (y-x)) + x; } //inclusivesss
ll n, m;
vector <spi> v[MAXN];
struct ufds
{
	ll p[MAXN];
	void init() { for(ll i = 1; i <= n; i++) p[i] = i; }
	ll find(ll x) { return (p[x] == x) ? x : p[x]=find(p[x]);}
	bool same(ll x, ll y) { return find(x) == find(y); }
	void merge(ll x, ll y) { p[find(x)] = find(y); }
} ufds;
struct edge{
	ll x,y,w,i;
	bool operator < (const edge &e) const
	{
		return w < e.w;
	}
};
vector <edge> edges;
bool in[MAXN];
ll ans[MAXN],eno[MAXN];
vector <ll> add[MAXN];
vector <ll> re[MAXN];
ll st[MAXN], en[MAXN], co, p[MAXN][21], depth[MAXN], d[MAXN][21];
struct lca_
{
	void main()
	{
		co=0;
		dfs(1,1);
		t2k();
	}
	void dfs(ll x, ll par)
	{
		st[x] = co ++;
		p[x][0] = par;
		for(auto ii : v[x])
		{
			ll i = ii.s.f;
			if(i==par) continue;
			depth[i]=depth[x]+1;
			d[i][0] = ii.s.s;
			eno[i]=ii.f;
			dfs(i,x);
		}
		en[x] = co;
	}
	void t2k() { for(ll j = 1; j < 21; j++) for(ll i = 1; i <= n; i++) { d[i][j]=max(d[p[i][j-1]][j-1], d[i][j-1]);p[i][j] = p[p[i][j-1]][j-1]; }}
	ll lca(ll x, ll y)
	{
		if(isp(x,y)) return x;
		if(isp(y,x)) return y;
		for(ll i = 20; i >= 0; i--)
		{
			if(!isp(p[x][i], y)) x = p[x][i];
		}
		return p[x][0];
	}
	bool isp(ll x, ll y) { return st[x] <= st[y] && en[x] >= en[y]; }
	ll solve(ll x, ll y)
	{
		// cout << x << ' ' << y << '\n';
		ll ans = 0; if(x==y) return ans;
		if(depth[x] < depth[y]) swap(x,y);
		for(ll i = 20; i >= 0; i--)
		{
			if(depth[p[x][i]] > depth[y]) { ans = max(ans, d[x][i]); x = p[x][i]; }
		}
		assert(x!=y);
		if(p[x][0]==y) return ans;
		if(depth[x]!=depth[y]){ans=max(ans,d[x][0]);x=p[x][0];}
		assert(depth[x]==depth[y]);
		assert(depth[x]==depth[y]);
		for(ll i = 20; i >= 0; i--)
		{
			if(p[x][i] != p[y][i]) { ans = max({ans, d[x][i], d[y][i]}); x = p[x][i]; y = p[y][i]; }
		}
		// ans = max(ans, d[x][0]);
		return ans;
	}
} lca;
multiset <ll> *s[MAXN];
void dfs(ll x, ll p)
{
	// cout<<"Node: " << x<<"\n";
	for(auto ii : v[x])
	{
		ll i = ii.s.f;
		if(i==p)continue;
		dfs(i,x);
	}
	s[x] = new multiset<ll>;
	ll pt = x;
	for(auto ii : v[x])
	{
		ll i=ii.s.f;
		if(i==p) continue;
		if(s[i]->size() > s[x]->size()) {pt=i;}
	}
	if(pt!=x) s[x] = s[pt];
	for(auto ii : v[x])
	{
		ll i=ii.s.f;
		if(i==p||i==pt) continue;
		for(auto j : *s[i]) s[x]->ins(j);
	}
	for(auto i : add[x]) s[x]->ins(i);
	for(auto i : re[x]) s[x]->erase(s[x]->find(i));
	// cout << x << ' ' << add[x].size() << '\n';
	if(s[x]->empty() == 0)ans[eno[x]] = *s[x]->begin();
	return;
}
void init()
{
	FOR(ii,0,m)
	{
		ll i=edges[ii].i,a=edges[ii].x,b=edges[ii].y,w=edges[ii].w;
		if(in[i]) continue;
		ll la = lca.lca(a,b);
		add[a].pb(w);
		add[b].pb(w);
		re[la].pb(w);
	}
}
int main()
{
	FAST
	cin >> n >> m;
	FOR(i,0,m)
	{
		ll a, b, c;
		cin >> a >> b >> c;
		edges.pb({a,b,c,i});
	}
	sort(all(edges));
	ufds.init();
	for(auto i : edges)
	{
		ll a = i.x, b = i.y;
		if(ufds.same(a,b)) continue;
		in[i.i] = 1;
		ufds.merge(a,b);
		v[a].pb(spi(i.i,pi(b,i.w)));
		v[b].pb(spi(i.i,pi(a,i.w)));
	}
	mmst(ans,-1);
	lca.main(); init();
	eno[1]=m+1;dfs(1,1);
	FOR(i,0,m)
	{
		if(in[i]) continue;
		else
		{
			// cout << lca.solve(edges[i].x, edges[i].y) << "\n";
			ans[i] = lca.solve(edges[i].x, edges[i].y);
		}
	}
	FOR(i,0,m) cout << (ans[i]!=-1 ? ans[i]-1 : -1) << " ";
	cout<<"\n";
}


#include "bits/stdc++.h"
using namespace std;
#define FAST ios_base::sync_with_stdio(false); cin.tie(0);
#define LLINF (long long) 1e18//1234567890987654321
#define INF 1234567890
#define pb push_back
#define ins insert
#define f first
#define s second
#define db 0
#define EPS (1e-7)    //0.0000001 the value
#define PI (acos(-1))
#define MAXN 300006-100000
#define MAXK 26
#define MAXX 15000006
#define ll /*long long*/ int
#define ld long double
#define rep0(kk, l1, l2)for(ll kk = l1; kk < l2; kk++)
#define rep1(kk, l1, l2)for(ll kk = l1; kk <= l2; kk++)
#define foritr(itr, A) for(set<ll>::iterator itr = A.begin(); itr != A.end(); itr++)
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());    //can be used by calling rng() or shuffle(A, A+n, rng)
#define FOR(ii, ss, ee) for(ll ii = ss; ii < ee; ii++)
#define cr(x) cerr << #x << " = " << x << "\n";
#define crA(x, A) cerr << #x << " = " << A[x] << "\n";
#define spacing if(db)cout << " ";
#define space " "
#define cbr cout << "hi\n"
#define mmst(x, v) memset((x), v, sizeof ((x)));
#define bg(ms) (*ms.begin())
#define ed(ms) (*prev(ms.end(), 1))
#define addedge(a, b, c, v) v[(a)].pb(pi((b), (c))); v[(b)].pb(pi((a), (c)))
#define ph push
#define btinpct(x) __builtin_popcountll(x)
#define p2(x) (1LL<<(x))
#define all(x) (x).begin(), (x).end()
#define lbd(x, y) lower_bound(all(x), y)
#define ubd(x, y) upper_bound(all(x), y)
typedef pair <ll, ll> pi;
typedef pair <ll, pi> spi;
typedef pair <pi, pi> dpi;
inline ll rand(ll x, ll y) { ++y; return (rng() % (y-x)) + x; } //inclusivesss
ll n, m;
vector <spi> v[MAXN];
struct ufds
{
	ll p[MAXN];
	void init() { for(ll i = 1; i <= n; i++) p[i] = i; }
	ll find(ll x) { return (p[x] == x) ? x : p[x]=find(p[x]);}
	bool same(ll x, ll y) { return find(x) == find(y); }
	void merge(ll x, ll y) { p[find(x)] = find(y); }
} ufds;
struct edge{
	ll x,y,w,i;
	bool operator < (const edge &e) const
	{
		return w < e.w;
	}
};
vector <edge> edges;
bool in[MAXN];
ll ans[MAXN],eno[MAXN];
vector <ll> add[MAXN];
vector <ll> re[MAXN];
ll st[MAXN], en[MAXN], co, p[MAXN][21], depth[MAXN], d[MAXN][21];
struct lca_
{
	void main()
	{
		co=0;
		dfs(1,1);
		t2k();
	}
	void dfs(ll x, ll par)
	{
		st[x] = co ++;
		p[x][0] = par;
		for(auto ii : v[x])
		{
			ll i = ii.s.f;
			if(i==par) continue;
			depth[i]=depth[x]+1;
			d[i][0] = ii.s.s;
			eno[i]=ii.f;
			dfs(i,x);
		}
		en[x] = co;
	}
	void t2k() { for(ll j = 1; j < 21; j++) for(ll i = 1; i <= n; i++) { d[i][j]=max(d[p[i][j-1]][j-1], d[i][j-1]);p[i][j] = p[p[i][j-1]][j-1]; }}
	ll lca(ll x, ll y)
	{
		if(isp(x,y)) return x;
		if(isp(y,x)) return y;
		for(ll i = 20; i >= 0; i--)
		{
			if(!isp(p[x][i], y)) x = p[x][i];
		}
		return p[x][0];
	}
	bool isp(ll x, ll y) { return st[x] <= st[y] && en[x] >= en[y]; }
	ll solve(ll x, ll y)
	{
		// cout << x << ' ' << y << '\n';
		ll ans = 0; if(x==y) return ans;
		if(depth[x] < depth[y]) swap(x,y);
		for(ll i = 20; i >= 0; i--)
		{
			if(depth[p[x][i]] > depth[y]) { ans = max(ans, d[x][i]); x = p[x][i]; }
		}
		assert(x!=y);
		if(p[x][0]==y) {ans=max(ans,d[x][0]);return ans;}
		if(depth[x]!=depth[y]){ans=max(ans,d[x][0]);x=p[x][0];}
		assert(depth[x]==depth[y]);
		assert(depth[x]==depth[y]);
		for(ll i = 20; i >= 0; i--)
		{
			if(p[x][i] != p[y][i]) { ans = max({ans, d[x][i], d[y][i]}); x = p[x][i]; y = p[y][i]; }
		}
		ans = max({ans, d[x][0],d[y][0]});
		return ans;
	}
} lca;
multiset <ll> *s[MAXN];
void dfs(ll x, ll p)
{
	// cout<<"Node: " << x<<"\n";
	for(auto ii : v[x])
	{
		ll i = ii.s.f;
		if(i==p)continue;
		dfs(i,x);
	}
	s[x] = new multiset<ll>;
	ll pt = x;
	for(auto ii : v[x])
	{
		ll i=ii.s.f;
		if(i==p) continue;
		if(s[i]->size() > s[x]->size()) {pt=i;}
	}
	if(pt!=x) s[x] = s[pt];
	for(auto ii : v[x])
	{
		ll i=ii.s.f;
		if(i==p||i==pt) continue;
		for(auto j : *s[i]) s[x]->ins(j);
	}
	if(x==1) return;
	for(auto i : add[x]) s[x]->ins(i);
	for(auto i : re[x]) s[x]->erase(s[x]->find(i));
	// cout << x << ' ' << add[x].size() << '\n';
	if(s[x]->empty() == 0)ans[eno[x]] = *s[x]->begin();
	else assert(ans[eno[x]] == -1);
	return;
}
void init()
{
	FOR(ii,0,m)
	{
		ll i=edges[ii].i,a=edges[ii].x,b=edges[ii].y,w=edges[ii].w;
		if(in[i]) continue;
		ll la = lca.lca(a,b);
		add[a].pb(w);
		add[b].pb(w);
		re[la].pb(w);
		re[la].pb(w);
	}
}
int main()
{
	// freopen("in.bew", "r", stdin);
	FAST
	cin >> n >> m;
	FOR(i,0,m)
	{
		ll a, b, c;
		cin >> a >> b >> c;
		edges.pb({a,b,c,i});
	}
	sort(all(edges));
	ufds.init();
	for(auto i : edges)
	{
		ll a = i.x, b = i.y;
		if(ufds.same(a,b)) continue;
		in[i.i] = 1;
		ufds.merge(a,b);
		v[a].pb(spi(i.i,pi(b,i.w)));
		v[b].pb(spi(i.i,pi(a,i.w)));
	}
	mmst(ans,-1);
	lca.main(); init();
	eno[1]=m+1;dfs(1,1);
	FOR(i,0,m)
	{
		if(in[edges[i].i]) continue;
		else
		{
			// cout << lca.solve(edges[i].x, edges[i].y) << "\n";
			ans[edges[i].i] = lca.solve(edges[i].x, edges[i].y);
		}
	}
	FOR(i,0,m){ cout << (ans[i]!=-1 ? ans[i]-1 : -1) << " ";}
	cout<<"\n";
}


#include "bits/stdc++.h"
using namespace std;
#define FAST ios_base::sync_with_stdio(false); cin.tie(0);
#define LLINF (long long) 1e18//1234567890987654321
#define INF 1234567890
#define pb push_back
#define ins insert
#define f first
#define s second
#define db 0
#define EPS (1e-7)    //0.0000001 the value
#define PI (acos(-1))
#define MAXN 300006-100000
#define MAXK 26
#define MAXX 15000006
#define ll long long int
#define ld long double
#define rep0(kk, l1, l2)for(ll kk = l1; kk < l2; kk++)
#define rep1(kk, l1, l2)for(ll kk = l1; kk <= l2; kk++)
#define foritr(itr, A) for(set<ll>::iterator itr = A.begin(); itr != A.end(); itr++)
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());    //can be used by calling rng() or shuffle(A, A+n, rng)
#define FOR(ii, ss, ee) for(ll ii = ss; ii < ee; ii++)
#define cr(x) cerr << #x << " = " << x << "\n";
#define crA(x, A) cerr << #x << " = " << A[x] << "\n";
#define spacing if(db)cout << " ";
#define space " "
#define cbr cout << "hi\n"
#define mmst(x, v) memset((x), v, sizeof ((x)));
#define bg(ms) (*ms.begin())
#define ed(ms) (*prev(ms.end(), 1))
#define addedge(a, b, c, v) v[(a)].pb(pi((b), (c))); v[(b)].pb(pi((a), (c)))
#define ph push
#define btinpct(x) __builtin_popcountll(x)
#define p2(x) (1LL<<(x))
#define all(x) (x).begin(), (x).end()
#define lbd(x, y) lower_bound(all(x), y)
#define ubd(x, y) upper_bound(all(x), y)
typedef pair <ll, ll> pi;
typedef pair <ll, pi> spi;
typedef pair <pi, pi> dpi;
inline ll rand(ll x, ll y) { ++y; return (rng() % (y-x)) + x; } //inclusivesss
ll n, m;
vector <spi> v[MAXN];
struct ufds
{
	ll p[MAXN];
	void init() { for(ll i = 1; i <= n; i++) p[i] = i; }
	ll find(ll x) { return (p[x] == x) ? x : p[x]=find(p[x]);}
	bool same(ll x, ll y) { return find(x) == find(y); }
	void merge(ll x, ll y) { p[find(x)] = find(y); }
} ufds;
struct edge{
	ll x,y,w,i;
	bool operator < (const edge &e) const
	{
		return w < e.w;
	}
};
vector <edge> edges;
bool in[MAXN];
ll ans[MAXN],eno[MAXN];
vector <ll> add[MAXN];
vector <ll> re[MAXN];
ll st[MAXN], en[MAXN], co, p[MAXN][21], depth[MAXN], d[MAXN][21];
struct lca_
{
	void main()
	{
		co=0;
		dfs(1,1);
		t2k();
	}
	void dfs(ll x, ll par)
	{
		st[x] = co ++;
		p[x][0] = par;
		for(auto ii : v[x])
		{
			ll i = ii.s.f;
			if(i==par) continue;
			depth[i]=depth[x]+1;
			d[i][0] = ii.s.s;
			eno[i]=ii.f;
			dfs(i,x);
		}
		en[x] = co;
	}
	void t2k() { for(ll j = 1; j < 21; j++) for(ll i = 1; i <= n; i++) { d[i][j]=max(d[p[i][j-1]][j-1], d[i][j-1]);p[i][j] = p[p[i][j-1]][j-1]; }}
	ll lca(ll x, ll y)
	{
		if(isp(x,y)) return x;
		if(isp(y,x)) return y;
		for(ll i = 20; i >= 0; i--)
		{
			if(!isp(p[x][i], y)) x = p[x][i];
		}
		return p[x][0];
	}
	bool isp(ll x, ll y) { return st[x] <= st[y] && en[x] >= en[y]; }
	ll solve(ll x, ll y)
	{
		// cout << x << ' ' << y << '\n';
		ll ans = 0; if(x==y) return ans;
		if(depth[x] < depth[y]) swap(x,y);
		for(ll i = 20; i >= 0; i--)
		{
			if(depth[p[x][i]] > depth[y]) { ans = max(ans, d[x][i]); x = p[x][i]; }
		}
		assert(x!=y);
		if(p[x][0]==y) {ans=max(ans,d[x][0]);return ans;}
		if(depth[x]!=depth[y]){ans=max(ans,d[x][0]);x=p[x][0];}
		assert(depth[x]==depth[y]);
		assert(depth[x]==depth[y]);
		for(ll i = 20; i >= 0; i--)
		{
			if(p[x][i] != p[y][i]) { ans = max({ans, d[x][i], d[y][i]}); x = p[x][i]; y = p[y][i]; }
		}
		ans = max({ans, d[x][0],d[y][0]});
		return ans;
	}
} lca;
multiset <ll> *s[MAXN];
void dfs(ll x, ll p)
{
	// cout<<"Node: " << x<<"\n";
	for(auto ii : v[x])
	{
		ll i = ii.s.f;
		if(i==p)continue;
		dfs(i,x);
	}
	s[x] = new multiset<ll>;
	ll pt = x;
	for(auto ii : v[x])
	{
		ll i=ii.s.f;
		if(i==p) continue;
		if(s[i]->size() > s[x]->size()) {pt=i;}
	}
	if(pt!=x) s[x] = s[pt];
	for(auto ii : v[x])
	{
		ll i=ii.s.f;
		if(i==p||i==pt) continue;
		for(auto j : *s[i]) s[x]->ins(j);
	}
	if(x==1) return;
	for(auto i : add[x]) s[x]->ins(i);
	for(auto i : re[x]) s[x]->erase(s[x]->find(i));
	// cout << x << ' ' << add[x].size() << '\n';
	if(s[x]->empty() == 0)ans[eno[x]] = *s[x]->begin();
	else assert(ans[eno[x]] == -1);
	return;
}
void init()
{
	FOR(ii,0,m)
	{
		ll i=edges[ii].i,a=edges[ii].x,b=edges[ii].y,w=edges[ii].w;
		if(in[i]) continue;
		ll la = lca.lca(a,b);
		add[a].pb(w);
		add[b].pb(w);
		re[la].pb(w);
		re[la].pb(w);
	}
}
int main()
{
	// freopen("in.bew", "r", stdin);
	FAST
	cin >> n >> m;
	FOR(i,0,m)
	{
		ll a, b, c;
		cin >> a >> b >> c;
		edges.pb({a,b,c,i});
	}
	sort(all(edges));
	ufds.init();
	for(auto i : edges)
	{
		ll a = i.x, b = i.y;
		if(ufds.same(a,b)) continue;
		in[i.i] = 1;
		ufds.merge(a,b);
		v[a].pb(spi(i.i,pi(b,i.w)));
		v[b].pb(spi(i.i,pi(a,i.w)));
	}
	mmst(ans,-1);
	lca.main(); init();
	eno[1]=m+1;dfs(1,1);
	FOR(i,0,m)
	{
		if(in[edges[i].i]) continue;
		else
		{
			// cout << lca.solve(edges[i].x, edges[i].y) << "\n";
			ans[edges[i].i] = lca.solve(edges[i].x, edges[i].y);
		}
	}
	FOR(i,0,m){ cout << (ans[i]!=-1 ? ans[i]-1 : -1) << " ";}
	cout<<"\n";
}


#include "bits/stdc++.h"
using namespace std;
#define FAST ios_base::sync_with_stdio(false); cin.tie(0);
#define LLINF (long long) 1e18//1234567890987654321
#define INF 1234567890
#define pb push_back
#define ins insert
#define f first
#define s second
#define db 0
#define EPS (1e-7)    //0.0000001 the value
#define PI (acos(-1))
#define MAXN 300006
#define MAXK 26
#define MAXX 15000006
#define ll long long int
#define ld long double
#define rep0(kk, l1, l2)for(ll kk = l1; kk < l2; kk++)
#define rep1(kk, l1, l2)for(ll kk = l1; kk <= l2; kk++)
#define foritr(itr, A) for(set<ll>::iterator itr = A.begin(); itr != A.end(); itr++)
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());    //can be used by calling rng() or shuffle(A, A+n, rng)
#define FOR(ii, ss, ee) for(ll ii = ss; ii < ee; ii++)
#define cr(x) cerr << #x << " = " << x << "\n";
#define crA(x, A) cerr << #x << " = " << A[x] << "\n";
#define spacing if(db)cout << " ";
#define space " "
#define cbr cout << "hi\n"
#define mmst(x, v) memset((x), v, sizeof ((x)));
#define bg(ms) (*ms.begin())
#define ed(ms) (*prev(ms.end(), 1))
#define addedge(a, b, c, v) v[(a)].pb(pi((b), (c))); v[(b)].pb(pi((a), (c)))
#define ph push
#define btinpct(x) __builtin_popcountll(x)
#define p2(x) (1LL<<(x))
#define all(x) (x).begin(), (x).end()
#define lbd(x, y) lower_bound(all(x), y)
#define ubd(x, y) upper_bound(all(x), y)
typedef pair <ll, ll> pi;
typedef pair <ll, pi> spi;
typedef pair <pi, pi> dpi;
inline ll rand(ll x, ll y) { ++y; return (rng() % (y-x)) + x; } //inclusivesss
ll n, m;
vector <spi> v[MAXN];
struct ufds
{
	ll p[MAXN];
	void init() { for(ll i = 1; i <= n; i++) p[i] = i; }
	ll find(ll x) { return (p[x] == x) ? x : p[x]=find(p[x]);}
	bool same(ll x, ll y) { return find(x) == find(y); }
	void merge(ll x, ll y) { p[find(x)] = find(y); }
} ufds;
struct edge{
	ll x,y,w,i;
	bool operator < (const edge &e) const
	{
		return w < e.w;
	}
};
vector <edge> edges;
bool in[MAXN];
ll ans[MAXN],eno[MAXN];
vector <ll> add[MAXN];
vector <ll> re[MAXN];
ll st[MAXN], en[MAXN], co, p[MAXN][21], depth[MAXN], d[MAXN][21];
struct lca_
{
	void main()
	{
		co=0;
		dfs(1,1);
		t2k();
	}
	void dfs(ll x, ll par)
	{
		st[x] = co ++;
		p[x][0] = par;
		for(auto ii : v[x])
		{
			ll i = ii.s.f;
			if(i==par) continue;
			depth[i]=depth[x]+1;
			d[i][0] = ii.s.s;
			eno[i]=ii.f;
			dfs(i,x);
		}
		en[x] = co;
	}
	void t2k() { for(ll j = 1; j < 21; j++) for(ll i = 1; i <= n; i++) { d[i][j]=max(d[p[i][j-1]][j-1], d[i][j-1]);p[i][j] = p[p[i][j-1]][j-1]; }}
	ll lca(ll x, ll y)
	{
		if(isp(x,y)) return x;
		if(isp(y,x)) return y;
		for(ll i = 20; i >= 0; i--)
		{
			if(!isp(p[x][i], y)) x = p[x][i];
		}
		return p[x][0];
	}
	bool isp(ll x, ll y) { return st[x] <= st[y] && en[x] >= en[y]; }
	ll solve(ll x, ll y)
	{
		// cout << x << ' ' << y << '\n';
		ll ans = 0; if(x==y) return ans;
		if(depth[x] < depth[y]) swap(x,y);
		for(ll i = 20; i >= 0; i--)
		{
			if(depth[p[x][i]] > depth[y]) { ans = max(ans, d[x][i]); x = p[x][i]; }
		}
		assert(x!=y);
		if(p[x][0]==y) {ans=max(ans,d[x][0]);return ans;}
		if(depth[x]!=depth[y]){ans=max(ans,d[x][0]);x=p[x][0];}
		assert(depth[x]==depth[y]);
		assert(depth[x]==depth[y]);
		for(ll i = 20; i >= 0; i--)
		{
			if(p[x][i] != p[y][i]) { ans = max({ans, d[x][i], d[y][i]}); x = p[x][i]; y = p[y][i]; }
		}
		ans = max({ans, d[x][0],d[y][0]});
		return ans;
	}
} lca;
multiset <ll> *s[MAXN];
void dfs(ll x, ll p)
{
	// cout<<"Node: " << x<<"\n";
	for(auto ii : v[x])
	{
		ll i = ii.s.f;
		if(i==p)continue;
		dfs(i,x);
	}
	s[x] = new multiset<ll>;
	ll pt = x;
	for(auto ii : v[x])
	{
		ll i=ii.s.f;
		if(i==p) continue;
		if(s[i]->size() > s[x]->size()) {pt=i;}
	}
	if(pt!=x) s[x] = s[pt];
	for(auto ii : v[x])
	{
		ll i=ii.s.f;
		if(i==p||i==pt) continue;
		for(auto j : *s[i]) s[x]->ins(j);
	}
	if(x==1) return;
	for(auto i : add[x]) s[x]->ins(i);
	for(auto i : re[x]) s[x]->erase(s[x]->find(i));
	// cout << x << ' ' << add[x].size() << '\n';
	if(s[x]->empty() == 0)ans[eno[x]] = *s[x]->begin();
	return;
}
void init()
{
	FOR(ii,0,m)
	{
		ll i=edges[ii].i,a=edges[ii].x,b=edges[ii].y,w=edges[ii].w;
		if(in[i]) continue;
		ll la = lca.lca(a,b);
		add[a].pb(w);
		add[b].pb(w);
		re[la].pb(w);
	}
}
int main()
{
	// freopen("in.bew", "r", stdin);
	FAST
	cin >> n >> m;
	FOR(i,0,m)
	{
		ll a, b, c;
		cin >> a >> b >> c;
		edges.pb({a,b,c,i});
	}
	sort(all(edges));
	ufds.init();
	for(auto i : edges)
	{
		ll a = i.x, b = i.y;
		if(ufds.same(a,b)) continue;
		in[i.i] = 1;
		ufds.merge(a,b);
		v[a].pb(spi(i.i,pi(b,i.w)));
		v[b].pb(spi(i.i,pi(a,i.w)));
	}
	mmst(ans,-1);
	lca.main(); init();
	eno[1]=m+1;dfs(1,1);
	FOR(i,0,m)
	{
		if(in[edges[i].i]) continue;
		else
		{
			// cout << lca.solve(edges[i].x, edges[i].y) << "\n";
			ans[edges[i].i] = lca.solve(edges[i].x, edges[i].y);
		}
	}
	FOR(i,0,m){ cout << (ans[i]!=-1 ? ans[i]-1 : -1) << " ";}
	cout<<"\n";
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=0;i<n;i++)
#define pi pair<int,int>
#define f first
#define s second
#define fr freopen("in.txt","r",stdin)
#define ll long long
#define pb push_back
struct Edge
{
    int u, v, c, ind;
    Edge(){}
    Edge(int _u, int _v, int _c, int _ind) {
        u = _u;
        v = _v;
        c = _c;
        ind = _ind;
    }
};

bool MSTEdge[200011];
int pa[200011];
int sz[200011];
Edge edge[200011];
int n, m;
int ans[200011];
bool func(Edge a, Edge b) {
    return a.c < b.c;
}
int f(int x) {
    if(x == pa[x]) return x;
    return pa[x] = f(pa[x]);
}
bool join(int u, int v) {
    u = f(u);
    v = f(v);
    if(u != v) {
        if(sz[u] < sz[v]) swap(u, v);
        sz[u] += sz[v];
        pa[v] = u;
        return 1;
    }
    return 0;
}

vector<pi> tree[200011];
vector<pi> badGraph[200011];

void makeSpanningTree() {
    vector<Edge> E;
    rep(i, m) {
        E.push_back(edge[i]);
    }
    for(int i=1;i<=n;i++) {
        pa[i] = i;
        sz[i] = 1;
    }
    sort(E.begin(), E.end(), func);
    rep(i, m) {
        if(join(E[i].u, E[i].v)) {
            MSTEdge[E[i].ind] = 1;
            tree[E[i].u].push_back(make_pair(E[i].v, E[i].ind));
            tree[E[i].v].push_back(make_pair(E[i].u, E[i].ind));
        }
        else{
            MSTEdge[E[i].ind] = 0;
            badGraph[E[i].u].push_back(make_pair(E[i].v, E[i].ind));
            badGraph[E[i].v].push_back(make_pair(E[i].u, E[i].ind));
        }
    }
}

int dp[200011][20];
int sdp[200011][20];
int d[200011];

void init(int v,int p, int w) {
    if(p != -1) {
        d[v] = d[p]+1;
        dp[v][0] = p;
        sdp[v][0] = w;
    }
    rep(i, tree[v].size()) {
        if(tree[v][i].f != p) {
            init(tree[v][i].f, v, edge[tree[v][i].s].c);
        }
    }
}
void build() {
    for(int j=1;j<20;j++) {
        for(int i=1; i<=n ;i++) {
            dp[i][j] = dp[dp[i][j-1]][j-1];
            sdp[i][j] = max(sdp[i][j-1], sdp[dp[i][j-1]][j-1]);
        }
    }
}
int LCA(int u, int v) {
    if(d[u] < d[v]) swap(u, v);
    int diff = d[u] - d[v];
    rep(i, 20) {
        if(diff&(1<<i)) u = dp[u][i];
    }
    if(u != v) {
        for(int i=19;i>=0;i--) {
            if(dp[u][i] != dp[v][i]) {
                u = dp[u][i];
                v = dp[v][i];
            }
        }
        u = dp[u][0];
    }
    return u;
}
int maxValue(int L, int u) {
    int diff = d[u] - d[L];
    int ans = 0;
    rep(i,20) {
        if(diff&(1<<i)) {
            ans = max(ans, sdp[u][i]);
            u = dp[u][i];
        }
    }
    return ans;
}
int maxPathValue(int u, int v) {
    int L = LCA(u, v);
    return max(maxValue(L, u), maxValue(L, v));
}
void calcForNonMSTEdges() {
    rep(i, m) {
        if(!MSTEdge[i]) {
            ans[i] = maxPathValue(edge[i].u, edge[i].v)-1;
        }
    }
}

int pa_edge[200011];
bool del[200011];
int curval[200011];
int tot = 0;
std::vector<int> V;
void dfs(int v, int p) {
    sz[v] = 1;
    tot++;
    V.pb(v);
    rep(i, tree[v].size()) {
        if(!del[tree[v][i].f] and tree[v][i].f != p) {
            dfs(tree[v][i].f, v);
            sz[v] += sz[tree[v][i].f];
        }
    }
}

int centroid(int v, int p) {
    int mx = -1;
    rep(i, tree[v].size()) {
        if(tree[v][i].f != p and !del[tree[v][i].f]) {
            if(mx == -1) {
                mx = tree[v][i].f;
            }
            else{
                if(sz[mx] < sz[tree[v][i].f]) mx = tree[v][i].f;
            }
        }
    }
    if(mx ==-1 or sz[mx] <= tot/2) return v;
    return centroid(mx, v);
}
int mark[200011];
void marknodes(int v, int p, int s) {
    mark[v] = s;
    curval[v] = INT_MAX;
    rep(i, tree[v].size()) {
        if(tree[v][i].f != p and !del[tree[v][i].f]) {
            marknodes(tree[v][i].f, v, s);
        }
    }
}
void dfscalc(int v,int p, int id) {
    rep(i, tree[v].size()) {
        if(tree[v][i].f != p and !del[tree[v][i].f]) {
            dfscalc(tree[v][i].f, v, tree[v][i].s);
            curval[v] = min(curval[v], curval[tree[v][i].f]);
        }
    }
    if(id!=-1 and curval[v]!=INT_MAX) {
        ans[id] = min(ans[id], curval[v]-1);
    }
}
void calcForMSTEdges(int v, int id) {

    tot = 0;
    V.clear();
    dfs(v, -1);

    int root = centroid(v,-1);
    del[root] = 1;

    int tmp = 1;
    rep(i, tree[root].size()) {
        if(!del[tree[root][i].f]) {
            marknodes(tree[root][i].f,root,tmp++);
        }
    }
    curval[root] = INT_MAX;
    mark[root] = tmp++;

    int x, y;
    rep(i, V.size()) {
        x = V[i];
        rep(j, badGraph[x].size()) {
            y = badGraph[x][j].f;
            if(mark[x]!=0 and mark[y]!=0 and mark[x] != mark[y]) {
                curval[x] = min(curval[x], edge[badGraph[x][j].s].c);
                curval[y] = min(curval[y], edge[badGraph[x][j].s].c);
            }
        }
    }

    rep(i, V.size()) mark[V[i]] = 0;
    mark[root] = 0;

    dfscalc(root,-1,-1);

    rep(i, tree[root].size()) {
        if(!del[tree[root][i].f]) {
            calcForMSTEdges(tree[root][i].f, tree[root][i].s);
        }
    }
}
int main() {
    cin >> n >> m;
    rep(i, m) {
        cin >> edge[i].u >>  edge[i].v >> edge[i].c;
        edge[i].ind = i;
    }
    makeSpanningTree();
    init(1, -1, -1);
    build();
    rep(i, m) {
        ans[i] = INT_MAX;
    }
    calcForNonMSTEdges();
    calcForMSTEdges(1,-1);
    rep(i, m) {
        if(ans[i] == INT_MAX) ans[i] = -1;
        if(ans[i] == -1) assert(MSTEdge[i]);
        cout << ans[i] << " ";
    }
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=0;i<n;i++)
#define pi pair<int,int>
#define f first
#define s second
#define fr freopen("in.txt","r",stdin)
#define ll long long
#define pb push_back
struct Edge
{
    int u, v, c, ind;
    Edge(){}
    Edge(int _u, int _v, int _c, int _ind) {
        u = _u;
        v = _v;
        c = _c;
        ind = _ind;
    }
};

bool MSTEdge[200011];
int pa[200011];
int sz[200011];
Edge edge[200011];
int n, m;
int ans[200011];
bool func(Edge a, Edge b) {
    return a.c < b.c;
}
int f(int x) {
    if(x == pa[x]) return x;
    return pa[x] = f(pa[x]);
}
bool join(int u, int v) {
    u = f(u);
    v = f(v);
    if(u != v) {
        if(sz[u] < sz[v]) swap(u, v);
        sz[u] += sz[v];
        pa[v] = u;
        return 1;
    }
    return 0;
}

vector<pi> tree[200011];
vector<pi> badGraph[200011];

void makeSpanningTree() {
    vector<Edge> E;
    rep(i, m) {
        E.push_back(edge[i]);
    }
    for(int i=1;i<=n;i++) {
        pa[i] = i;
        sz[i] = 1;
    }
    sort(E.begin(), E.end(), func);
    rep(i, m) {
        if(join(E[i].u, E[i].v)) {
            MSTEdge[E[i].ind] = 1;
            tree[E[i].u].push_back(make_pair(E[i].v, E[i].ind));
            tree[E[i].v].push_back(make_pair(E[i].u, E[i].ind));
        }
        else{
            MSTEdge[E[i].ind] = 0;
            badGraph[E[i].u].push_back(make_pair(E[i].v, E[i].ind));
            badGraph[E[i].v].push_back(make_pair(E[i].u, E[i].ind));
        }
    }
}

int dp[200011][20];
int sdp[200011][20];
int d[200011];

void init(int v,int p, int w) {
    if(p != -1) {
        d[v] = d[p]+1;
        dp[v][0] = p;
        sdp[v][0] = w;
    }
    rep(i, tree[v].size()) {
        if(tree[v][i].f != p) {
            init(tree[v][i].f, v, edge[tree[v][i].s].c);
        }
    }
}
void build() {
    for(int j=1;j<20;j++) {
        for(int i=1; i<=n ;i++) {
            dp[i][j] = dp[dp[i][j-1]][j-1];
            sdp[i][j] = max(sdp[i][j-1], sdp[dp[i][j-1]][j-1]);
        }
    }
}
int LCA(int u, int v) {
    if(d[u] < d[v]) swap(u, v);
    int diff = d[u] - d[v];
    rep(i, 20) {
        if(diff&(1<<i)) u = dp[u][i];
    }
    if(u != v) {
        for(int i=19;i>=0;i--) {
            if(dp[u][i] != dp[v][i]) {
                u = dp[u][i];
                v = dp[v][i];
            }
        }
        u = dp[u][0];
    }
    return u;
}
int maxValue(int L, int u) {
    int diff = d[u] - d[L];
    int ans = 0;
    rep(i,20) {
        if(diff&(1<<i)) {
            ans = max(ans, sdp[u][i]);
            u = dp[u][i];
        }
    }
    return ans;
}
int maxPathValue(int u, int v) {
    int L = LCA(u, v);
    return max(maxValue(L, u), maxValue(L, v));
}
void calcForNonMSTEdges() {
    rep(i, m) {
        if(!MSTEdge[i]) {
            ans[i] = maxPathValue(edge[i].u, edge[i].v)-1;
        }
    }
}

int pa_edge[200011];
bool del[200011];
int curval[200011];
int tot = 0;
std::vector<int> V;
void dfs(int v, int p) {
    curval[v] = INT_MAX;
    sz[v] = 1;
    tot++;
    V.pb(v);
    rep(i, tree[v].size()) {
        if(!del[tree[v][i].f] and tree[v][i].f != p) {
            dfs(tree[v][i].f, v);
            pa_edge[tree[v][i].f] = tree[v][i].s;
            sz[v] += sz[tree[v][i].f];
        }
    }
}
void dfs1(int v, int p) {

    rep(i, tree[v].size()) {
        if(!del[tree[v][i].f] and tree[v][i].f != p) {
            dfs1(tree[v][i].f, v);
            curval[v] = min(curval[v], curval[tree[v][i].f]);
        }
    }
    if(curval[v]!=INT_MAX)
        ans[pa_edge[v]] = min(ans[pa_edge[v]], curval[v]-1);
}

int centroid(int v, int p) {
    int mx = -1;
    rep(i, tree[v].size()) {
        if(tree[v][i].f != p and !del[tree[v][i].f]) {
            if(mx == -1) {
                mx = tree[v][i].f;
            }
            else{
                if(sz[mx] < sz[tree[v][i].f]) mx = tree[v][i].f;
            }
        }
    }
    if(mx ==-1 or sz[mx] <= tot/2) return v;
    return centroid(mx, v);
}
bool mark[200011];
void calcForMSTEdges(int v) {

    tot = 0;
    V.clear();
    dfs(v, -1);

    rep(i, V.size()) {
        mark[V[i]] = 1;
    }
    rep(i, V.size()) {
        int x = V[i];
        rep(j, badGraph[x].size()) {
            if(!mark[badGraph[x][j].f]) {
                curval[x] = min(curval[x], edge[badGraph[x][j].s].c);
            }
        }
    }
    dfs1(v, -1);
    rep(i, V.size()) {
        mark[V[i]] = 0;
    }

    int root = centroid(v,-1);
    del[root] = 1;
    rep(i, tree[root].size()) {
        if(!del[tree[root][i].f]) {
            calcForMSTEdges(tree[root][i].f);
        }
    }
}
int main() {

    cin >> n >> m;
    rep(i, m) {
        cin >> edge[i].u >>  edge[i].v >> edge[i].c;
        edge[i].ind = i;
    }
    makeSpanningTree();
    init(1, -1, -1);
    build();
    rep(i, m) {
        ans[i] = INT_MAX;
    }
    calcForNonMSTEdges();
    calcForMSTEdges(1);
    rep(i, m) {
        if(ans[i] == INT_MAX) ans[i] = -1;
        if(ans[i] == -1) assert(MSTEdge[i]);
        cout << ans[i] << " ";
    }
}


#include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=0;i<n;i++)
#define pi pair<int,int>
#define f first
#define s second
#define fr freopen("in.txt","r",stdin)
#define ll long long
#define pb push_back
struct Edge
{
    int u, v, c, ind;
    Edge(){}
    Edge(int _u, int _v, int _c, int _ind) {
        u = _u;
        v = _v;
        c = _c;
        ind = _ind;
    }
};

bool MSTEdge[200011];
int pa[200011];
int sz[200011];
Edge edge[200011];
int n, m;
int ans[200011];
bool func(Edge a, Edge b) {
    return a.c < b.c;
}
int f(int x) {
    if(x == pa[x]) return x;
    return pa[x] = f(pa[x]);
}
bool join(int u, int v) {
    u = f(u);
    v = f(v);
    if(u != v) {
        if(sz[u] < sz[v]) swap(u, v);
        sz[u] += sz[v];
        pa[v] = u;
        return 1;
    }
    return 0;
}

vector<pi> tree[200011];
vector<pi> badGraph[200011];

void makeSpanningTree() {
    vector<Edge> E;
    rep(i, m) {
        E.push_back(edge[i]);
    }
    for(int i=1;i<=n;i++) {
        pa[i] = i;
        sz[i] = 1;
    }
    sort(E.begin(), E.end(), func);
    rep(i, m) {
        if(join(E[i].u, E[i].v)) {
            MSTEdge[E[i].ind] = 1;
            tree[E[i].u].push_back(make_pair(E[i].v, E[i].ind));
            tree[E[i].v].push_back(make_pair(E[i].u, E[i].ind));
        }
        else{
            MSTEdge[E[i].ind] = 0;
            badGraph[E[i].u].push_back(make_pair(E[i].v, E[i].ind));
            badGraph[E[i].v].push_back(make_pair(E[i].u, E[i].ind));
        }
    }
}

int dp[200011][20];
int sdp[200011][20];
int d[200011];

void init(int v,int p, int w) {
    if(p != -1) {
        d[v] = d[p]+1;
        dp[v][0] = p;
        sdp[v][0] = w;
    }
    rep(i, tree[v].size()) {
        if(tree[v][i].f != p) {
            init(tree[v][i].f, v, edge[tree[v][i].s].c);
        }
    }
}
void build() {
    for(int j=1;j<20;j++) {
        for(int i=1; i<=n ;i++) {
            dp[i][j] = dp[dp[i][j-1]][j-1];
            sdp[i][j] = max(sdp[i][j-1], sdp[dp[i][j-1]][j-1]);
        }
    }
}
int LCA(int u, int v) {
    if(d[u] < d[v]) swap(u, v);
    int diff = d[u] - d[v];
    rep(i, 20) {
        if(diff&(1<<i)) u = dp[u][i];
    }
    if(u != v) {
        for(int i=19;i>=0;i--) {
            if(dp[u][i] != dp[v][i]) {
                u = dp[u][i];
                v = dp[v][i];
            }
        }
        u = dp[u][0];
    }
    return u;
}
int maxValue(int L, int u) {
    int diff = d[u] - d[L];
    int ans = 0;
    rep(i,20) {
        if(diff&(1<<i)) {
            ans = max(ans, sdp[u][i]);
            u = dp[u][i];
        }
    }
    return ans;
}
int maxPathValue(int u, int v) {
    int L = LCA(u, v);
    return max(maxValue(L, u), maxValue(L, v));
}
void calcForNonMSTEdges() {
    rep(i, m) {
        if(!MSTEdge[i]) {
            ans[i] = maxPathValue(edge[i].u, edge[i].v)-1;
        }
    }
}

int pa_edge[200011];
bool del[200011];
int curval[200011];
int tot = 0;
std::vector<int> V;
void dfs(int v, int p) {
    curval[v] = INT_MAX;
    sz[v] = 1;
    tot++;
    V.pb(v);
    rep(i, tree[v].size()) {
        if(!del[tree[v][i].f] and tree[v][i].f != p) {
            dfs(tree[v][i].f, v);
            pa_edge[tree[v][i].f] = tree[v][i].s;
            sz[v] += sz[tree[v][i].f];
        }
    }
}
void dfs1(int v, int p) {

    rep(i, tree[v].size()) {
        if(!del[tree[v][i].f] and tree[v][i].f != p) {
            dfs1(tree[v][i].f, v);
            curval[v] = min(curval[v], curval[tree[v][i].f]);
        }
    }
    if(curval[v]!=INT_MAX)
    ans[pa_edge[v]] = min(ans[pa_edge[v]], curval[v]-1);
}

int centroid(int v, int p) {
    int mx = -1;
    rep(i, tree[v].size()) {
        if(tree[v][i].f != p and !del[tree[v][i].f]) {
            if(mx == -1) {
                mx = tree[v][i].f;
            }
            else{
                if(sz[mx] < sz[tree[v][i].f]) mx = tree[v][i].f;
            }
        }
    }
    if(mx ==-1 or sz[mx] <= tot/2) return v;
    return centroid(mx, v);
}
bool mark[200011];
void calcForMSTEdges(int v, int id) {

    tot = 0;
    V.clear();
    dfs(v, -1);

    if(id != -1) {
        rep(i, V.size()) {
            mark[V[i]] = 1;
        }
        rep(i, V.size()) {
            int x = V[i];
            rep(j, badGraph[x].size()) {
                if(!mark[badGraph[x][j].f]) {
                    curval[x] = min(curval[x], edge[badGraph[x][j].s].c);
                }
            }
        }
        dfs1(v, -1);
        rep(i, V.size()) {
            mark[V[i]] = 0;
        }
        if(curval[v]!=INT_MAX)
            ans[id] = min(ans[id],curval[v]-1);
    }
    int root = centroid(v,-1);
    del[root] = 1;
    rep(i, tree[root].size()) {
        if(!del[tree[root][i].f]) {
            calcForMSTEdges(tree[root][i].f, tree[root][i].s);
        }
    }
}
int main() {
    cin >> n >> m;
    rep(i, m) {
        cin >> edge[i].u >>  edge[i].v >> edge[i].c;
        edge[i].ind = i;
    }
    makeSpanningTree();
    init(1, -1, -1);
    build();
    rep(i, m) {
        ans[i] = INT_MAX;
    }
    calcForNonMSTEdges();
    calcForMSTEdges(1,-1);
    rep(i, m) {
        if(ans[i] == INT_MAX) ans[i] = -1;
        if(ans[i] == -1) assert(MSTEdge[i]);
        cout << ans[i] << " ";
    }
}