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 }