結果

問題 No.3723 Climb or Detour
コンテスト
ユーザー 👑 p-adic
提出日時 2026-09-14 10:31:45
言語 C++17(gcc12)
(gcc 12.4.0 + boost 1.92.0 + ACL)
コンパイル:
g++-12 -O2 -lm -std=c++17 -Wuninitialized -DONLINE_JUDGE -o a.out _filename_
実行:
./a.out
結果
RE  
実行時間 -
コード長 53,242 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 2,721 ms
コンパイル使用メモリ 276,920 KB
実行使用メモリ 69,820 KB
最終ジャッジ日時 2026-09-19 13:20:17
合計ジャッジ時間 89,453 ms
ジャッジサーバーID
(参考情報)
judge5_0 / judge3_0
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample WA * 1 RE * 1
other AC * 25 WA * 23 RE * 10
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

#ifndef INCLUDE_MODE
  #define INCLUDE_MODE
  // #define REACTIVE
  // #define USE_GETLINE
  /* #define SUBMIT_ONLY */
  #define DEBUG_OUTPUT
  // #define SAMPLE_CHECK dummy
#endif
#ifdef INCLUDE_MAIN

class SimulatedAnnealing
{

public:
  // constexpr data
  static constexpr double log_temparature_min = 1e-2;
  static constexpr int updatability_scale = 1e5;
  static constexpr double log_updatability_scale = log( updatability_scale );

  // 山登りを行わない場合はtime_threshold0を-1にする。
  static constexpr double time_threshold0 = -1;
  static constexpr double time_threshold1 = 1800;
  static constexpr double time_threshold2 = 2200;

  // mode
  int mode; // 現在どの最適化を進めている段階か。mode==0の時は山登りを行う。
  int mode_temp; // mode確認用の変数。
  double start_time; // Execute開始時刻。

  // stable parameter
  int N;
  int K;
  int sx;
  int sy;
  int tx;
  int ty;

  // temporary/optimal parameter
  vector<string> S,S_opt;
  int black,black_opt;

  // 近傍探索用memory (先頭にmをつけて衝突を避ける)
  // ComputeScore()に計算コストがかかる場合は差分計算用の変数もここに用意する。
  // int mi;
  // int mj;
  vector<int> mi;
  vector<int> mj;

  // score
  using score_type = ll; // 変えても良いが、変える場合はUpdatable判定も変更が必要。
  score_type score,score_opt,score_local_opt;

  SimulatedAnnealing( const int& N , const int& K , const int& sx , const int& sy , const int& tx , const int& ty ) : N( N ) , K( K ) , sx( sx ) , sy( sy ) , tx( tx ) , ty( ty )
  {
    mode = 0;
    // temporary parameterの初期化
    S = grid;
    black = 0;
    // 近傍探索用memoryの初期化
    // mi = 0;
    // mj = 0;
    // 単発の貪欲法など、繰り返しをともなわない前処理を以下に行う。
    // VVV
    FOR( i , 0 , H ){
      FOR( j , 0 , W ){
        S[i][j] = ".#"[GetRand(0,1)];
      }
    }
    // AAA
    SetOptimal();
  }

  void SetOptimal()
  {
    S_opt = S;
    black_opt = black;
  }
  
  void OptimiseTemporary()
  {
    // 必要な部分のみ変更してもよい。
    S = S_opt;
    black = black_opt;
  }

  // 近傍探索用memoryの変更。
  // small testのインクリメント、random testの乱択に相当。
  void Increment0( const double& current_time )
  {
    // mode==0は山登り用。山登りが不要ならば実装は空で良い。
    // double rate = time_threshold0 - 0.001 < start_time ? 1.0 : ( current_time - start_time ) / ( time_threshold0 - start_time );
    // if( ++mj == H ){
    //   mj = 0;
    //   if( ++mi == W ){
    //     mi = 0;
    //   }
    // }
    // if( ( mi == sx && mj == sy ) || ( mi == tx && mj == ty ) ){
    //   Increment0( current_time );
    // }
  }

  // 近傍探索用memoryを用いたtemporary parameterの変更。
  void Shift0( const double& current_time )
  {
    Increment0( current_time );
    Revert0();
  }

  // 近傍探索用memoryを用いたtemporary parameterの復元。
  void Revert0()
  {
    // if( S[mi][mj] == '.' ){
    //   S[mi][mj] = '#';
    //   black++;
    // } else {
    //   S[mi][mj] = '.';
    //   black--;
    // }
    int L = len( mi );
    FOR( i , 0 , L ){
      if( S[mi[i]][mj[i]] == '.' ){
        S[mi[i]][mj[i]] = '#';
        black++;
      } else {
        S[mi[i]][mj[i]] = '.';
        black--;
      }
    }
    CERR( S );
  }

  void Increment1( const double& current_time )
  {
    // mode>0から焼き鈍す。
    // double rate = time_threshold1 - 0.001 < start_time ? 1.0 : ( current_time - start_time ) / ( time_threshold1 - start_time );
    // mi = GetRand( 0 , N - 1 );
    // mj = GetRand( 0 , N - 1 );
    // if( ( mi == sx && mj == sy ) || ( mi == tx && mj == ty ) ){
    //   Increment1( current_time );
    // }
    int k = K - score_local_opt / HW;
    REPEAT( k ){
      int i = GetRand( 0 , Hm );
      int j = GetRand( 0 , Wm );
      while( ( i == sx && j == sy ) || ( i == tx && j == ty ) ){
        i = GetRand( 0 , Hm );
        j = GetRand( 0 , Wm );
      }
      mi <<= i;
      mj <<= j;
    }
  }

  void Shift1( const double& current_time )
  {
    Increment1( current_time );
    Revert0();
  }

  void Revert1()
  {
    Revert0();
  }

  void Increment2( const double& current_time )
  {
    // double rate = time_threshold2 - 0.001 < start_time ? 1.0 : ( current_time - start_time ) / ( time_threshold2 - start_time );
    abort();
  }
  
  void Shift2( const double& current_time )
  {
    Increment2( current_time );
    abort();
  }

  void Revert2()
  {
    abort();
  }
  
  void ModeChange()
  {
    OptimiseTemporary();
    CERR( "" );
    CERR( "Changed mode:" , mode , "->" , mode_temp );
    CERR( "Current score:" , ComputeScore() );
    CERR( "" );
    mode = mode_temp;
  }

  void Shift( const double& current_time )
  {
    mode_temp = 0;
    if( mode == mode_temp++ ){
      // time_threshold0がfinal_time以上の時はmodeをこれ以上更新しない。
      if( current_time > time_threshold0 ){
        ModeChange();
      }
    } else if( mode == mode_temp++ ){
      if( current_time > time_threshold1 ){
        ModeChange();
      }
    } else if( mode == mode_temp++ ){
      if( current_time > time_threshold2 ){
        ModeChange();
      }
    } else {
      abort();
    }
    mode_temp = 0;
    if( mode == mode_temp++ ){
      Shift0( current_time );
    } else if( mode == mode_temp++ ){
      Shift1( current_time );
    } else if( mode == mode_temp++ ){
      Shift2( current_time );
    } else {
      abort();
    }
  }

  void Revert()
  {
    mode_temp = 0;
    if( mode == mode_temp++ ){
      Revert0();
    } else if( mode == mode_temp++ ){
      Revert1();
    } else if( mode == mode_temp++ ){
      Revert2();
    } else {
      abort();
    }
  }

  // コストではなくスコア。大きいほど良い。
  const score_type& ComputeScore()
  {
    /* 3次元化 */
    int D = 4 , HWD = HW * D;
    auto EnumHWD = [&]( const int& v ){
      auto [i,j] = EnumHW( v / D );
      return T3<int>( i , j , v % D );
    };
    auto EnumHWD_inv = [&]( const T3<int>& ijk ){
      auto& [i,j,k] = ijk;
      return EnumHW_inv( {i,j} ) * D + k;
    };
    auto edge = [&]( const T3<int>& v ){
      vector<T3<int>> answer{};
      auto& [i,j,k] = v;
      if( k == 1 ){
        answer <<= {i,j,2};
      } else if( k == 3 ){
        answer <<= {i,j,0};
      } else {
        RUN( EdgeOnGrid( {i,j} ) , [p,q] ){
          answer <<= {p,q,S[i][j]==S[p][q]?k:k+1};
        }
      }
      return answer;
    };
    EnumerationGraph graph{ HWD , EnumHWD , EnumHWD_inv , edge };
    using T = T3<int>;
    BFS bfs{ graph , T{-1,-1,-1} , T{sx,sy,0} };
    auto d = bfs.GetDistance();
    auto& di = d[EnumHWD_inv({tx,ty,0})]; 
    if( di <= K ){
      score = di * HW + black;
    } else {
      score = ( K * 2 - di + 1 ) * HW - black;
    }
    return score;
  }

  // 基本的に変えなくて良い。
  double Temparature( const double& log_temparature_min , const double& time , const int& time_lim )
  {
    return exp( ( log_temparature_min * time ) / time_lim );
  }

  // 基本的に変えなくて良い。  
  bool Updatable( const int& updatability_scale , const score_type& score , const score_type& score_local_opt , const double& log_temparature_min , const double& time , const int& time_lim )
  {
    return score > score_local_opt || ( mode > 0 && GetRand( 0 , updatability_scale ) < exp( ( score - score_local_opt ) / Temparature( log_temparature_min , time , time_lim ) + log_updatability_scale ) );
  }

  // 基本的に最適判定以外は変えなくて良い。
  const score_type& Execute( const double& log_temparature_min , const double& executed_time , const double& final_time , const int& updatability_scale )
  {
    START_WATCH;
    start_time = executed_time;
    const double time_lim = final_time - start_time;
    score_opt = ComputeScore(); score_local_opt = score_opt;
    while( CHECK_WATCH( time_lim ) ){
      if( score_opt >= K * HW ){
        CERR( "Reached the maximum:" , score_opt );
        break;
      }
      Shift( current_time );
      const score_type score = ComputeScore();
      if( Updatable( updatability_scale , score , score_local_opt , log_temparature_min , current_time , time_lim ) ){
        if( score > score_opt ){
          CERR( "Updated the optimal score:" , score_opt , "->" , score );
          SetOptimal();
          score_opt = score_local_opt = score;
        } else {
          if( score > score_local_opt ){
            CERR( "Updated the local optimal score:" , score_local_opt , "->" , score );
          } else if( score < score_local_opt ){
            CERR( "Changed the local optimal score:" , score_local_opt , "->" , score );
          } else {
            CERR( "Kept the local optimal score:" , score_local_opt );
          }
          score_local_opt = score;
        }
      } else {
        CERR( "Declined the last score:" , score );
        Revert();
      }
    }
    OptimiseTemporary();
    #ifdef DEBUG
      CERR( "The last score is:" , score_opt );
      assert( score_opt == ComputeScore() );
    #endif
    return score_opt;
  }
};

VO Solve()
{
  CEXPR( double , log_temparature_min , 1e-2 );
  CEXPR( int , updatability_scale , 1e5 );
  CIN( int , N , K , sx , sy , tx , ty ); --sx; --sy; --tx; --ty;
  if( K >= N * 4 ){
    RETURN( -1 );
  }
  START_WATCH; // SA.Executeに渡すCURRENT_TIMEに使う。
  SET_HW( N , N );
  grid = vector( H , string( W , '.' ) );
  SimulatedAnnealing SA{ N , K , sx , sy , tx , ty };
  CEXPR( int , final_time , 2000 );
  auto score = SA.Execute( log_temparature_min , CURRENT_TIME , final_time , updatability_scale );
  if( score >= K * HW ){
    FOR( i , 0 , N ){
      COUT( SA.S[i] );
    }
  } else {
    COUT( -1 );
  }
}
REPEAT_MAIN(1);

#else /* INCLUDE_MAIN */
#ifdef INCLUDE_SUB

// /* COMPAREに使用。圧縮時は削除する。*/
// using answer_type = ll;
// answer_type Naive( int N , int M , int K , const vector<int>& A , const bool& debug_output = true )
// {
//   answer_type a{};
//   return a;
// }
// 
// answer_type Answer( int N , int M , int K , const vector<int>& A , const bool& debug_output = true )
// {
//   answer_type a{};
//   return a;
// }

/* 圧縮時は中身だけ削除する。*/
IN VO Experiment()
{
  // 1変数 ../Contest/Template/Experiment/OneVariable.txt
  // 2変数 ../Contest/Template/Experiment/TwoVariable.txt
  // 3変数 ../Contest/Template/Experiment/ThreeVariable.txt
  
}

/* 圧縮時は中身だけ削除する。*/
IN VO SmallTest()
{
  // 数 ../Contest/Template/SmallTest/Number.txt
  // 配列 ../Contest/Template/SmallTest/Array.txt
  // 順列 ../Contest/Template/SmallTest/Permutation.txt
  // 文字列 ../Contest/Template/SmallTest/String.txt
  // グリッド ../Contest/Template/SmallTest/Grid.txt
  // グラフ ../Contest/Template/SmallTest/Graph.txt
  // 重み付きグラフ ../Contest/Template/SmallTest/WeightedGraph.txt
  // 区間クエリ ../Contest/Template/SmallTest/IntervalQuery.txt

  CERR( "全てのケースを確認しました。" );
}

/* 圧縮時は中身だけ削除する。*/
IN VO RandomTest( const int& test_case_num )
{
  // 数 ../Contest/Template/RandomTest/Number.txt
  // 配列 ../Contest/Template/RandomTest/Array.txt
  // 順列 ../Contest/Template/RandomTest/Permutation.txt
  // 文字列 ../Contest/Template/RandomTest/String.txt
  // グリッド ../Contest/Template/RandomTest/Grid.txt
  // グラフ ../Contest/Template/RandomTest/Graph.txt
  // 重み付きグラフ ../Contest/Template/RandomTest/WeightedGraph.txt
  // 区間クエリ ../Contest/Template/RandomTest/IntervalQuery.txt
  // 多種クエリ ../Contest/Template/RandomTest/MultiTypeQuery.txt
  REPEAT( test_case_num ){

  }
  CERR( "全てのケースを確認しました。" );
}

#define INCLUDE_MAIN
#include __FILE__
#else /* INCLUDE_SUB */
#ifdef INCLUDE_LIBRARY

/* VVV 常設でないライブラリは以下に挿入する。*/
// AffineSpace ../Contest/Template/Library/AffineSpace.txt
// Arithmetic ../Contest/Template/Library/Arithmetic.txt
// BFS ../Contest/Template/Library/BFS.txt
// BIT ../Contest/Template/Library/BIT.txt
// CoordinateCompress ../Contest/Template/Library/CoordinateCompress.txt
// DFS ../Contest/Template/Library/DFS.txt
// DifferenceSequence ../Contest/Template/Library/DifferenceSequence.txt
// Dijkstra ../Contest/Template/Library/Dijkstra.txt
// Knapsack ../Contest/Template/Library/Knapsack.txt
// Matrix ../Contest/Template/Library/Matrix.txt
// Polynomial ../Contest/Template/Library/Polynomial.txt
// Set ../Contest/Template/Library/Set.txt
// SqrtDecomposition ../Contest/Template/Library/SqrtDecomposition.txt
// UnionFind ../Contest/Template/Library/UnionFind.txt

#define BFS BreadthFirstSearch
#ifdef DEBUG
  #include "c:/Users/user/Documents/Programming/Mathematics/Geometry/Graph/Algorithm/BreadthFirstSearch/Debug/a_Body.hpp"
#else
#define VBFS VirtualBreadthFirstSearch

TE <TY T,TY GRAPH>CL VBFS{PU:GRAPH& m_G;T m_external;bool m_initialised;LI<pair<T,T>> m_next;VE<bool> m_reached;VE<T> m_prev;IN VBFS(GRAPH& G,CO T& external);TE <TY Arg> IN VBFS(GRAPH& G,CO T& external,Arg&& init);IN VO Initialise();IN VO Initialise(T init);TE <TE <TY...> TY VEC> IN VO Initialise(VEC<T> inits);IN VO Shift(T init);TE <TE <TY...> TY VEC> IN VO Shift(VEC<T> inits);IN CRI SZ()CO NE;IN VE<bool>::reference reached(CO T& t);IN CO T& prev(CO T& t);IN T Next();tuple<VE<int>,VE<VE<T>>,int> GetConnectedComponent();VE<T> GetNodeEnumeration();VE<T> GetReversedNodeEnumeration();VI VO Push(LI<pair<T,T>>& next,CO T& t,CO T& p)= 0;};
TE <TY T,TY GRAPH> IN VBFS<T,GRAPH>::VBFS(GRAPH& G,CO T& external):m_G(G),m_external(external),m_initialised(false),m_next(),m_reached(),m_prev(){ST_AS(is_same_v<inner_t<GRAPH>,T>);}TE <TY T,TY GRAPH> TE <TY Arg> IN VBFS<T,GRAPH>::VBFS(GRAPH& G,CO T& external,Arg&& init):VBFS<T,GRAPH>(G,external){Initialise(forward<Arg>(init));}TE <TY T,TY GRAPH> IN VO VBFS<T,GRAPH>::Initialise(){m_initialised = true;CRI V = SZ();m_next.clear();m_reached = VE<bool>(V);m_prev = VE<T>(V,m_external);}TE <TY T,TY GRAPH> IN VO VBFS<T,GRAPH>::Initialise(T init){Initialise();m_next <<={MO(init),m_external};}TE <TY T,TY GRAPH> TE <TE <TY...> TY VEC> IN VO VBFS<T,GRAPH>::Initialise(VEC<T> inits){Initialise();for(auto& init:inits){m_next <<={MO(init),m_external};}}TE <TY T,TY GRAPH> IN VO VBFS<T,GRAPH>::Shift(T init){if(m_initialised){m_next ={{MO(init),m_external}};}else{Initialise(MO(init));}}TE <TY T,TY GRAPH> TE <TE <TY...> TY VEC> IN VO VBFS<T,GRAPH>::Shift(VEC<T> inits){if(m_initialised){m_next.clear();for(auto& init:inits){m_next <<={MO(init),m_external};}}else{Initialise(MO(inits));}}TE <TY T,TY GRAPH> IN CRI VBFS<T,GRAPH>::SZ()CO NE{RE m_G.SZ();}TE <TY T,TY GRAPH> IN VE<bool>::reference VBFS<T,GRAPH>::reached(CO T& t){auto&& i = m_G.Enumeration_inv(t);if(!m_initialised){Initialise();}RE m_reached[i];}TE <TY T,TY GRAPH> IN CO T& VBFS<T,GRAPH>::prev(CO T& t){auto&& i = m_G.Enumeration_inv(t);if(!m_initialised){Initialise();}RE m_prev[i];}TE <TY T,TY GRAPH> IN T VBFS<T,GRAPH>::Next(){if(m_next.empty()){RE m_external;}auto[t_curr,p]= m_next.front();m_next.pop_front();auto&& i = m_G.Enumeration_inv(t_curr);if(m_reached[i]){RE Next();}m_reached[i]= true;m_prev[i]= p;for(auto& t:m_G.Edge(t_curr)){Push(m_next,m_G.Vertex(t),t_curr);}RE t_curr;}TE <TY T,TY GRAPH>tuple<VE<int>,VE<VE<T>>,int> VBFS<T,GRAPH>::GetConnectedComponent(){ST_AS(!is_same_v<GRAPH,MemorisationGraph<T,decldecay_t(m_G.edge())>>);CRI V = SZ();VE cc_num(V,-1);VE<VE<T>> cc_num_inv{};int count = 0;for(int i = 0;i < V;i++){if(cc_num[i]== -1){Shift(m_G.Enumeration(i));T t = Next();if(t != m_external){cc_num_inv <<={};WH(t != m_external){cc_num_inv[cc_num[m_G.Enumeration_inv(t)]= count]<<= t;t = Next();}count++;}}}RE{MO(cc_num),MO(cc_num_inv),count};}TE <TY T,TY GRAPH>VE<T> VBFS<T,GRAPH>::GetNodeEnumeration(){VE<T> AN{};T t = Next();WH(t != m_external){AN <<= t;t = Next();}RE AN;}TE <TY T,TY GRAPH>VE<T> VBFS<T,GRAPH>::GetReversedNodeEnumeration(){VE<T> AN{},next{};T t;bool searched;WH(!(searched =(t = Next())== m_external)|| !next.empty()){WH(!next.empty()&&(searched || next.back()!= m_prev[m_G.Enumeration_inv(t)])){AN <<= next.back();pop(next);}if(!searched){next <<= t;}}RE AN;}

TE <TY T,TY GRAPH>CL BFS:PU VBFS<T,GRAPH>{PU:TE <TY...Args> IN BFS(GRAPH& G,CO T& external,Args&&... args);TE <TY U = T> auto GetDistance()-> enable_if_t<is_same_v<GRAPH,MemorisationGraph<U,decldecay_t(declval<GRAPH>().edge())>>,Map<T,int>>;TE <TY U = T> auto GetDistance()-> enable_if_t<!is_same_v<GRAPH,MemorisationGraph<U,decldecay_t(declval<GRAPH>().edge())>>,VE<int>>;IN VO Push(LI<pair<T,T>>& next,CO T& t,CO T& p);};
TE <TY T,TY GRAPH> TE <TY...Args> IN BFS<T,GRAPH>::BFS(GRAPH& G,CO T& external,Args&&... args):VBFS<T,GRAPH>(G,external,forward<Args>(args)...){}TE <TY T,TY GRAPH> TE <TY U>auto BFS<T,GRAPH>::GetDistance()-> enable_if_t<is_same_v<GRAPH,MemorisationGraph<U,decldecay_t(declval<GRAPH>().edge())>>,Map<T,int>>{Map<T,int> AN{};for(auto&[t,u]:TH->m_next){AN[t]= 0;}T t;WH((t = TH->Next())!= TH->m_external){if(AN.count(t)== 0){AN[t]= AN[TH->m_prev[TH->m_G.Enumeration_inv(t)]]+ 1;}}RE AN;}TE <TY T,TY GRAPH> TE <TY U>auto BFS<T,GRAPH>::GetDistance()-> enable_if_t<!is_same_v<GRAPH,MemorisationGraph<U,decldecay_t(declval<GRAPH>().edge())>>,VE<int>>{VE AN(TH->SZ(),-1);for(auto&[t,p]:TH->m_next){AN[TH->m_G.Enumeration_inv(t)]= 0;}T t;WH((t = TH->Next())!= TH->m_external){auto&& i = TH->m_G.Enumeration_inv(t);AN[i]== -1?AN[i]= AN[TH->m_G.Enumeration_inv(TH->m_prev[i])]+ 1:AN[i];}RE AN;}TE <TY T,TY GRAPH> IN VO BFS<T,GRAPH>::Push(LI<pair<T,T>>& next,CO T& t,CO T& p){next <<={t,p};}
#endif

/* AAA 常設でないライブラリは以上に挿入する。*/

#define INCLUDE_SUB
#include __FILE__
#else /* INCLUDE_LIBRARY */
#ifdef DEBUG
  #define _GLIBCXX_DEBUG
#else
  #pragma GCC optimize ( "O3" )
  #pragma GCC optimize ( "unroll-loops" )
  #pragma GCC target ( "sse4.2,fma,avx2,popcnt,lzcnt,bmi2" )
  #define DEXPR( LL , BOUND , VALUE1 , VALUE2 ) CEXPR( LL , BOUND , VALUE1 )
  #define ASSERT( A , MIN , MAX ) AS( ( MIN ) <= A && A <= ( MAX ) )
  #define REPEAT_MAIN( BOUND ) START_MAIN; CEXPR( int , test_case_num_bound , BOUND ); int test_case_num = 1; if CE( test_case_num_bound > 1 ){ FINISH_MAIN
  #ifdef USE_GETLINE
    #define SET_SEPARATE( SEPARATOR , ... ) VariadicGetline( cin , SEPARATOR , __VA_ARGS__ )
    #define SET( ... ) SET_SEPARATE( '\n' , __VA_ARGS__ )
    #define GETLINE_SEPARATE( SEPARATOR , ... ) string __VA_ARGS__; SET_SEPARATE( SEPARATOR , __VA_ARGS__ )
    #define GETLINE( ... ) GETLINE_SEPARATE( '\n' , __VA_ARGS__ )
    #define FINISH_MAIN GETLINE( test_case_num_str ); test_case_num = stoi( test_case_num_str ); ASSERT( test_case_num , 1 , test_case_num_bound ); } REPEAT( test_case_num ){ Solve(); } }
  #else
    #define SET( ... ) VariadicCin( cin , __VA_ARGS__ )
    #define CIN( LL , ... ) LL __VA_ARGS__; SET( __VA_ARGS__ )
    #define SET_A( I , N , ... ) VariadicResize( N + I , __VA_ARGS__ ); FOR( VARIABLE_FOR_SET_A , 0 , N ){ VariadicSet( cin , VARIABLE_FOR_SET_A + I , __VA_ARGS__ ); }
    #define CIN_A( LL , I , N , ... ) VE<LL> __VA_ARGS__; SET_A( I , N , __VA_ARGS__ )
    #define CIN_AA( LL , I0 , N0 , I1 , N1 , VAR ) VE VAR( N0 + I0 , VE<LL>( N1 + I1 ) ); FOR( VARIABLE_FOR_CIN_AA , 0 , N0 ){ SET_A( I1 , N1 , VAR[VARIABLE_FOR_CIN_AA + I0] ); }
    #define FINISH_MAIN SET_ASSERT( test_case_num , 1 , test_case_num_bound ); } REPEAT( test_case_num ){ Solve(); } }
  #endif
  #define SET_ASSERT( A , MIN , MAX ) SET( A ); ASSERT( A , MIN , MAX )
  #define SOLVE_ONLY 
  #define COUT( ... ) VariadicCout( cout , __VA_ARGS__ ) << ENDL
  #define COUTNS( ... ) VariadicCoutNonSep( cout , __VA_ARGS__ )
  #define CERR( ... ) 
  #define CERRNS( ... ) 
  #define COUT_A( I , N , A ) CoutArray( cout , I , N , A ) << ENDL
  #define CERR_A( I , N , A ) 
  #define WHAT( ... ) 
  #define TLE( CONDITION ) if( !( CONDITION ) ){ cerr << "TLE" << endl; ll TLE_VAR = 1; while( TLE_VAR != 0 ){ ( TLE_VAR += 2 ) %= int( 1e9 ); } cerr << TLE_VAR << endl; }
  #define MLE( CONDITION ) if( !( CONDITION ) ){ cerr << "MLE" << endl; vector<vector<ll>> MLE_VAR{}; REPEAT( 1e6 ){ MLE_VAR.push_back( vector<ll>( 1e6 ) ); } cerr << MLE_VAR << endl; }
  #define OLE( CONDITION ) if( !( CONDITION ) ){ cerr << "OLE" << endl; REPEAT( 1e8 ){ COUT( "OLE" ); } }
#endif
#ifdef REACTIVE
  #ifndef DEBUG
    #define LOCAL( ... ) 
    #define RSET( A , ... ) SET( A )
  #endif
  #define RCIN( LL , A , ... ) LL A; RSET( A , __VA_ARGS__ )
  #define ENDL endl
#else
  #define ENDL "\n"
#endif
#include <bits/stdc++.h>
using namespace std;
#define ATT __attribute__( ( target( "sse4.2,fma,avx2,popcnt,lzcnt,bmi2" ) ) )
#define START_MAIN int main(){ ios_base::sync_with_stdio( false ); cin.tie( nullptr )
#define START_WATCH chrono::system_clock::time_point watch = chrono::system_clock::now(); double loop_average_time = 0.0 , loop_start_time = loop_average_time , current_time = loop_start_time; int loop_count = current_time; assert( loop_count == 0 )
#define CURRENT_TIME ( current_time = static_cast<double>( chrono::duration_cast<chrono::microseconds>( chrono::system_clock::now() - watch ).count() / 1000.0 ) )
#define CHECK_WATCH( TL_MS ) ( CURRENT_TIME , loop_count == 0 ? loop_start_time = current_time : loop_average_time = ( current_time - loop_start_time ) / loop_count , ++loop_count , current_time < TL_MS - loop_average_time * 2 - 100.0 )
#define CEXPR( LL , BOUND , VALUE ) CE LL BOUND = VALUE
#define SET_A_ASSERT( I , N , A , MIN , MAX ) FOR( VARIABLE_FOR_SET_A , 0 , N ){ SET_ASSERT( A[VARIABLE_FOR_SET_A + I] , MIN , MAX ); }
#define SET_AA_ASSERT( I0 , N0 , I1 , N1 , A , MIN , MAX ) FOR( VARIABLE_FOR_SET_AA0 , 0 , N0 ){ FOR( VARIABLE_FOR_SET_AA1 , 0 , N1 ){ SET_ASSERT( A[VARIABLE_FOR_SET_AA0 + I0][VARIABLE_FOR_SET_AA1 + I1] , MIN , MAX ); } }
#define CIN_ASSERT( A , MIN , MAX ) decldecay_t( MAX ) A; SET_ASSERT( A , MIN , MAX )
#define CIN_A_ASSERT( I , N , A , MIN , MAX ) vector<decldecay_t( MAX )> A( N + I ); SET_A_ASSERT( I , N , A , MIN , MAX )
#define CIN_AA_ASSERT( I0 , N0 , I1 , N1 , A , MIN , MAX ) vector A( N0 + I0 , vector<decldecay_t( MAX )>( N1 + I1 ) ); SET_AA_ASSERT( I0 , N0 , I1 , N1 , A , MIN , MAX )
#define PR1( A1 , ... ) A1
#define PR2( A1 , A2 , ... ) A2
#define PR3( A1 , A2 , A3 , ... ) A3
#define FOR_( VAR , INITIAL , FINAL , UPPER , COMP , INCR ) for( decldecay_t( UPPER ) VAR = INITIAL ; VAR COMP ( FINAL ) ; VAR INCR )
#define FOR( VAR , INITIAL , ... ) FOR_( VAR , INITIAL , PR1( __VA_ARGS__ ) , PR1( __VA_ARGS__ ) , < , PR3( __VA_ARGS__ , += PR2( __VA_ARGS__ , ? ) , ++ ) )
#define FOREQ( VAR , INITIAL , ... ) FOR_( VAR , INITIAL , PR1( __VA_ARGS__ ) , PR1( __VA_ARGS__ ) , <= , PR3( __VA_ARGS__ , += PR2( __VA_ARGS__ , ? ) , ++ ) )
#define FOREQINV( VAR , INITIAL , ... ) FOR_( VAR , INITIAL , PR1( __VA_ARGS__ ) , INITIAL , + 1 > , PR3( __VA_ARGS__ , -= PR2( __VA_ARGS__ , ? ) , -- ) )
#define ITR( ARRAY ) auto begin_ ## ARRAY = ARRAY .BE() , itr_ ## ARRAY = begin_ ## ARRAY , end_ ## ARRAY = ARRAY .EN()
#define FOR_ITR( ARRAY ) for( ITR( ARRAY ) , itr = itr_ ## ARRAY ; itr_ ## ARRAY != end_ ## ARRAY ; itr_ ## ARRAY ++ , itr++ )
#define RUN( ARRAY , ... ) for( auto&& __VA_ARGS__ : ARRAY )
#define REPEAT( HOW_MANY_TIMES ) FOR( VARIABLE_FOR_REPEAT , 0 , HOW_MANY_TIMES )
#define SET_PRECISION( DECIMAL_DIGITS ) cout << fixed << setprecision( DECIMAL_DIGITS ); cerr << fixed << setprecision( DECIMAL_DIGITS )
#define RETURN( ... ) SOLVE_ONLY; COUT( __VA_ARGS__ ); RE
#define COMPARE( ... ) auto naive = Naive( __VA_ARGS__ , false ); auto answer = Answer( __VA_ARGS__ , false ); bool match = naive == answer; CERR( "(" , #__VA_ARGS__ , ") == (" , __VA_ARGS__ , ") : Naive ==" , naive , match ? "==" : "!=" , answer , "== Answer" ); if( !match ){ CERR( "出力の不一致が検出されました。" ); RE; }
#define CHECK( ... ) auto answer = Answer( __VA_ARGS__ , false ); CERR( "(" , #__VA_ARGS__ , ") == (" , __VA_ARGS__ , ") : Answer == " , answer )

/* 圧縮用 */
#define TE template
#define TY typename
#define US using
#define ST static
#define AS assert
#define IN inline
#define CL class
#define PU public
#define OP operator
#define CE constexpr
#define CO const
#define NE noexcept
#define RE return 
#define WH while
#define VO void
#define VE vector
#define LI list
#define BE begin
#define EN end
#define SZ size
#define LE length
#define MO move
#define TH this
#define CRI CO int&
#define CRUI CO uint&
#define CRL CO ll&
#define VI virtual 
#define IS basic_istream<char,Traits>
#define OS basic_ostream<char,Traits>
#define ST_AS static_assert
#define reMO_CO remove_const
#define is_COructible_v is_constructible_v
#define rBE rbegin

/* 型のエイリアス */
#define decldecay_t(VAR)decay_t<decltype(VAR)>
TE <TY F,TY...Args> US ret_t = decltype(declval<F>()(declval<Args>()...));
TE <TY T> US inner_t = TY T::type;
US uint = unsigned int;
US ll = long long;
US ull = unsigned long long;
US ld = long double;
US lld = __float128;

/* VVV 常設ライブラリは以下に挿入する。*/
#ifdef DEBUG
  #include "C:/Users/user/Documents/Programming/Contest/Template/Local/a_Body.hpp"
  US MP = DMod;
  // US MP = Mod<P>;
#else

/* Random (1KB)*/
ll GetRand(CRL Rand_min,CRL Rand_max){AS(Rand_min <= Rand_max);ll AN = time(NULL);RE AN * rand()%(Rand_max + 1 - Rand_min)+ Rand_min;}

/* Set (2KB)*/
#define DC_OF_HASH(...)struct hash<__VA_ARGS__>{IN size_t OP()(CO __VA_ARGS__& n)CO;};
CL is_ordered{PU:is_ordered()= delete;TE <TY T> ST CE auto Check(CO T& t)-> decltype(t < t,true_type());ST CE false_type Check(...);TE <TY T> ST CE CO bool value = is_same_v< decltype(Check(declval<T>())),true_type >;};
TE <TY T>US Set = conditional_t<is_COructible_v<unordered_set<T>>,unordered_set<T>,conditional_t<is_ordered::value<T>,set<T>,VO>>;

#define DF_OF_POP_FOR_SET(SET)TE <TY T> IN T pop_max(SET& S){AS(!S.empty());auto IT = --S.EN();T AN = *IT;S.erase(IT);RE AN;}TE <TY T> IN T pop_min(SET& S){AS(!S.empty());auto IT = S.BE();T AN = *IT;S.erase(IT);RE AN;}TE <TY T> IN SET& OP<<=(SET& S,T t){S.insert(MO(t));RE S;}TE <TY T,TY U> IN SET& OP<<=(SET& S,U&& u){S.insert(T{forward<U>(u)});RE S;}TE <TY T> IN SET& OP>>=(SET& S,CO T& t){auto IT = S.find(t);if(IT != S.EN()){S.erase(IT);}RE S;}TE <TY T,TY U> IN SET& OP>>=(SET& S,CO U& u){RE S >>= T{u};}TE <TY T> IN CO T& Get(CO SET& S,int i){auto BE = S.BE(),EN = S.EN();auto& IT = i < 0?(++i,--EN):BE;WH(i > 0 && IT != EN){--i;++IT;}WH(i < 0 && IT != BE){++i;--IT;}AS(i == 0);RE *IT;}
#define DF_OF_UNION_FOR_SET(SET)TE <TY T> IN SET& OP|=(SET& S0,SET S1){S0.merge(MO(S1));RE S0;}TE <TY T> IN SET OP|(SET S0,SET S1){RE MO(S0.SZ()< S1.SZ()?S1 |= MO(S0):S0 |= MO(S1));}
TE <TY SET,TY T> IN TY SET::const_iterator MaximumLeq(CO SET& S,CO T& t){auto IT = S.upper_bound(t);RE IT == S.BE()?S.EN():--IT;}TE <TY SET,TY T> IN TY SET::const_iterator MaximumLt(CO SET& S,CO T& t){auto IT = S.lower_bound(t);RE IT == S.BE()?S.EN():--IT;}TE <TY SET,TY T> IN TY SET::const_iterator MinimumGeq(CO SET& S,CO T& t){RE S.lower_bound(t);}TE <TY SET,TY T> IN TY SET::const_iterator MinimumGt(CO SET& S,CO T& t){RE S.upper_bound(t);}TE <TY SET,TY ITERATOR> IN VO EraseBack(SET& S,ITERATOR& IT){IT = S.erase(IT);}TE <TY SET,TY ITERATOR> IN VO EraseFront(SET& S,ITERATOR& IT){IT = S.erase(IT);IT == S.BE()?IT = S.EN():--IT;}TE <TE <TY...> TY SET,TY T,TY...Args> IN bool In(CO T& t,CO SET<T,Args...>& S){RE S.count(t)> 0;}DF_OF_POP_FOR_SET(set<T>);DF_OF_POP_FOR_SET(unordered_set<T>);DF_OF_POP_FOR_SET(multiset<T>);DF_OF_POP_FOR_SET(unordered_multiset<T>);DF_OF_UNION_FOR_SET(set<T>);DF_OF_UNION_FOR_SET(unordered_set<T>);DF_OF_UNION_FOR_SET(multiset<T>);DF_OF_UNION_FOR_SET(unordered_multiset<T>);DF_OF_UNION_FOR_SET(VE<T>);DF_OF_UNION_FOR_SET(LI<T>);

/* Tuple (6KB)*/
#define DF_OF_AR_FOR_TUPLE(OPR)TE <TY T,TY U,TE <TY...> TY PAIR> IN auto OP OPR ## =(PAIR<T,U>& t0,CO PAIR<T,U>& t1)-> decltype((get<0>(t0),t0))&{get<0>(t0)OPR ## = get<0>(t1);get<1>(t0)OPR ## = get<1>(t1);RE t0;}TE <TY T,TY U,TY V,TE <TY...> TY TUPLE> IN auto OP OPR ## =(TUPLE<T,U,V>& t0,CO TUPLE<T,U,V>& t1)-> decltype((get<0>(t0),t0))&{get<0>(t0)OPR ## = get<0>(t1);get<1>(t0)OPR ## = get<1>(t1);get<2>(t0)OPR ## = get<2>(t1);RE t0;}TE <TY T,TY U,TY V,TY W,TE <TY...> TY TUPLE> IN auto OP OPR ## =(TUPLE<T,U,V,W>& t0,CO TUPLE<T,U,V,W>& t1)-> decltype((get<0>(t0),t0))&{get<0>(t0)OPR ## = get<0>(t1);get<1>(t0)OPR ## = get<1>(t1);get<2>(t0)OPR ## = get<2>(t1);get<3>(t0)OPR ## = get<3>(t1);RE t0;}TE <TY ARG,TY T,TY U,TE <TY...> TY PAIR> IN auto OP OPR ## =(PAIR<T,U>& t0,CO ARG& t1)-> decltype((get<0>(t0),t0))&{get<0>(t0)OPR ## = t1;get<1>(t0)OPR ## = t1;RE t0;}TE <TY ARG,TY T,TY U,TY V,TE <TY...> TY TUPLE> IN auto OP OPR ## =(TUPLE<T,U,V>& t0,CO ARG& t1)-> decltype((get<0>(t0),t0))&{get<0>(t0)OPR ## = t1;get<1>(t0)OPR ## = t1;get<2>(t0)OPR ## = t1;RE t0;}TE <TY ARG,TY T,TY U,TY V,TY W,TE <TY...> TY TUPLE> IN auto OP OPR ## =(TUPLE<T,U,V,W>& t0,CO ARG& t1)-> decltype((get<0>(t0),t0))&{get<0>(t0)OPR ## = t1;get<1>(t0)OPR ## = t1;get<2>(t0)OPR ## = t1;get<3>(t0)OPR ## = t1;RE t0;}TE <TE <TY...> TY TUPLE,TY...ARGS,TY ARG> IN auto OP OPR(CO TUPLE<ARGS...>& t0,CO ARG& t1)-> decldecay_t((get<0>(t0),t0)){auto t = t0;RE MO(t OPR ## = t1);}
#define DF_OF_INCREMENT_FOR_TUPLE(INCR)TE <TY T,TY U,TE <TY...> TY PAIR> IN auto OP INCR(PAIR<T,U>& t)-> decltype((get<0>(t),t))&{INCR get<0>(t);INCR get<1>(t);RE t;}TE <TY T,TY U,TY V,TE <TY...> TY TUPLE> IN auto OP INCR(TUPLE<T,U,V>& t)-> decltype((get<0>(t),t))&{INCR get<0>(t);INCR get<1>(t);INCR get<2>(t);RE t;}TE <TY T,TY U,TY V,TY W,TE <TY...> TY TUPLE> IN auto OP INCR(TUPLE<T,U,V,W>& t)-> decltype((get<0>(t),t))&{INCR get<0>(t);INCR get<1>(t);INCR get<2>(t);INCR get<3>(t);RE t;}
TE <CL Traits,TY T> IN IS& OP>>(IS& is,tuple<T>& arg){RE is >> get<0>(arg);}TE <CL Traits,TY T,TY U,TE <TY...> TY V> IN auto OP>>(IS& is,V<T,U>& arg)-> decltype((get<0>(arg),is))&{RE is >> get<0>(arg)>> get<1>(arg);}TE <CL Traits,TY T,TY U,TY V> IN IS& OP>>(IS& is,tuple<T,U,V>& arg){RE is >> get<0>(arg)>> get<1>(arg)>> get<2>(arg);}TE <CL Traits,TY T,TY U,TY V,TY W> IN IS& OP>>(IS& is,tuple<T,U,V,W>& arg){RE is >> get<0>(arg)>> get<1>(arg)>> get<2>(arg)>> get<3>(arg);}TE <CL Traits,TY T> IN OS& OP<<(OS& os,CO tuple<T>& arg){RE os << get<0>(arg);}TE <CL Traits,TY T,TY U,TE <TY...> TY V> IN auto OP<<(OS& os,CO V<T,U>& arg)-> decltype((get<0>(arg),os))&{RE os << get<0>(arg)<< " " << get<1>(arg);}TE <CL Traits,TY T,TY U,TY V> IN OS& OP<<(OS& os,CO tuple<T,U,V>& arg){RE os << get<0>(arg)<< " " << get<1>(arg)<< " " << get<2>(arg);}TE <CL Traits,TY T,TY U,TY V,TY W> IN OS& OP<<(OS& os,CO tuple<T,U,V,W>& arg){RE os << get<0>(arg)<< " " << get<1>(arg)<< " " << get<2>(arg)<< " " << get<3>(arg);}DF_OF_AR_FOR_TUPLE(+);TE <TY T,TY U,TE <TY...> TY V> IN auto OP-(CO V<T,U>& t)-> decldecay_t((get<0>(t),t)){RE{-get<0>(t),-get<1>(t)};}TE <TY T,TY U,TY V> IN tuple<T,U,V> OP-(CO tuple<T,U,V>& t){RE{-get<0>(t),-get<1>(t),-get<2>(t)};}TE <TY T,TY U,TY V,TY W> IN tuple<T,U,V,W> OP-(CO tuple<T,U,V,W>& t){RE{-get<0>(t),-get<1>(t),-get<2>(t),-get<3>(t)};}DF_OF_AR_FOR_TUPLE(-);DF_OF_AR_FOR_TUPLE(*);DF_OF_AR_FOR_TUPLE(/);DF_OF_AR_FOR_TUPLE(%);DF_OF_INCREMENT_FOR_TUPLE(++);DF_OF_INCREMENT_FOR_TUPLE(--);

TE <int n>CL TupleAccessIndex{};TE <TY...Types>CL Tuple:PU tuple<Types...>{PU:IN Tuple(Types&&... args);TE <TY...Args> IN Tuple(Args&&... args);TE <int n> IN auto& OP[](CO TupleAccessIndex<n>& i)NE;TE <int n> IN CO auto& OP[](CO TupleAccessIndex<n>& i)CO NE;};TE <TY...Types>CL tuple_size<Tuple<Types...>>:PU tuple_size<tuple<Types...>>{};TE <size_t n,TY...Types>CL tuple_element<n,Tuple<Types...>>:PU tuple_element<n,tuple<Types...>>{};
TE <TY T,TY U> US Pair = Tuple<T,U>;TE <TY INT> US T2 = Pair<INT,INT>;TE <TY INT> US T3 = Tuple<INT,INT,INT>;TE <TY INT> US T4 = Tuple<INT,INT,INT,INT>;
CE TupleAccessIndex<0> O{};CE TupleAccessIndex<1> I{};CE TupleAccessIndex<2> II{};CE TupleAccessIndex<3> III{};
TE <TY...Types> IN Tuple<Types...>::Tuple(Types&&... args):tuple<Types...>(MO(args)...){}TE <TY...Types> TE <TY...Args> IN Tuple<Types...>::Tuple(Args&&... args):tuple<Types...>(forward<Args>(args)...){}TE <TY...Types> TE <int n> IN auto& Tuple<Types...>::OP[](CO TupleAccessIndex<n>& i)NE{RE get<n>(*TH);}TE <TY...Types> TE <int n> IN CO auto& Tuple<Types...>::OP[](CO TupleAccessIndex<n>& i)CO NE{RE get<n>(*TH);}TE <TY RET,TE <TY...> TY PAIR,TY INT> T2<RET> cast(CO PAIR<INT,INT>& t){RE{get<0>(t),get<1>(t)};}TE <TY RET,TY INT> T3<RET> cast(CO tuple<INT,INT,INT>& t){RE{get<0>(t),get<1>(t),get<2>(t)};}TE <TY RET,TY INT> T4<RET> cast(CO tuple<INT,INT,INT,INT>& t){RE{get<0>(t),get<1>(t),get<2>(t),get<3>(t)};}

#define DF_OF_HASH_FOR_TUPLE(PAIR)TE <TY T,TY U> IN size_t hash<PAIR<T,U>>::OP()(CO PAIR<T,U>& n)CO{ST CO size_t seed =(GetRand(1e3,1e8)<< 1)| 1;ST CO hash<T> h0;ST CO hash<U> h1;RE(h0(get<0>(n))* seed)^ h1(get<1>(n));}
TE <TY T> DC_OF_HASH(tuple<T>);TE <TY T,TY U> DC_OF_HASH(pair<T,U>);TE <TY T,TY U> DC_OF_HASH(tuple<T,U>);TE <TY T,TY U,TY V> DC_OF_HASH(tuple<T,U,V>);TE <TY T,TY U,TY V,TY W> DC_OF_HASH(tuple<T,U,V,W>);
TE <TY T> IN size_t hash<tuple<T>>::OP()(CO tuple<T>& n)CO{ST CO hash<T> h;RE h(get<0>(n));}DF_OF_HASH_FOR_TUPLE(pair);DF_OF_HASH_FOR_TUPLE(tuple);TE <TY T,TY U,TY V> IN size_t hash<tuple<T,U,V>>::OP()(CO tuple<T,U,V>& n)CO{ST CO size_t seed =(GetRand(1e3,1e8)<< 1)| 1;ST CO hash<pair<T,U>> h01;ST CO hash<V> h2;RE(h01({get<0>(n),get<1>(n)})* seed)^ h2(get<2>(n));}TE <TY T,TY U,TY V,TY W> IN size_t hash<tuple<T,U,V,W>>::OP()(CO tuple<T,U,V,W>& n)CO{ST CO size_t seed =(GetRand(1e3,1e8)<< 1)| 1;ST CO hash<pair<T,U>> h01;ST CO hash<pair<V,W>> h23;RE(h01({get<0>(n),get<1>(n)})* seed)^ h23({get<2>(n),get<3>(n)});}

/* Vector (3KB)*/
#define DF_OF_COUT_FOR_VE(V)TE <CL Traits,TY Arg> IN OS& OP<<(OS& os,CO V<Arg>& arg){auto BE = arg.BE(),EN = arg.EN();auto IT = BE;WH(IT != EN){(IT == BE?os:os << " ")<< *IT;IT++;}RE os;}
DF_OF_COUT_FOR_VE(VE);DF_OF_COUT_FOR_VE(LI);DF_OF_COUT_FOR_VE(set);DF_OF_COUT_FOR_VE(unordered_set);DF_OF_COUT_FOR_VE(multiset);IN VO VariadicResize(CRI SZ){}TE <TY Arg,TY... ARGS> IN VO VariadicResize(CRI SZ,Arg& arg,ARGS&... args){arg.resize(SZ);VariadicResize(SZ,args...);}

#define DF_OF_AR_FOR_VE(V,OPR)TE <TY T> IN V<T>& OP OPR ## =(V<T>& a0,CO V<T>& a1){AS(a0.SZ()<= a1.SZ());auto IT0 = a0.BE(),EN0 = a0.EN();auto IT1 = a1.BE();WH(IT0 != EN0){*(IT0++)OPR ## = *(IT1++);}RE a0;}TE <TY T> IN V<T>& OP OPR ## =(V<T>& a,CO T& t){for(auto& x:a){x OPR## = t;}RE a;}TE <TY T,TY U> IN V<T> OP OPR(V<T> a,CO U& u){RE MO(a OPR ## = u);}
#define DF_OF_INCREMENT_FOR_VE(V,INCR)TE <TY T> IN V<T>& OP INCR(V<T>& a){for(auto& i:a){INCR i;}RE a;}
#define DF_OF_SHIFT_FOR_VE(V)TE <TY T> IN V<T>& OP<<=(V<T>& a,T t){a.push_back(MO(t));RE a;}TE <TY T,TY U> IN V<T>& OP<<=(V<T>& a,U&& u){RE a <<= forward<T>(u);}TE <TY T> IN T pop(V<T>& a){AS(!a.empty());T AN = MO(a.back());a.pop_back();RE AN;}
#define DF_OF_ARS_FOR_VE(V)DF_OF_AR_FOR_VE(V,+);DF_OF_AR_FOR_VE(V,-);DF_OF_AR_FOR_VE(V,*);DF_OF_AR_FOR_VE(V,/);DF_OF_AR_FOR_VE(V,%);DF_OF_INCREMENT_FOR_VE(V,++);DF_OF_INCREMENT_FOR_VE(V,--);TE <TY T> IN V<T> OP-(V<T> a){RE MO(a *= T(-1));}TE <TY T> IN V<T> OP*(CO T& t,V<T> v){RE MO(v *= t);}DF_OF_SHIFT_FOR_VE(V);
#define DF_FOR_VE_BOOL(OPR)IN VE<bool>::reference OP OPR ## =(VE<bool>::reference b0,CO bool& b1){RE MO(b0 = bool(b0)OPR b1);}IN VE<bool>& OP OPR ## =(VE<bool>& b0,CO VE<bool>& b1){CO int L = b0.SZ();for(int i = 0;i < L;i++){b0[i]OPR ## = b1[i];}RE b0;}IN VE<bool> OP OPR(VE<bool> b0,CO VE<bool>& b1){RE MO(b0 OPR ## = b1);}
DF_OF_ARS_FOR_VE(VE);DF_OF_ARS_FOR_VE(LI);DF_OF_SHIFT_FOR_VE(basic_string);
TE <TY V> IN auto Get(V& a){RE[&](CRI i = 0)-> CO decldecay_t(a[0])&{RE a[i];};}TE <TY T> IN VE<T> id(CRI SZ){VE<T> AN(SZ);for(int i = 0;i < SZ;i++){AN[i]= i;}RE AN;}TE <TY V> IN VO Sort(V& a,CO bool& reversed = false){US T = decldecay_t(a[0]);if(reversed){ST auto comp =[](CO T& t0,CO T& t1){RE t1 < t0;};sort(a.BE(),a.EN(),comp);}else{sort(a.BE(),a.EN());}}TE <TY V0,TY V1> IN VO Sort(V0& a,V1& b,CO bool& reversed = false){CO int SZ = a.SZ();AS(SZ == int(b.SZ()));VE<pair<decldecay_t(a[0]),decldecay_t(b[0])>> v(SZ);for(int i = 0;i < SZ;i++){v[i]={MO(a[i]),MO(b[i])};}Sort(v,reversed);for(int i = 0;i < SZ;i++){a[i]= MO(v[i].first);b[i]= MO(v[i].second);}}TE <TY V> IN pair<VE<int>,VE<int>> IndexSort(CO V& a,CO bool& reversed = false){CO int SZ = a.SZ();auto index = id<int>(SZ),ord = index;sort(index.BE(),index.EN(),[&](CRI i,CRI j){CO pair ti{a[i],i},tj{a[j],j};RE reversed?tj < ti:ti < tj;});for(int i = 0;i < SZ;i++){ord[index[i]]= i;}RE{MO(index),MO(ord)};}TE <TY V> IN int len(CO V& a){RE a.SZ();}TE <TY V> IN VO Reverse(V& a){CO int SZ = len(a),half = SZ / 2;for(int i = 0;i < half;i++){swap(a[i],a[SZ-1-i]);}};TE <TY V> IN V Reversed(V a){Reverse(a);RE MO(a);}TE <TY RET,TE <TY...> TY V,TY T> IN V<RET> cast(CO V<T>& a){V<RET> AN{};for(auto& x:a){AN <<= x;}RE AN;}
DF_FOR_VE_BOOL(&);DF_FOR_VE_BOOL(|);DF_FOR_VE_BOOL(^);

/* Map (1KB)*/
#define DF_OF_AR_FOR_MAP(MAP,OPR)TE <TY T,TY U> IN MAP<T,U>& OP OPR ## =(MAP<T,U>& a,CO pair<T,U>& v){a[v.first]OPR ## = v.second;RE a;}TE <TY T,TY U> IN MAP<T,U>& OP OPR ## =(MAP<T,U>& a0,CO MAP<T,U>& a1){for(auto&[t,u]:a1){a0[t]OPR ## = u;}RE a0;}TE <TY T,TY U,TY ARG> IN MAP<T,U> OP OPR(MAP<T,U> a,CO ARG& arg){RE MO(a OPR ## = arg);}
#define DF_OF_ARS_FOR_MAP(MAP)DF_OF_AR_FOR_MAP(MAP,+);DF_OF_AR_FOR_MAP(MAP,-);DF_OF_AR_FOR_MAP(MAP,*);DF_OF_AR_FOR_MAP(MAP,/);DF_OF_AR_FOR_MAP(MAP,%);
TE <TY T,TY U>US Map = conditional_t<is_COructible_v<unordered_map<T,int>>,unordered_map<T,U>,conditional_t<is_ordered::value<T>,map<T,U>,VO>>;
DF_OF_ARS_FOR_MAP(map);DF_OF_ARS_FOR_MAP(unordered_map);

/* StdStream (2KB)*/
TE <CL Traits> IN IS& VariadicCin(IS& is){RE is;}TE <CL Traits,TY Arg,TY... ARGS> IN IS& VariadicCin(IS& is,Arg& arg,ARGS&... args){RE VariadicCin(is >> arg,args...);}TE <CL Traits> IN IS& VariadicSet(IS& is,CRI i){RE is;}TE <CL Traits,TY Arg,TY... ARGS> IN IS& VariadicSet(IS& is,CRI i,Arg& arg,ARGS&... args){RE VariadicSet(is >> arg[i],i,args...);}TE <CL Traits> IN IS& VariadicGetline(IS& is,CO char& separator){RE is;}TE <CL Traits,TY Arg,TY... ARGS> IN IS& VariadicGetline(IS& is,CO char& separator,Arg& arg,ARGS&... args){RE VariadicGetline(getline(is,arg,separator),separator,args...);}TE <CL Traits,TY Arg> IN OS& VariadicCout(OS& os,Arg&& arg){RE os << forward<Arg>(arg);}TE <CL Traits,TY Arg1,TY Arg2,TY... ARGS> IN OS& VariadicCout(OS& os,Arg1&& arg1,Arg2&& arg2,ARGS&&... args){RE VariadicCout(os << forward<Arg1>(arg1)<< " ",forward<Arg2>(arg2),forward<ARGS>(args)...);}TE <CL Traits,TY Arg> IN OS& VariadicCoutNonSep(OS& os,Arg&& arg){RE os << forward<Arg>(arg);}TE <CL Traits,TY Arg1,TY Arg2,TY... ARGS> IN OS& VariadicCoutNonSep(OS& os,Arg1&& arg1,Arg2&& arg2,ARGS&&... args){RE VariadicCoutNonSep(os << forward<Arg1>(arg1),forward<Arg2>(arg2),forward<ARGS>(args)...);}TE <CL Traits,TY ARRAY> IN OS& CoutArray(OS& os,CRI i_start,CRI i_ulim,ARRAY&& a){for(int i = i_start;i < i_ulim;i++){(i == i_start?os:(os << " "))<< a[i];}RE os;}

/* Module (6KB)*/
#define DC_OF_CPOINT(POINT)IN CO U& POINT()CO NE
#define DC_OF_POINT(POINT)IN U& POINT()NE
#define DF_OF_CPOINT(POINT)TE <TY U> IN CO U& VirtualPointedSet<U>::POINT()CO NE{RE Point();}
#define DF_OF_POINT(POINT)TE <TY U> IN U& VirtualPointedSet<U>::POINT()NE{RE Point();}
TE <TY U>CL UnderlyingSet{PU:US type = U;};TE <TY U>CL VirtualPointedSet:VI PU UnderlyingSet<U>{PU:VI CO U& Point()CO NE = 0;VI U& Point()NE = 0;DC_OF_CPOINT(Unit);DC_OF_CPOINT(Zero);DC_OF_CPOINT(One);DC_OF_CPOINT(Infty);DC_OF_POINT(init);DC_OF_POINT(root);};TE <TY U>CL PointedSet:VI PU VirtualPointedSet<U>{PU:U m_b_U;IN PointedSet(U b_u = U());IN CO U& Point()CO NE;IN U& Point()NE;};TE <TY U>CL VirtualNSet:VI PU UnderlyingSet<U>{PU:VI U Transfer(CO U& u)= 0;IN U Inverse(CO U& u);};TE <TY U,TY F_U>CL AbstractNSet:VI PU VirtualNSet<U>{PU:F_U m_f_U;IN AbstractNSet(F_U f_U);IN AbstractNSet<U,F_U>& OP=(CO AbstractNSet&)NE;IN U Transfer(CO U& u);};TE <TY U>CL VirtualMagma:VI PU UnderlyingSet<U>{PU:VI U Product(U u0,CO U& u1)= 0;IN U Sum(U u0,CO U& u1);};TE <TY U = ll>CL AdditiveMagma:VI PU VirtualMagma<U>{PU:IN U Product(U u0,CO U& u1);};TE <TY U = ll>CL MultiplicativeMagma:VI PU VirtualMagma<U>{PU:IN U Product(U u0,CO U& u1);};TE <TY U,TY M_U>CL AbstractMagma:VI PU VirtualMagma<U>{PU:M_U m_m_U;IN AbstractMagma(M_U m_U);IN AbstractMagma<U,M_U>& OP=(CO AbstractMagma<U,M_U>&)NE;IN U Product(U u0,CO U& u1);};
TE <TY U> IN PointedSet<U>::PointedSet(U b_U):m_b_U(MO(b_U)){}TE <TY U> IN CO U& PointedSet<U>::Point()CO NE{RE m_b_U;}TE <TY U> IN U& PointedSet<U>::Point()NE{RE m_b_U;}DF_OF_CPOINT(Unit);DF_OF_CPOINT(Zero);DF_OF_CPOINT(One);DF_OF_CPOINT(Infty);DF_OF_POINT(init);DF_OF_POINT(root);TE <TY U,TY F_U> IN AbstractNSet<U,F_U>::AbstractNSet(F_U f_U):m_f_U(MO(f_U)){ST_AS(is_invocable_r_v<U,F_U,U>);}TE <TY U,TY F_U> IN AbstractNSet<U,F_U>& AbstractNSet<U,F_U>::operator=(CO AbstractNSet<U,F_U>&)NE{RE *TH;}TE <TY U,TY F_U> IN U AbstractNSet<U,F_U>::Transfer(CO U& u){RE m_f_U(u);}TE <TY U> IN U VirtualNSet<U>::Inverse(CO U& u){RE Transfer(u);}TE <TY U,TY M_U> IN AbstractMagma<U,M_U>::AbstractMagma(M_U m_U):m_m_U(MO(m_U)){ST_AS(is_invocable_r_v<U,M_U,U,U>);}TE <TY U,TY M_U> IN AbstractMagma<U,M_U>& AbstractMagma<U,M_U>::OP=(CO AbstractMagma<U,M_U>&)NE{RE *TH;}TE <TY U> IN U AdditiveMagma<U>::Product(U u0,CO U& u1){RE MO(u0 += u1);}TE <TY U> IN U MultiplicativeMagma<U>::Product(U u0,CO U& u1){RE MO(u0 *= u1);}TE <TY U,TY M_U> IN U AbstractMagma<U,M_U>::Product(U u0,CO U& u1){RE m_m_U(MO(u0),u1);}TE <TY U> IN U VirtualMagma<U>::Sum(U u0,CO U& u1){RE Product(MO(u0),u1);}

TE <TY U>CL VirtualMonoid:VI PU VirtualMagma<U>,VI PU VirtualPointedSet<U>{};TE <TY U = ll>CL AdditiveMonoid:VI PU VirtualMonoid<U>,PU AdditiveMagma<U>,PU PointedSet<U>{};TE <TY U = ll>CL MultiplicativeMonoid:VI PU VirtualMonoid<U>,PU MultiplicativeMagma<U>,PU PointedSet<U>{PU:IN MultiplicativeMonoid(U e_U);};TE <TY U,TY M_U>CL AbstractMonoid:VI PU VirtualMonoid<U>,PU AbstractMagma<U,M_U>,PU PointedSet<U>{PU:IN AbstractMonoid(M_U m_U,U e_U);};
TE <TY U> IN MultiplicativeMonoid<U>::MultiplicativeMonoid(U e_U):PointedSet<U>(MO(e_U)){}TE <TY U,TY M_U> IN AbstractMonoid<U,M_U>::AbstractMonoid(M_U m_U,U e_U):AbstractMagma<U,M_U>(MO(m_U)),PointedSet<U>(MO(e_U)){}

TE <TY U>CL VirtualGroup:VI PU VirtualMonoid<U>,VI PU VirtualPointedSet<U>,VI PU VirtualNSet<U>{};TE <TY U = ll>CL AdditiveGroup:VI PU VirtualGroup<U>,PU AdditiveMonoid<U>{PU:IN U Transfer(CO U& u);};TE <TY U,TY M_U,TY I_U>CL AbstractGroup:VI PU VirtualGroup<U>,PU AbstractMonoid<U,M_U>,PU AbstractNSet<U,I_U>{PU:IN AbstractGroup(M_U m_U,U e_U,I_U i_U);};
TE <TY U,TY M_U,TY I_U> IN AbstractGroup<U,M_U,I_U>::AbstractGroup(M_U m_U,U e_U,I_U i_U):AbstractMonoid<U,M_U>(MO(m_U),MO(e_U)),AbstractNSet<U,I_U>(MO(i_U)){}TE <TY U> IN U AdditiveGroup<U>::Transfer(CO U& u){RE -u;}

TE <TY R,TY U>CL VirtualRSet:VI PU UnderlyingSet<U>{PU:VI U Action(CO R& r,U u)= 0;IN U Power(U u,CO R& r);IN U ScalarProduct(CO R& r,U u);};TE <TY MAGMA,TY U = inner_t<MAGMA>>CL RegularRSet:VI PU VirtualRSet<U,U>,PU MAGMA{PU:IN RegularRSet(MAGMA magma);IN U Action(CO U& r,U u);};TE <TY R,TY U,TY O_U>CL AbstractRSet:VI PU VirtualRSet<R,U>{PU:O_U m_o_U;IN AbstractRSet(CO R& dummy0,CO U& dummy1,O_U o_U);IN AbstractRSet<R,U,O_U>& OP=(CO AbstractRSet<R,U,O_U>&)NE;IN U Action(CO R& r,U u);};TE <TY R,TY O_U,TY GROUP,TY U = inner_t<GROUP>>CL AbstractModule:PU AbstractRSet<R,U,O_U>,PU GROUP{PU:IN AbstractModule(CO R& dummy,O_U o_U,GROUP M);};TE <TY R,TY U>CL Module:VI PU VirtualRSet<R,U>,PU AdditiveGroup<U>{PU:IN U Action(CO R& r,U u);};
TE <TY MAGMA,TY U> IN RegularRSet<MAGMA,U>::RegularRSet(MAGMA magma):MAGMA(MO(magma)){}TE <TY R,TY U,TY O_U> IN AbstractRSet<R,U,O_U>::AbstractRSet(CO R& dummy0,CO U& dummy1,O_U o_U):m_o_U(MO(o_U)){ST_AS(is_invocable_r_v<U,O_U,R,U>);}TE <TY R,TY O_U,TY GROUP,TY U> IN AbstractModule<R,O_U,GROUP,U>::AbstractModule(CO R& dummy,O_U o_U,GROUP M):AbstractRSet<R,U,O_U>(dummy,M.One(),MO(o_U)),GROUP(MO(M)){ST_AS(is_same_v<U,inner_t<GROUP>>);}TE <TY R,TY U,TY O_U> IN AbstractRSet<R,U,O_U>& AbstractRSet<R,U,O_U>::OP=(CO AbstractRSet<R,U,O_U>&)NE{RE *TH;}TE <TY MAGMA,TY U> IN U RegularRSet<MAGMA,U>::Action(CO U& r,U u){RE TH->Product(r,MO(u));}TE <TY R,TY U,TY O_U> IN U AbstractRSet<R,U,O_U>::Action(CO R& r,U u){RE m_o_U(r,MO(u));}TE <TY R,TY U> IN U Module<R,U>::Action(CO R& r,U u){RE MO(u *= r);}TE <TY R,TY U> IN U VirtualRSet<R,U>::Power(U u,CO R& r){RE Action(r,MO(u));}TE <TY R,TY U> IN U VirtualRSet<R,U>::ScalarProduct(CO R& r,U u){RE Action(r,MO(u));}

/* Graph (5KB)*/
TE <TY T,TY R1,TY R2,TY E>CL VirtualGraph:VI PU UnderlyingSet<T>{PU:VI R1 Enumeration(CRI i)= 0;IN R2 Enumeration_inv(CO T& t);TE <TY PATH> IN R2 Enumeration_inv(CO PATH& p);IN VO Reset();VI CRI SZ()CO NE = 0;VI E& edge()NE = 0;VI ret_t<E,T> Edge(CO T& t)= 0;TE <TY PATH> IN ret_t<E,T> Edge(CO PATH& p);ST IN CO T& Vertex(CO T& t)NE;TE <TY PATH> ST IN CO T& Vertex(CO PATH& e)NE;VI R2 Enumeration_inv_Body(CO T& t)= 0;};TE <TY T,TY R1,TY R2,TY E>CL EdgeImplimentation:VI PU VirtualGraph<T,R1,R2,E>{PU:int m_SZ;E m_edge;IN EdgeImplimentation(CRI SZ,E edge);IN CRI SZ()CO NE;IN E& edge()NE;IN ret_t<E,T> Edge(CO T& t);};TE <TY E>CL Graph:PU EdgeImplimentation<int,CRI,CRI,E>{PU:IN Graph(CRI SZ,E edge);IN CRI Enumeration(CRI i);TE <TY F> IN Graph<F> GetGraph(F edge)CO;IN CRI Enumeration_inv_Body(CRI t);};TE <TY T,TY Enum_T,TY Enum_T_inv,TY E>CL EnumerationGraph:PU EdgeImplimentation<T,ret_t<Enum_T,int>,ret_t<Enum_T_inv,T>,E>{PU:Enum_T m_enum_T;Enum_T_inv m_enum_T_inv;IN EnumerationGraph(CRI SZ,Enum_T enum_T,Enum_T_inv enum_T_inv,E edge);IN ret_t<Enum_T,int> Enumeration(CRI i);TE <TY F> IN EnumerationGraph<T,Enum_T,Enum_T_inv,F> GetGraph(F edge)CO;IN ret_t<Enum_T_inv,T> Enumeration_inv_Body(CO T& t);};TE <TY Enum_T,TY Enum_T_inv,TY E> EnumerationGraph(CRI SZ,Enum_T enum_T,Enum_T_inv enum_T_inv,E edge)-> EnumerationGraph<decldecay_t(declval<Enum_T>()(0)),Enum_T,Enum_T_inv,E>;TE <TY T,TY E>CL MemorisationGraph:PU EdgeImplimentation<T,T,CRI,E>{PU:int m_LE;VE<T> m_memory;Map<T,int> m_memory_inv;IN MemorisationGraph(CRI SZ,CO T& dummy,E edge);IN T Enumeration(CRI i);IN VO Reset();TE <TY F> IN MemorisationGraph<T,F> GetGraph(F edge)CO;IN CRI Enumeration_inv_Body(CO T& t);};
TE <TY T,TY R1,TY R2,TY E> IN EdgeImplimentation<T,R1,R2,E>::EdgeImplimentation(CRI SZ,E edge):m_SZ(SZ),m_edge(MO(edge)){ST_AS(is_COructible_v<T,R1> && is_COructible_v<int,R2> && is_invocable_v<E,T>);}TE <TY E> IN Graph<E>::Graph(CRI SZ,E edge):EdgeImplimentation<int,CRI,CRI,E>(SZ,MO(edge)){}TE <TY T,TY Enum_T,TY Enum_T_inv,TY E> IN EnumerationGraph<T,Enum_T,Enum_T_inv,E>::EnumerationGraph(CRI SZ,Enum_T enum_T,Enum_T_inv enum_T_inv,E edge):EdgeImplimentation<T,ret_t<Enum_T,int>,ret_t<Enum_T_inv,T>,E>(SZ,MO(edge)),m_enum_T(MO(enum_T)),m_enum_T_inv(MO(enum_T_inv)){}TE <TY T,TY E> IN MemorisationGraph<T,E>::MemorisationGraph(CRI SZ,CO T& dummy,E edge):EdgeImplimentation<T,T,CRI,E>(SZ,MO(edge)),m_LE(),m_memory(),m_memory_inv(){ST_AS(is_invocable_v<E,T>);}TE <TY E> IN CRI Graph<E>::Enumeration(CRI i){RE i;}TE <TY T,TY Enum_T,TY Enum_T_inv,TY E> IN ret_t<Enum_T,int> EnumerationGraph<T,Enum_T,Enum_T_inv,E>::Enumeration(CRI i){RE m_enum_T(i);}TE <TY T,TY E> IN T MemorisationGraph<T,E>::Enumeration(CRI i){AS(0 <= i && i < m_LE);RE m_memory[i];}TE <TY T,TY R1,TY R2,TY E> IN R2 VirtualGraph<T,R1,R2,E>::Enumeration_inv(CO T& t){RE Enumeration_inv_Body(t);}TE <TY T,TY R1,TY R2,TY E> TE <TY PATH> IN R2 VirtualGraph<T,R1,R2,E>::Enumeration_inv(CO PATH& p){RE Enumeration_inv_Body(get<0>(p));}TE <TY E> IN CRI Graph<E>::Enumeration_inv_Body(CRI i){RE i;}TE <TY T,TY Enum_T,TY Enum_T_inv,TY E> IN ret_t<Enum_T_inv,T> EnumerationGraph<T,Enum_T,Enum_T_inv,E>::Enumeration_inv_Body(CO T& t){RE m_enum_T_inv(t);}TE <TY T,TY E> IN CRI MemorisationGraph<T,E>::Enumeration_inv_Body(CO T& t){if(m_memory_inv.count(t)== 0){AS(m_LE < TH->SZ());m_memory.push_back(t);RE m_memory_inv[t]= m_LE++;}RE m_memory_inv[t];}TE <TY T,TY R1,TY R2,TY E> VO VirtualGraph<T,R1,R2,E>::Reset(){}TE <TY T,TY E> IN VO MemorisationGraph<T,E>::Reset(){m_LE = 0;m_memory.clear();m_memory_inv.clear();}TE <TY T,TY R1,TY R2,TY E> IN CRI EdgeImplimentation<T,R1,R2,E>::SZ()CO NE{RE m_SZ;}TE <TY T,TY R1,TY R2,TY E> IN E& EdgeImplimentation<T,R1,R2,E>::edge()NE{RE m_edge;}TE <TY T,TY R1,TY R2,TY E> IN ret_t<E,T> EdgeImplimentation<T,R1,R2,E>::Edge(CO T& t){RE m_edge(t);}TE <TY T,TY R1,TY R2,TY E> TE <TY PATH> IN ret_t<E,T> VirtualGraph<T,R1,R2,E>::Edge(CO PATH& p){RE Edge(get<0>(p));}TE <TY E> TE <TY F> IN Graph<F> Graph<E>::GetGraph(F edge)CO{RE Graph<F>(TH->SZ(),MO(edge));}TE <TY T,TY Enum_T,TY Enum_T_inv,TY E> TE <TY F> IN EnumerationGraph<T,Enum_T,Enum_T_inv,F> EnumerationGraph<T,Enum_T,Enum_T_inv,E>::GetGraph(F edge)CO{RE EnumerationGraph<T,Enum_T,Enum_T_inv,F>(TH->SZ(),m_enum_T,m_enum_T_inv,MO(edge));}TE <TY T,TY E> TE <TY F> IN MemorisationGraph<T,F> MemorisationGraph<T,E>::GetGraph(F edge)CO{RE MemorisationGraph<T,F>(TH->SZ(),MO(edge));}TE <TY T,TY R1,TY R2,TY E> IN CO T& VirtualGraph<T,R1,R2,E>::Vertex(CO T& t)NE{RE t;}TE <TY T,TY R1,TY R2,TY E> TE <TY PATH> IN CO T& VirtualGraph<T,R1,R2,E>::Vertex(CO PATH& e)NE{RE Vertex(get<0>(e));}

/* Grid (3KB)*/
#define SET_GRID Hm = H - 1;Wm = W - 1;HW = ll{H}* W
#define SET_HW(h,w)H = h;W = w;SET_GRID
#define CIN_HW SET(H,W);SET_GRID
TE <TY E>CL GridGraph:PU EnumerationGraph<T2<int>,T2<int>(&)(CRI),int(&)(CO T2<int>&),E>{PU:IN GridGraph(E e);};int H,W,Hm,Wm;ll HW;VE<string> grid;char walkable = '.';CO string direction="URDL";VE<VE<bool>> grid_edge ={{false,true,false},{true,false,true},{false,true,false}};
IN T2<int> EnumHW(CRI v){RE{v / W,v % W};}IN int EnumHW_inv(CO T2<int>& ij){auto&[i,j]= ij;RE i * W + j;}TE <TY E> IN GridGraph<E>::GridGraph(E e):EnumerationGraph<T2<int>,T2<int>(&)(CRI),int(&)(CO T2<int>&),E>(HW,EnumHW,EnumHW_inv,MO(e)){AS(HW >> 31 == 0 && H * W == HW);}VE<T2<int>> EdgeOnGrid(CO T2<int>& v){VE<T2<int>> AN{};auto&[i,j]= v;if(grid[i][j]== walkable){for(int di = -1;di <= 1;di++){CO int ni = i + di;if(0 <= ni && ni < H){for(int dj = -1;dj <= 1;dj++){CO int nj = j + dj;if(grid_edge[di+1][dj+1]&& 0 <= nj && nj < W && grid[ni][nj]== walkable){AN <<={ni,nj};}}}}}RE AN;}VE<Pair<T2<int>,ll>> WEdgeOnGrid(CO T2<int>& v){VE<Pair<T2<int>,ll>> AN{};auto&[i,j]= v;if(grid[i][j]== walkable){for(int di = -1;di <= 1;di++){CO int ni = i + di;if(0 <= ni && ni < H){for(int dj = -1;dj <= 1;dj++){CO int nj = j + dj;if(grid_edge[di+1][dj+1]&& 0 <= nj && nj < W && grid[ni][nj]== walkable){AN <<={{ni,nj},1};}}}}}RE AN;}IN VO SetWallStringOnGrid(){grid.resize(H);for(int i = 0;i < H;i++){SET(grid[i]);AS(int(grid[i].SZ())== W);}}IN int DirectionNumberOnGrid(CRI i,CRI j,CRI k,CRI h,CO bool& xy_axis = false){RE xy_axis?i < k?1:i > k?3:j < h?0:j > h?2:-1:i < k?2:i > k?0:j < h?1:j > h?3:-1;}IN int DirectionNumberOnGrid(CO T2<int>& v,CO T2<int>& w,CO bool& xy_axis = false){auto&[i,j]= v;auto&[k,h]= w;RE DirectionNumberOnGrid(i,j,k,h);}IN int DirectionNumberOnGrid(CRI v,CRI w,CO bool& xy_axis = false){RE DirectionNumberOnGrid(EnumHW(v),EnumHW(w));}IN int DirectionNumberOnGrid(CO char& c){RE c == 'U'?0:c == 'R'?1:c == 'D'?2:c == 'L'?3:-1;}IN int ReverseDirectionNumberOnGrid(CRI n){AS(0 <= n && n < 4);RE n ^ 2;}IN T2<int> DirectionVEOnGrid(CO char& c,CO bool& xy_axis = false){CO int n = DirectionNumberOnGrid(c);AS(n != -1);RE T2<int>{xy_axis?n == 1?1:n == 3?-1:0:n == 0?-1:n == 2?1:0,xy_axis?n == 0?1:n == 2?-1:0:n == 1?1:n == 3?-1:0};}

/* Loop (1KB)*/
TE <TY INT> bool NextLoop(CRI SZ,CO VE<INT>& lower_bound,CO VE<INT>& upper_limit,VE<INT>& index){int depth = 0;WH(depth < SZ){if(++index[depth]< upper_limit[depth]){break;}index[depth]= lower_bound[depth];depth++;}RE depth < SZ;}TE <TY INT> bool NextLoop(CO VE<INT>& lower_bound,CO VE<INT>& upper_limit,VE<INT>& index){RE NextLoop(index.SZ(),lower_bound,upper_limit,index);}TE <TY INT> bool NextLoopEq(CRI SZ,CO VE<INT>& lower_bound,CO VE<INT>& upper_bound,VE<INT>& index){int depth = 0;WH(depth < SZ){if(++index[depth]<= upper_bound[depth]){break;}index[depth]= lower_bound[depth];depth++;}RE depth < SZ;}TE <TY INT> bool NextLoopEq(CO VE<INT>& lower_bound,CO VE<INT>& upper_bound,VE<INT>& index){RE NextLoopEq(index.SZ(),lower_bound,upper_bound,index);}

/* string (1KB)*/
TE <TY INT> IN char IntToChar(CO INT& i,CO char& c = 'a'){RE c + i;}TE <TY INT = int> IN INT CharToInt(CO char& i){RE i -(i < 'a'?'A':'a');}TE <TY INT>string ArrayToString(CO VE<INT>& A,CO char& c = 'a'){CO int N = A.SZ();string S(N,c);for(int i = 0;i < N;i++){S[i]= IntToChar<INT>(A[i],c);}RE S;}TE <TY INT = int>VE<INT> StringToArray(CO string& S){CO int N = S.SZ();VE<int> A(N);for(int i = 0;i < N;i++){A[i]= CharToInt<INT>(S[i]);}RE A;}TE <TY INT>string ArrayToParenthesisString(CO VE<INT>& A){CO int N = A.SZ();string S(N,'(');for(int i = 0;i < N;i++){AS(0 <= A[i]&& A[i]<= 1);S[i]= "()"[A[i]];}RE S;}TE <TY INT = int>VE<INT> ParenthesisStringToArray(CO string& S){CO int N = S.SZ();VE<int> A(N);for(int i = 0;i < N;i++){A[i]= S[i]- '(';}RE A;}
#endif
/* AAA 常設ライブラリは以上に挿入する。*/

#define INCLUDE_LIBRARY
#include __FILE__
#endif /* INCLUDE_LIBRARY */
#endif /* INCLUDE_SUB */
#endif /* INCLUDE_MAIN */
0