rt.
#include <bits/stdc++.h>
using namespace std;
const int N = 5e4 + 100;
int n, m, fa[N], now, head[N], cnt, f[N][30], depth[N], minn, q, dis[N][30];
bool vis[N];
struct Edge{
int to, nxt, k;
} e[N];
struct Node{
int x, y, z;
const bool operator < (const Node& e) const {
return z > e.z;
}
} a[N];
int find(int x ) {
return x == fa[x] ? x : fa[x] = find(fa[x]);
}
void merge(int x, int y) {
fa[find(x)] = find(y);
}
void add(int x, int y, int z) {
e[++cnt].to = y;
e[cnt].nxt = head[x];
e[cnt].k = z;
head[x] = cnt;
}
void dfs(int x, int y, int k) {
f[x][0] = y;
dis[x][0] = k;
vis[x] = 1;
depth[x] = depth[y] + 1;
for (int i = 1; i <= __lg(depth[x]); i++) {
f[x][i] = f[f[x][i - 1]][i - 1];
dis[x][i] = min(dis[x][i - 1], dis[f[x][i - 1]][i - 1]);
}
for (int i = head[x]; i; i = e[i].nxt) {
if(e[i].to == y) {
continue;
}
dfs(e[i].to, x, e[i].k);
}
}
int LCA(int x, int y) {
if (find(x) != find(y)) {
return -1;
}
if (depth[x] < depth[y]) {
swap(x, y);
}
while (depth[x] > depth[y]) {
minn = min(minn, dis[x][__lg(depth[x] - depth[y]) - 1]);
x = f[x][__lg(depth[x] - depth[y]) - 1];
}
if (x == y) {
return minn;
}
for (int i = __lg(depth[x]) - 1; i >= 0; i--) {
if (f[x][i] != f[y][i]) {
minn = min({minn, dis[x][i], dis[y][i]});
x = f[x][i];
y = f[y][i];
}
}
return min({minn, dis[x][0], dis[y][0]});
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
fa[i] = i;
}
for (int i = 1; i <= m; i++) {
cin >> a[i].x >> a[i].y >> a[i].z;
}
sort(a + 1, a + m + 1);
for (int i = 1; i <= m; i++) {
int nx = find(a[i].x);
int ny = find(a[i].y);
if (nx == ny) {
continue;
}
merge(nx, ny);
now++;
add(a[i].x, a[i].y, a[i].z);
add(a[i].y, a[i].x, a[i].z);
if (now == n - 1) {
break;
}
}
for (int i = 1; i <= n; i++) {
if (!vis[i]) {
dfs(i, 0, 0);
}
}
cin >> q;
for (int i = 1; i <= q; i++) {
int x, y;
minn = 1e9;
cin >> x >> y;
cout << LCA(x, y) << endl;
}
return 0;
}