public List<Integer> numIslands2(int m, int n, int[][] positions) {
    if (m < 0 || n < 0 || positions == null) {
      throw new IllegalArgumentException();
    }

    List<Integer> result = new ArrayList<Integer>();
    UnionFind uf = new UnionFind();
    int[] x = new int[] {-1, 1, 0, 0};
    int[] y = new int[] {0, 0, -1, 1};

    for (int[] p : positions) {
      int i = p[0];
      int j = p[1];

      int cur = id(i, j, n);
      uf.add(cur);

      for (int k = 0; k < x.length; k++) {
        if (valid(i + x[k], j + y[k], m, n)) {
          int neighbor = id(i + x[k], j + y[k], n);
          uf.union(cur, neighbor);
        }
      }

      result.add(uf.count);
    }

    return result;
  }