#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const int inf = 0x3f3f3f3f;
struct Edge{
int u, v, w;
bool operator <(const Edge &a) const{
return w > a.w;
}
};
struct Node{
int x, w;
};
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int n, m;
cin >> n >> m;
vector<Edge> g;
vector<int> pre(n + 1);
vector<vector<Node>> e(n + 1);
for(int i = 1; i <= m; i ++){
int u, v, w;
cin >> u >> v >> w;
g.push_back({u, v, w});
}
sort(g.begin(), g.end());
for(int i = 1; i <= n; i ++) pre[i] = i;
function <int(int)> find = [&](int x){
return pre[x] = (x == pre[x] ? x : find(pre[x]));
};
for(const auto &t : g){
int u = t.u, v = t.v, w = t.w;
if(find(u) != find(v)){
pre[pre[u]] = pre[v];
e[u].push_back({v, w});
e[v].push_back({u, w});
}
}
vector<int> dep(n + 1);
vector<vector<int>> fa(n + 1, vector<int>(15)), load(n + 1, vector<int>(15, inf));
int mdep = 0;
function <void(int, int)> dfs = [&](int x, int p){
dep[x] = dep[p] + 1;
mdep = max(mdep, dep[x]);
fa[x][0] = p;
for(const auto &t : e[x]){
int v = t.x, w = t.w;
if(v == p) continue;
dfs(v, x);
load[v][0] = w;
}
};
for(int i = 1; i <= n;i ++) if(!dep[i]) dfs(i, 0);
mdep = log(mdep)/log(2) + 1;
for(int i = 1; i <= mdep; i ++){
for(int j = 1; j <= n; j ++){
fa[j][i] = fa[fa[j][i - 1]][i - 1];
load[j][i] = min(load[j][i - 1], load[fa[j][i - 1]][i - 1]);
}
}
function <int(int, int)> lca = [&](int x, int y){
if(find(x) != find(y)) return -1;
int res = inf;
if(dep[x] < dep[y]) swap(x, y);
for(int i = mdep; i >= 0; i --) if(dep[fa[x][i]] >= dep[y]) res = min(res, load[x][i]), x = fa[x][i];
if(x == y) return res;
for(int i = mdep; i >= 0; i --){
if(fa[x][i] != fa[y][i]){
res = min(res, load[x][i]);
res = min(res, load[y][i]);
x = fa[x][i], y = fa[y][i];
}
}
res = min(res, load[x][0]);
res = min(res, load[y][0]);
return res;
};
int q;
cin >> q;
while(q --){
int x, y;
cin >> x >> y;
cout << lca(x, y);
}
return 0;
}