class Solution:
    def countRestrictedPaths(self, n: int, edges: List[List[int]]) -> int:
        """
        1.  build graph + dijkstra get min distance from node x to node n with map  
        2.  start from nth node to ith node distance to make dis(i+1) < dis(i) ===> distance from current node to last node is strictly decreasing 
        dfs + memo 
        Dijkstra:  single source, non-negtive weight 
        Elg(E)
        what to memo?  
        pathNum(x1) = pathNum(x2) + pathNum(x3)+...
        pathNum(x2) = pathNum(x3) + ... 
        -  note here when we do dfs+memo, we don't do visited.  why???? each recursion. we favor lower dis 
                                        but for Dijkstra part we need visited 
        """
        M = 10**9+7
        # build g, adjecency list  
        g = collections.defaultdict(list)
        dmin = {}# min distance from node x to node n 
        for v1,v2,d in edges:
            g[v1].append([v2,d])
            g[v2].append([v1,d])
        # dijkstra 
        pq = []
        # 0. initialize seen set 
        seen = set()
        # 1. put source node with distance in front into pq 
        heappush(pq,[0,n])
        while pq:
            # 2. pop node with min distance  
            d,node = heappop(pq)
            # 3. check if current node has visited  <===  check seen,update seen (1)
            if node in seen:
                continue
            seen.add(node)
            #4. update min distance from source node to current node 
            dmin[node] = d
            # 5. get unvisited neibour node, push <acuumutive distance> with <neighbour node>  into hp.
            for nxt,dis in g[node]:
                if nxt in seen:               #<=====  check seen,no update seen(2)
                    continue
                heappush(pq,[d+dis,nxt])
        # dfs + memo : get total dis
        #!!! note here dfs + memo no need to check seen / handle cycle because restriction distanceToLastNode(zi) > distanceToLastNode(zi+1)
        memo = {}
        def dfs(cur):
            # 1.termination edge case 
            if cur == n:
                return 1
            # 2. check memo 
            if cur in memo:
                return memo[cur]
            #4. initialize path_cnt 
            cnt = 0
            # 3. check distance if restrctly increase 
            for nei,_ in g[cur]:
                if dmin[nei] >= dmin[cur]: #distanceToLastNode(zi) > distanceToLastNode(zi+1)
                    continue
                #5. get acuumulative path from current to nei node 
                cnt += dfs(nei)
                #6. mod cnt 
                cnt %= M
            #7. cache memo
            memo[cur] = cnt
            return cnt
        res = dfs(1)
        return res