#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
const int kMaxN = 2e5 + 1, kMaxL = 20;
int n, m, sum;
struct Side {
int u, v, w;
friend bool operator>(Side a, Side b) {
return a.w > b.w;
}
} s[kMaxN];
struct V {
int d, f[20], st[20];
vector<pair<int, int>> e;
} v[kMaxN];
class DSU {
private:
static const int kMaxN = 2e5 + 1;
int n;
vector<int> f;
public:
DSU() {}
DSU(int size) {
n = size;
f.clear();
for (int i = 0; i <= n; i++) {
f.push_back(i);
}
}
int Find(int x) {
return f[x] == x ? x : f[x] = Find(f[x]);
}
bool Union(int x, int y) {
int fx = Find(x), fy = Find(y);
if (fx == fy) {
return 0;
} else {
f[f[y]] = f[x];
return 1;
}
}
bool Same(int x, int y) {
return Find(x) == Find(y);
}
};
void Kruskal(DSU dsu) {
sort(s + 1, s + m + 1, greater<Side>());
for (int i = 1; i <= m; i++) {
if (dsu.Union(s[i].u, s[i].v)) {
sum += s[i].w;
v[s[i].u].e.push_back({s[i].v, s[i].w});
v[s[i].v].e.push_back({s[i].u, s[i].w});
}
}
}
void Walk(int x, int f) {
v[x].f[0] = f, v[x].d = v[f].d + 1;
for (pair<int, int> i : v[x].e) {
if (i.first != f) {
v[i.first].st[0] = i.second;
Walk(i.first, x);
}
}
}
void CalcF() {
for (int j = 0; j < kMaxL - 1; j++) {
for (int i = 1; i <= n; i++) {
v[i].f[j + 1] = v[v[i].f[j]].f[j];
v[i].st[j + 1] = min(v[i].st[j], v[v[i].f[j]].st[j]);
}
}
}
int Query(int x, int y) {
int ans = 1e9;
if (v[x].d > v[y].d) {
swap(x, y);
}
for (int i = 0; i < kMaxL; i++) {
if (((v[y].d - v[x].d) >> i) & 1) {
ans = min(ans, v[y].st[i]);
y = v[y].f[i];
}
}
for (int i = kMaxL - 1; i >= 0; i--) {
if (v[x].f[i] != v[y].f[i]) {
ans = min({ans, v[x].st[i], v[y].st[i]});
x = v[x].f[i], y = v[y].f[i];
}
}
return x == y ? ans : min({ans, v[x].st[0], v[y].st[0]});
}
int main() {
cin >> m >> n;
for (int i = 1; i <= m; i++) {
cin >> s[i].u >> s[i].v >> s[i].w;
}
DSU dsu(n);
Kruskal(dsu);
for (int i = 1; i <= n; i++) {
if (!v[i].d) {
Walk(i, 0);
}
}
CalcF();
int q;
cin >> q;
for (int x, y; q; q--) {
cin >> x >> y;
cout << (dsu.Same(x, y) ? Query(x, y) : -1) << '\n';
}
return 0;
}