#include <iostream>
#include <queue>
#include <unordered_set>
#include <algorithm>
using namespace std;
priority_queue <pair<int,pair<int,int> > > pq;
unordered_set<int> us;
queue <int> q;
vector<pair<int,int >  > /*vv[100005],*/graf[100005],legit[100005];
int tata[100005],sz[100005],n,m,nivel[1000005],euclid[1000005],cnt,fr[100005],rmq[1000005][22],loga[1000005],put[1000005],nex[100005][22],str[100005][22],tata_next[100005],costuri[100005],solutie[1000005];
pair<int,pair<int,int> >to_upd[1000005];

long long cost;
pair<int,pair<int,int> > v[1000005];
void unite(int a,int b,int c){
    int cp=a;
    while(cp!=tata[cp]){
        cp=tata[cp];
    }
    int cp1=a;
    while(cp1!=cp){
        int aux=tata[cp1];
        tata[cp1]=cp;
        cp1=aux;
    }
    cp=b;
    cp1=b;
    while(cp!=tata[cp]){
        cp=tata[cp];
    }
    while(cp1!=cp){
        int aux=tata[cp1];
        tata[cp1]=cp;
        cp1=aux;
    }
    if(tata[a]==tata[b]){
        return;
    }
    else
    if(sz[tata[a]]>sz[tata[b]]){
        tata[tata[b]]=tata[a];
        sz[tata[a]]+=sz[tata[b]];
    }
    else{
        tata[tata[a]]=tata[b];
        sz[tata[b]]+=sz[tata[a]];
    }
    cost+=c;
    graf[a].push_back(make_pair(b,c));
    graf[b].push_back(make_pair(a,c));
}
void dfs(int nod,int niv){
    nivel[++cnt]=niv;
    euclid[cnt]=nod;
    if(fr[nod]==0){
        fr[nod]=cnt;
    }
    for(int i=0;i<legit[nod].size();i++){
        dfs(legit[nod][i].first,niv+1);
        nivel[++cnt]=niv;
        euclid[cnt]=nod;
    }
}
int find_lca(int a,int b){
    int st=fr[a],dr=fr[b];
    if(st>dr)
        swap(st,dr);
    int dist=dr-st+1;
    if(nivel[rmq[st][loga[dist]]]<nivel[rmq[dr-put[loga[dist]]+1][loga[dist]]]){
        return euclid[rmq[st][loga[dist]]];
    }
    return euclid[rmq[dr-put[loga[dist]]+1][loga[dist]]];
}
long long mi(long long a,long long b){
    if(a>b)
        return b;
    return a;
}
long long ma(long long a,long long b){
    if(a>b)
        return a;
    return b;
}
long long find_max(int down,int up){
    if(nivel[fr[down]]<nivel[fr[up]])
        swap(up,down);
    int dist=nivel[fr[down]]-nivel[fr[up]],maxim=0;
    while(dist!=0){
        int e=loga[dist];
        maxim=ma(str[down][e],maxim);
        down=nex[down][e];
        dist-=put[e];
    }
    return maxim;
}
bool exista(int ind){
    int a=v[ind].first,b=v[ind].second.first;
    for(int i=0;i<legit[a].size();i++)
        if(legit[a][i].first==b)
            return true;
    swap(a,b);
    for(int i=0;i<legit[a].size();i++)
        if(legit[a][i].first==b)
            return true;
    return false;
}
bool mysort(pair<int,pair<int,int> > a, pair<int,pair<int,int> > b){
    return a.first<b.first;
}
void update(int down,int up,int val){
    int cop=down;
    //cout<<"-="<<down<<" "<<up<<"\n";
    while(cop!=up){
        int aux=tata_next[cop];
        if(aux==tata[cop] and costuri[cop]==1000000000){
            costuri[cop]=val;
        }
        cop=aux;
    }
    cop=down;
    while(cop!=up){
        int aux=tata_next[cop];
        tata_next[cop]=up;
        cop=aux;
    }
}
int find_lca_inef(int up, int down){
    while(up!=down){
        if(nivel[fr[up]]>nivel[fr[down]]){
            up=tata_next[up];
        }
        else
            down=tata_next[down];
    }
    return up;
}
int main()
{

    int a,b,c,contt=0;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        costuri[i]=1000000000;
    for(int i=1;i<=m;i++)
        solutie[i]=-1;
    for(int i=1;i<=m;i++){
        cin>>v[i].first>>v[i].second.first>>v[i].second.second;
        a=v[i].first;
        b=v[i].second.first;
        c=v[i].second.second;
        pq.push(make_pair(-c,make_pair(a,b)));
        //vv[a].push_back(make_pair(b,c));
        //vv[b].push_back(make_pair(a,c));
    }
    for(int i=1;i<=n;i++)
        tata[i]=i;
    for(int i=1;i<=n;i++)
        sz[i]=1;
    while(pq.empty()==false){
        pair<int,pair<int,int> >x=pq.top();
        pq.pop();
        unite(x.second.first,x.second.second,-x.first);
    }
    q.push(1);
    us.insert(1);
    while(q.empty()==false){
        int nod=q.front();
        q.pop();
        for(int i=0;i<graf[nod].size();i++){
            if(us.count(graf[nod][i].first)==0){
                legit[nod].push_back(graf[nod][i]);
                us.insert(graf[nod][i].first);
                q.push(graf[nod][i].first);
            }
        }
        graf[nod].clear();
    }
    //for(int i=1;i<=n;i++)
      //  graf[i].clear();
    dfs(1,1);
    for(int i=1;i<=cnt;i++){
        rmq[i][0]=i;
    }
    put[0]=1;
    //loga[1]=1;
    for(int i=1;i<=25;i++){
        put[i]=put[i-1]*2;
        if(put[i]<=cnt)
        loga[put[i]]=1;
    }
    for(int i=1;i<=cnt;i++){
        loga[i]+=loga[i-1];
    }
    for(int j=1;j<=20;j++){
        for(int i=1;i<=cnt;i++){
            if(i+put[j]<=cnt)
            if(nivel[rmq[i][j-1]]<nivel[rmq[i+put[j-1]][j-1]]){
                rmq[i][j]=rmq[i][j-1];
            }
            else
                rmq[i][j]=rmq[i+put[j-1]][j-1];
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=0;j<legit[i].size();j++){
            nex[legit[i][j].first][0]=i;
            str[legit[i][j].first][0]=legit[i][j].second;
        }
    }

    nex[1][0]=1;
    for(int j=1;j<=20;j++){
        for(int i=1;i<=n;i++){
            nex[i][j]=nex[nex[i][j-1]][j-1];
            str[i][j]=ma(str[i][j-1],str[nex[i][j-1]][j-1]);
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=0;j<legit[i].size();j++){
            tata_next[legit[i][j].first]=i;
            tata[legit[i][j].first]=i;
        }
    }
    tata[1]=1;
    tata_next[1]=1;
    for(int i=1;i<=m;i++){
        int a=v[i].first,b=v[i].second.first;
        int lca=find_lca(a,b);
        /*if(nivel[fr[lca]]>nivel[fr[tata_next[a]]] or nivel[fr[lca]]>nivel[fr[tata_next[b]]]){
            if(nivel[fr[tata_next[a]]]>nivel[fr[tata_next[b]]]){
                lca=tata_next[b];
            }
            else
                lca=tata_next[a];
        }
        */
        long long maxim=ma(find_max(a,lca),find_max(b,lca));
        if(exista(i)==false){
            //cout<<maxim<<"\n";
            solutie[i]=maxim;
            to_upd[++contt]=make_pair(v[i].second.second,make_pair(a,b));
        }
    }
    sort(to_upd+1,to_upd+contt+1,mysort);
    //for(int i=1;i<=n;i++)
      //  cout<<tata[i]<<" ";
    //cout<<"\n\n";
    //cout<<contt<<"\n";
    //for(int i=1;i<=contt;i++)
      //  cout<<to_upd[i].first<<" "<<to_upd[i].second.first<<" "<<to_upd[i].second.second<<"\n";
    //cout<<"\n\n";
    //cout<<contt<<" "<<"\n";
    for(int i=1;i<=contt;i++){
        int a=to_upd[i].second.second;
        int b=to_upd[i].second.first;
        int lca=find_lca_inef(a,b);
        //cout<<"GIGEL\n";
        update(a,lca,to_upd[i].first);
        update(b,lca,to_upd[i].first);
    }
    for(int i=1;i<=m;i++){
        if(solutie[i]==-1){
            int a=v[i].first;
            int b=v[i].second.first;
            if(nivel[fr[a]]>nivel[fr[b]]){
                swap(a,b);
            }
            solutie[i]=costuri[b];
        }
    }
    for(int i=1;i<=m;i++){
        if(solutie[i]==1000000000)
            cout<<-1<<" ";
        else
            cout<<solutie[i]-1<<" ";
    }

    return 0;
}
/**
3 3
1 2 8
2 3 3
3 1 4

5 5
1 2 5
1 3 5
1 4 5
1 5 5
2 3 5
HEEEEEELU
*/


#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using db = double;
using vi = vector<int>;
using pii = pair<int,int>;
#define pb push_back
#define fir first
#define sec second

void merge(set<pii> *&a, set<pii> *&b) {
	if (a->size() < b->size()) swap(a, b);
	for (auto i : (*b)) {
		if (a->find(i) == a->end()) a->insert(i);
		else a->erase(i);
	}
	b->clear();
}

const int maxn = 200006;
const int D = 20;

int n, m;
int a[maxn], b[maxn], c[maxn];
int f[maxn];
int no[maxn];
vector<pii> e[maxn];
int ans[maxn];
int fe[maxn];
set<pii> *q[maxn];
set<pii> sq[maxn];
bool intree[maxn];
int fa[D][maxn];
int val[D][maxn];
int d[maxn];

bool cmp(int x, int y) {
	return c[x] < c[y];
}
int getf(int v) {
	if (f[v] == v) return v;
	f[v] = getf(f[v]);
	return f[v];
}
int ask(int x, int y) {
	int ret = 0;
	if (d[x] < d[y]) swap(x, y);
	for (int i = D-1; i >= 0; --i)
		if (d[x]-(1<<i) >= d[y]) {
			ret = max(ret, val[i][x]);
			x = fa[i][x];
		}
	if (x==y) return ret;
	for (int i = D-1; i >= 0; --i)
		if (fa[i][x] != fa[i][y]) {
			ret = max(ret, max(val[i][x], val[i][y]));
			x = fa[i][x];
			y = fa[i][y];
		}
	ret = max(ret, max(val[0][x], val[0][y]));
	return ret;
}
void build(int x, int f) {
	fa[0][x] = f;
	d[x] = d[f]+1;
	if (x != 1) val[0][x] = c[fe[x]];
	for (int i = 1; i < D; ++i) {
		fa[i][x] = fa[i-1][fa[i-1][x]];
		val[i][x] = min(val[i-1][x], val[i-1][fa[i-1][x]]);
	}
	for (auto i : e[x])
		if (i.fir != f) {
			fe[i.fir] = i.sec;
			build(i.fir, x);
		}
}

void dfs(int x, int f) {
	for (auto i : e[x])
		if (i.fir != f) {
			dfs(i.fir, x);
			merge(q[x], q[i.fir]);
		}
	//cout<<x<<' '<<fe[x]<<' '<<q[x]->size()<<endl;
	if (!q[x]->empty())
		ans[fe[x]] = (q[x]->begin())->fir-1;
	else ans[fe[x]] = -1;
}

int main() {
	scanf( "%d%d", &n, &m );
	for (int i = 1; i <= m; ++i) {
		scanf( "%d%d%d", &a[i], &b[i], &c[i] );
		no[i] = i;
	}
	sort(no+1, no+m+1, cmp);
	for (int i = 1; i <= n; ++i) f[i] = i;
	for (int i = 1; i <= m; ++i) {
		int x = a[no[i]], y = b[no[i]];
		int fx = getf(x), fy = getf(y);
		if (fx != fy) {
			e[x].pb( {y, no[i]} );
			e[y].pb( {x, no[i]} );
			f[fx] = fy;
			intree[no[i]] = true;
			//cout<<x<<' '<<y<<endl;
		}
		else {
			sq[x].insert({c[no[i]], no[i]});
			sq[y].insert({c[no[i]], no[i]});
		}
	}
	for (int i = 1; i <= n; ++i) q[i] = &sq[i];
	build(1, 0);
	dfs(1, 0);
	for (int i = 1; i <= m; ++i)
		if (!intree[i])
			ans[i] = ask(a[i], b[i])-1;
	for (int i = 1; i <= m; ++i) printf( "%d ", ans[i] );
	puts( "" );
}


#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using db = double;
using vi = vector<int>;
using pii = pair<int,int>;
#define pb push_back
#define fir first
#define sec second

void merge(set<pii> *&a, set<pii> *&b) {
	if (a->size() < b->size()) swap(a, b);
	for (auto i : (*b)) {
		if (a->find(i) == a->end()) a->insert(i);
		else a->erase(i);
	}
	b->clear();
}

const int maxn = 200006;
const int D = 20;

int n, m;
int a[maxn], b[maxn], c[maxn];
int f[maxn];
int no[maxn];
vector<pii> e[maxn];
int ans[maxn];
int fe[maxn];
set<pii> *q[maxn];
set<pii> sq[maxn];
bool intree[maxn];
int fa[D][maxn];
int val[D][maxn];
int d[maxn];

bool cmp(int x, int y) {
	return c[x] < c[y];
}
int getf(int v) {
	if (f[v] == v) return v;
	f[v] = getf(f[v]);
	return f[v];
}
int ask(int x, int y) {
	int ret = 0;
	if (d[x] < d[y]) swap(x, y);
	for (int i = D-1; i >= 0; --i)
		if (d[x]-(1<<i) >= d[y]) {
			ret = max(ret, val[i][x]);
			x = fa[i][x];
		}
	if (x==y) return ret;
	for (int i = D-1; i >= 0; --i)
		if (fa[i][x] != fa[i][y]) {
			ret = max(ret, max(val[i][x], val[i][y]));
			x = fa[i][x];
			y = fa[i][y];
		}
	ret = max(ret, max(val[0][x], val[0][y]));
	return ret;
}
void build(int x, int f) {
	d[x] = d[f]+1;
	fa[0][x] = f;
	if (x != 1) val[0][x] = c[fe[x]];
	for (int i = 1; i < D; ++i) {
		fa[i][x] = fa[i-1][fa[i-1][x]];
		val[i][x] = max(val[i-1][x], val[i-1][fa[i-1][x]]);
	}
	for (auto i : e[x])
		if (i.fir != f) {
			fe[i.fir] = i.sec;
			build(i.fir, x);
		}
}

void dfs(int x, int f) {
	for (auto i : e[x])
		if (i.fir != f) {
			dfs(i.fir, x);
			merge(q[x], q[i.fir]);
		}
	//cout<<x<<' '<<fe[x]<<' '<<q[x]->size()<<endl;
	if (!q[x]->empty())
		ans[fe[x]] = (q[x]->begin())->fir-1;
	else ans[fe[x]] = -1;
}

int main() {
	scanf( "%d%d", &n, &m );
	for (int i = 1; i <= m; ++i) {
		scanf( "%d%d%d", &a[i], &b[i], &c[i] );
		no[i] = i;
	}
	sort(no+1, no+m+1, cmp);
	for (int i = 1; i <= n; ++i) f[i] = i;
	for (int i = 1; i <= m; ++i) {
		int x = a[no[i]], y = b[no[i]];
		int fx = getf(x), fy = getf(y);
		if (fx != fy) {
			e[x].pb( {y, no[i]} );
			e[y].pb( {x, no[i]} );
			f[fx] = fy;
			intree[no[i]] = true;
			//cout<<x<<' '<<y<<endl;
		}
		else {
			sq[x].insert({c[no[i]], no[i]});
			sq[y].insert({c[no[i]], no[i]});
		}
	}
	for (int i = 1; i <= n; ++i) q[i] = &sq[i];
	build(1, 0);
	dfs(1, 0);
	for (int i = 1; i <= m; ++i)
		if (!intree[i])
			ans[i] = ask(a[i], b[i])-1;
	for (int i = 1; i <= m; ++i) printf( "%d ", ans[i] );
	puts( "" );
}


#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using db = double;
using vi = vector<int>;
using pii = pair<int,int>;
#define pb push_back
#define fir first
#define sec second

void merge(set<pii> *&a, set<pii> *&b) {
	if (a->size() < b->size()) swap(a, b);
	for (auto i : (*b)) {
		if (a->find(i) == a->end()) a->insert(i);
		else a->erase(i);
	}
	b->clear();
}

const int maxn = 200006;
const int D = 20;

int n, m;
int a[maxn], b[maxn], c[maxn];
int f[maxn];
int no[maxn];
vector<pii> e[maxn];
int ans[maxn];
int fe[maxn];
set<pii> *q[maxn];
set<pii> sq[maxn];
bool intree[maxn];
int fa[D][maxn];
int val[D][maxn];
int d[maxn];

bool cmp(int x, int y) {
	return c[x] < c[y];
}
int getf(int v) {
	if (f[v] == v) return v;
	f[v] = getf(f[v]);
	return f[v];
}
int ask(int x, int y) {
	int ret = 0;
	if (d[x] < d[y]) swap(x, y);
	for (int i = D-1; i >= 0; --i)
		if (d[x]-(1<<i) >= d[y]) {
			ret = max(ret, val[i][x]);
			x = fa[i][x];
		}
	if (x==y) return ret;
	for (int i = D-1; i >= 0; --i)
		if (fa[i][x] != fa[i][y]) {
			ret = max(ret, max(val[i][x], val[i][y]));
			x = fa[i][x];
			y = fa[i][y];
		}
	return ret;
}
void build(int x, int f) {
	fa[0][x] = f;
	d[x] = d[f]+1;
	if (x != 1) val[0][x] = c[fe[x]];
	for (int i = 1; i < D; ++i) {
		fa[i][x] = fa[i-1][fa[i-1][x]];
		val[i][x] = min(val[i-1][x], val[i-1][fa[i-1][x]]);
	}
	for (auto i : e[x])
		if (i.fir != f) {
			fe[i.fir] = i.sec;
			build(i.fir, x);
		}
}

void dfs(int x, int f) {
	for (auto i : e[x])
		if (i.fir != f) {
			dfs(i.fir, x);
			merge(q[x], q[i.fir]);
		}
	//cout<<x<<' '<<fe[x]<<' '<<q[x]->size()<<endl;
	if (!q[x]->empty())
		ans[fe[x]] = (q[x]->begin())->fir-1;
	else ans[fe[x]] = -1;
}

int main() {
	scanf( "%d%d", &n, &m );
	for (int i = 1; i <= m; ++i) {
		scanf( "%d%d%d", &a[i], &b[i], &c[i] );
		no[i] = i;
	}
	sort(no+1, no+m+1, cmp);
	for (int i = 1; i <= n; ++i) f[i] = i;
	for (int i = 1; i <= m; ++i) {
		int x = a[no[i]], y = b[no[i]];
		int fx = getf(x), fy = getf(y);
		if (fx != fy) {
			e[x].pb( {y, no[i]} );
			e[y].pb( {x, no[i]} );
			f[fx] = fy;
			intree[no[i]] = true;
			//cout<<x<<' '<<y<<endl;
		}
		else {
			sq[x].insert({c[no[i]], no[i]});
			sq[y].insert({c[no[i]], no[i]});
		}
	}
	for (int i = 1; i <= n; ++i) q[i] = &sq[i];
	build(1, 0);
	dfs(1, 0);
	for (int i = 1; i <= m; ++i)
		if (!intree[i])
			ans[i] = ask(a[i], b[i])-1;
	for (int i = 1; i <= m; ++i) printf( "%d ", ans[i] );
	puts( "" );
}


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

typedef pair<int, int> ii;
struct dataEdge {
	int u, v, w, id;
	dataEdge() {}; dataEdge(int u, int v, int w, int id) : u(u), v(v), w(w), id(id) {};
	bool operator < (const dataEdge &a) const { return w < a.w; }
	// int get(int x) { return (x^u^v); }
};

const int N = 2e5 + 4, LOG = 20, oo = 1e9 + 7;
int n, m, ans[N];
vector<dataEdge> Edge;
vector<int> adj[N];

int dsu[N];
bool inTree[N];

int getRoot(int u) { return (dsu[u] < 0) ? u : (dsu[u] = getRoot(dsu[u])); }
bool Merge(int u, int v) {
	u = getRoot(u); v = getRoot(v);
	if (u == v) return false;
	if (dsu[u] > dsu[v]) swap(dsu[u], dsu[v]);
	dsu[u] += dsu[v]; dsu[v] = u;
	return true;
}

void Build_MST() {
	sort(Edge.begin(), Edge.end());
	for (int i = 1; i <= n; ++i) dsu[i] = -1;

	for (int i = 0; i < m; ++i) {
		int u = Edge[i].u, v = Edge[i].v, w = Edge[i].w, id = Edge[i].id;
		if (Merge(u, v)) {
			adj[u].push_back(i); adj[v].push_back(i);
			inTree[i] = true;
		}
	}
}

int hei[N], numChild[N], par[N][LOG+4], maxVal[N][LOG+4];

void DFS(int dad, int u) {
	hei[u] = hei[dad] + 1;
	numChild[u] = 1;

	for (int id : adj[u]) {
		int v = (Edge[id].u ^ Edge[id].v ^ u), w = Edge[id].w;
		if (v == dad) continue;

			// cerr << "EDGE : " << id << " " << u << " " << v << " " << w << '\n';
			// cerr << "?? " << Edge[id].u << " " << Edge[id].v << '\n'; cerr << '\n';

		par[v][0] = u; maxVal[v][0] = w;
		DFS(u, v);
		numChild[u] += numChild[v];
	}
}

void Build_LCA() {
	for (int j = 1; j <= LOG; ++j) for (int i = 1; i <= n; ++i) {
		par[i][j] = par[par[i][j-1]][j-1];
		maxVal[i][j] = max(maxVal[i][j-1], maxVal[par[i][j-1]][j-1]);
	}
}

ii LCA(int u, int v) {
	if (hei[u] < hei[v]) swap(u, v);
	int ore_max = 0;

	for (int i = LOG; i >= 0; --i)
		if (hei[u] - (1<<i) >= hei[v]) {
			ore_max = max(ore_max, maxVal[u][i]);
			u = par[u][i];
		}
	if (u == v) return ii(u, ore_max);

	for (int i = LOG; i >= 0; --i)
		if (par[u][i] != 0 && par[v][i] != 0 && par[u][i] != par[v][i]) {
			ore_max = max({ ore_max, maxVal[u][i], maxVal[v][i] });
			u = par[u][i]; v = par[v][i];
		}
	ore_max = max({ ore_max, maxVal[u][0], maxVal[v][0] }); u = par[u][0];

	return ii(u, ore_max);
}
int Jump(int u, int step) {
	for (int i = LOG; i >= 0; --i)
		if (step - (1<<i) >= 0) step -= (1<<i), u = par[u][i];
	return (step != 0) ? -1 : u;
}

int numChain, numArr, headChain[N], belong[N], pos[N];

void HLD(int dad, int u) {
	if (!headChain[numChain]) headChain[numChain] = u;
	belong[u] = numChain; pos[u] = ++numArr;

	int big = -1;
	for (int id : adj[u]) {
		int v = Edge[id].u ^ Edge[id].v ^ u;
		if (v != dad) big = (big == -1 || numChild[v] > numChild[big]) ? v : big;
	}

	if (big != -1) HLD(u, big);
	for (int id : adj[u]) {
		int v = Edge[id].u ^ Edge[id].v ^ u;
		if (v != dad && v != big) ++numChain, HLD(u, v);
	}
}

struct Interval_Tree {
	int node[4*N], lazy[4*N];
	Interval_Tree() {
		for (int i = 0; i < 4*N; ++i) node[i] = lazy[i] = oo;
	}

	void Down(int i) {
		node[2*i] = min(node[2*i], lazy[i]);
		node[2*i+1] = min(node[2*i+1], lazy[i]);

		lazy[2*i] = min(lazy[2*i], lazy[i]);
		lazy[2*i+1] = min(lazy[2*i+1], lazy[i]);

		lazy[i] = oo;
 	}

	void update(int i, int l, int r, int x, int y, int val) {
		if (l > y || x > r) return;
		if (x <= l && r <= y) {
			node[i] = min(node[i], val);
			lazy[i] = min(lazy[i], val);
			return;
		}
		Down(i);
		int mid = (l + r) / 2;
		update(2*i, l, mid, x, y, val);
		update(2*i+1, mid+1, r, x, y, val);
		node[i] = min(node[2*i], node[2*i+1]);
	}

	int get(int i, int l, int r, int x, int y) {
		if (l > y || x > r) return oo;
		if (x <= l && r <= y) return node[i];
		Down(i);
		int mid = (l + r) / 2;
		int tmp1 = get(2*i, l, mid, x, y), tmp2 = get(2*i+1, mid+1, r, x, y);
		return min(tmp1, tmp2);
	}
} IT;

void update_HLD(int u, int dad, int val) {
	if (dad <= 0) return;
	while (true) {
		if (belong[u] == belong[dad]) {
			IT.update(1, 1, n, pos[dad], pos[u], val);
			assert(pos[dad] <= pos[u]);
			return;
		}
		int anc = headChain[belong[u]];
		IT.update(1, 1, n, pos[anc], pos[u], val);
		assert(pos[anc] <= pos[u]);
		u = par[anc][0];
 	}
}

int get_HLD(int u, int dad) {
	if (dad <= 0) return oo;

	int res = oo;
	while (true) {
		if (belong[u] == belong[dad]) {
			res = min(res, IT.get(1, 1, n, pos[dad], pos[u]));
			return res;
		}
		int anc = headChain[belong[u]];
		res = min(res, IT.get(1, 1, n, pos[anc], pos[u]));
		u = par[anc][0];
 	}
}

void get_Res() {
	for (int i = 0; i < m; ++i) {
		if (!inTree[i]) {
			int u = Edge[i].u, v = Edge[i].v, id = Edge[i].id;
			ii foo = LCA(u, v);
			ans[id] = foo.second - 1;
			continue;
		}

		int u = Edge[i].u, v = Edge[i].v, id = Edge[i].id;
		int dad = LCA(u, v).first;

		int dad_u = Jump(u, hei[u] - hei[dad] - 1);
		int dad_v = Jump(v, hei[v] - hei[dad] - 1);

		int umin = get_HLD(u, dad_u);
		int vmin = get_HLD(v, dad_v);

		if (min(umin, vmin) == oo) ans[id] = -1;
		else ans[id] = min(umin, vmin) - 1;
	}

	for (int i = 0; i < m; ++i) cout << ans[i] << " "; cout << '\n';
}

void sol() {
	Build_MST();

	DFS(0, 1);
	Build_LCA();

	++numChain; HLD(0, 1);

	for (int i = 0; i < m; ++i) {
		if (inTree[i]) continue;
		int u = Edge[i].u, v = Edge[i].v, w = Edge[i].w;
		int dad = LCA(u, v).first;

		int dad_u = Jump(u, hei[u] - hei[dad] - 1);
		int dad_v = Jump(v, hei[v] - hei[dad] - 1);

		update_HLD(u, dad_u, w);
		update_HLD(v, dad_v, w);
	}

	get_Res();
}

int main() {
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	if (fopen("input.txt", "r")) {
		freopen("input.txt", "r", stdin);
		freopen("output.txt", "w", stdout);
	}

	cin >> n >> m;
	int u, v, w;
	for (int i = 0; i < m; ++i) {
		cin >> u >> v >> w;
		Edge.push_back(dataEdge(u, v, w, i));
	}

	sol();

	return 0;
}


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

typedef pair<int, int> ii;
struct dataEdge {
	int u, v, w, id;
	dataEdge() {}; dataEdge(int u, int v, int w, int id) : u(u), v(v), w(w), id(id) {};
	bool operator < (const dataEdge &a) const { return w < a.w; }
	int get(int x) { return x^u^v; }
};

const int N = 2e5 + 4, LOG = 20;
int n, m, ans[N];
vector<dataEdge> Edge;
vector<int> adj[N];

int dsu[N];
bool inTree[N];

int getRoot(int u) { return (dsu[u] < 0) ? u : (dsu[u] = getRoot(dsu[u])); }
bool Merge(int u, int v) {
	u = getRoot(u); v = getRoot(v);
	if (u == v) return false;
	if (dsu[u] > dsu[v]) swap(dsu[u], dsu[v]);
	dsu[u] += dsu[v]; dsu[v] = u;
	return true;
}

void Build_MST() {
	sort(Edge.begin(), Edge.end());
	for (int i = 1; i <= n; ++i) dsu[i] = -1;

	for (int i = 0; i < m; ++i) {
		int u = Edge[i].u, v = Edge[i].v, w = Edge[i].w, id = Edge[i].id;
		if (Merge(u, v)) {
			adj[u].push_back(id); adj[v].push_back(id);
			inTree[i] = true;
		}
	}
}

int hei[N], numChild[N], par[N][LOG+4], maxVal[N][LOG+4];

void DFS(int dad, int u) {
	hei[u] = hei[dad] + 1;
	numChild[u] = 1;

	for (int id : adj[u]) {
		int v = Edge[id].get(u), w = Edge[id].w;
		if (v == dad) continue;

		par[v][0] = u; maxVal[v][0] = w;
		DFS(u, v);
		numChild[u] += numChild[v];
	}
}

void Build_LCA() {
	for (int j = 1; j <= LOG; ++j) for (int i = 1; i <= n; ++i) {
		par[i][j] = par[par[i][j-1]][j-1];
		maxVal[i][j] = max(maxVal[i][j-1], maxVal[par[i][j-1]][j-1]);
	}
}

ii LCA(int u, int v) {
	if (hei[u] < hei[v]) swap(u, v);
	int ore_max = 0;

	for (int i = LOG; i >= 0; --i)
		if (hei[u] - (1<<i) >= hei[v]) {
			ore_max = max(ore_max, maxVal[u][i]);
			u = par[u][i];
		}
	if (u == v) return ii(u, ore_max);

	for (int i = LOG; i >= 0; --i)
		if (par[u][i] != 0 && par[v][i] != 0 && par[u][i] != par[v][i]) {
			ore_max = max({ ore_max, maxVal[u][i], maxVal[v][i] });
			u = par[u][i]; v = par[v][i];
		}
	ore_max = max(ore_max, maxVal[u][0]); u = par[u][0];

	return ii(u, ore_max);
}
int Jump(int u, int step) {
	for (int i = LOG; i >= 0; --i)
		if (step - (1<<i) >= 0) step -= (1<<i), u = par[u][i];
	return (step != 0) ? -1 : u;
}

int numChain, numArr, headChain[N], belong[N], pos[N];

void HLD(int dad, int u) {
	if (!headChain[numChain]) headChain[numChain] = u;
	belong[u] = numChain; pos[u] = ++numArr;

	int big = -1;
	for (int id : adj[u]) {
		int v = Edge[id].get(u);
		if (v != dad) big = (big == -1 || numChild[v] > numChild[big]) ? v : big;
	}

	if (big != -1) HLD(u, big);
	for (int id : adj[u]) {
		int v = Edge[id].get(u);
		if (v != dad && v != big) ++numChain, HLD(u, v);
	}
}

struct Interval_Tree {
	int node[4*N], lazy[4*N];
	Interval_Tree() {
		memset(node, -1, sizeof(node));
		memset(lazy, -1, sizeof(lazy));
	}

	void Down(int i) {
		node[2*i] = max(node[2*i], lazy[i]);
		node[2*i+1] = max(node[2*i+1], lazy[i]);

		lazy[2*i] = max(lazy[2*i], lazy[i]);
		lazy[2*i+1] = max(lazy[2*i+1], lazy[i]);

		lazy[i] = -1;
 	}

	void update(int i, int l, int r, int x, int y, int val) {
		if (l > y || x > r) return;
		if (x <= l && r <= y) {
			node[i] = max(node[i], val);
			lazy[i] = max(lazy[i], val);
			return;
		}
		Down(i);
		int mid = (l + r) / 2;
		update(2*i, l, mid, x, y, val);
		update(2*i+1, mid+1, r, x, y, val);
		node[i] = max(node[2*i], node[2*i+1]);
	}

	int get(int i, int l, int r, int x, int y) {
		if (l > y || x > r) return -1;
		if (x <= l && r <= y) return node[i];
		Down(i);
		int mid = (l + r) / 2;
		int tmp1 = get(2*i, l, mid, x, y), tmp2 = get(2*i+1, mid+1, r, x, y);
		return max(tmp1, tmp2);
	}
} IT;

void update_HLD(int u, int dad, int val) {
	if (dad <= 0) return;
	while (true) {
		if (belong[u] == belong[dad]) {
			IT.update(1, 1, n, pos[dad], pos[u], val);
			return;
		}
		int anc = headChain[belong[u]];
		IT.update(1, 1, n, pos[anc], pos[u], val);
		u = par[anc][0];
 	}
}

int get_HLD(int u, int dad) {
	if (dad <= 0) return -1;

	int res = -1;
	while (true) {
		if (belong[u] == belong[dad]) {
			res = max(res, IT.get(1, 1, n, pos[dad], pos[u]));
			return res;
		}
		int anc = headChain[belong[u]];
		res = max(res, IT.get(1, 1, n, pos[anc], pos[u]));
		u = par[anc][0];
 	}
}

void get_Res() {
	for (int i = 0; i < m; ++i) {
		if (!inTree[i]) {
			int u = Edge[i].u, v = Edge[i].v, id = Edge[i].id;
			ii foo = LCA(u, v);
			ans[id] = foo.second - 1;
			continue;
		}

		int u = Edge[i].u, v = Edge[i].v, id = Edge[i].id;
		int dad = LCA(u, v).first;

		int dad_u = Jump(u, hei[u] - hei[dad] - 1);
		int dad_v = Jump(v, hei[v] - hei[dad] - 1);

		int umax = get_HLD(u, dad);
		int vmax = get_HLD(v, dad);

		if (max(umax, vmax) == -1) ans[id] = -1;
		else ans[id] = max(umax, vmax) - 1;
	}

	for (int i = 0; i < m; ++i) cout << ans[i] << " "; cout << '\n';
}

void sol() {
	Build_MST();

	DFS(0, 1);
	Build_LCA();

	++numChain; HLD(0, 1);

	for (int i = 0; i < m; ++i) {
		if (inTree[i]) continue;
		int u = Edge[i].u, v = Edge[i].v, w = Edge[i].w;
		int dad = LCA(u, v).first;

		int dad_u = Jump(u, hei[u] - hei[dad] - 1);
		int dad_v = Jump(v, hei[v] - hei[dad] - 1);

		update_HLD(u, dad_u, w);
		update_HLD(v, dad_v, w);
	}

	get_Res();
}

int main() {
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	if (fopen("input.txt", "r")) {
		freopen("input.txt", "r", stdin);
		freopen("output.txt", "w", stdout);
	}

	cin >> n >> m;
	int u, v, w;
	for (int i = 0; i < m; ++i) {
		cin >> u >> v >> w;
		Edge.push_back(dataEdge(u, v, w, i));
	}

	sol();

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define fo(i,a,b) for(int i=(a);i<(b);i++)
#define MOD 1000000007
#define MP make_pair
#define PB push_back
#define SZ(a) ((int)a.size())
typedef long long ll;

void umax (int& i, int j) {
	if (j>i) i = j;
}

namespace UF {
	int p[200200];
	void init () { fo(i, 0, 200200) p[i] = i; }
	int g (int i) { return p[i] == i ? i : p[i] = g(p[i]); }
	bool m (int i, int j) {
		i = g(i), j = g(j);
		if (i != j) {
			p[i] = j;
			return true;
		}
		return false;
	}
}

int N;

namespace LCA {
	int p[20][200200], mx[20][200200], depth[200200];

	pair<int, int> lca (int u, int v) {
		int ret = int(-2e9);
		if (depth[u] < depth[v]) swap(u, v);
		for (int i = 20; i--; ) if (depth[u] - (1<<i) >= depth[v]) {
			umax(ret, mx[i][u]);
			u = p[i][u];
		}
		if (u == v) return MP(u, ret);
		for (int i = 20; i--; ) if (p[i][u] != p[i][v]) {
			umax(ret, mx[i][u]);
			umax(ret, mx[i][v]);
			u = p[i][u], v = p[i][v];
		}
		umax(ret, mx[0][u]);
		umax(ret, mx[0][v]);
		return MP(p[0][u], ret);
	}

	void setup () {
		for (int i = 1; i < 20; i++) fo(j, 1, N+1) {
			p[i][j] = p[i-1][p[i-1][j]];
			mx[i][j] = max(mx[i-1][j], mx[i-1][p[i-1][j]]);
		}
	}
}

int E, upid[200200], ans[200200];
vector<int> tadj[200200], fk[200200], add[200200], rem[200200];
multiset<int> m[200200];
bool used[200200];

struct edge {
	int a, b, c, mx, i;
	bool operator < (const edge& o) const {
		return c < o.c;
	}
} e[200200];

void dfs (int i, int p) {
	LCA::p[0][i] = p;
	if (i != 1) {
		LCA::mx[0][i] = e[upid[i]].c;
	} else {
		LCA::mx[0][i] = int(-2e9);
	}

	fo(x, 0, SZ(tadj[i])) {
		int j = tadj[i][x];
		if (j != p) {
			upid[j] = fk[i][x];
			LCA::depth[j] = LCA::depth[i] + 1;
			dfs(j, i);
		}
	}
}

void procquery (int i, int p) {
	for (int j : tadj[i]) if (j != p) {
		procquery(j, i);
		if (m[j].size() > m[i].size()) swap(m[i], m[j]);
		for (int x : m[j]) m[i].insert(x);
	}
	for (int j : add[i]) m[i].insert(j);
	for (int j : rem[i]) m[i].erase(m[i].find(j));
	if (m[i].size()) {
		if (*m[i].begin() - 1 < e[upid[i]].mx) {
			e[upid[i]].mx = *m[i].begin() - 1;
		}
	}
}

int main () {
	scanf("%d %d", &N, &E);

	UF::init();
	fo(i, 0, E) {
		scanf("%d %d %d", &e[i].a, &e[i].b, &e[i].c);
		e[i].mx = (int) 2e9;
		e[i].i = i;
	}

	sort(e, e+E);
	fo(i, 0, E) {
		if (UF::m(e[i].a, e[i].b)) {
			//printf("%d %d %d\n", e[i].a, e[i].b, e[i].c);
			tadj[e[i].a].PB(e[i].b);
			fk[e[i].a].PB(i);
			tadj[e[i].b].PB(e[i].a);
			fk[e[i].b].PB(i);
			used[i] = true;
		}
	}

	dfs(1, 1);
	LCA::setup();

	fo(i, 0, E) if (!used[i]) {
		int l,t;
		tie(l,t) = LCA::lca(e[i].a, e[i].b);

		if (l != e[i].a) {
			add[e[i].a].PB(e[i].c);
			rem[l].PB(e[i].c);
			//printf("uchain %d %d\n", LCA::kth(e[i].a, ld), e[i].a);
		}
		if (l != e[i].b) {
			add[e[i].b].PB(e[i].c);
			rem[l].PB(e[i].c);
			//printf("uchain %d %d\n", LCA::kth(e[i].b, ld), e[i].b);
		}

		e[i].mx = t-1;
		//printf("%d %d flat %d\n", e[i].a, e[i].b, t);
	}

	procquery(1, 1);

	fo(i, 0, E) ans[e[i].i] = e[i].mx;
	fo(i, 0, E) {
		printf("%d\n", ans[i] == int(2e9) ? -1 : ans[i]);
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define fo(i,a,b) for(int i=(a);i<(b);i++)
#define MOD 1000000007
#define MP make_pair
#define PB push_back
#define SZ(a) ((int)a.size())
typedef long long ll;

void umax (int& i, int j) {
	if (j>i) i = j;
}

namespace UF {
	int p[200200];
	void init () { fo(i, 0, 200200) p[i] = i; }
	int g (int i) { return p[i] == i ? i : p[i] = g(p[i]); }
	bool m (int i, int j) {
		i = g(i), j = g(j);
		if (i != j) {
			p[i] = j;
			return true;
		}
		return false;
	}
}

int N;

namespace LCA {
	int p[20][200200], mx[20][200200], depth[200200];

	pair<int, int> lca (int u, int v) {
		int ret = int(-2e9);
		if (depth[u] < depth[v]) swap(u, v);
		for (int i = 20; i--; ) if (depth[u] - (1<<i) >= depth[v]) {
			umax(ret, mx[i][u]);
			u = p[i][u];
		}
		if (u == v) return MP(u, ret);
		for (int i = 20; i--; ) if (p[i][u] != p[i][v]) {
			umax(ret, mx[i][u]);
			umax(ret, mx[i][v]);
			u = p[i][u], v = p[i][v];
		}
		umax(ret, mx[0][u]);
		return MP(p[0][u], ret);
	}

	void setup () {
		for (int i = 1; i < 20; i++) fo(j, 1, N+1) {
			p[i][j] = p[i-1][p[i-1][j]];
			mx[i][j] = max(mx[i-1][j], mx[i-1][p[i-1][j]]);
		}
	}
}

int E, upid[200200], ans[200200];
vector<int> tadj[200200], fk[200200], add[200200], rem[200200];
multiset<int> m[200200];
bool used[200200];

struct edge {
	int a, b, c, mx, i;
	bool operator < (const edge& o) const {
		return c < o.c;
	}
} e[200200];

void dfs (int i, int p) {
	LCA::p[0][i] = p;
	if (i != 1) {
		LCA::mx[0][i] = e[upid[i]].c;
	} else {
		LCA::mx[0][i] = int(-2e9);
	}

	fo(x, 0, SZ(tadj[i])) {
		int j = tadj[i][x];
		if (j != p) {
			upid[j] = fk[i][x];
			LCA::depth[j] = LCA::depth[i] + 1;
			dfs(j, i);
		}
	}
}

void procquery (int i, int p) {
	for (int j : tadj[i]) if (j != p) {
		procquery(j, i);
		if (m[j].size() > m[i].size()) swap(m[i], m[j]);
		for (int x : m[j]) m[i].insert(x);
	}
	for (int j : add[i]) m[i].insert(j);
	for (int j : rem[i]) m[i].erase(m[i].find(j));
	if (m[i].size()) {
		if (*m[i].begin() - 1 < e[upid[i]].mx) {
			e[upid[i]].mx = *m[i].begin() - 1;
		}
	}
}

int main () {
	scanf("%d %d", &N, &E);

	UF::init();
	fo(i, 0, E) {
		scanf("%d %d %d", &e[i].a, &e[i].b, &e[i].c);
		e[i].mx = (int) 2e9;
		e[i].i = i;
	}

	sort(e, e+E);
	fo(i, 0, E) {
		if (UF::m(e[i].a, e[i].b)) {
			//printf("%d %d %d\n", e[i].a, e[i].b, e[i].c);
			tadj[e[i].a].PB(e[i].b);
			fk[e[i].a].PB(i);
			tadj[e[i].b].PB(e[i].a);
			fk[e[i].b].PB(i);
			used[i] = true;
		}
	}

	dfs(1, 1);
	LCA::setup();

	fo(i, 0, E) if (!used[i]) {
		int l,t;
		tie(l,t) = LCA::lca(e[i].a, e[i].b);

		if (l != e[i].a) {
			add[e[i].a].PB(e[i].c);
			rem[l].PB(e[i].c);
			//printf("uchain %d %d\n", LCA::kth(e[i].a, ld), e[i].a);
		}
		if (l != e[i].b) {
			add[e[i].b].PB(e[i].c);
			rem[l].PB(e[i].c);
			//printf("uchain %d %d\n", LCA::kth(e[i].b, ld), e[i].b);
		}

		e[i].mx = t-1;
		//printf("%d %d flat %d\n", e[i].a, e[i].b, t);
	}

	procquery(1, 1);

	fo(i, 0, E) ans[e[i].i] = e[i].mx;
	fo(i, 0, E) {
		printf("%d\n", ans[i] == int(2e9) ? -1 : ans[i]);
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define fo(i,a,b) for(int i=(a);i<(b);i++)
#define MOD 1000000007
#define MP make_pair
#define PB push_back
#define SZ(a) ((int)a.size())
typedef long long ll;

//if something already optimal we can just assume it will be used for someone else anyway?

void umin (int& i, int j) {
	if (j<i) i = j;
}

namespace UF {
	int p[200200];
	void init () { fo(i, 0, 200200) p[i] = i; }
	int g (int i) { return p[i] == i ? i : p[i] = g(p[i]); }
	bool m (int i, int j) {
		i = g(i), j = g(j);
		if (i != j) {
			p[i] = j;
			return true;
		}
		return false;
	}
}

int N;

namespace LCA {
	int p[20][200200], mn[20][200200], depth[200200];

	pair<int, int> lca (int u, int v) {
		int ret = int(2e9);
		if (depth[u] < depth[v]) swap(u, v);
		for (int i = 20; i--; ) if (depth[u] - (1<<i) >= depth[v]) {
			umin(ret, mn[i][u]);
			u = p[i][u];
		}
		if (u == v) return MP(u, ret);
		for (int i = 20; i--; ) if (p[i][u] != p[i][v]) {
			umin(ret, mn[i][u]);
			umin(ret, mn[i][v]);
			u = p[i][u], v = p[i][v];
		}
		umin(ret, mn[0][u]);
		return MP(p[0][u], ret);
	}

	void setup () {
		for (int i = 1; i < 20; i++) fo(j, 1, N+1) {
			p[i][j] = p[i-1][p[i-1][j]];
			mn[i][j] = min(mn[i-1][j], mn[i-1][p[i-1][j]]);
		}
	}
}

int E, upid[200200], ans[200200];
vector<int> tadj[200200], fk[200200], add[200200], rem[200200];
multiset<int> m[200200];
bool used[200200];

struct edge {
	int a, b, c, mx, i;
	bool operator < (const edge& o) const {
		return c < o.c;
	}
} e[200200];

void dfs (int i, int p) {
	LCA::p[0][i] = p;
	if (i != 1) {
		LCA::mn[0][i] = e[upid[i]].c;
	} else {
		LCA::mn[0][i] = int(2e9);
	}

	fo(x, 0, SZ(tadj[i])) {
		int j = tadj[i][x];
		if (j != p) {
			upid[j] = fk[i][x];
			LCA::depth[j] = LCA::depth[i] + 1;
			dfs(j, i);
		}
	}
}

void procquery (int i, int p) {
	for (int j : tadj[i]) if (j != p) {
		procquery(j, i);
		if (m[j].size() > m[i].size()) swap(m[i], m[j]);
		for (int x : m[j]) m[i].insert(x);
	}
	for (int j : add[i]) m[i].insert(j);
	for (int j : rem[i]) m[i].erase(m[i].find(j));
	if (m[i].size()) {
		umin(e[upid[i]].mx, *m[i].begin() - 1);
	}
}

int main () {
	scanf("%d %d", &N, &E);

	UF::init();
	fo(i, 0, E) {
		scanf("%d %d %d", &e[i].a, &e[i].b, &e[i].c);
		e[i].mx = (int) 2e9;
		e[i].i = i;
	}

	sort(e, e+E);
	fo(i, 0, E) {
		if (UF::m(e[i].a, e[i].b)) {
			tadj[e[i].a].PB(e[i].b);
			fk[e[i].a].PB(i);
			tadj[e[i].b].PB(e[i].a);
			fk[e[i].b].PB(i);
			used[i] = true;
		}
	}

	dfs(1, 1);
	LCA::setup();

	fo(i, 0, E) if (!used[i]) {
		int l,t;
		tie(l,t) = LCA::lca(e[i].a, e[i].b);

		if (l != e[i].a) {
			add[e[i].a].PB(e[i].c);
			rem[l].PB(e[i].c);
			//printf("uchain %d %d\n", LCA::kth(e[i].a, ld), e[i].a);
		}
		if (l != e[i].b) {
			add[e[i].b].PB(e[i].c);
			rem[l].PB(e[i].c);
			//printf("uchain %d %d\n", LCA::kth(e[i].b, ld), e[i].b);
		}

		e[i].mx = t-1;
	}

	procquery(1, 1);

	fo(i, 0, E) ans[e[i].i] = e[i].mx;
	fo(i, 0, E) {
		printf("%d\n", ans[i] == int(2e9) ? -1 : ans[i]);
	}

	return 0;
}


#include<bits/stdc++.h>
#define ls (u << 1)
#define rs (ls | 1)
#define mid (L + R >> 1)

using namespace std;

using INT = long long;

const int NN = 402000;
const int MM = 20;
int p[NN][MM], deep[NN];
int mx[NN][MM], L[NN], R[NN], nn = 0;

int head[NN], nxt[NN], to[NN], wt[NN], id[NN], pv[NN];
int E = 0, pid[NN];
int flag[NN];

int add_edge(int u, int v, int w, int ID) {
	pv[E] = u; nxt[E] = head[u]; wt[E] = w; id[E] = ID; to[E] = v; head[u] = E++;
	pv[E] = v; nxt[E] = head[v]; wt[E] = w; id[E] = ID; to[E] = u; head[v] = E++;
}

struct LCA {
	void dfs(int u, int fa, int w){
		L[u] = ++nn;
		p[u][0]=fa; mx[u][0] = w;
		deep[u]=deep[fa]+1;
		for(int i=1; i<MM; i++) {
			p[u][i]=p[p[u][i-1]][i-1];
			mx[u][i] = max(mx[u][i-1], mx[p[u][i-1]][i-1]);
		}
		for(int e=head[u]; e!=-1; e=nxt[e]) if(flag[e]) {
			int v=to[e];
			if(v==fa) continue;
			pid[v] = e;
			dfs(v, u, wt[e]);
		}
		R[u] = nn;
	}
	int k_th(int u, int k){
		for(int i=0; i<MM; i++){
			if(k&(1<<i)) u=p[u][i];
		}
		return u;
	}
	int lca(int a, int b){
		if(deep[a]>deep[b]) swap(a, b);
		b=k_th(b, deep[b]-deep[a]);
		if(a==b) return a;
		for(int i=MM-1; i>=0; i--){
			if(p[a][0]==p[b][0]) break;
			if(p[a][i]!=p[b][i]) a=p[a][i], b=p[b][i];
		}
		return p[a][0];
	}
	int calc_fa(int u, int dep) {
		int ans = 0;
		for(int i=MM-1; i>=0; i--) if( ((dep>>i)&1) == 1 ){
			ans = max(ans, mx[u][i]);
			u = p[u][i];
		}
		return ans;
	}
	int calc(int u, int v) {
		int fa = lca(u, v);
		return max(calc_fa(u, deep[u] - deep[fa]), calc_fa(v, deep[v] - deep[fa]));
	}
	int isfa(int u, int v) {
		if(p[u][0] == v || p[v][0] == u) return 1;
		return 0;
	}
} lca;

int root[NN];
int ans[NN];
int n, m;

int find_root(int u) {
	if(root[u] == u) return u;
	return root[u] = find_root(root[u]);
}

int MN[NN<<2];

int build(int u, int L, int R) {
	MN[u] = 2e9;
	if(L + 1 == R) return 0;
	build(ls, L, mid);
	build(rs, mid, R);
}

int update(int u, int L, int R, int st, int ed, int dep) {
	if(L >= ed || R <= st) return 0;
	if(L >= st and R <= ed) {
		MN[u] = min(MN[u], dep);
		return 0;
	}
	update(ls, L, mid, st, ed, dep);
	update(rs, mid, R, st, ed, dep);
	MN[u] = min(MN[ls], MN[rs]);
}

int calc(int u, int L, int R, int st, int ed) {
	if(L >= ed || R <= st) return 2e9;
	if(L >= st and R <= ed) return MN[u];
	return min(calc(ls, L, mid, st, ed), calc(rs, mid, R, st, ed));
}

vector<pair<int, int> > dep[NN];
int ID[NN];

int main() {
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
	freopen("out.out", "w", stdout);
#endif
	memset(head, -1, sizeof head);
	cin >> n >> m;
	for(int i=1; i<=n; i++) {
		root[i] = i;
		ID[i] = i;
	}

	vector<int> te, oe;
	vector<int> buf;

	for(int i=1; i<=m; i++) {
		int u, v, w;
		scanf("%d %d %d", &u, &v, &w);
		buf.push_back(E);
		add_edge(u, v, w, i);
	}

	sort(buf.begin(), buf.end(), [&] (int u, int v) {
		return wt[u] < wt[v];
	});

	for(auto e : buf) {
		int u = pv[e], v = to[e];
		if(find_root(u) == find_root(v)) {
			oe.push_back(e);
			continue;
		}
		te.push_back(e);
		flag[e] = 1; flag[e+1] = 1;
		root[root[u]] = root[v];
	}
	lca.dfs(1, 0, 0);

	sort(te.begin(), te.end(), [&] (int u, int v) {
		return wt[u] < wt[v];
	});
	sort(oe.begin(), oe.end(), [&] (int u, int v) {
		return wt[u] < wt[v];
	});

	build(1, 1, n + 1);

	for(auto e : oe) {
		int u = pv[e], v = to[e];
		int fa = lca.lca(u, v);
		dep[deep[fa]].push_back({u, wt[e]});
		dep[deep[fa]].push_back({v, wt[e]});
	}

	sort(ID+1, ID+n+1, [&] (int u, int v) {
		return deep[u] < deep[v];
	});

	int pos = 0;
	for(int i=2; i<=n; i++) {
		int u = ID[i];
		while(pos < deep[u]) {
			for(auto pp : dep[pos]) {
				int v = pp.first, w = pp.second;
				update(1, 1, n + 1, L[v], L[v]+1, w);
			}
			pos++;
		}
		ans[id[pid[u]]] = calc(1, 1, n + 1, L[u], R[u]+1) - 1;
		if(ans[id[pid[u]]] > 1e9+10) ans[id[pid[u]]] = -1;
	}

	for(int i=1; i<=m; i++) {
		printf("%d ", ans[i]);
	}
}


#define _CRT_SECURE_NO_WARNINGS
#include <cctype>
#include <climits>
#include <cmath>
#include <cstring>
#include <deque>
#include <fstream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <bitset>
#include <numeric>
#include <ratio>
#include <regex>
#include <sstream>
#include <string>
#include <tuple>
#include <utility>
#include <valarray>

using namespace std;

#define sz(v) (int)v.size()
#define eps 1e-10
#define all(v) v.begin(), v.end()
#define CLR(a) memset(a,0,sizeof(a))
#define SET(a) memset(a,-1,sizeof(a))
#define chk(a,k) ((bool)(a&(1<<(k))))
#define set0(a,k) (a&(~(1<<(k))))
#define set1(a,k) (a|(1<<(k)))
#define in(v, x) (find(all(v),x) != v.end())
#define re return
#define sum(v) accumulate(v.begin(),v.end(),(ld)0)
#define tr(v,it) for(auto it=v.begin();it != v.end();it++)
#define asrt(v) sort(v.begin(),v.end())
#define dsrt(v) sort(v.rbegin(),v.rend())
#define rev(v) reverse(v.begin(),v.end())
#define pi 3.1415926535897932384626433832795
#define MOD 1000000007
#define print(v) for (auto& i:v) cout<<i<<endl
#define endl '\n'

typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<long long> vl;
typedef vector<string> vs;
typedef vector<vi> vvi;

#define N 1000+5

ll P[N], dp[N],X[N];

int main() {
	ios_base::sync_with_stdio(false); cin.tie(0);
	cout<<setprecision(15);
#ifndef ONLINE_JUDGE
	freopen("Data/input.txt", "r", stdin);
	freopen("Data/output.txt", "w", stdout);
#endif
	ll n, m, x, y;
	cin>>n;
	for(int i=1; i<=n; i++) {
		cin>>x;
		P[i]=x;
	}

	dp[n+1]=1;
	ll r=0;
	for(int i=n; i>=1; i--) {
		x=dp[i+1];
		dp[i]=2*(x-X[i+1]);
		dp[i]%=MOD;
		X[P[i]]+=dp[i]/2;
		r+=dp[i];
		r%=MOD;
	}

	cout<<r;

	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <cctype>
#include <climits>
#include <cmath>
#include <cstring>
#include <deque>
#include <fstream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <bitset>
#include <numeric>
#include <ratio>
#include <regex>
#include <sstream>
#include <string>
#include <tuple>
#include <utility>
#include <valarray>

using namespace std;

#define sz(v) (int)v.size()
#define eps 1e-10
#define all(v) v.begin(), v.end()
#define CLR(a) memset(a,0,sizeof(a))
#define SET(a) memset(a,-1,sizeof(a))
#define chk(a,k) ((bool)(a&(1<<(k))))
#define set0(a,k) (a&(~(1<<(k))))
#define set1(a,k) (a|(1<<(k)))
#define in(v, x) (find(all(v),x) != v.end())
#define re return
#define sum(v) accumulate(v.begin(),v.end(),(ld)0)
#define tr(v,it) for(auto it=v.begin();it != v.end();it++)
#define asrt(v) sort(v.begin(),v.end())
#define dsrt(v) sort(v.rbegin(),v.rend())
#define rev(v) reverse(v.begin(),v.end())
#define pi 3.1415926535897932384626433832795
#define MOD 1000000007LL
#define print(v) for (auto& i:v) cout<<i<<endl
#define endl '\n'

typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<long long> vl;
typedef vector<string> vs;
typedef vector<vi> vvi;

#define N 1000+5

ll P[N], dp[N],X[N];

ll modInv(ll a, ll m){
	ll b0=m, t, q;
	ll x0=0, x1=1;
	if(m == 1) return 1;
	while(a > 1) {
		q=a / m;
		t=m, m=a % m, a=t;
		t=x0, x0=x1 - q * x0, x1=t;
	}
	if(x1 < 0) x1+=b0;
	return x1;
}

template<class T> T mod(T a, T b) {
	return ((a%b)+b)%b;
}

int main() {
	ios_base::sync_with_stdio(false); cin.tie(0);
	cout<<setprecision(15);
#ifndef ONLINE_JUDGE
	freopen("Data/input.txt", "r", stdin);
	freopen("Data/output.txt", "w", stdout);
#endif
	ll n, m, x, y;
	ll z=modInv(2,MOD);
	cin>>n;
	for(int i=1; i<=n; i++) {
		cin>>x;
		P[i]=x;
	}

	dp[n+1]=1;
	ll r=0;
	for(int i=n; i>=1; i--) {
		x=dp[i+1];
		dp[i]=2*(x-X[i+1]);
		dp[i]=mod(dp[i],MOD);
		X[P[i]]+=dp[i]*z;
		X[P[i]]%=MOD;
		r+=dp[i];
		r%=MOD;
	}

	cout<<r;

	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <cctype>
#include <climits>
#include <cmath>
#include <cstring>
#include <deque>
#include <fstream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <bitset>
#include <numeric>
#include <ratio>
#include <regex>
#include <sstream>
#include <string>
#include <tuple>
#include <utility>
#include <valarray>

using namespace std;

#define sz(v) (int)v.size()
#define eps 1e-10
#define all(v) v.begin(), v.end()
#define CLR(a) memset(a,0,sizeof(a))
#define SET(a) memset(a,-1,sizeof(a))
#define chk(a,k) ((bool)(a&(1<<(k))))
#define set0(a,k) (a&(~(1<<(k))))
#define set1(a,k) (a|(1<<(k)))
#define in(v, x) (find(all(v),x) != v.end())
#define re return
#define sum(v) accumulate(v.begin(),v.end(),(ld)0)
#define tr(v,it) for(auto it=v.begin();it != v.end();it++)
#define asrt(v) sort(v.begin(),v.end())
#define dsrt(v) sort(v.rbegin(),v.rend())
#define rev(v) reverse(v.begin(),v.end())
#define pi 3.1415926535897932384626433832795
#define MOD 1000000007
#define print(v) for (auto& i:v) cout<<i<<endl
#define endl '\n'

typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<long long> vl;
typedef vector<string> vs;
typedef vector<vi> vvi;

#define N 1000+5

ll P[N], dp[N],X[N];

ll modInv(ll a, ll m){
	ll b0=m, t, q;
	ll x0=0, x1=1;
	if(m == 1) return 1;
	while(a > 1) {
		q=a / m;
		t=m, m=a % m, a=t;
		t=x0, x0=x1 - q * x0, x1=t;
	}
	if(x1 < 0) x1+=b0;
	return x1;
}

int main() {
	ios_base::sync_with_stdio(false); cin.tie(0);
	cout<<setprecision(15);
#ifndef ONLINE_JUDGE
	freopen("Data/input.txt", "r", stdin);
	freopen("Data/output.txt", "w", stdout);
#endif
	ll n, m, x, y;
	ll z=modInv(2,MOD);
	cin>>n;
	for(int i=1; i<=n; i++) {
		cin>>x;
		P[i]=x;
	}

	dp[n+1]=1;
	ll r=0;
	for(int i=n; i>=1; i--) {
		x=dp[i+1];
		dp[i]=2*(x-X[i+1]);
		dp[i]%=MOD;
		X[P[i]]+=dp[i]*z;
		X[P[i]]%=MOD;
		r+=dp[i];
		r%=MOD;
	}

	cout<<r;

	return 0;
}


import java.util.Scanner;

public class Main {
  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    char [] a, b;
    String s = sc.next();
    a = s.toCharArray();
    s = sc.next();
    b = s.toCharArray();

    int [] cnt = new int[26];
    for (int i = 0; i < a.length; ++i) {
      int x = a[i] - 'a';
      ++cnt[x];
    }
    for (int i = 0; i < 26; ++i)
      if(cnt[i] == 0)
        cnt[i] = -1;
    int ans = 0;
    for (int i = 0; i < b.length; ++i) {
      int x = b[i] - 'a';
      if(cnt[x] == -1) {
        ans = -1;
        break;
      }
      if(cnt[x] > 0) {
        ++ans;
        --cnt[x];
      }
    }
    System.out.println(ans);
 }

}


import java.util.Scanner;

public class Main {
  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    char [] a, b;
    String s = sc.next();
    a = s.toCharArray();
    s = sc.next();
    b = s.toCharArray();

    int [] cnt = new int[26];
    for (int i = 0; i < a.length; ++i) {
      int x = a[i] - 'a';
      ++cnt[x];
    }
    int ans = 0;
    for (int i = 0; i < b.length; ++i) {
      int x = b[i] - 'a';
      if(cnt[x] > 0) {
        ++ans;
        --cnt[x];
      }
    }
    if(ans == 0) ans = -1;
    System.out.println(ans);
 }

}


import java.util.*;
public class Garland
{
	public static void main(String[] args)
	{
		Scanner sc=new Scanner(System.in);
		String s1=sc.next();
		String s2=sc.next();
		int a[]=new int[26];
		int b[]=new int[26];

		for(int i=0;i<s1.length();i++)
		{
			a[s1.charAt(i)-'a']++;
		}

		for(int i=0;i<s2.length();i++)
		{
			b[s2.charAt(i)-'a']++;
		}

		int sum=0;
		int flag=0;
		for(int i=0;i<a.length;i++)
		{
			if(a[i]==0 && b[i]>0)
			{
				flag=1;
				break;
			}

			else
			{
				sum=sum+Math.min(a[i],b[i]);
			}
		}

		if(flag==1)
		{
			System.out.println("-1");
		}
		else
		{
			System.out.println(sum);
		}
	}
}


import java.util.*;
import java.io.*;

public class Template {

	static Scanner sc = new Scanner(System.in);
	static InputStreamReader stream = new InputStreamReader(System.in);
	static BufferedReader br = new BufferedReader(stream);

	public static void main(String[] args) throws IOException{

		String have = br.readLine();
		String want = br.readLine();
		int[] cnt = new int[26];
		for(char c:want.toCharArray()) {
			cnt[(int)c-97]++;
		}
		int ans = 0;
		for(char c:have.toCharArray()) {
			if(cnt[(int)c-97]>=1) {
				cnt[(int)c-97]--;
				ans++;
			}
		}
		if(ans>0)System.out.println(ans);
		else System.out.println(-1);
	}

	public static int function(int n, int[] a) {
		int last = a[0];
		int moves = a[0]+1;
		for(int i=1 ; i<n ; i++) {
			if(a[i]>=last) {
				moves++;
				moves += a[i]-last+1;
				last = a[i];
			}else {
				moves += last-a[i] + 2;
				last = a[i];
			}
		}
		return moves;
	}

	//BufferedReader Input functions
	public static int readInt() throws IOException{
		return (Integer.parseInt(br.readLine()));
	}

	public static int[] readArray(int n) throws IOException{
		int[] a = new int[n];
		for(int i=0 ; i<n ; i++) {
			a[i]= readInt();
		}
		return a;
	}

	public static int[] readArrayline(int n) throws IOException{
		int[] a = new int[n];
		String[] s = br.readLine().split(" ");
		for(int i=0 ; i<n ; i++) {
			a[i]= Integer.parseInt(s[i]);
		}
		return a;
	}

	public static int[] readA(int n) {
		int[] a = new int[n];
		for(int i=0 ; i<n ; i++) {
			a[i] = sc.nextInt();
		} return a;
	}

}


import java.util.*;
import java.io.*;

public class Template {

	static Scanner sc = new Scanner(System.in);
	static InputStreamReader stream = new InputStreamReader(System.in);
	static BufferedReader br = new BufferedReader(stream);

	public static void main(String[] args) throws IOException{

		String have = br.readLine();
		String want = br.readLine();
		int[] hcnt = new int[26];
		int[] wcnt = new int[26];
		for(char c:have.toCharArray()) {
			hcnt[(int)c-97]++;
		}
		for(char c:want.toCharArray()) {
			wcnt[(int)c-97]++;
		}
		Set<Character> set = new HashSet<>();
		for(char c:want.toCharArray()) {
			set.add(c);
		}
		boolean possible = true;
		for(char c:set) {
			if(hcnt[(int)c-97]==0) {
				possible = false;
				break;
			}
		}
		if(!possible) {
			System.out.println(-1);
		}else {
			int ans = 0;
			for(int i=0 ; i<wcnt.length ; i++) {
				if(wcnt[i]>0) {
					ans += Math.min(wcnt[i], hcnt[i]);
				}
			}
			System.out.println(ans);
		}
	}

	public static int function(int n, int[] a) {
		int last = a[0];
		int moves = a[0]+1;
		for(int i=1 ; i<n ; i++) {
			if(a[i]>=last) {
				moves++;
				moves += a[i]-last+1;
				last = a[i];
			}else {
				moves += last-a[i] + 2;
				last = a[i];
			}
		}
		return moves;
	}

	//BufferedReader Input functions
	public static int readInt() throws IOException{
		return (Integer.parseInt(br.readLine()));
	}

	public static int[] readArray(int n) throws IOException{
		int[] a = new int[n];
		for(int i=0 ; i<n ; i++) {
			a[i]= readInt();
		}
		return a;
	}

	public static int[] readArrayline(int n) throws IOException{
		int[] a = new int[n];
		String[] s = br.readLine().split(" ");
		for(int i=0 ; i<n ; i++) {
			a[i]= Integer.parseInt(s[i]);
		}
		return a;
	}

	public static int[] readA(int n) {
		int[] a = new int[n];
		for(int i=0 ; i<n ; i++) {
			a[i] = sc.nextInt();
		} return a;
	}

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class garland {
    static class FastReader {
        BufferedReader br;
        StringTokenizer st;

        public FastReader() {
            br = new BufferedReader(new
                    InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }

    public static void main(String[] args) {
        FastReader sc=new FastReader();
        String n=sc.next();
        String m=sc.next();
        int[]f1=new int[26];
        int[]f2=new int[26];
        for(int i=0;i<n.length();i++){
            f1[n.charAt(i)-'a']++;
        }
        for(int i=0;i<m.length();i++){
            f2[m.charAt(i)-'a']++;
        }
        int sum=0;
        boolean tf=true;
        for(int i=0;i<26;i++){
            if(f1[i]>0 && f2[i]>0){
                sum+=Math.min(f1[i],f2[i]);
            }
            else if(f1[i]==0 && f2[i]>0){
                tf=false;
            }
        }
        if(tf) {
            System.out.println(sum);
        }
        else{
            System.out.println(-1);
        }
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class garland {
    static class FastReader {
        BufferedReader br;
        StringTokenizer st;

        public FastReader() {
            br = new BufferedReader(new
                    InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
    }

    public static void main(String[] args) {
        FastReader sc=new FastReader();
        String n=sc.next();
        String m=sc.next();
        int[]f1=new int[26];
        int[]f2=new int[26];
        for(int i=0;i<n.length();i++){
            f1[n.charAt(i)-'a']++;
        }
        for(int i=0;i<m.length();i++){
            f2[m.charAt(i)-'a']++;
        }
        int sum=0;
        for(int i=0;i<26;i++){
            if(f1[i]!=0 && f2[i]!=0){
                if(f1[i]>f2[i]){
                    sum+=f2[i];
                }
                if(f1[i]==f2[i]){
                    sum+=f1[i];
                }
                if(f1[i]<f2[i]){
                    sum+=f1[i];
                }
            }
        }
        if(sum>0) {
            System.out.println(sum);
        }
        else{
            System.out.println(-1);
        }
    }
}


import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

    public class Codeforces {

        public static void main(String[] args) throws IOException {
           BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
           String n = br.readLine();
           String m = br.readLine();
           HashMap<Character, Integer> Nmap = new HashMap<>();
           HashMap<Character, Integer> Mmap = new HashMap<>();
           for(char c : n.toCharArray()){
               if(Nmap.containsKey(c)){
                   Nmap.put(c, Nmap.get(c) + 1);
               }
               else Nmap.put(c, 1);
           }
            for(char c : m.toCharArray()){
               if(Mmap.containsKey(c)){
                   Mmap.put(c, Mmap.get(c) + 1);
               }
               else Mmap.put(c, 1);
           }
            boolean NotPossible = false;
            int res = 0;
            for(Map.Entry e: Mmap.entrySet() ){
                if(!Nmap.containsKey(e.getKey())){
                    NotPossible = true;
                    break;
                }
                else{
                    res += Math.min((int)e.getValue(),(int) Nmap.get(e.getKey()));
                }
            }
            if(NotPossible) System.out.println(-1);
            else  System.out.println(res);

        }
    }


/* package codechef; // don't place package name! */

import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
public class Solution
{
    // Complete the maximumSum function below.
    public static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private SpaceCharFilter filter;
        private BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars==-1)
                throw new InputMismatchException();

            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                }
                catch (IOException e) {
                    throw new InputMismatchException();
                }

                if(numChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        public String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
        public int nextInt() {
            int c = read();

            while(isSpaceChar(c))
                c = read();

            int sgn = 1;

            if (c == '-') {
                sgn = -1;
                c = read();
            }

            int res = 0;
            do {
                if(c<'0'||c>'9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            }
            while (!isSpaceChar(c));

            return res * sgn;
        }

        public long nextLong() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;

            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            }
            while (!isSpaceChar(c));
            return res * sgn;
        }

        public double nextDouble() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            double res = 0;
            while (!isSpaceChar(c) && c != '.') {
                if (c == 'e' || c == 'E')
                    return res * Math.pow(10, nextInt());
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            }
            if (c == '.') {
                c = read();
                double m = 1;
                while (!isSpaceChar(c)) {
                    if (c == 'e' || c == 'E')
                        return res * Math.pow(10, nextInt());
                    if (c < '0' || c > '9')
                        throw new InputMismatchException();
                    m /= 10;
                    res += (c - '0') * m;
                    c = read();
                }
            }
            return res * sgn;
        }

        public String readString() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            }
            while (!isSpaceChar(c));

            return res.toString();
        }

        public boolean isSpaceChar(int c) {
            if (filter != null)
                return filter.isSpaceChar(c);
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public String next() {
            return readString();
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);
        }
    }

    public static  long gcd(long a,long b){
        if(b==0)
            return a;
        long r=a%b;
        return gcd(b,r);
    }

    static long lcm(long a, long b)
    {
        return (a*b)/gcd(a, b);
    }

    public class ListNode {
        int val;
        ListNode next;
        ListNode() {}
        ListNode(int val) { this.val = val; }
        ListNode(int val, ListNode next) { this.val = val; this.next = next; }
    }

    public class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;
        TreeNode() {}
        TreeNode(int val) { this.val = val; }
        TreeNode(int val, TreeNode left, TreeNode right) {
            this.val = val;
            this.left = left;
            this.right = right;
        }
    }

    class Node {
        public int val;
        public List<Node> children;

        public Node() {}

        public Node(int _val) {
            val = _val;
        }

        public Node(int _val, List<Node> _children) {
            val = _val;
            children = _children;
        }
    }

    public static void main(String[] args) throws IOException {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader scanner = new InputReader(inputStream);
        PrintWriter w = new PrintWriter(outputStream);
        //int t=scanner.nextInt();
        //while (t-->0){
        String a=scanner.next();
        String b=scanner.next();
        int arr[]=new int[26];
        int brr[]=new int[26];
        int op=0;
        for(int i=0;i<a.length();i++)
            arr[a.charAt(i)-'a']++;
        for(int j=0;j<b.length();j++)
            brr[b.charAt(j)-'a']++;
        for(int i=0;i<26;i++)
            op+=Math.min(arr[i],brr[i]);
        if(op==0)
            w.println(-1);
        else
        w.println(op);
        w.close();
    }
}


/* package codechef; // don't place package name! */

import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
public class Solution
{
    // Complete the maximumSum function below.
    public static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private SpaceCharFilter filter;
        private BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars==-1)
                throw new InputMismatchException();

            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                }
                catch (IOException e) {
                    throw new InputMismatchException();
                }

                if(numChars <= 0)
                    return -1;
            }
            return buf[curChar++];
        }

        public String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
        public int nextInt() {
            int c = read();

            while(isSpaceChar(c))
                c = read();

            int sgn = 1;

            if (c == '-') {
                sgn = -1;
                c = read();
            }

            int res = 0;
            do {
                if(c<'0'||c>'9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            }
            while (!isSpaceChar(c));

            return res * sgn;
        }

        public long nextLong() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            long res = 0;

            do {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            }
            while (!isSpaceChar(c));
            return res * sgn;
        }

        public double nextDouble() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            double res = 0;
            while (!isSpaceChar(c) && c != '.') {
                if (c == 'e' || c == 'E')
                    return res * Math.pow(10, nextInt());
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            }
            if (c == '.') {
                c = read();
                double m = 1;
                while (!isSpaceChar(c)) {
                    if (c == 'e' || c == 'E')
                        return res * Math.pow(10, nextInt());
                    if (c < '0' || c > '9')
                        throw new InputMismatchException();
                    m /= 10;
                    res += (c - '0') * m;
                    c = read();
                }
            }
            return res * sgn;
        }

        public String readString() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            StringBuilder res = new StringBuilder();
            do {
                res.appendCodePoint(c);
                c = read();
            }
            while (!isSpaceChar(c));

            return res.toString();
        }

        public boolean isSpaceChar(int c) {
            if (filter != null)
                return filter.isSpaceChar(c);
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public String next() {
            return readString();
        }

        public interface SpaceCharFilter {
            public boolean isSpaceChar(int ch);
        }
    }

    public static  long gcd(long a,long b){
        if(b==0)
            return a;
        long r=a%b;
        return gcd(b,r);
    }

    static long lcm(long a, long b)
    {
        return (a*b)/gcd(a, b);
    }

    public class ListNode {
        int val;
        ListNode next;
        ListNode() {}
        ListNode(int val) { this.val = val; }
        ListNode(int val, ListNode next) { this.val = val; this.next = next; }
    }

    public class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;
        TreeNode() {}
        TreeNode(int val) { this.val = val; }
        TreeNode(int val, TreeNode left, TreeNode right) {
            this.val = val;
            this.left = left;
            this.right = right;
        }
    }

    class Node {
        public int val;
        public List<Node> children;

        public Node() {}

        public Node(int _val) {
            val = _val;
        }

        public Node(int _val, List<Node> _children) {
            val = _val;
            children = _children;
        }
    }

    public static void main(String[] args) throws IOException {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader scanner = new InputReader(inputStream);
        PrintWriter w = new PrintWriter(outputStream);
        //int t=scanner.nextInt();
        //while (t-->0){
        String a=scanner.next();
        String b=scanner.next();
        int arr[]=new int[26];
        int brr[]=new int[26];
        int op=0;
        for(int i=0;i<a.length();i++)
            arr[a.charAt(i)-'a']++;
        for(int j=0;j<b.length();j++)
            brr[b.charAt(j)-'a']++;
        for(int i=0;i<26;i++) {
            op += Math.min(arr[i], brr[i]);
            if(arr[i]==0&&brr[i]!=0){
                op=0;
                break;
            }
        }
        if(op==0)
            w.println(-1);
        else
        w.println(op);
        w.close();
    }
}


import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class B {

	public static void main(String[] args) throws IOException{
		FastScanner sc = new FastScanner();

//		int yo = sc.nextInt();
//		while(yo-->0) {
//		}

		char[] n = sc.next().toCharArray();
		char[] m = sc.next().toCharArray();

		Map<Character,Integer> map1 = new HashMap<>();
		Map<Character,Integer> map2 = new HashMap<>();
		for(char e : n) {
			map1.put(e, map1.getOrDefault(e, 0)+1);
		}
		for(char e : m) {
			map2.put(e, map2.getOrDefault(e, 0)+1);
		}

		Set<Character> set = new HashSet<>();
		for(char e : m) {
			set.add(e);
		}
		int count = 0;

		for(char c : set) {
			if(map1.containsKey(c)) {
				if(map1.get(c) >= map2.get(c)) {
					count += map2.get(c);
				}
				else {
					count += map1.get(c);
				}
			}
			else {
				System.out.println(-1);
				return;
			}
//			System.out.println(c + " " + count);
		}
		System.out.println(count);
	}

	static class Pair{
		int start;
		int end;
		public Pair(int start, int y) {
			this.start = start;
			this.end = end;
		}
	}

	static int mod = 1000000007;

	static long pow(int a, int b) {
		if(b == 0) {
			return 1;
		}
		if(b == 1) {
			return a;
		}
		if(b%2 == 0) {
			long ans = pow(a,b/2);
			return ans*ans;
		}
		else {
			long ans = pow(a,(b-1)/2);
			return a * ans * ans;
		}

	}

	static class FastScanner {
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st=new StringTokenizer("");
		String next() {
			while (!st.hasMoreTokens())
				try {
					st=new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}
		int[] readArray(int n) {
			int[] a=new int[n];
			for (int i=0; i<n; i++) a[i]=nextInt();
			return a;
		}
		long nextLong() {
			return Long.parseLong(next());
		}
	}

	static int gcd(int a, int b) {
		return a%b == 0 ? b : gcd(b,a%b);
	}

	static boolean[] sieve(int n) {

		boolean isPrime[] = new boolean[n+1];
		for(int i = 2; i <= n; i++) {
			if(isPrime[i]) continue;
			for(int j = 2*i; j <= n; j+=i) {
				isPrime[j] = true;
			}

		}
		return isPrime;

	}

//	For Input.txt and Output.txt

//	FileInputStream in = new FileInputStream("input.txt");
//	FileOutputStream out = new FileOutputStream("output.txt");
//	PrintWriter pw = new PrintWriter(out);
//	Scanner sc = new Scanner(in);

// 	sc.nextLine()

}


import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class B {

	public static void main(String[] args) throws IOException{
		FastScanner sc = new FastScanner();

//		int yo = sc.nextInt();
//		while(yo-->0) {
//		}

		char[] n = sc.next().toCharArray();
		char[] m = sc.next().toCharArray();

		Map<Character,Integer> map1 = new HashMap<>();
		Map<Character,Integer> map2 = new HashMap<>();
		for(char e : n) {
			map1.put(e, map1.getOrDefault(e, 0)+1);
		}
		for(char e : m) {
			map2.put(e, map2.getOrDefault(e, 0)+1);
		}

		PriorityQueue<Character> pq = new PriorityQueue<>((x,y) -> map2.get(y)-map2.get(x));
		pq.addAll(map2.keySet());

		int max1 = Integer.MIN_VALUE, max2 = Integer.MIN_VALUE;

		while(!pq.isEmpty()) {
			char c = pq.poll();
//			System.out.println(c);
			if(map1.containsKey(c)) {
				if(map2.get(c) <= map1.get(c)) {
					if(max1 == Integer.MIN_VALUE) {
						max1 = map2.get(c);
					}
					else {
						max2 = map2.get(c);
						break;
					}
				}
			}
		}
		if(max1 == Integer.MIN_VALUE && max2 == Integer.MIN_VALUE) {
			System.out.println(-1);
			return;
		}
		else if(max2 == Integer.MIN_VALUE) {
			System.out.println(1);
			return;
		}
		else {
			System.out.println(max1*max2);
			return;
		}

	}

	static class Pair{
		int start;
		int end;
		public Pair(int start, int y) {
			this.start = start;
			this.end = end;
		}
	}

	static int mod = 1000000007;

	static long pow(int a, int b) {
		if(b == 0) {
			return 1;
		}
		if(b == 1) {
			return a;
		}
		if(b%2 == 0) {
			long ans = pow(a,b/2);
			return ans*ans;
		}
		else {
			long ans = pow(a,(b-1)/2);
			return a * ans * ans;
		}

	}

	static class FastScanner {
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st=new StringTokenizer("");
		String next() {
			while (!st.hasMoreTokens())
				try {
					st=new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}
		int[] readArray(int n) {
			int[] a=new int[n];
			for (int i=0; i<n; i++) a[i]=nextInt();
			return a;
		}
		long nextLong() {
			return Long.parseLong(next());
		}
	}

	static int gcd(int a, int b) {
		return a%b == 0 ? b : gcd(b,a%b);
	}

	static boolean[] sieve(int n) {

		boolean isPrime[] = new boolean[n+1];
		for(int i = 2; i <= n; i++) {
			if(isPrime[i]) continue;
			for(int j = 2*i; j <= n; j+=i) {
				isPrime[j] = true;
			}

		}
		return isPrime;

	}

//	For Input.txt and Output.txt

//	FileInputStream in = new FileInputStream("input.txt");
//	FileOutputStream out = new FileOutputStream("output.txt");
//	PrintWriter pw = new PrintWriter(out);
//	Scanner sc = new Scanner(in);

// 	sc.nextLine()

}


import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class B {

	public static void main(String[] args) throws IOException{
		FastScanner sc = new FastScanner();

//		int yo = sc.nextInt();
//		while(yo-->0) {
//		}

		char[] n = sc.next().toCharArray();
		char[] m = sc.next().toCharArray();

		Map<Character,Integer> map1 = new HashMap<>();
		Map<Character,Integer> map2 = new HashMap<>();
		for(char e : n) {
			map1.put(e, map1.getOrDefault(e, 0)+1);
		}
		for(char e : m) {
			map2.put(e, map2.getOrDefault(e, 0)+1);
		}

		PriorityQueue<Character> pq = new PriorityQueue<>((x,y) -> map2.get(y)-map2.get(x));
		pq.addAll(map2.keySet());

		int count = -1;

		while(!pq.isEmpty()) {
			char c = pq.poll();
//			System.out.println(c);

			if(map1.containsKey(c)) {
				if(map2.get(c) <= map1.get(c)) {
					count += map2.get(c);
				}
				else {
					int diff = map2.get(c)-map1.get(c);
					count += diff;
				}
			}

		}

		System.out.println(count == 0 ? 1 : count);

	}

	static class Pair{
		int start;
		int end;
		public Pair(int start, int y) {
			this.start = start;
			this.end = end;
		}
	}

	static int mod = 1000000007;

	static long pow(int a, int b) {
		if(b == 0) {
			return 1;
		}
		if(b == 1) {
			return a;
		}
		if(b%2 == 0) {
			long ans = pow(a,b/2);
			return ans*ans;
		}
		else {
			long ans = pow(a,(b-1)/2);
			return a * ans * ans;
		}

	}

	static class FastScanner {
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st=new StringTokenizer("");
		String next() {
			while (!st.hasMoreTokens())
				try {
					st=new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}
		int[] readArray(int n) {
			int[] a=new int[n];
			for (int i=0; i<n; i++) a[i]=nextInt();
			return a;
		}
		long nextLong() {
			return Long.parseLong(next());
		}
	}

	static int gcd(int a, int b) {
		return a%b == 0 ? b : gcd(b,a%b);
	}

	static boolean[] sieve(int n) {

		boolean isPrime[] = new boolean[n+1];
		for(int i = 2; i <= n; i++) {
			if(isPrime[i]) continue;
			for(int j = 2*i; j <= n; j+=i) {
				isPrime[j] = true;
			}

		}
		return isPrime;

	}

//	For Input.txt and Output.txt

//	FileInputStream in = new FileInputStream("input.txt");
//	FileOutputStream out = new FileOutputStream("output.txt");
//	PrintWriter pw = new PrintWriter(out);
//	Scanner sc = new Scanner(in);

// 	sc.nextLine()

}


import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class B {

	public static void main(String[] args) throws IOException{
		FastScanner sc = new FastScanner();

//		int yo = sc.nextInt();
//		while(yo-->0) {
//		}

		char[] n = sc.next().toCharArray();
		char[] m = sc.next().toCharArray();

		Map<Character,Integer> map1 = new HashMap<>();
		Map<Character,Integer> map2 = new HashMap<>();
		for(char e : n) {
			map1.put(e, map1.getOrDefault(e, 0)+1);
		}
		for(char e : m) {
			map2.put(e, map2.getOrDefault(e, 0)+1);
		}

		PriorityQueue<Character> pq = new PriorityQueue<>((x,y) -> map2.get(y)-map2.get(x));
		pq.addAll(map2.keySet());

		int max1 = Integer.MIN_VALUE, max2 = Integer.MIN_VALUE;

		while(!pq.isEmpty()) {
			char c = pq.poll();
//			System.out.println(c);
			if(map1.containsKey(c)) {
				if(map2.get(c) <= map1.get(c)) {
					if(max1 == Integer.MIN_VALUE) {
						max1 = map2.get(c);
					}
					else {
						max2 = map2.get(c);
						break;
					}
				}
			}
		}
		if(max1 == Integer.MIN_VALUE || max2 == Integer.MIN_VALUE) {
			System.out.println(-1);
			return;
		}
		System.out.println(max1*max2);

	}

	static class Pair{
		int start;
		int end;
		public Pair(int start, int y) {
			this.start = start;
			this.end = end;
		}
	}

	static int mod = 1000000007;

	static long pow(int a, int b) {
		if(b == 0) {
			return 1;
		}
		if(b == 1) {
			return a;
		}
		if(b%2 == 0) {
			long ans = pow(a,b/2);
			return ans*ans;
		}
		else {
			long ans = pow(a,(b-1)/2);
			return a * ans * ans;
		}

	}

	static class FastScanner {
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st=new StringTokenizer("");
		String next() {
			while (!st.hasMoreTokens())
				try {
					st=new StringTokenizer(br.readLine());
				} catch (IOException e) {
					e.printStackTrace();
				}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());
		}
		int[] readArray(int n) {
			int[] a=new int[n];
			for (int i=0; i<n; i++) a[i]=nextInt();
			return a;
		}
		long nextLong() {
			return Long.parseLong(next());
		}
	}

	static int gcd(int a, int b) {
		return a%b == 0 ? b : gcd(b,a%b);
	}

	static boolean[] sieve(int n) {

		boolean isPrime[] = new boolean[n+1];
		for(int i = 2; i <= n; i++) {
			if(isPrime[i]) continue;
			for(int j = 2*i; j <= n; j+=i) {
				isPrime[j] = true;
			}

		}
		return isPrime;

	}

//	For Input.txt and Output.txt

//	FileInputStream in = new FileInputStream("input.txt");
//	FileOutputStream out = new FileOutputStream("output.txt");
//	PrintWriter pw = new PrintWriter(out);
//	Scanner sc = new Scanner(in);

// 	sc.nextLine()

}


import java.util.*;
public class vv {

 public static void main(String[] args) {
  Scanner no=new Scanner(System.in);
  int arr[]=new int[27];
  int arr1[]=new int[27];
  int sum=0;
  boolean t=true;
  String s=no.nextLine();
  String s1=no.nextLine();
  for(int i=0;i<s.length();i++){
    arr[s.charAt(i)-'a']++;
  }
  for(int i=0;i<s1.length();i++){
    arr1[s1.charAt(i)-'a']++;
  }
  for(int i=0;i<27;i++){
    if(arr[i]>0&&arr1[i]>0){
      sum=sum+Math.min(arr[i],arr1[i]);
    }
    else if(arr1[i]>0&&arr[i]==0){
      t=false;
      break;
    }
  }
  if(t){
    System.out.println(sum);
  }
  else{
    System.out.println("-1");
  }
 }

}


import com.sun.jdi.ArrayReference;
import jdk.swing.interop.SwingInterOpUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Array;
import java.math.BigInteger;
import java.text.DecimalFormat;
import java.util.*;

public class Main {

    public static void main(String[] args) {
        FastScanner fs = new FastScanner();
        String n = fs.next();
        String m = fs.next();
        HashMap<Character, Integer> nMap = new HashMap<>();
        HashMap<Character, Integer> mMap = new HashMap<>();

        for (int i = 0; i<n.length(); i++) {
            char current = n.charAt(i);
            if (nMap.containsKey(n.charAt(i))) {
                nMap.put(current, nMap.get(current)+1);
            } else {
                nMap.put(current, 1);
            }
        }
        for (int i = 0; i<m.length(); i++) {
            char current = m.charAt(i);
            if (mMap.containsKey(m.charAt(i))) {
                mMap.put(current, mMap.get(current)+1);
            } else {
                mMap.put(current, 1);
            }
        }

        int ans = 0;
        for (Character k : mMap.keySet()) {
            if (nMap.containsKey(k)) {
                ans += Math.min(mMap.get(k), nMap.get(k));
            } else {
                ans = -1;
                break;
            }
        }
        System.out.println(ans);

    }

    public static int gcd(int a, int b)
    {
        if (a == 0)
            return b;
        return gcd(b % a, a);
    }

    static class FastScanner {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st=new StringTokenizer("");
        String next() {
            while (!st.hasMoreTokens())
                try {
                    st=new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }
        int[] readArray(int n) {
            int[] a=new int[n];
            for (int i=0; i<n; i++) a[i]=nextInt();
            return a;
        }
        long nextLong() {
            return Long.parseLong(next());
        }
    }

}


import java.util.*;
import java.math.*;
import java.io.*;
 public class A{

    static FastReader scan=new FastReader();
   public static PrintWriter out = new PrintWriter (new BufferedOutputStream(System.out));

   static int n;
   static char orig[][];

   static int check(char arr[][]){
    int c=0;

    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
        if(arr[j][i]!='1')
            continue;
        if(j==n-1&&arr[j][i]=='1')
            c++;

}

    }
return c;
   }
   static int tmp=0;
   static int solve(int op){
    char arr[][]=new char[n][n];
            for(int l = 0; l <n; l++)
{
  for (int m = 0; m < n; m++)
  {
    arr[l][m] = orig[l][m];
  }
}

for(int i=0;i<n;i++){
   if(arr[op][i]=='1')
                arr[op][i]='0';
            else arr[op][i]='1';
     }
   tmp=Math.max(tmp,check(arr));

return tmp;
   }
public static void main(String[] args)  throws IOException
{
    int a1[]=new int[265];
    int a2[]=new int[265];
    char chars1[]=scan.next().toCharArray();
    char chars2[]=scan.next().toCharArray();
    for(int i=0;i<chars1.length;i++)
        a1[chars1[i]]++;
    for(int i=0;i<chars2.length;i++)
        a2[chars2[i]]++;
    int res=0;
    boolean ok=false;
    int min=0;
    //out.println(a1['s']);
    for(int i=0;i<265;i++){
        char c=(char)i;
        min = (a1[c]<a2[c])?a1[c]:a2[c];
        if(min==0&&a2[c]!=0)
        {
           res=0;
           break;
        }
        res+=min;
    }
    if(res==0)
        res--;
    out.println(res);

 out.close();

}
 public static  long pow(long b, long e) {
            long r = 1;
            while (e > 0) {
                if (e % 2 == 1) r = r * b ;
                b = b * b;
                e >>= 1;
            }
            return r;
        }
private static void sort(long[] arr) {
        List<Long> list = new ArrayList<>();
        for (long object : arr) list.add(object);
        Collections.sort(list);
        for (int i = 0; i < list.size(); ++i) arr[i] = list.get(i);
    }
 public static class FastReader {
        BufferedReader br;
        StringTokenizer root;

        public FastReader() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String next() {
            while (root == null || !root.hasMoreTokens()) {
                try {
                    root = new StringTokenizer(br.readLine());
                } catch (Exception addd) {
                    addd.printStackTrace();
                }
            }
            return root.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (Exception addd) {
                addd.printStackTrace();
            }
            return str;
        }
         public int[] nextIntArray(int arraySize) {
            int array[] = new int[arraySize];

            for (int i = 0; i < arraySize; i++) {
                array[i] = nextInt();
            }

            return array;
        }
}
static class pair{
    int i;
    int j;
pair(int i,int j){
    this.i=i;
    this.j=j;
}

}}


import java.util.*;
import java.math.*;
import java.io.*;
 public class A{

    static FastReader scan=new FastReader();
   public static PrintWriter out = new PrintWriter (new BufferedOutputStream(System.out));

   static int n;
   static char orig[][];

   static int check(char arr[][]){
    int c=0;

    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
        if(arr[j][i]!='1')
            continue;
        if(j==n-1&&arr[j][i]=='1')
            c++;

}

    }
return c;
   }
   static int tmp=0;
   static int solve(int op){
    char arr[][]=new char[n][n];
            for(int l = 0; l <n; l++)
{
  for (int m = 0; m < n; m++)
  {
    arr[l][m] = orig[l][m];
  }
}

for(int i=0;i<n;i++){
   if(arr[op][i]=='1')
                arr[op][i]='0';
            else arr[op][i]='1';
     }
   tmp=Math.max(tmp,check(arr));

return tmp;
   }
public static void main(String[] args)  throws IOException
{
    int a1[]=new int[265];
    int a2[]=new int[265];
    char chars1[]=scan.next().toCharArray();
    char chars2[]=scan.next().toCharArray();
    for(int i=0;i<chars1.length;i++)
        a1[chars1[i]]++;
    for(int i=0;i<chars2.length;i++)
        a2[chars2[i]]++;
    int res=0;
    boolean ok=false;
   // out.println(a1['s']);
    for(int i=0;i<265;i++){
        char c=(char)i;

            if(a1[c]<a2[c]){
             //   out.println(c);
               // ok=true;
                res+=a1[c];
            }
            else res+=a2[c];

    }

    if(res==0)res--;
    out.println(res);

 out.close();

}
 public static  long pow(long b, long e) {
            long r = 1;
            while (e > 0) {
                if (e % 2 == 1) r = r * b ;
                b = b * b;
                e >>= 1;
            }
            return r;
        }
private static void sort(long[] arr) {
        List<Long> list = new ArrayList<>();
        for (long object : arr) list.add(object);
        Collections.sort(list);
        for (int i = 0; i < list.size(); ++i) arr[i] = list.get(i);
    }
 public static class FastReader {
        BufferedReader br;
        StringTokenizer root;

        public FastReader() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String next() {
            while (root == null || !root.hasMoreTokens()) {
                try {
                    root = new StringTokenizer(br.readLine());
                } catch (Exception addd) {
                    addd.printStackTrace();
                }
            }
            return root.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (Exception addd) {
                addd.printStackTrace();
            }
            return str;
        }
         public int[] nextIntArray(int arraySize) {
            int array[] = new int[arraySize];

            for (int i = 0; i < arraySize; i++) {
                array[i] = nextInt();
            }

            return array;
        }
}
static class pair{
    int i;
    int j;
pair(int i,int j){
    this.i=i;
    this.j=j;
}

}}


import java.util.*;
import java.math.*;
import java.io.*;
 public class A{

    static FastReader scan=new FastReader();
   public static PrintWriter out = new PrintWriter (new BufferedOutputStream(System.out));

//a
   static int n;
   static char orig[][];

   static int check(char arr[][]){
    int c=0;

    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
        if(arr[j][i]!='1')
            continue;
        if(j==n-1&&arr[j][i]=='1')
            c++;

}

    }
return c;
   }
   static int tmp=0;
   static int solve(int op){
    char arr[][]=new char[n][n];
            for(int l = 0; l <n; l++)
{
  for (int m = 0; m < n; m++)
  {
    arr[l][m] = orig[l][m];
  }
}

for(int i=0;i<n;i++){
   if(arr[op][i]=='1')
                arr[op][i]='0';
            else arr[op][i]='1';
     }
   tmp=Math.max(tmp,check(arr));

return tmp;
   }
public static void main(String[] args)  throws IOException
{
    int a1[]=new int[265];
    int a2[]=new int[265];
    char chars1[]=scan.next().toCharArray();
    char chars2[]=scan.next().toCharArray();
    for(int i=0;i<chars1.length;i++)
        a1[chars1[i]]++;
    for(int i=0;i<chars2.length;i++)
        a2[chars2[i]]++;
    int res=0;
    boolean ok=false;
    int min=0;
    //out.println(a1['s']);
    for(int i=0;i<265;i++){
        char c=(char)i;
        min = (a1[c]<a2[c])?a1[c]:a2[c];
        if(min==0&&a2[c]!=0)
        {
           res=0;
           break;
        }
        res+=min;
    }
    if(res==0)
        res--;
    out.println(res);

 out.close();

}
 public static  long pow(long b, long e) {
            long r = 1;
            while (e > 0) {
                if (e % 2 == 1) r = r * b ;
                b = b * b;
                e >>= 1;
            }
            return r;
        }
private static void sort(long[] arr) {
        List<Long> list = new ArrayList<>();
        for (long object : arr) list.add(object);
        Collections.sort(list);
        for (int i = 0; i < list.size(); ++i) arr[i] = list.get(i);
    }
 public static class FastReader {
        BufferedReader br;
        StringTokenizer root;

        public FastReader() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String next() {
            while (root == null || !root.hasMoreTokens()) {
                try {
                    root = new StringTokenizer(br.readLine());
                } catch (Exception addd) {
                    addd.printStackTrace();
                }
            }
            return root.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (Exception addd) {
                addd.printStackTrace();
            }
            return str;
        }
         public int[] nextIntArray(int arraySize) {
            int array[] = new int[arraySize];

            for (int i = 0; i < arraySize; i++) {
                array[i] = nextInt();
            }

            return array;
        }
}
static class pair{
    int i;
    int j;
pair(int i,int j){
    this.i=i;
    this.j=j;
}

}}


import java.util.*;
import java.math.*;
import java.io.*;
 public class A{

    static FastReader scan=new FastReader();
   public static PrintWriter out = new PrintWriter (new BufferedOutputStream(System.out));

   static int n;
   static char orig[][];

   static int check(char arr[][]){
    int c=0;

    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
        if(arr[j][i]!='1')
            continue;
        if(j==n-1&&arr[j][i]=='1')
            c++;

}

    }
return c;
   }
   static int tmp=0;
   static int solve(int op){
    char arr[][]=new char[n][n];
            for(int l = 0; l <n; l++)
{
  for (int m = 0; m < n; m++)
  {
    arr[l][m] = orig[l][m];
  }
}

for(int i=0;i<n;i++){
   if(arr[op][i]=='1')
                arr[op][i]='0';
            else arr[op][i]='1';
     }
   tmp=Math.max(tmp,check(arr));

return tmp;
   }
public static void main(String[] args)  throws IOException
{
    int a1[]=new int[265];
    int a2[]=new int[265];
    char chars1[]=scan.next().toCharArray();
    char chars2[]=scan.next().toCharArray();
    for(int i=0;i<chars1.length;i++)
        a1[chars1[i]]++;
    for(int i=0;i<chars2.length;i++)
        a2[chars2[i]]++;
    int res=1;
    boolean ok=false;
    for(int i=0;i<265;i++){
        char c=(char)i;
        if(a1[c]!=0)
        {
            if(a2[c]!=0&&a1[c]>=a2[c]){
                ok=true;
                res*=a2[c];
            }
        }
    }
    if(!ok)
        out.println(-1);
    else
    out.println(res);

 out.close();

}
 public static  long pow(long b, long e) {
            long r = 1;
            while (e > 0) {
                if (e % 2 == 1) r = r * b ;
                b = b * b;
                e >>= 1;
            }
            return r;
        }
private static void sort(long[] arr) {
        List<Long> list = new ArrayList<>();
        for (long object : arr) list.add(object);
        Collections.sort(list);
        for (int i = 0; i < list.size(); ++i) arr[i] = list.get(i);
    }
 public static class FastReader {
        BufferedReader br;
        StringTokenizer root;

        public FastReader() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String next() {
            while (root == null || !root.hasMoreTokens()) {
                try {
                    root = new StringTokenizer(br.readLine());
                } catch (Exception addd) {
                    addd.printStackTrace();
                }
            }
            return root.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (Exception addd) {
                addd.printStackTrace();
            }
            return str;
        }
         public int[] nextIntArray(int arraySize) {
            int array[] = new int[arraySize];

            for (int i = 0; i < arraySize; i++) {
                array[i] = nextInt();
            }

            return array;
        }
}
static class pair{
    int i;
    int j;
pair(int i,int j){
    this.i=i;
    this.j=j;
}

}}


import java.util.HashMap;
import java.util.Scanner;

public class test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner sc=new Scanner(System.in);
		String s1=sc.next();
		String s2=sc.next();
		HashMap<Character,Integer> input=new HashMap<>();
		HashMap<Character,Integer> output=new HashMap<>();

		for(int i=0;i<s1.length();i++) {
			char ch=s1.charAt(i);
			if(input.containsKey(ch)) {
				int val=input.get(ch);
				val++;
				input.put(ch, val);
			}
			else
				input.put(ch, 1);
		}
		for(int i=0;i<s2.length();i++) {
			char ch=s2.charAt(i);
			if(output.containsKey(ch)) {
				int val=output.get(ch);
				val++;
				output.put(ch, val);
			}
			else
				output.put(ch, 1);
		}

		for(char i: output.keySet()) {
			if(input.containsKey(i))
				continue;
			else {
				System.out.println(-1);
				System.exit(0);
			}
		}
		int ans=0;
		for(char i: output.keySet()){
			if(input.get(i)>=output.get(i))
				ans+=output.get(i);
			else {
				ans+=input.get(i);
			}
		}
		System.out.println(ans);

	}

}


import java.io.*;
import java.text.*;
import java.util.*;
import java.math.*;

public class CF408B {
	public static void main(String[] args) throws Exception {
		new CF408B().run();
	}

	public void run() throws Exception {
		FastScanner f = new FastScanner();
		PrintWriter out = new PrintWriter(System.out);
		///
		String fst = f.nextLine();
		String sec = f.nextLine();

		int[] sumfst = new int[26];
		int[] sumsec = new int[26];

		for(int i = 0; i < fst.length(); i++) {
			sumfst[fst.charAt(i) - 'a']++;
		}
		for(int i = 0; i < sec.length(); i++) {
			sumsec[sec.charAt(i) - 'a']++;
		}

		int tot = 0;
		for(int i = 0; i < 26; i++) {
			tot += Math.min(sumfst[i], sumsec[i]);
		}
		out.println(tot == 0 ? -1 : tot);

		///
		f.close();
		out.flush();
	}

	///
	static class FastScanner {
		public BufferedReader reader;
		public StringTokenizer tokenizer;

		public FastScanner() {
			reader = new BufferedReader(new InputStreamReader(System.in), 32768);
			tokenizer = null;
		}

		public String next() {
			while (tokenizer == null || !tokenizer.hasMoreTokens()) {
				try {
					tokenizer = new StringTokenizer(reader.readLine());
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
			return tokenizer.nextToken();
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}

		public long nextLong() {
			return Long.parseLong(next());
		}

		public double nextDouble() {
			return Double.parseDouble(next());
		}

		public String nextLine() {
			try {
				return reader.readLine();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}

		public void close() throws IOException {
			reader.close();
		}
	}
}


import java.io.*;
import java.text.*;
import java.util.*;
import java.math.*;

public class CF408B {
	public static void main(String[] args) throws Exception {
		new CF408B().run();
	}

	public void run() throws Exception {
		FastScanner f = new FastScanner();
		PrintWriter out = new PrintWriter(System.out);
		///

		char[] c = f.nextLine().toCharArray();

		int[] sumfst = new int[26];
		int[] sumsec = new int[26];

		for(char cc : c) {
			sumfst[cc - 'a']++;
		}

		c = f.nextLine().toCharArray();
		for(char cc : c) {
			sumsec[cc - 'a']++;
		}

		int tot = 0;
		for(int i = 0; i < 26; i++) {
			if(sumfst[i] == 0 && sumsec[i] != 0) {
				tot = -1;
				break;
			} else tot += Math.min(sumfst[i], sumsec[i]);
		}
		out.println(tot);

		///
		f.close();
		out.flush();
	}

	///
	static class FastScanner {
		public BufferedReader reader;
		public StringTokenizer tokenizer;

		public FastScanner() {
			reader = new BufferedReader(new InputStreamReader(System.in), 32768);
			tokenizer = null;
		}

		public String next() {
			while (tokenizer == null || !tokenizer.hasMoreTokens()) {
				try {
					tokenizer = new StringTokenizer(reader.readLine());
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
			return tokenizer.nextToken();
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}

		public long nextLong() {
			return Long.parseLong(next());
		}

		public double nextDouble() {
			return Double.parseDouble(next());
		}

		public String nextLine() {
			try {
				return reader.readLine();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}

		public void close() throws IOException {
			reader.close();
		}
	}
}