求神犇救救蒟蒻吧!!!orz
#define N 10001
#define M 50001
#include <iostream>
#include <cstdio>
#include <cctype>
#include <algorithm>
using namespace std;
struct Edge {
int from, next, to, len;
bool operator < (const Edge& arg) const {
return len > arg.len;
}
} edge[M], tree[M];
int n, m, num_edge, num_tree, head_edge[N], dep[N], f[N][21], q, head_tree[N], fa[N], mi[N][21];
inline int read() {
register char c = getchar();
register int sign = 1, res = 0;
while (!isdigit(c)) sign = c == '-' ? -1 : 1, c = getchar();
while (isdigit(c)) res = res * 10 + c - 48, c = getchar();
return sign * res;
}
void add_edge(int u, int v, int w) {
edge[++num_edge].from = u;
edge[num_edge].to = v;
edge[num_edge].len = w;
edge[num_edge].next = head_edge[u];
head_edge[u] = num_edge;
}
void add_tree(int u, int v, int w) {
tree[++num_tree].from = u;
tree[num_tree].to = v;
tree[num_tree].len = w;
tree[num_tree].next = head_tree[u];
head_tree[u] = num_tree;
}
void preprocess(int u, int father) {
dep[u] = dep[father] + 1;
f[u][0] = father;
for (int i = 1; i <= 20; i++) {
f[u][i] = f[f[u][i - 1]][i - 1];
mi[u][i] = min(mi[u][i - 1], mi[f[u][i - 1]][i - 1]);
}
for (int i = head_tree[u]; i; i = tree[i].next) {
int v = tree[i].to;
if (v == father) continue;
mi[v][0] = tree[i].len;
preprocess(v, u);
}
}
int get_fa(int x) {
if (fa[x] == x) return x;
return fa[x] = get_fa(fa[x]);
}
int get_min(int x, int y) {
if (get_fa(x) != get_fa(y)) return -1;
if (dep[x] < dep[y]) swap(x, y);
int res = 0x7fffffff;
for (int i = 20; i >= 0; i--) {
if (dep[f[x][i]] >= dep[y]) {
res = min(res, mi[x][i]);
x = f[x][i];
}
if (x == y) return res;
}
for (int i = 20; i >= 0; i--) {
if (f[x][i] != f[y][i]) {
res = min(res, min(mi[x][i], mi[y][i]));
x = f[x][i];
y = f[y][i];
}
}
return min(res, min(mi[x][0], mi[y][0]));
}
void merge(int x, int y) {
fa[get_fa(x)] = get_fa(y);
}
void kruskal() {
for (int i = 1; i <= n; i++) fa[i] = i;
sort(edge + 1, edge + num_edge + 1);
for (int i = 1; i <= num_edge; i++) {
int u = edge[i].from, v = edge[i].to;
if (get_fa(u) != get_fa(v)) {
merge(u, v);
add_tree(u, v, edge[i].len);
add_tree(v, u, edge[i].len);
}
}
}
int main() {
n = read(), m = read();
for (int i = 1; i <= m; i++) {
int u = read(), v = read(), w = read();
add_edge(u, v, w);
add_edge(v, u, w);
}
kruskal();
for (int i = 1; i <= n; i++) {
if (fa[i] == i) preprocess(i, 0);
}
q = read();
for (int i = 1; i <= q; i++) {
int x = read(), y = read();
printf("%d\n", get_min(x, y));
}
return 0;
}