rt
#include <bits/stdc++.h>
using namespace std ;
const int MAXN = 5e4 + 10 ;
struct edge {
int x, y, w ;
}e[MAXN] ;
struct node {
int to, w ;
} ;
vector<node> g[MAXN] ;
inline bool cmp (edge a, edge b) {
return a.w > b.w ;
}
int fa[MAXN], dep[MAXN], f[MAXN][25], val[MAXN], k[MAXN][25] ;
inline int find (int x) {
if (x == fa[x]) return x ;
return fa[x] = find(fa[x]) ;
}
inline void dfs (int x, int fa) {
for (auto i : g[x]) {
int v = i.to ;
if (v == fa) continue ;
dep[v] = dep[x] + 1 ;
val[v] = i.w ;
k[v][0] = x ;
f[v][0] = i.w ;
dfs(v, x) ;
}
}
inline int query (int x, int y) {
if (find(x) != find(y)) return -1 ;
if (dep[x] < dep[y]) swap(x, y) ;
int ans = 1000000007 ;
for (int i = 20 ; i >= 0 ; i--) {
if (dep[k[x][i]] >= dep[y]) {
ans = min (ans, f[x][i]) ;
x = k[x][i] ;
}
}
if (x == y) return ans ;
for (int i = 20 ; i >= 0 ; i--) {
if (k[x][i] != k[y][i]) {
ans = min (ans, f[x][i]) ;
ans = min (ans, f[y][i]) ;
x = k[x][i] ;
y = k[y][i] ;
}
}
ans = min(ans, min(f[x][0], f[y][0])) ;
return ans ;
}
int main () {
int n, m ;
cin >> n >> m ;
for (int i = 1 ; i <= m ; i++) cin >> e[i].x >> e[i].y >> e[i].w ;
sort(e + 1, e + m + 1, cmp) ;
int tot = 0, sum = 0 ;
for (int i = 1 ; i <= n ; i++) fa[i] = i ;
for (int i = 1 ; i <= m ; i++) {
int x = find(e[i].x), y = find(e[i].y) ;
if (x == y) continue ;
fa[x] = y ;
g[e[i].x].push_back({e[i].y, e[i].w}) ;
g[e[i].y].push_back({e[i].x, e[i].w}) ;
sum += e[i].w ;
if (++tot == n - 1) break ;
}
for (int i = 1 ; i <= MAXN ; i++)
for (int j = 1 ; j <= 20 ; j++) f[i][j] = 1000000007 ;
dep[1] = 1 ;
dfs(1, 0) ;
for (int j = 1 ; j <= 20 ; j++) {
for (int i = 1 ; i <= n ; i++) f[i][j] = min(f[i][j - 1], f[f[i][j - 1]][j - 1]) ;
}
for (int j = 1 ; j <= 20 ; j++) {
for (int i = 1 ; i <= n ; i++) k[i][j] = k[k[i][j - 1]][j - 1] ;
}
int q, x, y ;
cin >> q ;
while (q--) {
cin >> x >> y ;
cout << query(x, y) << '\n' ;
}
return 0 ;
}