
#include<stdio.h>
#include<stdlib.h>
#define MAXN 3005
#define MAX 2147483646
int G[MAXN][MAXN],Ne,Nv,src,des;
void BuildGraph()
{
int i,j,v1,v2,w;
scanf("%d",&Nv);
for(i=0; i<Nv; i++)
for(j=0; j<Nv; j++){
if(i==j)G[i][j] = 0;
else G[i][j] = MAX;
}
scanf("%d",&Ne);
scanf("%d %d",&src,&des);
for(i=0; i<Ne; i++)
{
scanf("%d %d %d",&v1,&v2,&w);
G[v1-1][v2-1] = w;
G[v2-1][v1-1] = w;
}
}
int dist[MAXN],path[MAXN],collected[MAXN];
int count[MAXN];
int FindMinDist(){
int MinV,i;
int MinDist = MAX;
for(i=0; i<Nv; i++){
if(collected[i] == false && dist[i]<MinDist){
MinDist = dist[i];
MinV = i;
}
}
if(MinDist < MAX)return MinV;
else return -1;
}
int Dijkstra(){
int s = src-1;
int i,j;
for(i = 0; i < Nv; i++){
dist[i] = G[s][i];
if(dist[i] < MAX){
path[i] = s;
}
else{
path[i] = -1;
}
collected[i] = false;
}
for(int j = 0; j < Nv;j++)if( G[s][j] < MAX )count[j] = 1;
dist[s] = 0;
collected[s] = true;
while(1){
i = FindMinDist();
if(i == -1)break;
collected[i] = true;
for(j = 0; j < Nv ;j++){
if(collected[j]==false && G[i][j] < MAX)
{
if(G[i][j]<0)return 0;
if(dist[i] + G[i][j] <= dist[j]){
// printf("%d %d %d %d\n",i,count[i],j,count[j]);
if(dist[i] + G[i][j] < dist[j])count[j] = count[i];
else count[j] += count[i];
dist[j] = dist[i] + G[i][j];
path[j] = i;
}
}
}
}
printf("%d %d",dist[des-1],count[des-1]);
return 1;
}
int main(){
BuildGraph();
Dijkstra();
return 0;
}