#pragma once
#include<stack>
#include<vector>
#include"Mylib/Graph/Template/graph.cpp"namespacehaar_lib{namespacetwo_edge_connected_components_impl{template<typenameT>intdfs(constgraph<T>&g,intcur,intpar,std::vector<int>&low,std::vector<int>&order,std::vector<std::vector<int>>&ret,std::stack<int>&st,int&v){if(order[cur]!=-1)returnorder[cur];order[cur]=v;inttemp=v++;st.push(cur);intcount=0;for(constauto&e:g[cur]){if(e.to==par){++count;if(count==1)continue;}constintt=dfs(g,e.to,cur,low,order,ret,st,v);temp=std::min(temp,t);if(low[e.to]>order[cur]){// e is a bridgestd::vector<int>cc;while(true){intc=st.top();cc.emplace_back(c);st.pop();if(c==e.to)break;}ret.emplace_back(cc);}}returnlow[cur]=temp;}}// namespace two_edge_connected_components_impltemplate<typenameT>autotwo_edge_connected_components(constgraph<T>&g){constintn=g.size();std::vector<int>low(n,-1),order(n,-1);std::vector<std::vector<int>>ret;std::stack<int>st;intv=0;for(inti=0;i<n;++i){if(order[i]==-1){two_edge_connected_components_impl::dfs(g,i,-1,low,order,ret,st,v);if(notst.empty()){std::vector<int>cc;while(notst.empty())cc.emplace_back(st.top()),st.pop();ret.emplace_back(cc);}}}returnret;}}// namespace haar_lib
#line 2 "Mylib/Graph/GraphUtils/two_edge_connected_components.cpp"
#include<stack>
#include<vector>
#line 2 "Mylib/Graph/Template/graph.cpp"
#include<iostream>
#line 4 "Mylib/Graph/Template/graph.cpp"
namespacehaar_lib{template<typenameT>structedge{intfrom,to;Tcost;intindex=-1;edge(){}edge(intfrom,intto,Tcost):from(from),to(to),cost(cost){}edge(intfrom,intto,Tcost,intindex):from(from),to(to),cost(cost),index(index){}};template<typenameT>structgraph{usingweight_type=T;usingedge_type=edge<T>;std::vector<std::vector<edge<T>>>data;auto&operator[](size_ti){returndata[i];}constauto&operator[](size_ti)const{returndata[i];}autobegin()const{returndata.begin();}autoend()const{returndata.end();}graph(){}graph(intN):data(N){}boolempty()const{returndata.empty();}intsize()const{returndata.size();}voidadd_edge(inti,intj,Tw,intindex=-1){data[i].emplace_back(i,j,w,index);}voidadd_undirected(inti,intj,Tw,intindex=-1){add_edge(i,j,w,index);add_edge(j,i,w,index);}template<size_tI,boolDIRECTED=true,boolWEIGHTED=true>voidread(intM){for(inti=0;i<M;++i){intu,v;std::cin>>u>>v;u-=I;v-=I;Tw=1;if(WEIGHTED)std::cin>>w;if(DIRECTED)add_edge(u,v,w,i);elseadd_undirected(u,v,w,i);}}};template<typenameT>usingtree=graph<T>;}// namespace haar_lib#line 5 "Mylib/Graph/GraphUtils/two_edge_connected_components.cpp"
namespacehaar_lib{namespacetwo_edge_connected_components_impl{template<typenameT>intdfs(constgraph<T>&g,intcur,intpar,std::vector<int>&low,std::vector<int>&order,std::vector<std::vector<int>>&ret,std::stack<int>&st,int&v){if(order[cur]!=-1)returnorder[cur];order[cur]=v;inttemp=v++;st.push(cur);intcount=0;for(constauto&e:g[cur]){if(e.to==par){++count;if(count==1)continue;}constintt=dfs(g,e.to,cur,low,order,ret,st,v);temp=std::min(temp,t);if(low[e.to]>order[cur]){// e is a bridgestd::vector<int>cc;while(true){intc=st.top();cc.emplace_back(c);st.pop();if(c==e.to)break;}ret.emplace_back(cc);}}returnlow[cur]=temp;}}// namespace two_edge_connected_components_impltemplate<typenameT>autotwo_edge_connected_components(constgraph<T>&g){constintn=g.size();std::vector<int>low(n,-1),order(n,-1);std::vector<std::vector<int>>ret;std::stack<int>st;intv=0;for(inti=0;i<n;++i){if(order[i]==-1){two_edge_connected_components_impl::dfs(g,i,-1,low,order,ret,st,v);if(notst.empty()){std::vector<int>cc;while(notst.empty())cc.emplace_back(st.top()),st.pop();ret.emplace_back(cc);}}}returnret;}}// namespace haar_lib