Simple O(n) solution
Complexity
Time complexity: O(n)

Space complexity: O(n)
Code
# Complexity
- Time complexity: $$O(n)$$
<!-- Add your time complexity here, e.g. $$O(n)$$ -->

- Space complexity: $$O(n)$$
<!-- Add your space complexity here, e.g. $$O(n)$$ -->

# Code
```golang []
func minimumCost(n int, edges [][]int, queries [][]int) []int {
    // Initialize Union-Find data structure
    uf := newUnionFind(n)

    // Join nodes based on edges to form connected components
    for _, edge := range edges {
        uf.join(edge[0], edge[1])
    }

    // Map to store the minimum cost (bitwise AND) for each component
    componentCost := make(map[int]int)

    // Calculate the minimum cost for each component
    for _, edge := range edges {
        root := uf.find(edge[0]) // Find the root of the component
        if _, exists := componentCost[root]; !exists {
            componentCost[root] = edge[2] // Initialize cost if not already set
        }
        componentCost[root] &= edge[2] // Update cost using bitwise AND
    }

    // Process each query
    ans := make([]int, len(queries))
    for i, query := range queries {
        start, end := query[0], query[1]
        rootStart := uf.find(start)
        rootEnd := uf.find(end)

        // If start and end are in different components, return -1
        if rootStart != rootEnd {
            ans[i] = -1
        } else {
            // Otherwise, return the precomputed cost of the component
            ans[i] = componentCost[rootStart]
        }
    }

    return ans
}

// Union-Find data structure
type unionFind []int

// newUnionFind initializes a Union-Find structure with `n` elements
func newUnionFind(n int) unionFind {
    uf := make([]int, n)
    for i := range uf {
        uf[i] = i // Each node is its own parent initially
    }
    return uf
}

// find locates the root of a component with path compression
func (uf unionFind) find(i int) int {
    if i != uf[i] {
        uf[i] = uf.find(uf[i]) // Path compression
    }
    return uf[i]
}

// join merges two components and returns true if they were separate
func (uf unionFind) join(i, j int) bool {
    rootI := uf.find(i)
    rootJ := uf.find(j)

    // If already in the same component, do nothing
    if rootI == rootJ {
        return false
    }

    // Union by rank: attach the smaller tree to the larger one
    if rootI > rootJ {
        rootI, rootJ = rootJ, rootI
    }
    uf[rootJ] = rootI // Merge components
    return true
}
```
['Go']