public int kthSmallest(int[][] matrix, int k) {
        if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return -1;

        int m = matrix.length, n = matrix[0].length;
        PriorityQueue<Integer> q = new PriorityQueue<>((p1, p2) -> matrix[p1 / n][p1 % n] - matrix[p2 / n][p2 % n]);
        for (int j = 0; j < n && j < k; ++j) q.offer(j);

        int node = 0;
        while (k-- > 0) {
            node = q.poll();
            int x = node / n, y = node % n;
            if (x < m - 1) q.offer((x + 1) * n + y);
        }
        return matrix[node / n][node % n];
    }