RT
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MAXN=2e6;
ll t,n,m,x,y,z;
struct Graph{
struct edge{
ll u,v,w,nxt;
}e[MAXN];
ll head[MAXN],edge_num;
ll dfn[MAXN],low[MAXN],cnt,st[MAXN],top,scc[MAXN];
bool in_stack[MAXN];
void init(ll N,ll M){
for(int i=1;i<=N;i++)head[i]=dfn[i]=low[i]=st[i]=scc[i]=in_stack[i]=0;
for(int i=1;i<=(M<<2);i++)e[i]=(edge){0,0,0,0};
edge_num=cnt=top=0;
return;
}
void add_edge(ll From,ll To,ll Len){
edge_num++;
// cout<<"debug "<<From<<" "<<To<<" "<<Len<<" "<<head[From]<<'\n';
e[edge_num]=(edge){From,To,Len,head[From]};
head[From]=edge_num;
return;
}
void tarjan(ll now){
dfn[now]=low[now]=++cnt,st[++top]=now,in_stack[now]=1;
for(int i=head[now];i;i=e[i].nxt){
if(!dfn[e[i].v]){
tarjan(e[i].v);
low[now]=min(low[now],low[e[i].v]);
}
else if(in_stack[e[i].v])low[now]=min(low[now],dfn[e[i].v]);
}
if(dfn[now]==low[now]){
ll pos;
while(pos=st[top--]){
scc[pos]=now;
in_stack[now]=0;
if(pos==now)break;
}
}
return;
}
}G,tmp,dag;
ll fa[MAXN];
ll Find(ll num){
return fa[num]==num?num:fa[num]=Find(fa[num]);
}
ll in[MAXN];
bool check(ll num){
tmp=G;
for(int i=1;i<=G.edge_num;i++)if(tmp.e[i].w<=num)tmp.add_edge(tmp.e[i].v,tmp.e[i].u,tmp.e[i].w);
for(int i=1;i<=n;i++)if(!tmp.dfn[i])tmp.tarjan(i);
for(int i=1;i<=n;i++)in[i]=0;
dag.init(n,m);
for(int i=1;i<=tmp.edge_num;i++){
if(tmp.scc[tmp.e[i].u]==tmp.scc[tmp.e[i].v])continue;
in[tmp.scc[tmp.e[i].v]]++;
}
ll pos=0;
for(int i=1;i<=n;i++){
if(i!=tmp.scc[i])continue;
if(in[i]==0){
if(pos)return 0;
pos=i;
}
}
return pos;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>t;
while(t--){
cin>>n>>m;
G.init(n,m);
for(int i=1;i<=n;i++)fa[i]=i;
ll L=0,R=0,mid;
for(int i=1;i<=m;i++){
cin>>x>>y>>z;
G.add_edge(x,y,z);
fa[Find(x)]=Find(y);
R=max(R,z);
}
bool fl=0;
for(int i=2;i<=n;i++)if(Find(i)!=Find(1)){
fl=1;
break;
}
if(fl==1){
cout<<"-1\n";
continue;
}
while(L<=R){
mid=(L+R)>>1;
if(check(mid))R=mid-1;
else L=mid+1;
}
cout<<L<<'\n';
}
return 0;
}