#pragma once
#include"./graph-template.hpp"// Strongly Connected Components// DAG of SC graph ... scc.dag (including multiedges)// new node of k ... scc[k]// inv of scc[k] = i ... scc.belong(i)template<typenameG>structStronglyConnectedComponents{private:constG&g;vector<vector<int>>rg;vector<int>comp,order;vector<char>used;vector<vector<int>>blng;public:vector<vector<int>>dag;StronglyConnectedComponents(G&_g):g(_g),used(g.size(),0){build();}intoperator[](intk){returncomp[k];}vector<int>&belong(inti){returnblng[i];}private:voiddfs(intidx){if(used[idx])return;used[idx]=true;for(autoto:g[idx])dfs(int(to));order.push_back(idx);}voidrdfs(intidx,intcnt){if(comp[idx]!=-1)return;comp[idx]=cnt;for(intto:rg[idx])rdfs(to,cnt);}voidbuild(){for(inti=0;i<(int)g.size();i++)dfs(i);reverse(begin(order),end(order));used.clear();used.shrink_to_fit();comp.resize(g.size(),-1);rg.resize(g.size());for(inti=0;i<(int)g.size();i++){for(autoe:g[i]){rg[(int)e].emplace_back(i);}}intptr=0;for(inti:order)if(comp[i]==-1)rdfs(i,ptr),ptr++;rg.clear();rg.shrink_to_fit();order.clear();order.shrink_to_fit();dag.resize(ptr);blng.resize(ptr);for(inti=0;i<(int)g.size();i++){blng[comp[i]].push_back(i);for(auto&to:g[i]){intx=comp[i],y=comp[to];if(x==y)continue;dag[x].push_back(y);}}}};
#line 2 "graph/strongly-connected-components.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 グラフテンプレート
*/#line 4 "graph/strongly-connected-components.hpp"
// Strongly Connected Components// DAG of SC graph ... scc.dag (including multiedges)// new node of k ... scc[k]// inv of scc[k] = i ... scc.belong(i)template<typenameG>structStronglyConnectedComponents{private:constG&g;vector<vector<int>>rg;vector<int>comp,order;vector<char>used;vector<vector<int>>blng;public:vector<vector<int>>dag;StronglyConnectedComponents(G&_g):g(_g),used(g.size(),0){build();}intoperator[](intk){returncomp[k];}vector<int>&belong(inti){returnblng[i];}private:voiddfs(intidx){if(used[idx])return;used[idx]=true;for(autoto:g[idx])dfs(int(to));order.push_back(idx);}voidrdfs(intidx,intcnt){if(comp[idx]!=-1)return;comp[idx]=cnt;for(intto:rg[idx])rdfs(to,cnt);}voidbuild(){for(inti=0;i<(int)g.size();i++)dfs(i);reverse(begin(order),end(order));used.clear();used.shrink_to_fit();comp.resize(g.size(),-1);rg.resize(g.size());for(inti=0;i<(int)g.size();i++){for(autoe:g[i]){rg[(int)e].emplace_back(i);}}intptr=0;for(inti:order)if(comp[i]==-1)rdfs(i,ptr),ptr++;rg.clear();rg.shrink_to_fit();order.clear();order.shrink_to_fit();dag.resize(ptr);blng.resize(ptr);for(inti=0;i<(int)g.size();i++){blng[comp[i]].push_back(i);for(auto&to:g[i]){intx=comp[i],y=comp[to];if(x==y)continue;dag[x].push_back(y);}}}};