import std.stdio, std.string, std.conv;
import std.range, std.algorithm, std.array;
import std.typecons : Tuple;

alias Edge = Tuple!(int, "to", long, "cost");

void main() {
    int n, m, s, t;

    scan(n, m);
    scan(s, t);
    s--, t--;

    auto adj = new Edge[][](n, 0);

    foreach (i ; 0 .. m) {
        int u, v, d;
        scan(u, v, d);
        adj[u-1] ~= Edge(v-1, d);
        adj[v-1] ~= Edge(u-1, d);
    }

    immutable inf = 10L^^17;

    auto dist = new long[](n);
    dist[] = inf;
    dist[s] = 0;

    alias Pair = Tuple!(int, "node", long, "dist");

    import std.container;

    auto h = new BinaryHeap!(Array!Pair, "a.dist > b.dist")();

    h.insert(Pair(s, 0));

    while(!h.empty) {
        auto u = h.front;
        h.removeFront;

        if (u.dist < dist[u.node]) continue;

        foreach (e ; adj[u.node]) {
            if (dist[e.to] > dist[u.node] + e.cost) {
                dist[e.to] = dist[u.node] + e.cost;
                h.insert(Pair(e.to, dist[e.to]));
            }
        }
    }

    debug {
        writeln("dist:", dist);
    }

    auto ord = new Pair[](n);

    foreach (i ; 0 .. n) {
        ord[i] = Pair(i, dist[i]);
    }

    ord.sort!"a.dist < b.dist"();

    immutable mod = 10^^9 + 7;

    auto dp1 = new int[](n);
    auto dp2 = new int[](n);

    dp1[s] = 1;

    foreach (v ; ord) {
        foreach (e ; adj[v.node]) {
            if (dist[e.to] + e.cost == dist[v.node]) {
                dp1[v.node] += dp1[e.to];
                dp1[v.node] %= mod;
            }
        }
    }

    dp2[t] = 1;

    foreach_reverse (v ; ord) {
        foreach (e ; adj[v.node]) {
            if (dist[e.to] - e.cost == dist[v.node]) {
                dp2[v.node] += dp2[e.to];
                dp2[v.node] %= mod;
            }
        }
    }

    debug {
        writeln(dp1);
        writeln(dp2);
    }

    long ans = dp1[t] * dp1[t] % mod;

    foreach (i ; 0 .. n) {
        if (dist[i]*2 == dist[t]) {
            ans -= dp1[i] * dp1[i] % mod * dp2[i] % mod * dp2[i] % mod;
            if (ans < 0) ans += mod;
        }
        foreach (e ; adj[i]) {
            if (dist[i]*2 < dist[t] && dist[e.to]*2 > dist[t]
                && dist[i] + e.cost == dist[e.to]) {
                ans -= dp1[i] * dp1[i] % mod * dp2[e.to] % mod * dp2[e.to] % mod;
                if (ans < 0) ans += mod;
            }
        }
    }

    writeln(ans);

}




void scan(T...)(ref T args) {
    import std.stdio : readln;
    import std.algorithm : splitter;
    import std.conv : to;
    import std.range.primitives;

    auto line = readln().splitter();
    foreach (ref arg; args) {
        arg = line.front.to!(typeof(arg));
        line.popFront();
    }
    assert(line.empty);
}



void fillAll(R, T)(ref R arr, T value) {
    static if (is(typeof(arr[] = value))) {
        arr[] = value;
    }
    else {
        foreach (ref e; arr) {
            fillAll(e, value);
        }
    }
}
