DSU - Union and find | O(n) Solution 
IntuitionThis problem involves processing a graph with weighted edges and answering queries about connectivity and minimum cost constraints between nodes. The s
# Intuition
<!-- Describe your first thoughts on how to solve this problem. -->
This problem involves processing a graph with weighted edges and answering queries about connectivity and minimum cost constraints between nodes. The solution uses Disjoint Set Union (DSU) (also known as Union-Find) to efficiently determine whether two nodes are connected and to track the bitwise AND of edge weights within each connected component.

Key Observations:
DSU for Connectivity:

We use path compression in the find function to optimize lookup time.
We use union by rank (or size) to merge components efficiently.
Tracking Minimum Edge Cost using AND operation:

When two components are merged, the cost of the resulting component is the bitwise AND of all edges connecting its nodes.
This is because taking AND ensures that only the common bits among all edges are retained.
Processing Queries Efficiently:

For each query (u, v), we check if u and v belong to the same connected component using DSU.
If they are connected, the answer is the cost of their component.
Otherwise, they are unreachable, so the answer is -1.

# Complexity
- Time complexity:
<!-- Add your time complexity here, e.g. $$O(n)$$ -->
where m is the number of edges.
where q is the number of queries.
Final Complexity:O(m+q)
- Space complexity:
<!-- Add your space complexity here, e.g. $$O(n)$$ -->
Parent and Cost Arrays: O(n)
Input Storage (edges & query): O(m + q)
Total Space Complexity: O(n+m+q)
# Code
```java []
class Solution 
{
    int parent[];
    int cost[];
    public int[] minimumCost(int n, int[][] edges, int[][] query) 
    {
        cost=new int[n];
        parent=new int[n];
        for(int i=0;i<n;i++)
        {
            cost[i]=-1;
            parent[i]=i;
        }
        
        for(int edge[]:edges)
        {
            int u=edge[0];
            int v=edge[1];
            int wt=edge[2];
            int parent_u=find(u);
            int parent_v=find(v);
            if(parent_u!=parent_v)
            {
                union(parent_u,parent_v);
                cost[parent_u]&=cost[parent_v];
            }
            cost[parent_u]&=wt;
        }
        int indx=0;
        int result[]=new int[query.length];
        for(int querys[]:query)
        {
            int sr=querys[0];
            int des=querys[1];
            int parent_sr=find(sr);
            int parent_des=find(des);
            if(sr==des)
                result[indx]=0;
            else if(parent_sr==parent_des)
                result[indx]=cost[parent_sr];
            else
                result[indx]=-1;
            indx++;
        }
        return result;
    }
    private int find(int node)
    {
        if(parent[node]==node)
            return node;
        return parent[node]=find(parent[node]);
    }
    private void union(int node1, int node2)
    {
        parent[node2]=node1;
    }
}
```
['Java']