import java.util.*

fun main(args: Array<String>) {
    val (N, M) = readLine()!!.split(" ").map{it.toInt()}
    val (S, T) = readLine()!!.split(" ").map{it.toInt()}
    val INF = 1e15.toLong()

    val g = Graph(N + 1, 0L, INF) { a, b -> a + b}
    val es = ArrayList<Edge<Long>>()

    for (i in 1..M) {
        val (U, V, D) = readLine()!!.split(" ").map{it.toInt()}
        g.edges[U].add(Edge(U, V, D.toLong()))
        g.edges[V].add(Edge(V, U, D.toLong()))
        es.add(Edge(U, V, D.toLong()))
    }

    val (dist, prev, cnt) = dijkstra(g, S)
    val (rdist, rprev, rcnt) = dijkstra(g, T)

    var res = (cnt[T].pow(2L))

    for (e in es) {
        val u: Int
        val v: Int
        if (dist[e.from] < dist[e.to]) {
            u = e.from
            v = e.to
        } else {
            u = e.to
            v = e.from
        }

        if (dist[u] + rdist[v] + e.weight != dist[T]) {
            continue
        }

        if (dist[u] * 2 >= dist[T] || rdist[v] * 2 >= dist[T]) {
            continue
        }

        res -= cnt[u].pow(2L) * rcnt[v].pow(2L)
    }

    for (i in 0..N) {
        if (dist[i] * 2 != dist[T]) {
            continue
        }

        res -= cnt[i].pow(2L) * rcnt[i].pow(2L)
    }

    println(res.value)
}

data class Edge<T: Comparable<T>>(val from: Int, val to: Int, val weight: T): Comparable<Edge<T>> {
    constructor(from: Long, to: Long, weight: T) : this(from.toInt(), to.toInt(), weight)

    override fun compareTo(other: Edge<T>) = weight.compareTo(other.weight)
}

class Graph<T: Comparable<T>>(val n: Int, val zero: T, val inf: T, val plus: (T, T) -> T) {
    val edges = Array(n) { ArrayList<Edge<T>>() }
}

val MOD = 1e9.toLong() + 7

inline fun <reified T: Comparable<T>>dijkstra(g: Graph<T>, s: Int): Triple<Array<T>, Array<Int>, Array<ModInt>> {
    val N = g.n
    val dist = Array(N) { g.inf }
    val prev = Array(N) { -1 }
    val cnt = Array(N) { ModInt(0, MOD) }

    val Q = PriorityQueue<Edge<T>>()

    dist[s] = g.zero
    cnt[s] = ModInt(1, MOD)
    Q.add(Edge(-2, s, g.zero))

    while(Q.isNotEmpty()) {
        val e = Q.peek()
        val v = e.to
        Q.poll()

        if (prev[v] != -1) continue
        prev[v] = e.from
        for (i in g.edges[v]) {
            val d = g.plus(dist[v], i.weight)
            if (dist[i.to] > d) {
                dist[i.to] = d
                cnt[i.to] = cnt[i.from]
                Q.add(Edge(i.from, i.to, d))
            } else if (dist[i.to] == d) {
                cnt[i.to] += cnt[i.from]
            }
        }
    }

    return Triple(dist, prev, cnt)
}

class ModInt (value: Long, val mod: Long) {
    init {
        if (mod <= 0) {
            throw IllegalArgumentException("ModInt cannot be created for non-positive modulus: $mod")
        }
    }

    val value = (value % mod + mod) % mod

    private fun assertSameMod(other: ModInt) {
        if (mod != other.mod) {
            throw IllegalArgumentException(
                "You cannot operate summation, subtraction and multiplication for ModInts with different moduli: $mod, ${other.mod}"
            )
        }
    }

    operator fun unaryMinus() = ModInt(mod - value, mod)

    operator fun plus(other: ModInt): ModInt {
        assertSameMod(other)

        return ModInt((value + other.value) % mod, mod)
    }

    operator fun plus(other: Long) = plus(ModInt(other, mod))

    operator fun minus(other: ModInt): ModInt {
        assertSameMod(other)

        return plus(-other)
    }

    operator fun minus(other: Long) = minus(ModInt(other, mod))

    operator fun times(other: ModInt): ModInt {
        assertSameMod(other)

        return ModInt((value * other.value) % mod, mod)
    }

    operator fun times(other: Long) = times(ModInt(other, mod))

    fun pow(k: Long): ModInt {
        var res = 1L
        var a = value
        var l = k

        while (l > 0) {
            if ((l and 1L) == 1L) {
                res = (res * a) % mod
            }

            a = a * a % mod
            l /= 2L
        }

        return ModInt(res, mod)
    }

    /**
     * Returns an inverse element of the value.
     * To ensure `m * m.inv() = 1`, the modulus should be prime, since it uses Fermat's little theorem.
     */
    fun inv() = pow(mod - 2)

    operator fun div(other: ModInt): ModInt {
        assertSameMod(other)
        if (other.value == 0L) {
            throw ArithmeticException()
        }

        return times(other.inv())
    }

    operator fun div(other: Long) = div(ModInt(other, mod))
}


Measured memory_bytes: 151364