import java.util.*

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

    val g = Graph(N + 1, 0L, 1e+18.toLong()) { a, b -> a + b }

    val (S, T) = readLine()!!.split(" ").map{it.toInt()}

    val es = Array(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()))

        g.edges[U].last()
    }

    val (dist, prev, cnt) = dijkstra(g, S)
    val (rDist, rPrev, rCnt) = dijkstra(g, T)

    var res = cnt[T] * cnt[T]

    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 (2 * dist[u] >= dist[T] || 2 * rDist[v] >= dist[T]) {
            continue
        }

        val m = cnt[u] * rCnt[v]
        res -= m * m
    }

    for (i in 1..N) {
        if (dist[i] + rDist[i] != dist[T] || dist[i] != rDist[i]) {
            continue
        }

        val m = cnt[i] * rCnt[i]
        res -= m * m
    }

    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>>() }
}

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(0L, 1e9.toLong() + 7L) }

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

    dist[s] = g.zero
    cnt[s] =  cnt[s] + 1L
    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: 154204