def chain_frames(dist_matrix, first_frame=0, valid_idxs=None):
    """Chain together frames that are similar

    Args:
        dist_matrix (numpy.ndarray[N, N]): frame codistance matrix
        first_frame (int, optional): index of the first frame
        valid_idxs (list<int>, optional): list of valid frame indices

    Returns:
        list<int>: ordered frame indices
    """

    current_frame = first_frame
    used_frames = [current_frame]

    # For each frame, find the best match that has not been used yet
    for _ in range(dist_matrix.shape[0] - 1):
        sorted_candidates = dist_matrix[current_frame].argsort()
        for frame in sorted_candidates:
            # Skip invalid frames
            if isinstance(valid_idxs, list) and frame not in valid_idxs:
                continue
            if frame not in used_frames:
                used_frames.append(frame)
                current_frame = frame
                break

    return used_frames