func_code_string: #include<bits/stdc++.h>   #define int long long   using namespace std;   const int mod=1e9+7;   const int N=3e5+100;   int fa[N];   //并查集,表示i的祖父fa[i]   int begi;   //记录可以随意放的点的位置(只有一个)   int n,m;   int a[N],b[N],c[N],in[N],ans[N];   //a[i]和b[i]表示i必须在a[i]的左边，b[i]的右边   //c[i]表示在缩成一个点的一段中的开头(b[i]的限制中能无限制的放位置)   //in[i]表示入度,ans[i]表示答案   vector<int>g[N],h[N];   //h[i]存储i必须在h[i][1..n]左边   //g[i]表示缩点之后i必须在g[i][1..n]左边   bool vis[N];   //判断序列是否合法   int find(int x)//并查集搜爸爸   {    if(fa[x]==x)return x;    return fa[x]=find(fa[x]);   }   signed main()   {    scanf( %lld%lld ,&n,&m);    for(int i=1;i<=n;i++)    fa[i]=i;     for(int i=1;i<=n;i++)     {     int x,y;     scanf( %lld ,&x);     if(x==0)begi=i;//储存无限制放的点的位置       else h[x].push_back(i);//记录顺序    }    while(m--)//判能否组成序列    {     int x,y;     scanf( %lld%lld ,&x,&y);   //  cout<<x<<   <<y<<endl;      a[x]=y;     b[y]=x;     x=find(x),y=find(y);    // cout<<x<<   <<y<<endl;     if(x==y)//如果成环     {      puts( 0 );      return 0;     }     fa[x]=y;//合并     //无义，相当于把两个集合合并，用来判环后就没用了     //如果一个集合内的元素互相指向，就矛盾了    }     for(int i=1;i<=n;i++)    {     if(b[i]==0)c[find(i)]=i;     //缩点，也就是把一段互相关联的区间缩成一个点去做     //c[find(i)]也就是这一段区间的开头     //也就是说这一个开头不受这一段区间内的点的限制     //反而这个点可以限制这个区间内的其他点     for(int j=0;j<h[i].size();j++)     {      int x=h[i][j];      if(find(i)!=find(x))         {          g[find(i)].push_back(find(x));       //因为把一段缩成一个点       //所以需要把这一段区间内的点的限制关系都转移到这一个点上          in[find(x)]++;       //这一个点的入度(做拓扑排序)         }     }    }    queue<int>q;    //拓扑排序专属队列    q.push(find(begi));    //从无限制的点开始    int ct=0;    while(!q.empty())    {     int x=q.front();     q.pop();     int t=c[x];     //找到缩点     while(t)//把这缩点里面的一个区间记录到答案内     {      ans[++ct]=t;      t=a[t];     }     for(int i=0;i<g[x].size();i++)//拓扑排序pd操作     {      int y=g[x][i];      in[y]--;      if(in[y]==0)q.push(y);      }     }    if(ct!=n)//如果答案数不等于n,就相当于不合法    {     puts( 0 );     return 0;    }    vis[begi]=1;    //判断序列前后关系是否合法    //因为begi没有限制，所以第一个判    for(int i=1;i<=n;i++)    //按答案顺序说    {     if(vis[ans[i]]==0)//如果按照限制关系还没被判断(就相当于i要在j的左边，可j先比i出现了)               return puts( 0 ),0;      for(int j=0;j<h[ans[i]].size();j++)//类似拓扑，把能在接下来队列里的点判为1          vis[h[ans[i]][j]]=1;    }    for(int i=1;i<=n;i++)//输出    {     printf( %lld  ,ans[i]);    }    return 0;   }    