#pragma once
#include"../graph/topological-sort.hpp"vector<int>GrundyNumber(vector<vector<int>>&g){vector<int>topo=TopologicalSort(g);if((int)topo.size()==0)returnvector<int>();vector<int>grundy(g.size(),0);vector<int>memo(g.size()+1,0);for(int_=(int)g.size()-1;_>=0;_--){inti=topo[_];if(g[i].size()==0)continue;for(auto&x:g[i]){memo[grundy[x]]++;}while(memo[grundy[i]]>0)grundy[i]++;for(auto&x:g[i]){memo[grundy[x]]--;}}returngrundy;};/**
* @brief Grundy Number
*/
#line 2 "math/grundy-number.hpp"
#line 2 "graph/topological-sort.hpp"
#line 2 "graph/graph-template.hpp"
template<typenameT>structedge{intsrc,to;Tcost;edge(int_to,T_cost):src(-1),to(_to),cost(_cost){}edge(int_src,int_to,T_cost):src(_src),to(_to),cost(_cost){}edge&operator=(constint&x){to=x;return*this;}operatorint()const{returnto;}};template<typenameT>usingEdges=vector<edge<T>>;template<typenameT>usingWeightedGraph=vector<Edges<T>>;usingUnweightedGraph=vector<vector<int>>;// Input of (Unweighted) GraphUnweightedGraphgraph(intN,intM=-1,boolis_directed=false,boolis_1origin=true){UnweightedGraphg(N);if(M==-1)M=N-1;for(int_=0;_<M;_++){intx,y;cin>>x>>y;if(is_1origin)x--,y--;g[x].push_back(y);if(!is_directed)g[y].push_back(x);}returng;}// Input of Weighted Graphtemplate<typenameT>WeightedGraph<T>wgraph(intN,intM=-1,boolis_directed=false,boolis_1origin=true){WeightedGraph<T>g(N);if(M==-1)M=N-1;for(int_=0;_<M;_++){intx,y;cin>>x>>y;Tc;cin>>c;if(is_1origin)x--,y--;g[x].emplace_back(x,y,c);if(!is_directed)g[y].emplace_back(y,x,c);}returng;}// Input of Edgestemplate<typenameT>Edges<T>esgraph([[maybe_unused]]intN,intM,intis_weighted=true,boolis_1origin=true){Edges<T>es;for(int_=0;_<M;_++){intx,y;cin>>x>>y;Tc;if(is_weighted)cin>>c;elsec=1;if(is_1origin)x--,y--;es.emplace_back(x,y,c);}returnes;}// Input of Adjacency Matrixtemplate<typenameT>vector<vector<T>>adjgraph(intN,intM,TINF,intis_weighted=true,boolis_directed=false,boolis_1origin=true){vector<vector<T>>d(N,vector<T>(N,INF));for(int_=0;_<M;_++){intx,y;cin>>x>>y;Tc;if(is_weighted)cin>>c;elsec=1;if(is_1origin)x--,y--;d[x][y]=c;if(!is_directed)d[y][x]=c;}returnd;}/**
* @brief グラフテンプレート
* @docs docs/graph/graph-template.md
*/#line 4 "graph/topological-sort.hpp"
// if the graph is not DAG, return empty vectortemplate<typenameT>vector<int>TopologicalSort(T&g){intN=g.size();vector<int>marked(N,0),temp(N,0),v;autovisit=[&](autof,inti)->bool{if(temp[i]==1)returnfalse;if(marked[i]==0){temp[i]=1;for(auto&e:g[i]){if(f(f,e)==false)returnfalse;}marked[i]=1;v.push_back(i);temp[i]=0;}returntrue;};for(inti=0;i<N;i++){if(marked[i]==0){if(visit(visit,i)==false)returnvector<int>();}}reverse(v.begin(),v.end());returnv;}#line 6 "math/grundy-number.hpp"
vector<int>GrundyNumber(vector<vector<int>>&g){vector<int>topo=TopologicalSort(g);if((int)topo.size()==0)returnvector<int>();vector<int>grundy(g.size(),0);vector<int>memo(g.size()+1,0);for(int_=(int)g.size()-1;_>=0;_--){inti=topo[_];if(g[i].size()==0)continue;for(auto&x:g[i]){memo[grundy[x]]++;}while(memo[grundy[i]]>0)grundy[i]++;for(auto&x:g[i]){memo[grundy[x]]--;}}returngrundy;};/**
* @brief Grundy Number
*/