#include<map>

#include<set>

#include<stack>

#include<queue>

#include<string>

#include<cstdio>

#include<vector>

#include<cctype>

#include<cassert>

#include<utility>

#include<numeric>

#include<cstring>

#include<iostream>

#include<algorithm>

using namespace std;

#define pr pair

#define MP make_pair

#define SI(x) set<x>::iterator

#define VI(x) vector<x>::iterator

#define MI(x,y) map<x,y>::iterator

#define SRI(x) set<x>::reverse_iterator

#define VRI(x) vector<x>::reverse_iterator

#define MRI(x,y) map<x,y>::reverse_iterator

#define F first

#define S second

#define clrQ(x) while(!x.empty)x.pop();

#define clrA(x,y) memset(x,y,sizeof(x));

#if defined (_WIN32) || defined (__WIN32) || defined (WIN32) || defined (__WIN32__)

#define LL __int64

#define LLS "%" "I" "6" "4" "d"

#define LLU "%" "I" "6" "4" "u"

#define LL_MAX _I64_MAX

#else

#define LL long long

#define LLS "%" "l" "l" "d"

#define LLU "%" "l" "l" "u"

#define LL_MAX _I64_MAX

#endif

const int inf = ~0u >> 1;

const LL lnf = ~0ull >> 1;

#define N 40005

#define M 40005

int n, m;

int head[N], pos;

struct Edge {

int v, w, nxt;

} e[M << 1];

void initEdge() {

memset(head, -1, sizeof(head));

pos = 0;

}

void add(int u, int v, int w) {

e[pos].v = v;

e[pos].w = w;

e[pos].nxt = head[u];

head[u] = pos++;

}

int dpM[20][N<<1|1];

int lg2[N<<1|1];

#define getLeft(R,L) (R-(L)+1)

void initRMQ(int n) {

lg2[0]=-1;int limit;

for(int i=1;i<=n;i++) {

lg2[i]=(i&(i-1))?lg2[i-1]:lg2[i-1]+1;

}

for(int i=1;i<=lg2[n];i++){

limit=getLeft(n,1<<i);

for(int j=1;j<=limit;j++){

dpM[i][j]=min(dpM[i-1][j],dpM[i-1][j+(1<<i>>1)]);

}

}

}

int getRMQ(int a,int b) {

int t=lg2[b-a+1];

int s1=a;

int s2=getLeft(b,1<<t);

return min(dpM[t][s1],dpM[t][s2]);

}

#undef getLeft

int dist[N];

int H[N];

int E[N<<1|1];

int cnt,depth;

int findRoot(){

for(int i=1;i<=n;i++)return i;

return -1;

}

void getEuler(int u=findRoot(),int fa=-1){

int tmp=dpM[0][H[u]=++cnt]=++depth;

E[tmp]=u;

for(int i=head[u];~i;i=e[i].nxt){

int v=e[i].v;

if(v==fa)continue;

dist[v]=dist[u]+e[i].w;

getEuler(v,u);

dpM[0][++cnt]=tmp;

}

}

void initLCA(){

memset(dist,0,sizeof(dist));

cnt=depth=0;

getEuler();

initRMQ(cnt);

}

int getLCA(int u,int v){

if(H[u]>H[v])swap(u,v);

return E[getRMQ(H[u],H[v])];

}

int main() {

while (~scanf("%d%d", &n, &m)) {

int u, v, w;

char c;

initEdge();

for (int i = 1; i <= m; i++) {

scanf("%d%d%d %c", &u, &v, &w, &c);

add(u, v, w);

add(v, u, w);

}

initLCA();

scanf("%d",&m);

while(m--){

scanf("%d%d",&u,&v);

printf("%d\n",dist[u]+dist[v]-2*dist[getLCA(u,v)]);

}

}

}