#include <iostream>
#include <algorithm>
#include <vector>
#include <string.h>
using namespace std;
struct node1
{
int x , y , z;
}in_g[50005];
struct node2
{
int y , z;
};
int n , m , q , cnt ,f[10005] , depth[10005] , fa[10005][30] , w[10005][30] , vis[10005];
vector <node2> g[10005];
bool cmp (node1 a , node1 b)
{
return a.z > b.z;
}
void link (int x , int y , int z)
{
cnt++;
in_g[cnt].x = x;
in_g[cnt].y = y;
in_g[cnt].y = z;
return;
}
void init ()
{
int x , y , z;
scanf("%d%d" , &n , &m);
for (int i = 1 ; i <= m ; i++)
{
scanf("%d%d%d" , &x , &y , &z);
link(x,y,z);
}
return;
}
int find (int x)
{
if(f[x] == x) return f[x];
return f[x] = find (f[x]);
}
void kruskal()
{
sort (in_g+1 , in_g+m+1 , cmp);
for (int i = 1 ; i <= n ; i++) f[i] = i;
int x , y , z;
for (int i = 1 ; i <= cnt ; i++)
{
x = in_g[i].x;
y = in_g[i].y;
z = in_g[i].z;
if (find(x) != find(y))
{
f[find(x)] = find(y);
g[x].push_back(node2{y,z});
g[y].push_back(node2{x,z});
}
}
return;
}
void dfs (int x)
{
vis[x] = true;
for (auto i : g[x])
{
if (vis[i.y]) continue;
depth[i.y] = depth[x]+1;
fa[i.y][0] = x;
w[i.y][0] = i.z;
dfs(i.y);
}
return;
}
int lca (int x , int y)
{
if (find(x) != find(y)) return -1;
if (depth[x] < depth[y]) swap(x , y);
int ans = 1e9;
for (int i = 20 ; i >= 0 ; i--)
if (depth[fa[x][i] >= depth[y]])
ans = min(ans , w[x][i]) , x = fa[x][i];
if (x == y) return ans;
for (int i = 20 ; i >= 0 ; i++)
{
if (fa[x][i] == fa[y][i]) continue;
ans = min(ans , min(w[x][i] , w[y][i]));
x = fa[x][i];
y = fa[y][i];
}
ans = min(ans , min(w[x][0] , w[y][0]));
return ans;
}
int main()
{
init();
kruskal();
for(int i = 1; i <= n; i++)
if(!vis[i])
{
depth[i] = 0;
dfs(i);
}
for (int i = 1 ; i <= 20 ; i++)
for (int j = 1 ; j <= n ; j++)
{
fa[j][i] = fa[fa[j][i-1]][i-1];
w[j][i] = min (w[j][i-1] , w[fa[j][i-1]][i-1]);
}
int x , y;
scanf("%d", &q);
for(int i = 1; i <= q; i++)
{
scanf("%d%d", &x , &y);
printf("%d\n", lca(x,y));
}
return 0;
}