// Original C++ solution (slower):
#include<bits/stdc++.h>

#define ll long long

#define pli pair<ll, int>

#define fir first

#define sec second

using namespace std;

const int MAXN = 1e5 + 7;

const int mod = 1e9 + 7;

const ll INF = 1e17;

inline ll add(ll x, ll y) {return (x + y) % mod;}

inline ll mul(ll x, ll y) {return (x * y) % mod;}

inline ll sub(ll x, ll y) {return (x - y + mod) % mod;}

vector<pli>G[MAXN];

bool vis[MAXN];

int n, m;

void dijkstra(int s, ll *dis, ll *f)

{

    priority_queue<pli, vector<pli>, greater<pli> >pq;

    for (int i = 1; i <= n; i++) vis[i] = 0, dis[i] = INF;

    pq.push({dis[s] = 0, s}); f[s] = 1;

    while (pq.size())

    {

        int u = pq.top().sec; pq.pop();

        if (vis[u]) continue;

        vis[u] = 1;

        for (pli e : G[u])

        {

            int v = e.sec, w = e.fir;

            if (dis[v] > dis[u] + w)

            {

                pq.push({dis[v] = dis[u] + w, v});

                f[v] = f[u];

            }

            else if (dis[v] == dis[u] + w) f[v] = add(f[v], f[u]);

        }

    }

}



ll dis[2][MAXN], f[2][MAXN];

int main()

{

    scanf("%d%d", &n, &m); 

    int S, T; scanf("%d%d", &S, &T);

    for (int i = 1, u, v, w; i <= m; i++)

    {

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

        G[u].emplace_back(w, v);

        G[v].emplace_back(w, u);

    }

    dijkstra(S, dis[0], f[0]);

    dijkstra(T, dis[1], f[1]);

    ll len = dis[0][T]; 

    ll ans = mul(f[0][T], f[0][T]); 

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

        if (dis[0][i] + dis[1][i] == len && dis[0][i] == dis[1][i]) 

            ans = sub(ans, mul(mul(f[0][i], f[1][i]), mul(f[1][i], f[0][i])));

    for (int u = 1; u <= n; u++)

        for (pli e : G[u])

        {

            int v = e.sec; ll w = e.fir;

            if (dis[0][u] + w + dis[1][v] == len && dis[0][u] + w > dis[1][v] && dis[1][v] + w > dis[0][u])

                ans = sub(ans, mul(mul(f[0][u], f[1][v]), mul(f[1][v], f[0][u])));

        }

    printf("%lld\n", ans);

    return 0;

}

// Optimized solution to the same problem (faster):
#include<bits/stdc++.h>

#define F(i,a,b) for(int i=(a);i<=(b);++i)

#define eF(i,u) for(int i=h[u];i;i=nxt[i])

#define Mod 1000000007

using namespace std;

typedef long long ll;

typedef pair<ll,int> pli;



int n,m,S,T;

ll Ans;

int U[200001],V[200001],D[200001];

int h[100001],nxt[400001],to[400001],w[400001],tot;

void ins(int x,int y,int z){nxt[++tot]=h[x];to[tot]=y;w[tot]=z;h[x]=tot;}



ll d1[100001],d2[100001],g1[100001],g2[100001];bool v1[100001],v2[100001];

priority_queue<pli,vector<pli>,greater<pli> > pq;



void Dij(ll*d,ll*g,bool*v,int s){

    d[s]=0ll;

    pq.push(pli(0ll,s));

    g[s]=1;

    while(!pq.empty()){

        pli P=pq.top(); pq.pop();

        int u=P.second; ll du=P.first;

        if(v[u]||d[u]<du) continue;

        v[u]=1;

        eF(i,u){

            if(d[to[i]]==du+w[i])

                g[to[i]]=(g[to[i]]+g[u])%Mod;

            if(d[to[i]]>du+w[i])

                g[to[i]]=g[u],

                        d[to[i]]=du+w[i], pq.push(pli(d[to[i]],to[i]));

        }

    }

}



int main(){

    int x,y,z;

    scanf("%d%d",&n,&m);

    scanf("%d%d",&S,&T);

    F(i,1,m) scanf("%d%d%d",&x,&y,&z), ins(x,y,z), ins(y,x,z), U[i]=x, V[i]=y, D[i]=z;

    memset(d1,0x3f,sizeof d1);

    Dij(d1,g1,v1,S);

    memset(d2,0x3f,sizeof d2);

    Dij(d2,g2,v2,T);

    ll Dist=d1[T];

    Ans=g1[T]*g1[T]%Mod;

    F(i,1,n){

        if(d1[i]+d2[i]==Dist&&d1[i]==d2[i])

            Ans=(Ans-g1[i]*g1[i]%Mod*g2[i]%Mod*g2[i]%Mod)%Mod;

    }

    int u,v,d;

    F(i,1,m){

        u=U[i], v=V[i], d=D[i];

        if(d1[u]+d+d2[v]==Dist && d1[u]+d>d2[v] && d2[v]+d>d1[u]){

            Ans=(Ans-g1[u]*g2[v]%Mod*g1[u]%Mod*g2[v]%Mod)%Mod;

        }

        u=V[i], v=U[i], d=D[i];

        if(d1[u]+d+d2[v]==Dist && d1[u]+d>d2[v] && d2[v]+d>d1[u]){

            Ans=(Ans-g1[u]*g2[v]%Mod*g1[u]%Mod*g2[v]%Mod)%Mod;

        }

    }

    printf("%lld",(Ans%Mod+Mod)%Mod);

    return 0;

}

// Fastest known solution for this problem: