Problem: Graph Connectivity With Threshold

We have `n` cities labeled from `1` to `n`. Two different cities with labels
`x` and `y` are directly connected by a bidirectional road if and only if `x`
and `y` share a common divisor strictly greater than some `threshold`. More
formally, cities with labels `x` and `y` have a road between them if there
exists an integer `z` such that all of the following are true:

* `x % z == 0`,
* `y % z == 0`, and
* `z > threshold`.

Given the two integers, `n` and `threshold`, and an array of `queries`, you
must determine for each `queries[i] = [ai, bi]` if cities `ai` and `bi` are
connected directly or indirectly. (i.e. there is some path between them).

Return an array `answer`, where `answer.length == queries.length` and
`answer[i]` is `true` if for the `ith` query, there is a path between `ai` and
`bi`, or `answer[i]` is `false` if there is no path.


Python solution:
import math
import itertools
import bisect
import collections
import string
import heapq
import functools
import sortedcontainers
from typing import List, Dict, Tuple, Iterator

class UnionFind:
  def __init__(self, n: int):
    self.id = list(range(n))
    self.rank = [0] * n

  def unionByRank(self, u: int, v: int) -> bool:
    i = self.find(u)
    j = self.find(v)
    if i == j:
      return False
    if self.rank[i] < self.rank[j]:
      self.id[i] = j
    elif self.rank[i] > self.rank[j]:
      self.id[j] = i
    else:
      self.id[i] = j
      self.rank[j] += 1
    return True

  def find(self, u: int) -> int:
    if self.id[u] != u:
      self.id[u] = self.find(self.id[u])
    return self.id[u]


class Solution:
  def areConnected(self, n: int, threshold: int, queries: List[List[int]]) -> List[bool]:
    uf = UnionFind(n + 1)

    for z in range(threshold + 1, n + 1):
      for x in range(z * 2, n + 1, z):
        uf.unionByRank(z, x)

    return [uf.find(a) == uf.find(b) for a, b in queries]


Java solution:
class UnionFind {
  public UnionFind(int n) {
    id = new int[n];
    rank = new int[n];
    for (int i = 0; i < n; ++i)
      id[i] = i;
  }

  public boolean unionByRank(int u, int v) {
    final int i = find(u);
    final int j = find(v);
    if (i == j)
      return false;
    if (rank[i] < rank[j]) {
      id[i] = j;
    } else if (rank[i] > rank[j]) {
      id[j] = i;
    } else {
      id[i] = j;
      ++rank[j];
    }
    return true;
  }

  public int find(int u) {
    return id[u] == u ? u : (id[u] = find(id[u]));
  }

  private int[] id;
  private int[] rank;
}

class Solution {
  public List<Boolean> areConnected(int n, int threshold, int[][] queries) {
    List<Boolean> ans = new ArrayList<>();
    UnionFind uf = new UnionFind(n + 1);

    for (int z = threshold + 1; z <= n; ++z)
      for (int x = z * 2; x <= n; x += z)
        uf.unionByRank(z, x);

    for (int[] query : queries) {
      final int a = query[0];
      final int b = query[1];
      ans.add(uf.find(a) == uf.find(b));
    }

    return ans;
  }
}


C++ solution:
class UnionFind {
 public:
  UnionFind(int n) : id(n), rank(n) {
    iota(id.begin(), id.end(), 0);
  }

  bool unionByRank(int u, int v) {
    const int i = find(u);
    const int j = find(v);
    if (i == j)
      return false;
    if (rank[i] < rank[j]) {
      id[i] = j;
    } else if (rank[i] > rank[j]) {
      id[j] = i;
    } else {
      id[i] = j;
      ++rank[j];
    }
    return true;
  }

  int find(int u) {
    return id[u] == u ? u : id[u] = find(id[u]);
  }

 private:
  vector<int> id;
  vector<int> rank;
};

class Solution {
 public:
  vector<bool> areConnected(int n, int threshold,
                            vector<vector<int>>& queries) {
    vector<bool> ans;
    UnionFind uf(n + 1);

    for (int z = threshold + 1; z <= n; ++z)
      for (int x = z * 2; x <= n; x += z)
        uf.unionByRank(z, x);

    for (const vector<int>& query : queries) {
      const int a = query[0];
      const int b = query[1];
      ans.push_back(uf.find(a) == uf.find(b));
    }

    return ans;
  }
};