#include<bits/stdc++.h>
#define endl '\n';
using namespace std;
int n,m;
const int N=1e4+10;
struct node{
int u,v,w;
friend bool operator <(const node a,const node b){
return a.w>b.w;
}
}a[5*N];
struct EDGE{
int v,w;
};
vector<EDGE>v[5*N];
int f[N];
int d[N],dp[N][40],w[N][40];
void init(){
for(int i=1;i<=n;i++){
f[i]=i;
}return;
}int _find(int x){
if(f[x]==x)return x;
f[x]=_find(f[x]);
return f[x];
}void _merge(int x,int y){
int fx=_find(x);
int fy=_find(y);
if(fx!=fy){
f[fx]=fy;
}return;
}void kruskal(){
int cnt=0;
for(int i=1;i<=m;i++){
int fx=_find(a[i].u);
int fy=_find(a[i].v);
if(fx!=fy){
_merge(fx,fy);
v[a[i].u].push_back({a[i].v,a[i].w});
v[a[i].v].push_back({a[i].u,a[i].w});
cnt++;
if(cnt==n-1){
return;
}
}
}return;
}void dfs(int x,int fa){
d[x]=d[fa]+1;
dp[x][0]=fa;
for(int i=0;i<=30;i++){
dp[x][i]=dp[dp[x][i-1]][i-1];
w[x][i]=min(w[x][i],w[dp[x][i-1]][i-1]);
}
for(auto i:v[x]){
if(i.v==fa)continue;
w[i.v][0]=i.w;
dfs(i.v,x);
}
}int lca(int x,int y){
if(_find(x)!=_find(y))return -1;
if(d[x]<d[y])swap(x,y);
int ans=0;
int cha=d[x]-d[y];
ans=1e9;
for(int i=30;i>=0;i--){
if((1<<i)<=cha){
cha-=(1<<i);
ans=min(ans,w[x][i]);
x=dp[x][i];
}
}if(x==y){
return ans;
}for(int i=30;i>=0;i--){
if((1<<i)<=d[x]&&dp[x][i]!=dp[y][i]){
ans=min(ans,w[x][i]);
x=dp[x][i];
ans=min(ans,w[y][i]);
y=dp[y][i];
}
}return min(ans,min(w[x][0],w[y][0]));
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
init();
memset(w,0x3f,sizeof(w));
for(int i=1;i<=m;i++){
cin>>a[i].u>>a[i].v>>a[i].w;
}kruskal();
for(int i=1;i<=n;i++){
if(!d[i]){
dfs(i,0);
}
}
int q;
cin>>q;
while(q--){
int x,y;
cin>>x>>y;
cout<<lca(x,y)<<endl;
}
return 0;
}