import sys
from heapq import heappush, heappop

INF = sys.maxsize

def dijkstra(graph, source):
    # collect all vertex labels (sources + destinations)
    labels = set(graph.keys())
    for u in graph:
        labels.update(graph[u].keys())
    if source not in labels:
        labels.add(source)
    if not labels:
        return [], {}

    n = max(labels) + 1  # assumes nonnegative int labels (0..N-1 possibly with gaps)
    dist = [INF] * n
    dist[source] = 0

    heap = []
    heappush(heap, (0, source))

    path = {source: []}  # path[d] = nodes leading up to d (excluding d)

    while heap:
        w, u = heappop(heap)
        # skip stale entries
        if w != dist[u]:
            continue
        for v, w_uv in graph.get(u, {}).items():
            alt = w + w_uv
            if alt < dist[v]:
                dist[v] = alt
                heappush(heap, (alt, v))
                if u not in path:
                    path[u] = []
                path[v] = path[u] + [u]

    return dist, path

from collections import deque

def breadth_first_search(graph, source):
    """
    Unweighted shortest paths in a graph.
    Graph may be {u: {v: w}} or {u: [v, ...]}.
    Returns:
        dist: dict[int,int] (distance in edges)
        path: dict[int,list[int]] (sequence of nodes leading up to each node)
    """
    def nbrs(u):
        g = graph.get(u, {})
        return g.keys() if isinstance(g, dict) else g

    dist = {source: 0}
    prev = {source: None}
    q = deque([source])

    while q:
        u = q.popleft()
        for v in nbrs(u):
            if v not in dist:
                dist[v] = dist[u] + 1
                prev[v] = u
                q.append(v)

    def recon(t):
        if t not in dist: 
            return []
        route = []
        cur = t
        while cur is not None:
            route.append(cur)
            cur = prev[cur]
        route.reverse()
        return route

    # path[d] = nodes leading up to d (excluding d), same style as dijkstra
    path = {t: recon(t)[:-1] for t in dist}
    return dist, path