//临时学的tarjan离线LCA,解题报告有空补上,ps:并查集类很给力
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<climits>
#include<vector>
using namespace std;
const int V=40010,E=V*2,Q=20010;
class UnionFindSet
{
public:
UnionFindSet(){}
UnionFindSet(int n):father(n,-1),num(n,1){}
int Union(int a,int b)
{
int u1=Find(a),u2=Find(b);
return father[u2]=u1;
}
int Find(int a)
{
return father[a]==-1?a:(father[a]=Find(father[a]));
}
void assign(int n)
{
father.assign(n,-1);
num.assign(n,1);
}
private:
std::vector<int> father;
std::vector<int> num;
};
bool vis[V];
UnionFindSet s;
int ans[Q],dis[V];
vector<pair<int,int> > edge[V];
vector<pair<int,int> > query[V];
void tarjan(int u,int fa)
{
vis[u]=1;
for(int i=0;i<query[u].size();i++)
{
int v=query[u][i].first;
if(vis[v])
{
ans[query[u][i].second]=dis[u]+dis[v]-2*dis[s.Find(v)];
}
}
for(int i=0;i<edge[u].size();i++)
{
int v=edge[u][i].first;
if(v==fa)continue;
dis[v]=dis[u]+edge[u][i].second;
tarjan(v,u);
s.Union(u,v);
}
}
int main()
{
//freopen("in.txt","r",stdin);
int v,e,a,b,l,n;
char c;
scanf("%d%d",&v,&e);
s.assign(v+1);
for(int i=0;i<e;i++)
{
scanf("%d%d%d %c",&a,&b,&l,&c);
edge[a].push_back(make_pair(b,l));
edge[b].push_back(make_pair(a,l));
}
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%d%d",&a,&b);
query[a].push_back(make_pair(b,i));
query[b].push_back(make_pair(a,i));
}
tarjan(1,-1);
for(int i=0;i<n;i++)
printf("%d\n",ans[i]);
}