#include<bits/stdc++.h>
using namespace std;
const int N=1e5+2,M=3e5+2;
int n,m,a,b,l,q,fa[N],dep[N],p[N][51],maxn[N][51];
int head[2*N],nex[2*N],to[2*N],val[2*N],cnt;
struct node{
int u,v,w;
}edge[M];
int Find(int x)
{
if(fa[x]==x) return x;
return fa[x]=Find(fa[x]);
}
bool cmp(node a,node b)
{
return a.w<b.w;
}
void addedge(int u,int v,int w)
{
to[++cnt]=v;
nex[cnt]=head[u];
head[u]=cnt;
val[cnt]=w;
}
void dfs(int u)
{
for(int i=head[u];i;i=nex[i])
{
int v=to[i];
if(!dep[v])
{
dep[v]=dep[u]+1;
p[v][0]=u;
maxn[v][0]=val[i];
dfs(v);
}
}
}
void LCA()
{
for(int j=1;(1<<j)<=n;++j)
{
for(int i=1;i<=n;++i)
{
p[i][j]=p[p[i][j-1]][j-1];
maxn[i][j]=max(maxn[i][j-1],maxn[p[i][j-1]][j-1]);
}
}
}
int query(int u,int v)
{
int ans=0;
if(dep[u]<dep[v])swap(u,v);
for(int j=20;j>=0;--j)
if(p[u][j]&&dep[p[u][j]]>=dep[v])
{
ans=max(ans,maxn[u][j]);
u=p[u][j];
}
if(u==v) return ans;
for(int j=20;j>=0;--j)
{
if(p[u][j]!=p[v][j])
{
ans=max(ans,maxn[u][j]);
ans=max(ans,maxn[v][j]);
u=p[u][j];
v=p[v][j];
}
}
ans=max(ans,maxn[u][0]);
ans=max(ans,maxn[v][0]);
return ans;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;++i)
{
scanf("%d%d%d",&a,&b,&l);
edge[i]=(node){a,b,l};
}
sort(edge+1,edge+1+m,cmp);
for(int i=1;i<=n;++i) fa[i]=i;
for(int i=1;i<n;++i)
{
int u=edge[i].u,v=edge[i].v;
if(Find(u)==Find(v)) continue;
fa[Find(u)]=Find(v);
addedge(u,v,edge[i].w);
addedge(v,u,edge[i].w);
}
for(int i=1;i<=n;++i)
{
if(!dep[i])
{
dep[i]=1;
dfs(i);
}
}
LCA();
scanf("%d",&q);
for(int i=1;i<=q;++i)
{
scanf("%d%d",&a,&b);
if(Find(a)!=Find(b)) printf("impossible\n");
else printf("%d\n",query(a,b));
}
return 0;
}