#include <bits/stdc++.h>
using namespace std;
struct DSU{
int n;
vector<int> par;
DSU(){}
DSU(int _n){
n=_n;
par.assign(n+1,0);
iota(par.begin(),par.end(),0);
}
int find_set(int v){return v==par[v]?v:par[v]=find_set(par[v]);}
bool union_set(int u,int v){
u=find_set(u);
v=find_set(v);
if(u!=v){
par[u]=v;
return 1;
}
return 0;
}
};
int n,m,q;
vector<tuple<int,int,int>> edges;
DSU dsu0[30];
DSU dsu1[30];
bool good[100005];
int main(){
ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n>>m;
for(int i=0;i<30;i++){
dsu0[i]=DSU(n);
dsu1[i]=DSU(n);
}
for(int i=1;i<=m;i++){
int u,v,w;
cin>>u>>v>>w;
edges.push_back({u,v,w});
}
for(int j=0;j<30;j++){
for(auto [u,v,w]:edges){
if((w>>j)&1){
dsu0[j].union_set(u,v);
}
}
}
for(int j=1;j<30;j++){
for(auto [u,v,w]:edges){
if((w>>j)&1){
dsu1[j].union_set(u,v);
}
}
vector<int> vis(n+1);
for(auto [u,v,w]:edges){
if(!(w&1)){
vis[dsu1[j].find_set(u)]=1;
vis[dsu1[j].find_set(v)]=1;
}
}
for(int i=1;i<=n;i++){
if(vis[dsu1[j].find_set(i)]) good[i]=1;
}
}
cin>>q;
while(q--){
int u,v;
cin>>u>>v;
bool ok=0;
for(int j=0;j<30;j++){
if(dsu0[j].find_set(u)==dsu0[j].find_set(v)){
cout<<0<<'\n';
ok=1;
break;
}
}
if(ok) continue;
if(good[u]){
cout<<1<<'\n';
continue;
}
for(int j=1;j<30;j++){
if(dsu1[j].find_set(u)==dsu1[j].find_set(v)){
cout<<1<<'\n';
ok=1;
break;
}
}
if(!ok) cout<<2<<'\n';
}
}