#include <bits/stdc++.h>
using namespace std;
const int maxn=100010;
struct edge{
int u,v,w;
}a[maxn*5];
bool cmp(edge a,edge b){
return a.w>b.w;
}
struct node{
int v;
int w;
};
int n,m,sum;
vector<node> e[maxn];
int fa[maxn],w[maxn],vis[maxn];
int deep[maxn],jump[maxn][25];
int dis[maxn],val[maxn][25];
int find(int k){
if(fa[k]==k) return k;
return fa[k]=find(fa[k]);
}
void kruskal(){
sort(a+1,a+m+1,cmp);
for (int i=1;i<=n;i++){
fa[i]=i;
}
for (int i=1;i<=m;i++){
if (find(a[i].u) != find(a[i].v)){
int x=a[i].u,y=a[i].v;
e[y].push_back(node{x,a[i].w});
e[x].push_back(node{y,a[i].w});
fa[find(a[i].u)] = find(a[i].v);
}
}
}
void bfs(int i){
memset(deep,0x3f,sizeof(deep));
deep[0]=0;
deep[i]=1;
vis[i]=1;
queue<int> q;
q.push(i);
while (!q.empty()){
int x = q.front();
q.pop();
for (node y : e[x]){
vis[y.v]=1;
int i=y.v;
if (deep[i]<deep[x]){
continue;
}
q.push(i);
deep[i] = deep[x]+1;
val[i][0]=y.w;
jump[i][0]=x;
for (int j=1;j<=22;j++){
jump[i][j]=jump[jump[i][j-1]][j-1];
val[i][j]=min(val[i][j-1],val[jump[i][j-1]][j-1]);
}
}
}
}
int lca(int a,int b){
int ans=0x3f3f3f3f3f3f3f3f;
if(deep[a]<deep[b]) swap(a,b);
for (int i=20;i>=0;i--){
if (deep[jump[a][i]]>=deep[b]){
ans=min(ans,val[a][i]);
a=jump[a][i];
}
}
if(a==b) return ans;
for (int i=20;i>=0;i--){
if (jump[a][i]!=jump[b][i]){
ans=min(ans,min(val[a][i],val[b][i]));
a=jump[a][i];
b=jump[b][i];
}
}
ans=min(ans,min(val[a][0],val[b][0]));
return ans;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w);
}
int q;
scanf("%d",&q);
memset(val,0x3f,sizeof(val));
kruskal();
for (int i=1;i<=n;i++){
if (!vis[i]) bfs(i);
}
for(int i=1; i<=q; i++){
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",lca(x,y));
}
return 0;
}