使用知识点:二分,并查集 先存边,然后排序,(不排序也可以ac,但是数据一大就会te) 可以用结构体存,我这里是用tuple,个人觉得tuple比结构体容易写一点 然后二分判断长度是否满足, 注意在检验两个点是否联通的时候是调用find去判断(一开始手抽用f[a]!=f[b]调了半天)

*/
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define if1(x) for(int i =1 ;i<=x;i++)
#define if0(x) for(int i = 0;i<x;i++)
#define jf0(x) for(int j = 0;j<x;j++)
#define jf1(x) for(int j = 1;j<=x;j++)
const int mod = 1e9+7;
const int inf = 0x3f3f3f;
int f[100009];
vector<tuple<int,int,int> >wedg;
vector<vector<int>> reque;
int m,n,a,b,c,k;
bool cmp(tuple<int,int,int>x,tuple<int,int,int> y){
    auto[xa,xb,xc] = x;
    auto [ya,yb,yc] = y;
    return xc<yc;
}
int find(int x){
    if(f[x]!=x)
    f[x] = find(f[x]);
    return f[x];
}

bool isac(int x){
    if0(n+1) f[i] = i;
    if0(x+1){
        auto it = wedg[i];
        auto [a1,b1,c1] = it;
            f[find(a1)] = f[find(b1)];
    }
    if0(k){
        int no = find(reque[i][0]);
        for(auto jj:reque[i]){
            if(find(jj)!=no)return false;
        }
    }
    return true;

}
int main(){
    //ios::sync_with_stdio(false);
    cin.tie(nullptr); 
    cin>>n>>m;
    if0(m){
        cin>>a>>b>>c;
        wedg.push_back(make_tuple(a,b,c));
    }
    sort(wedg.begin(),wedg.end(),cmp);    
    cin>>k;
    if0(k){
        vector<int >temp;
        int tt,yt;
        cin>>tt;
        if0(tt){
            cin>>yt;
            temp.push_back(yt);
        }
        reque.push_back(temp);

    }
    int l = 0,r = m-1;
    while(l<r){
        int mid = (l+r)/2;
        bool flag= isac(mid);
        if(flag){
            r = mid;
        }
        else l = mid+1;
    }
    cout<<get<2>(wedg[l])<<endl;
    
    return 0;
}