{ Free Pascal }

const maxN = 1000;

var n, i, v, left, right: longint;
var all: array[1..maxN] of array of longint;
var allHeads: array[1..maxN] of longint;
var edgesLeft, edgesRight: array of longint;
var edgesHead: longint;

procedure pop(v: longint);
var adjacent: longint;
begin
    inc(allHeads[v]);
    if (allHeads[v] < length(all[v])) then
    begin
        adjacent := all[v][allHeads[v]];
        if (allHeads[adjacent] < length(all[adjacent])) and (all[adjacent][allHeads[adjacent]] = v) then
        begin
            setlength(edgesLeft, length(edgesLeft) + 1);
            setlength(edgesRight, length(edgesRight) + 1);
            if v < adjacent then begin
                edgesLeft[length(edgesLeft) - 1] := v;
                edgesRight[length(edgesRight) - 1] := adjacent;
            end else begin
                edgesLeft[length(edgesLeft) - 1] := adjacent;
                edgesRight[length(edgesRight) - 1] := v;
            end;
        end;
    end;
end;

begin
    assign(input, 'graph.in');
    reset(input);
    assign(output, 'graph.out');
    rewrite(output);

    readln(n);
    for i := 1 to n do
        allHeads[i] := 0;

    for i := 1 to n do
    begin
        while not seekeoln do begin
            read(v);
            setlength(all[i], length(all[i]) + 1);
            all[i][length(all[i]) - 1] := v;
        end;
        readln;

        if (all[i][0] < i) and (all[all[i][0]][0] = i) then begin
            setlength(edgesLeft, length(edgesLeft) + 1);
            setlength(edgesRight, length(edgesRight) + 1);
            edgesLeft[length(edgesLeft) - 1] := all[i][0];
            edgesRight[length(edgesRight) - 1] := i;
        end;
    end;

    while (edgesHead < length(edgesLeft)) do
    begin
        left := edgesLeft[edgesHead];
        right := edgesRight[edgesHead];
        inc(edgesHead);
        writeln(left, ' ', right);
        pop(left);
        pop(right);
    end;
end.
