# Истоки и стоки. Вершина ориентированного графа называется истоком,
# если в нее не входит ни одно ребро и стоком, если из нее не выходит ни одного ребра.
# Ориентированный граф задан матрицей смежности. Найдите все вершины графа,
# которые являются истоками, и все его вершины, которые являются стоками.
# Формат входных данных
# Cначала вводится число n ( 1 ≤ n ≤ 100) – количество вершин в графе,
# а затем n строк по n чисел, каждое из которых равно 0 или 1, – его матрица смежности.
# Нумерация вершин начинается с 1.
# Формат выходных данных
# Сначала в одну строку выведите все истоки, в следующей строке все стоки.

n = int(input())

graph = [0] * (n + 1)  # Предусматриваем лишнюю 0-ю строку,
# т.к. фактически нумерация вершин графа начинается с 1.

for i in range(1, n + 1):  # Считываем строки в матрицу смежности
    graph[i] = [0] + [int(s) for s in input().split()]
    # В каждой строке предусматриваем лишний 0-й столбец.

outgoing = []
incoming = []

for row in range(1, n + 1):
    # Если вершина не имеет исходящих ребер, то сумма строки = 0.
    if sum(graph[row]) == 0:
        incoming.append(row)

for column in range(1, n + 1):
    # Переменная для подсчета суммы столбца матрицы. Обнуляется на каждом цикле.
    sum_column = 0
    for row in range(1, n + 1):
        sum_column += graph[row][column]

    # Если вершина не имеет входящих ребер, то сумма столбца = 0.
    if sum_column == 0:
        outgoing.append(column)

for vertex in outgoing:
    print(vertex, end=' ')
print()

for vertex in incoming:
    print(vertex, end=' ')
