1 #include<iostream>
2 #include<string>
3 #include<queue>
4 #include<stack>
5 #include<vector>
6 #include<map>
7 #include<cstdio>
8 #include<cstdlib>
9 #include<algorithm>
10 #include<set>
11 #include<iomanip>
12 #include<cstring>
13 #include<cmath>
14 #include<limits>
15 using namespace std;
16
17 #define au auto
18 #define debug(i) cout<<"<debug>"<<i<<"<\debug>"<<endl
19 #define mfor(i,a,b) for(register int i=(a);i<=(b);i++)
20 #define mrep(i,a,b) for(register int i=(a);i>=(b);i--)
21 #define LLL __int128
22 #define Re register
23 #define il inline
24 #define mem(a,b) memset(a,(b),sizeof(a))
25 typedef pair<int, int> intpair;
26 typedef long long int LL;
27 const int INF = 0x3f3f3f3f;
28 const long long int INFLL = 0x3f3f3f3f3f3f3f3f;
29
30 const int maxn = 100010;
31 int fa[maxn];
32
33 int find(int x)
34 {
35 if (fa[x] == x) return x;
36 fa[x] = find(fa[x]);
37 return fa[x];
38 }
39
40 void merge(int a, int b)
41 {
42 fa[find(a)] = find(b);
43 }
44
45 bool check(int a, int b)
46 {
47 return find(a) == find(b);
48 }
49
50 int n, m;
51 int cnt;
52
53 struct Edge
54 {
55 int u, nxt, w;
56 }tr[300010];
57
58 struct Edge1
59 {
60 int u, v, w;
61 bool operator>(Edge1 s)const
62 {
63 return w > s.w;
64 }
65 }e[300010];
66
67 int head[maxn];
68
69 void add(int a, int b, int w)
70 {
71 tr[++cnt].u = b;
72 tr[cnt].nxt = head[a];
73 head[a] = cnt;
74 tr[cnt].w = w;
75 }
76
77 void kruskal()
78 {
79 sort(e + 1, e + m + 1, greater<Edge1>());
80 mfor(i, 1, n) fa[i] = i;
81 int tot = 1;
82 mfor(i, 1, m)
83 {
84 if (!check(e[i].u, e[i].v))
85 {
86 merge(e[i].u, e[i].v);
87 add(e[i].u, e[i].v, e[i].w);
88 add(e[i].v, e[i].u, e[i].w);
89 if (++tot >= n)
90 {
91 break;
92 }
93 }
94 }
95 }
96
97 int d[maxn];
98 int dis[maxn];
99 int f[maxn][100];
100 int w[maxn][100];
101 int k;
102 int ans;
103
104 void dfs(int x)
105 {
106 for (int i = head[x]; i; i = tr[i].nxt)
107 {
108 int u = tr[i].u;
109 if (d[u]) continue;
110 d[u] = d[x] + 1;
111 f[u][0] = x;
112 w[u][0] = tr[i].w;
113 dfs(u);
114 }
115 }
116
117 int lca(int a, int b)
118 {
119 if (!check(a, b)) return -1;
120 ans = INF;
121 if (d[a] < d[b]) swap(a, b);
122 mrep(i, k, 0)
123 {
124 if (d[f[a][i]] >= d[b])
125 {
126 ans = min(ans, w[a][i]);
127 a = f[a][i];
128 }
129 }
130 if (a == b) return a;
131 mrep(i, k, 0)
132 {
133 if (f[a][i] != f[b][i])
134 {
135 ans = min(ans, min(w[a][i], w[b][i]));
136 a = f[a][i];
137 b = f[b][i];
138 }
139 }
140 ans = min(ans, min(w[a][0], w[b][0]));
141 return f[a][0];
142 }
143
144 int main()
145 {
146 cin >> n >> m;
147 k = (int)(log(n) / log(2)) + 1;
148 mfor(i, 1, m)
149 {
150 cin >> e[i].u >> e[i].v >> e[i].w;
151 }
152 kruskal();
153 mfor(i, 1, n)
154 {
155 if (!d[i])
156 {
157 d[i] = 1;
158 dfs(i);
159 f[i][0] = i;
160 w[i][0] = INF;
161 }
162 }
163 mfor(i, 1, k)
164 {
165 mfor(j, 1, n)
166 {
167 f[j][i] = f[f[j][i - 1]][i - 1];
168 w[j][i] = min(w[j][i - 1], w[f[j][i - 1]][i - 1]);
169 }
170 }
171 int T;
172 cin >> T;
173 mfor(i, 1, T)
174 {
175 int a, b;
176 cin >> a >> b;
177 int t = lca(a, b);
178 if (t == -1) cout << t << endl;
179 else cout << ans << endl;
180 }
181 }