#include<iostream>
#include<vector>
#include<queue>
#define ll long long
using namespace std;
struct node{
ll v;
double w;
};
struct comp{
bool operator()(const node &a,const node &b) const
{
return a.w>b.w;
}
};
float findMin(vector<pair<ll,double>> adj[],bool visited[],double dist[],ll a,ll b){
dist[a] = 0;
priority_queue<node,vector<node>,comp> q;
q.push({a,0});
visited[a] = true;
while(!q.empty()){
node p = q.top();
q.pop();
for(auto x:adj[p.v]){
if(!visited[x.first]&&dist[x.first]> dist[p.v] + x.second){
dist[x.first] = dist[p.v] + x.second;
q.push({x.first,dist[x.first]});
}
}
visited[p.v] = true;
}
if(visited[b])
return dist[b];
else return -1;
}
int main(){
int t;
cin >>t;
while(t--){
ll n,m,a,b,i,x,y,d,s;
cin >> n>>m>>a>>b;
vector<pair<ll,double>> adj[n+1];
bool visited[n+1];
double dist[n+1];
for(i=0;i<=n;i++){
visited[i] = false;
dist[i] = 1e18;
}
for(i=0;i<m;i++){
cin >>x>>y>>d>>s;
adj[x].push_back(make_pair(y,(double)d/s));
adj[y].push_back(make_pair(x,(double)d/s));
}
cout <<findMin(adj,visited,dist,a,b)<<endl;
}
return 0;
}
I2luY2x1ZGU8aW9zdHJlYW0+CiNpbmNsdWRlPHZlY3Rvcj4KI2luY2x1ZGU8cXVldWU+CiNkZWZpbmUgbGwgbG9uZyBsb25nCgp1c2luZyBuYW1lc3BhY2Ugc3RkOwpzdHJ1Y3Qgbm9kZXsKCWxsIHY7Cglkb3VibGUgdzsKfTsKc3RydWN0IGNvbXB7Cglib29sIG9wZXJhdG9yKCkoY29uc3Qgbm9kZSAmYSxjb25zdCBub2RlICZiKSBjb25zdAoJewoJCXJldHVybiBhLnc+Yi53OwoJfQp9OwpmbG9hdCBmaW5kTWluKHZlY3RvcjxwYWlyPGxsLGRvdWJsZT4+IGFkaltdLGJvb2wgdmlzaXRlZFtdLGRvdWJsZSBkaXN0W10sbGwgYSxsbCBiKXsKCWRpc3RbYV0gPSAwOwoJcHJpb3JpdHlfcXVldWU8bm9kZSx2ZWN0b3I8bm9kZT4sY29tcD4gcTsKCXEucHVzaCh7YSwwfSk7CiAgICB2aXNpdGVkW2FdID0gdHJ1ZTsKCXdoaWxlKCFxLmVtcHR5KCkpewoJCW5vZGUgcCA9IHEudG9wKCk7CiAgICAgICAgcS5wb3AoKTsKCQlmb3IoYXV0byB4OmFkaltwLnZdKXsKCQkJaWYoIXZpc2l0ZWRbeC5maXJzdF0mJmRpc3RbeC5maXJzdF0+IGRpc3RbcC52XSArIHguc2Vjb25kKXsKCQkJCWRpc3RbeC5maXJzdF0gPSAgZGlzdFtwLnZdICsgeC5zZWNvbmQ7CgkJCQlxLnB1c2goe3guZmlyc3QsZGlzdFt4LmZpcnN0XX0pOwoJCQl9CgkJfQoJCXZpc2l0ZWRbcC52XSA9IHRydWU7Cgl9CmlmKHZpc2l0ZWRbYl0pCglyZXR1cm4gZGlzdFtiXTsKZWxzZSByZXR1cm4gLTE7Cn0KaW50IG1haW4oKXsKCWludCB0OwoJY2luID4+dDsKCXdoaWxlKHQtLSl7CgkJbGwgbixtLGEsYixpLHgseSxkLHM7CgkJY2luID4+IG4+Pm0+PmE+PmI7CgkJdmVjdG9yPHBhaXI8bGwsZG91YmxlPj4gYWRqW24rMV07CgkJYm9vbCB2aXNpdGVkW24rMV07CgkJZG91YmxlIGRpc3RbbisxXTsKCQlmb3IoaT0wO2k8PW47aSsrKXsKICAgICAgICAgICAgdmlzaXRlZFtpXSA9IGZhbHNlOwoJCQlkaXN0W2ldID0gMWUxODsKCQl9CgkJZm9yKGk9MDtpPG07aSsrKXsKCQkJY2luID4+eD4+eT4+ZD4+czsKCQkJYWRqW3hdLnB1c2hfYmFjayhtYWtlX3BhaXIoeSwoZG91YmxlKWQvcykpOwoJCQlhZGpbeV0ucHVzaF9iYWNrKG1ha2VfcGFpcih4LChkb3VibGUpZC9zKSk7CgkJfQoJCWNvdXQgPDxmaW5kTWluKGFkaix2aXNpdGVkLGRpc3QsYSxiKTw8ZW5kbDsKCX0KcmV0dXJuIDA7Cn0K