input: from typing import List
  
  def min_travel_cost(n: int, edges: List[List[int]], queries: List[List[int]]) -> List[int]:
      """
      Consider an undirected weighted graph with n nodes numbered from 0 to n - 1.
  
      Given the integer n and a list edges, where edges[i] = [u_i, v_i, w_i] signifies an edge between nodes u_i and v_i with a weight of w_i.
  
      A traversal of the graph is defined as a sequence of nodes and edges, starting and ending at specific nodes, where each edge connects the preceding and following nodes. Note that a traversal might revisit nodes or edges multiple times.
  
      The traversal cost starting at node u and ending at node v is defined as the bitwise AND of the weights of all edges traversed. Specifically, if the weights encountered during the traversal are w_0, w_1, w_2, ..., w_k, the cost is computed as w_0 & w_1 & w_2 & ... & w_k, where & represents the bitwise AND operation.
  
      Also given is a 2D list queries, where queries[i] = [s_i, t_i]. For each query, determine the minimum cost of the traversal beginning at node s_i and ending at node t_i. If no such traversal exists, return -1.
  
      Return a list answers, where answers[i] indicates the minimum cost for the traversal corresponding to query i.
  
      Examples:
      >>> n = 5, edges = [[0,1,7],[1,3,7],[1,2,1]], queries = [[0,3],[3,4]]
      [1,-1]
      >>> n = 3, edges = [[0,2,7],[0,1,15],[1,2,6],[1,2,1]], queries = [[1,2]]
      [0]
  
      Constraints:
      2 <= n <= 10^5
      0 <= edges.length <= 10^5
      edges[i].length == 3
      0 <= u_i, v_i <= n - 1
      u_i != v_i
      0 <= w_i <= 10^5
      1 <= queries.length <= 10^5
      queries[i].length == 2
      0 <= s_i, t_i <= n - 1
      s_i != t_i
      """
output:     
      import heapq
      from collections import defaultdict
  
      def dijkstra(start: int, graph: defaultdict(list)) -> List[int]:
          costs = [float('inf')] * n
          costs[start] = (1 << 31) - 1  # All 1s
          pq = [(costs[start], start)]
          while pq:
              current_cost, u = heapq.heappop(pq)
              for v, weight in graph[u]:
                  new_cost = current_cost & weight
                  if new_cost > costs[v]:
                      costs[v] = new_cost
                      heapq.heappush(pq, (new_cost, v))
          return costs
  
      graph = defaultdict(list)
      for u, v, w in edges:
          graph[u].append((v, w))
          graph[v].append((u, w))
      
      answers = []
      for s, t in queries:
          costs = dijkstra(s, graph)
          answer = costs[t] if costs[t] != float('inf') else -1
          answers.append(answer)
          
      return answers
  