#include<iostream>//简单拓扑排序
usingnamespace std;
int n,side[102][102],in[102],path[102];
int main()
{
    cin>>n;
    int a,rear=0;
    for(int id=1;id<=n;++id)
    {
        while(cin>>a&&a)
        {
            side[id][a]=1;
            in[a]++;
        }
    }
    for(int i=1;i<=n;++i)
        if(in[i]==0)
            path[rear++]=i;
    for(int i=0;i<rear;++i)
    {
        for(int j=1;j<=n;++j)
            if(side[path[i]][j]==1)
            {
                in[j]--;
                if(in[j]==0)
                    path[rear++]=j;
            }
    }
    for(int i=0;i<rear;++i)
        cout<<path[i]<<"";
    cout<<endl;
    return0;
}
 
  
#include<iostream>            //算法竞赛入门经典 P111
#include <string.h>
using namespace std;
const int MAXN=120;
int g[MAXN][MAXN],topo[MAXN],tag[MAXN],n,pos;    
//tag[u]=0表示该结点还未访问过,tag[u]=1表示已经访问过,还递归访问过它的所有子孙,tag[u]=-1表示正在访问
bool dfs(int u)
{
    tag[u]=-1;
    for(int v=0;v<n;++v)
        if(g[u][v])    //有向边(u,v)
        {
            if(tag[v]==-1)    //存在有向环,失败退出
                return false;
            if(tag[v]==0&&!dfs(v))
                return false;
        }
        tag[u]=1;
        topo[--pos]=u;    //访问完一个结点后把它加到当前拓扑序的头部
        return true;
}
bool toposort()
{
    pos=n;
    memset(tag,0,sizeof(tag));
    for(int i=0;i<n;++i)
        if(tag[i]==0&&!dfs(i))
            return false;
    return true;
}
int main()
{
    memset(g,0,sizeof(g));
    scanf("%d",&n);
    for(int i=0;i<n;++i)
    {
        int j;
        while(scanf("%d",&j)&&j)
            g[i][j-1]=1;    //结点下标从0开始,所以要-1
    }
    if(toposort())
    {
        for(int i=0;i<n;++i)
            printf("%d ",topo[i]+1);    //恢复结点原先下标
        printf("\n");
    }
    return 0;
}