#include <cstdio>
#include <algorithm>
using namespace std;
const int INF = 0x7fffffff;
const int MAXN = 50001;
const int MAXM = 50001;
const int MAXLOG = 21;
struct Edge {
int from;
int to;
int val;
} edge[MAXN];
struct CFS {
int to;
int next;
int val;
} mst[MAXM * 2];
int n, m, x, y, z, q;
int head[MAXN], tot;
int fa[MAXN], dep[MAXN];
int anc[MAXN][MAXLOG], w[MAXN][MAXLOG];
bool vis[MAXN];
void add(int from, int to, int val) {
mst[++tot].to = to;
mst[tot].val = val;
mst[tot].next = head[from];
head[from] = tot;
}
bool cmp(Edge x, Edge y) {
return x.val > y.val;
}
int find(int x) {
if (fa[x] != x) fa[x] = find(fa[x]);
return fa[x];
}
void kruskal() {
for (int i = 1; i <= n; i++) fa[i] = i;
sort(edge + 1, edge + m + 1, cmp);
for (int i = 1; i <= m; i++) {
int f = find(edge[i].from), t = find(edge[i].to);
if (f != t) {
add(edge[i].from, edge[i].to, edge[i].val);
add(edge[i].to, edge[i].from, edge[i].val);
fa[f] = t;
}
}
}
void dfs(int x) {
vis[x] = 1;
for (int i = head[x]; i; i = mst[i].next) {
int to = mst[i].to;
if (!vis[to]) {
dep[to] = dep[x] + 1;
anc[to][0] = x;
w[to][0] = mst[i].val;
dfs(to);
}
}
}
void init() {
for (int i = 1; i < MAXLOG; i++)
for (int j = 1; j <= n; j++) {
anc[j][i] = anc[anc[j][i - 1]][i - 1];
w[j][i] = min(w[j][i - 1], w[anc[j][i - 1]][i - 1]);
}
}
int getlca(int x, int y) {
if (find(x) != find(y)) return -1;
int ans = INF;
if (dep[x] < dep[y]) swap(x, y);
for (int i = MAXLOG - 1; i >= 0; i--)
if (dep[anc[x][i]] >= dep[y]) {
ans = min(ans, min(w[x][i], w[y][i]));
x = anc[x][i];
}
ans = min(ans, min(w[x][0], w[y][0]));
return ans;
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; i++) {
scanf("%d%d%d", &x, &y, &z);
edge[i].from = x;
edge[i].to = y;
edge[i].val = z;
}
kruskal();
for (int i = 1; i <= n; i++)
if (!vis[i]) {
dep[i] = 1;
dfs(i);
anc[i][0] = 1;
w[i][0] = INF;
}
init();
scanf("%d", &q);
for (int i = 1; i <= q; i++) {
scanf("%d%d", &x, &y);
printf("%d\n", getlca(x, y));
}
return 0;
}