#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define N 200005
#define INF (1ll<<60)
using namespace std;
typedef long long LL;
namespace Segment_Tree {
struct Node {
Node* ch[2];
int l,r;
LL v;
Node() {}
Node(int _l,int _r):l(_l),r(_r),v(INF) {
ch[0]=ch[1]=NULL;
}
void* operator new(size_t) {
static Node *mempool,*C;
if(mempool==C) mempool=(C=new Node[1<<20])+(1<<20);
return C++;
}
}*root;
void Init(Node*& o,int l,int r) {
o=new Node(l,r);
if(l==r) return ;
int mid=l+r>>1;
Init(o->ch[0],l,mid), Init(o->ch[1],mid+1,r);
return ;
}
void Change(Node* o,int l,int r,LL v) {
if(o->l==l && o->r==r) {
o->v=min(o->v,v);
return ;
}
int mid=o->l+o->r>>1;
if(r<=mid) Change(o->ch[0],l,r,v);
else if(l>mid) Change(o->ch[1],l,r,v);
else Change(o->ch[0],l,mid,v), Change(o->ch[1],mid+1,r,v);
return ;
}
LL Query(Node* o,int pos) {
if(o->l==o->r) return o->v;
int mid=o->l+o->r>>1,dir=pos<=mid?0:1;
return min(Query(o->ch[dir],pos),o->v);
}
}
#define ST Segment_Tree
struct Data {
int ord;
LL val;
Data() {}
Data(int _ord,LL _val):ord(_ord),val(_val) {}
bool operator < (const Data& rhs) const {
return val>rhs.val;
}
};
struct Edge {
int from,to,nxt,val;
Edge() {}
Edge(int _from,int _to,int _nxt,int _val):
from(_from),to(_to),nxt(_nxt),val(_val) {}
}e[N*2];
int n,m,tot,S,T,Q,top,fir[N],fromS[N],fromT[N],seq[N],pos[N];
LL distS[N],distT[N],ans[N];
void Add_Edge(int u,int v,int c) {
e[++tot]=Edge(u,v,fir[u],c), fir[u]=tot;
e[++tot]=Edge(v,u,fir[v],c), fir[v]=tot;
return ;
}
void Dijkstra(int st,LL dist[]) {
static bool k[N];
priority_queue<Data> q;
for(int i=1;i<=n;++i) dist[i]=INF, k[i]=false;
dist[st]=0, q.push(Data(st,0));
while(!q.empty()) {
Data tmp=q.top(); q.pop();
int x=tmp.ord;
if(k[x]) continue;
k[x]=true;
for(int i=fir[x];~i;i=e[i].nxt) {
if(dist[e[i].to]<=dist[x]+e[i].val) continue;
dist[e[i].to]=dist[x]+e[i].val;
q.push(Data(e[i].to,dist[e[i].to]));
}
}
return ;
}
void Find_path() {
int x=S;
while(x!=T) {
seq[++top]=x;
pos[x]=top;
for(int i=fir[x];~i;i=e[i].nxt) {
if(distT[e[i].to]+e[i].val>distT[x]) continue;
x=e[i].to;
break;
}
}
seq[++top]=x, pos[x]=top;
return ;
}
void bfs(int ord,LL dist[],int from[]) {
int st=seq[ord];
queue<int> q;
q.push(st);
while(!q.empty()) {
int x=q.front(); q.pop();
for(int i=fir[x];~i;i=e[i].nxt)
if(!from[e[i].to] && dist[e[i].to]==dist[x]+e[i].val)
from[e[i].to]=ord, q.push(e[i].to);
}
return ;
}
void calc_from() {
for(int i=1;i<=top;++i) fromS[seq[i]]=fromT[seq[i]]=i;
for(int i=1;i<=top;++i) bfs(i,distS,fromS);
for(int i=top;i;--i) bfs(i,distT,fromT);
return ;
}
int main() {
memset(fir,-1,sizeof fir), tot=-1;
scanf("%d%d",&n,&m);
for(int i=1,x,y,z;i<=m;++i)
scanf("%d%d%d",&x,&y,&z), Add_Edge(x,y,z);
scanf("%d%d",&S,&T);
Dijkstra(S,distS), Dijkstra(T,distT);
Find_path(), calc_from();
ST::Init(ST::root,1,top-1);
for(int i=0;i<=tot;++i) {
int from=e[i].from,to=e[i].to;
if(pos[from] && pos[to] && abs(pos[from]-pos[to])==1) continue;
if(fromS[from] && fromT[to] && fromS[from]<fromT[to]) ST::Change(ST::root,fromS[from],fromT[to]-1,distS[from]+e[i].val+distT[to]);
}
for(int i=1;i<top;++i) ans[i]=ST::Query(ST::root,i);
for(scanf("%d",&Q);Q;--Q) {
int x,y;
scanf("%d%d",&x,&y);
if(pos[x]>pos[y]) swap(x,y);
LL tmp;
if(pos[x] && pos[y] && pos[x]+1==pos[y]) tmp=ans[pos[x]];
else tmp=distS[T];
printf(tmp==INF ? "Infinity\n" : "%lld\n",tmp);
}
return 0;
}