#pragma once
#include"library/graph/WeightedGraph.hpp"
#define REP_(i, n) for (int i = 0; i < (n); i++)
template<typenameT>classGrid{constinth,w;std::optional<T>ban;// D,R,U,Lstaticconstexprstd::pair<int,int>d4[4]={{1,0},{0,1},{-1,0},{0,-1}};template<typenamevecvecT>voidbuild(constvecvecT&grid){REP_(y,h)REP_(x,w){intp=id(y,x);v[p]=grid[y][x];if(banandv[p]==ban.value())continue;REP_(d,4){inty2=y+d4[d].first,x2=x+d4[d].second;if(in(y2,x2)and(!banorban.value()!=grid[y2][x2]))G.add_arc(p,id(y2,x2),d);}}G.build();}public:std::vector<T>v;WeightedGraph<int>G;boolin(inty,intx)const{return0<=yandy<hand0<=xandx<w;}intid(inty,intx)const{assert(in(y,x));returny*w+x;}std::pair<int,int>r2(inta)const{assert(0<=aanda<h*w);return{a/w,a%w};}Grid(conststd::vector<std::vector<T>>&grid,conststd::optional<T>&ban=std::nullopt):h(grid.size()),w(grid[0].size()),ban(ban),v(h*w),G(h*w){build(grid);}Grid(conststd::vector<std::string>&s,conststd::optional<T>&ban=std::nullopt):h(s.size()),w(s[0].size()),ban(ban),v(h*w),G(h*w){static_assert(std::is_same<T,char>::value,"value_type==char");build(s);}intfind(constT&c)const{REP_(i,h*w)if(v[i]==c)returni;return-1;}};#undef REP_
#line 2 "library/graph/WeightedGraph.hpp"
template<typenameT>structWeightedEdge{WeightedEdge()=default;WeightedEdge(intfrom,intto,Tweight):from(from),to(to),weight(weight){}intfrom,to;Tweight;operatorint()const{returnto;}};template<typenameT>structWeightedGraph{intn;usingweight_type=T;usingedge_type=WeightedEdge<T>;std::vector<edge_type>edges;protected:std::vector<int>in_deg;boolprepared;classOutgoingEdges{WeightedGraph*g;intl,r;public:OutgoingEdges(WeightedGraph*g,intl,intr):g(g),l(l),r(r){}edge_type*begin(){return&(g->edges[l]);}edge_type*end(){return&(g->edges[r]);}edge_type&operator[](inti){returng->edges[l+i];}intsize()const{returnr-l;}};classConstOutgoingEdges{constWeightedGraph*g;intl,r;public:ConstOutgoingEdges(constWeightedGraph*g,intl,intr):g(g),l(l),r(r){}constedge_type*begin()const{return&(g->edges[l]);}constedge_type*end()const{return&(g->edges[r]);}constedge_type&operator[](inti)const{returng->edges[l+i];}intsize()const{returnr-l;}};public:OutgoingEdgesoperator[](intv){assert(prepared);return{this,in_deg[v],in_deg[v+1]};}constConstOutgoingEdgesoperator[](intv)const{assert(prepared);return{this,in_deg[v],in_deg[v+1]};}boolis_prepared()const{returnprepared;}WeightedGraph():n(0),in_deg(1,0),prepared(false){}WeightedGraph(intn):n(n),in_deg(n+1,0),prepared(false){}WeightedGraph(intn,intm,booldirected=false,intindexed=1):n(n),in_deg(n+1,0),prepared(false){scan(m,directed,indexed);}voidresize(intn){n=n;}voidadd_arc(intfrom,intto,Tweight){assert(!prepared);assert(0<=fromandfrom<nand0<=toandto<n);edges.emplace_back(from,to,weight);in_deg[from+1]++;}voidadd_edge(intu,intv,Tweight){add_arc(u,v,weight);add_arc(v,u,weight);}voidadd_arc(constedge_type&e){add_arc(e.from,e.to,e.weight);}voidadd_edge(constedge_type&e){add_edge(e.from,e.to,e.weight);}voidscan(intm,booldirected=false,intindexed=1){edges.reserve(directed?m:2*m);while(m--){intu,v;std::cin>>u>>v;u-=indexed;v-=indexed;Tweight;std::cin>>weight;if(directed)add_arc(u,v,weight);elseadd_edge(u,v,weight);}build();}voidbuild(){assert(!prepared);prepared=true;for(intv=0;v<n;v++)in_deg[v+1]+=in_deg[v];std::vector<edge_type>new_edges(in_deg.back());autocounter=in_deg;for(auto&&e:edges)new_edges[counter[e.from]++]=e;edges=new_edges;}voidgraph_debug()const{#ifndef __DEBUG
return;#endif
assert(prepared);for(intfrom=0;from<n;from++){std::cerr<<from<<";";for(inti=in_deg[from];i<in_deg[from+1];i++)std::cerr<<"("<<edges[i].to<<","<<edges[i].weight<<")";std::cerr<<"\n";}}};#line 3 "library/graph/Grid.hpp"
#define REP_(i, n) for (int i = 0; i < (n); i++)
template<typenameT>classGrid{constinth,w;std::optional<T>ban;// D,R,U,Lstaticconstexprstd::pair<int,int>d4[4]={{1,0},{0,1},{-1,0},{0,-1}};template<typenamevecvecT>voidbuild(constvecvecT&grid){REP_(y,h)REP_(x,w){intp=id(y,x);v[p]=grid[y][x];if(banandv[p]==ban.value())continue;REP_(d,4){inty2=y+d4[d].first,x2=x+d4[d].second;if(in(y2,x2)and(!banorban.value()!=grid[y2][x2]))G.add_arc(p,id(y2,x2),d);}}G.build();}public:std::vector<T>v;WeightedGraph<int>G;boolin(inty,intx)const{return0<=yandy<hand0<=xandx<w;}intid(inty,intx)const{assert(in(y,x));returny*w+x;}std::pair<int,int>r2(inta)const{assert(0<=aanda<h*w);return{a/w,a%w};}Grid(conststd::vector<std::vector<T>>&grid,conststd::optional<T>&ban=std::nullopt):h(grid.size()),w(grid[0].size()),ban(ban),v(h*w),G(h*w){build(grid);}Grid(conststd::vector<std::string>&s,conststd::optional<T>&ban=std::nullopt):h(s.size()),w(s[0].size()),ban(ban),v(h*w),G(h*w){static_assert(std::is_same<T,char>::value,"value_type==char");build(s);}intfind(constT&c)const{REP_(i,h*w)if(v[i]==c)returni;return-1;}};#undef REP_