#define PROBLEM "https://judge.yosupo.jp/problem/aplusb"
#include<algorithm>
#include<cassert>
#include<cmath>
#include<iostream>
#include<limits>#include"../../heuristic/all.hpp"
#include"../../utilities/random.hpp"usingm1une::heuristic::AnnealingCooling;usingm1une::heuristic::AnnealingObjective;usingm1une::heuristic::SimulatedAnnealing;boolclose(doublefirst,doublesecond){returnstd::abs(first-second)<=1e-12*std::max(1.0,std::abs(second));}voidtest_temperature(){SimulatedAnnealingexponential(100.0,1.0);assert(close(exponential.temperature(0.0),100.0));assert(close(exponential.temperature(0.5),10.0));assert(close(exponential.temperature(1.0),1.0));SimulatedAnnealinglinear(100.0,0.0,AnnealingObjective::maximize,AnnealingCooling::linear);assert(close(linear.temperature(0.0),100.0));assert(close(linear.temperature(0.25),75.0));assert(close(linear.temperature(1.0),0.0));}voidtest_maximization(){SimulatedAnnealingannealing(10.0,10.0);assert(annealing.acceptance_probability(3,4,0.5)==1.0);assert(annealing.acceptance_probability(3,3,0.5)==1.0);assert(close(annealing.acceptance_probability(3,-7,0.5),std::exp(-1.0)));assert(annealing.accept(3,4,0.5,0.999999));assert(annealing.accept(3,-7,0.5,0.3));assert(!annealing.accept(3,-7,0.5,0.4));}voidtest_minimization(){SimulatedAnnealingannealing(2.0,2.0,AnnealingObjective::minimize);assert(annealing.acceptance_probability(5,4,0.0)==1.0);assert(close(annealing.acceptance_probability(5,7,0.0),std::exp(-1.0)));assert(annealing.accept_delta(-1.0,0.0,0.999999));assert(!annealing.accept_delta(2.0,0.0,0.4));}voidtest_zero_temperature_and_large_scores(){SimulatedAnnealinggreedy(1.0,0.0,AnnealingObjective::maximize,AnnealingCooling::linear);assert(greedy.acceptance_probability_delta(-1.0,1.0)==0.0);assert(!greedy.accept_delta(-1.0,1.0,0.0));assert(greedy.accept_delta(0.0,1.0,0.999999));longlonglow=std::numeric_limits<longlong>::min();longlonghigh=std::numeric_limits<longlong>::max();assert(greedy.acceptance_probability(low,high,1.0)==1.0);assert(greedy.acceptance_probability(high,low,1.0)==0.0);}voidtest_randomized_against_formula(){m1une::utilities::Randomrandom(0x51a7edULL);for(AnnealingObjectiveobjective:{AnnealingObjective::minimize,AnnealingObjective::maximize}){SimulatedAnnealingannealing(30.0,0.03,objective);for(inttrial=0;trial<10000;trial++){longlongcurrent=random.uniform(-1000000000,1000000000);longlongcandidate=random.uniform(-1000000000,1000000000);doubleprogress=random.real();doublerandom01=random.real();longdoubledelta=static_cast<longdouble>(candidate)-static_cast<longdouble>(current);longdoubleimprovement=objective==AnnealingObjective::maximize?delta:-delta;doubleexpected=1.0;if(improvement<0.0L){expected=std::exp(static_cast<double>(improvement/annealing.temperature(progress)));}assert(close(annealing.acceptance_probability(current,candidate,progress),expected));assert(annealing.accept(current,candidate,progress,random01)==(random01<expected));}}}intmain(){test_temperature();test_maximization();test_minimization();test_zero_temperature_and_large_scores();test_randomized_against_formula();longlonga,b;std::cin>>a>>b;std::cout<<a+b<<'\n';}
#line 1 "verify/heuristic/simulated_annealing.test.cpp"
#define PROBLEM "https://judge.yosupo.jp/problem/aplusb"
#include<algorithm>
#include<cassert>
#include<cmath>
#include<iostream>
#include<limits>#line 1 "heuristic/all.hpp"
#line 1 "heuristic/beam_search.hpp"
#line 6 "heuristic/beam_search.hpp"
#include<concepts>
#include<cstddef>
#include<functional>
#include<type_traits>
#include<utility>
#include<vector>#line 1 "heuristic/objective.hpp"
namespacem1une{namespaceheuristic{enumclassObjective{minimize,maximize,};template<classScore>boolbetter_score(constScore&first,constScore&second,Objectiveobjective){if(objective==Objective::maximize)returnsecond<first;returnfirst<second;}}// namespace heuristic}// namespace m1une#line 14 "heuristic/beam_search.hpp"
namespacem1une{namespaceheuristic{template<classState,classScore>structBeamSearchResult{Statestate;Scorescore;intdepth;std::size_texpanded_states;std::size_tgenerated_states;};namespacebeam_search_detail{template<classState,classScore>structNode{Statestate;Scorescore;std::size_torder;};template<classState,classScore>structBetterNode{Objectiveobjective;booloperator()(constNode<State,Score>&first,constNode<State,Score>&second)const{if(better_score(first.score,second.score,objective))returntrue;if(better_score(second.score,first.score,objective))returnfalse;returnfirst.order<second.order;}};}// namespace beam_search_detail// expand(state, next_depth) may return a range of children. For allocation-free// generation, expand(state, next_depth, emit) may instead call emit(child).// evaluate(state) returns its score. The best beam_width states are retained at// every depth, and the best state in the last non-empty layer is returned.template<classState,classExpand,classEvaluate>autobeam_search(Stateinitial_state,intdepth_limit,intbeam_width,Expandexpand,Evaluateevaluate,Objectiveobjective=Objective::maximize){assert(0<=depth_limit);assert(0<beam_width);usingScore=std::remove_cvref_t<std::invoke_result_t<Evaluate&,constState&>>;usingNode=beam_search_detail::Node<State,Score>;usingBetter=beam_search_detail::BetterNode<State,Score>;Scoreinitial_score=std::invoke(evaluate,initial_state);std::vector<Node>beam;beam.push_back(Node{std::move(initial_state),std::move(initial_score),0});std::size_texpanded_states=0;std::size_tgenerated_states=0;intreached_depth=0;if(depth_limit<0||beam_width<=0)depth_limit=0;Betterbetter{objective};for(intnext_depth=1;next_depth<=depth_limit;next_depth++){std::vector<Node>candidates;candidates.reserve(static_cast<std::size_t>(beam_width));std::size_torder=0;for(constNode&node:beam){expanded_states++;autoemit=[&](auto&&candidate_state){usingCandidate=decltype(candidate_state);static_assert(std::is_constructible_v<State,Candidate>);Statestate(std::forward<Candidate>(candidate_state));Scorecandidate_score=std::invoke(evaluate,state);Nodecandidate{std::move(state),std::move(candidate_score),order++};generated_states++;if(int(candidates.size())<beam_width){candidates.push_back(std::move(candidate));std::push_heap(candidates.begin(),candidates.end(),better);}elseif(better(candidate,candidates.front())){std::pop_heap(candidates.begin(),candidates.end(),better);candidates.back()=std::move(candidate);std::push_heap(candidates.begin(),candidates.end(),better);}};ifconstexpr(std::invocable<Expand&,constState&,int>){autonext_states=std::invoke(expand,node.state,next_depth);for(auto&candidate_state:next_states){emit(std::move(candidate_state));}}elseifconstexpr(std::invocable<Expand&,constState&>){autonext_states=std::invoke(expand,node.state);for(auto&candidate_state:next_states){emit(std::move(candidate_state));}}else{std::invoke(expand,node.state,next_depth,emit);}}if(candidates.empty())break;beam=std::move(candidates);reached_depth=next_depth;}intbest=0;for(intindex=1;index<int(beam.size());index++){if(better(beam[index],beam[best]))best=index;}returnBeamSearchResult<State,Score>{std::move(beam[best].state),std::move(beam[best].score),reached_depth,expanded_states,generated_states};}}// namespace heuristic}// namespace m1une#line 1 "heuristic/hill_climbing.hpp"
#line 5 "heuristic/hill_climbing.hpp"
#line 7 "heuristic/hill_climbing.hpp"
namespacem1une{namespaceheuristic{usingHillClimbingObjective=Objective;classHillClimbing{private:Objective_objective;bool_accept_equal;public:explicitHillClimbing(Objectiveobjective=Objective::maximize,boolaccept_equal=false):_objective(objective),_accept_equal(accept_equal){}boolaccept_delta(longdoublecandidate_minus_current)const{if(_objective==Objective::maximize){return_accept_equal?0.0L<=candidate_minus_current:0.0L<candidate_minus_current;}return_accept_equal?candidate_minus_current<=0.0L:candidate_minus_current<0.0L;}template<std::convertible_to<longdouble>CurrentScore,std::convertible_to<longdouble>CandidateScore>boolaccept(CurrentScorecurrent_score,CandidateScorecandidate_score)const{longdoubledelta=static_cast<longdouble>(candidate_score)-static_cast<longdouble>(current_score);returnaccept_delta(delta);}};}// namespace heuristic}// namespace m1une#line 1 "heuristic/simulated_annealing.hpp"
#line 8 "heuristic/simulated_annealing.hpp"
#line 10 "heuristic/simulated_annealing.hpp"
namespacem1une{namespaceheuristic{usingAnnealingObjective=Objective;enumclassAnnealingCooling{linear,exponential,};classSimulatedAnnealing{private:double_start_temperature;double_end_temperature;AnnealingObjective_objective;AnnealingCooling_cooling;longdoubledirected_delta(longdoublecandidate_minus_current)const{if(_objective==AnnealingObjective::maximize){returncandidate_minus_current;}return-candidate_minus_current;}public:SimulatedAnnealing(doublestart_temperature,doubleend_temperature,AnnealingObjectiveobjective=AnnealingObjective::maximize,AnnealingCoolingcooling=AnnealingCooling::exponential):_start_temperature(start_temperature),_end_temperature(end_temperature),_objective(objective),_cooling(cooling){assert(std::isfinite(start_temperature));assert(std::isfinite(end_temperature));assert(0.0<=end_temperature);assert(end_temperature<=start_temperature);assert(cooling!=AnnealingCooling::exponential||0.0<end_temperature);}doubletemperature(doubleprogress)const{assert(std::isfinite(progress));assert(0.0<=progress&&progress<=1.0);progress=std::clamp(progress,0.0,1.0);if(_cooling==AnnealingCooling::linear){return_start_temperature+(_end_temperature-_start_temperature)*progress;}return_start_temperature*std::pow(_end_temperature/_start_temperature,progress);}doubleacceptance_probability_delta(longdoublecandidate_minus_current,doubleprogress)const{longdoubleimprovement=directed_delta(candidate_minus_current);if(0.0L<=improvement)return1.0;doublecurrent_temperature=temperature(progress);if(current_temperature==0.0)return0.0;returnstd::exp(static_cast<double>(improvement/static_cast<longdouble>(current_temperature)));}boolaccept_delta(longdoublecandidate_minus_current,doubleprogress,doublerandom01)const{assert(std::isfinite(random01));assert(0.0<=random01&&random01<1.0);returnrandom01<acceptance_probability_delta(candidate_minus_current,progress);}template<std::convertible_to<longdouble>CurrentScore,std::convertible_to<longdouble>CandidateScore>doubleacceptance_probability(CurrentScorecurrent_score,CandidateScorecandidate_score,doubleprogress)const{longdoubledelta=static_cast<longdouble>(candidate_score)-static_cast<longdouble>(current_score);returnacceptance_probability_delta(delta,progress);}template<std::convertible_to<longdouble>CurrentScore,std::convertible_to<longdouble>CandidateScore>boolaccept(CurrentScorecurrent_score,CandidateScorecandidate_score,doubleprogress,doublerandom01)const{longdoubledelta=static_cast<longdouble>(candidate_score)-static_cast<longdouble>(current_score);returnaccept_delta(delta,progress,random01);}};}// namespace heuristic}// namespace m1une#line 8 "heuristic/all.hpp"
#line 1 "utilities/random.hpp"
#line 6 "utilities/random.hpp"
#include<chrono>
#line 8 "utilities/random.hpp"
#include<cstdint>
#line 10 "utilities/random.hpp"
#include<numeric>
#include<queue>
#include<random>
#include<string>
#include<string_view>
#include<tuple>
#line 17 "utilities/random.hpp"
#include<unordered_set>
#line 20 "utilities/random.hpp"
namespacem1une{namespaceutilities{structRandomGraphOptions{booldirected=false;boolallow_self_loops=false;boolallow_parallel_edges=false;};structRandom{private:std::mt19937_64_engine;staticunsignedlonglongchrono_seed(){returnstatic_cast<unsignedlonglong>(std::chrono::steady_clock::now().time_since_epoch().count());}staticstd::uint64_tgraph_edge_count(intvertex_count,constRandomGraphOptions&options){std::uint64_tn=static_cast<unsignedint>(vertex_count);if(options.directed){returnoptions.allow_self_loops?n*n:n*(n-1);}returnoptions.allow_self_loops?n*(n+1)/2:n*(n-1)/2;}staticstd::pair<int,int>decode_graph_edge(std::uint64_tindex,intvertex_count,constRandomGraphOptions&options){std::uint64_tn=static_cast<unsignedint>(vertex_count);if(options.directed){std::uint64_twidth=options.allow_self_loops?n:n-1;intfrom=int(index/width);intoffset=int(index%width);intto=options.allow_self_loops||offset<from?offset:offset+1;return{from,to};}autoprefix=[&](std::uint64_tvertex){if(options.allow_self_loops){returnvertex*(2*n-vertex+1)/2;}returnvertex*(2*n-vertex-1)/2;};std::uint64_tlow=0;std::uint64_thigh=n;while(low+1<high){std::uint64_tmiddle=(low+high)/2;if(prefix(middle)<=index){low=middle;}else{high=middle;}}intfrom=int(low);intto=from+int(index-prefix(low))+(options.allow_self_loops?0:1);return{from,to};}public:Random():_engine(chrono_seed()){}explicitRandom(unsignedlonglongseed):_engine(seed){}voidseed(unsignedlonglongvalue){_engine.seed(value);}std::mt19937_64&engine(){return_engine;}unsignedlonglongoperator()(){return_engine();}longlonguniform(longlongl,longlongr){returnstd::uniform_int_distribution<longlong>(l,r)(_engine);}unsignedlonglonguniform_unsigned(unsignedlonglongl,unsignedlonglongr){returnstd::uniform_int_distribution<unsignedlonglong>(l,r)(_engine);}doublereal(doublel=0.0,doubler=1.0){returnstd::uniform_real_distribution<double>(l,r)(_engine);}template<std::integralT>requires(!std::same_as<std::remove_cv_t<T>,bool>)std::vector<T>sequence(intsize,Tlower,Tupper){assert(0<=size);assert(lower<=upper);if(size<0||upper<lower)return{};std::vector<T>result(size);ifconstexpr(std::signed_integral<T>){std::uniform_int_distribution<longlong>distribution(static_cast<longlong>(lower),static_cast<longlong>(upper));for(T&value:result)value=static_cast<T>(distribution(_engine));}else{std::uniform_int_distribution<unsignedlonglong>distribution(static_cast<unsignedlonglong>(lower),static_cast<unsignedlonglong>(upper));for(T&value:result)value=static_cast<T>(distribution(_engine));}returnresult;}std::stringstring(intlength,std::string_viewalphabet="abcdefghijklmnopqrstuvwxyz"){assert(0<=length);assert(length==0||!alphabet.empty());if(length<0||(0<length&&alphabet.empty()))return{};std::stringresult(length,'\0');for(char&character:result){character=alphabet[uniform(0,int(alphabet.size())-1)];}returnresult;}std::vector<int>permutation(intsize,intfirst=0){assert(0<=size);if(size<0)return{};std::vector<int>result(size);std::iota(result.begin(),result.end(),first);shuffle(result);returnresult;}// Returns the edges of a uniformly random labeled tree on [0, size).std::vector<std::pair<int,int>>tree(intsize){assert(0<=size);if(size<=1)return{};std::vector<int>prufer=sequence(size-2,0,size-1);std::vector<int>degree(size,1);for(intvertex:prufer)degree[vertex]++;std::priority_queue<int,std::vector<int>,std::greater<int>>leaves;for(intvertex=0;vertex<size;vertex++){if(degree[vertex]==1)leaves.push(vertex);}std::vector<std::pair<int,int>>edges;edges.reserve(size-1);for(intvertex:prufer){intleaf=leaves.top();leaves.pop();edges.emplace_back(leaf,vertex);if(--degree[vertex]==1)leaves.push(vertex);}intfirst=leaves.top();leaves.pop();edges.emplace_back(first,leaves.top());shuffle(edges);for(auto&[from,to]:edges){if(uniform(0,1))std::swap(from,to);}returnedges;}// Returns m random edges on [0, vertex_count). By default the result is// a simple undirected graph without self-loops.std::vector<std::pair<int,int>>graph(intvertex_count,intedge_count,RandomGraphOptionsoptions={}){assert(0<=vertex_count);assert(0<=edge_count);if(vertex_count<0||edge_count<0)return{};if(edge_count==0)return{};assert(0<vertex_count);if(vertex_count==0)return{};if(!options.allow_self_loops){assert(2<=vertex_count||edge_count==0);if(vertex_count<2)return{};}std::vector<std::pair<int,int>>edges;edges.reserve(edge_count);if(options.allow_parallel_edges){for(intedge=0;edge<edge_count;edge++){intfrom=int(uniform(0,vertex_count-1));intto;if(options.allow_self_loops){to=int(uniform(0,vertex_count-1));}else{to=int(uniform(0,vertex_count-2));if(from<=to)to++;}if(!options.directed&&to<from)std::swap(from,to);edges.emplace_back(from,to);}returnedges;}std::uint64_tmaximum=graph_edge_count(vertex_count,options);assert(static_cast<std::uint64_t>(edge_count)<=maximum);if(maximum<static_cast<std::uint64_t>(edge_count))return{};std::unordered_set<std::uint64_t>selected;selected.reserve(static_cast<std::size_t>(edge_count)*2+1);std::vector<std::uint64_t>indices;indices.reserve(edge_count);for(std::uint64_tcurrent=maximum-edge_count;current<maximum;current++){std::uint64_tcandidate=uniform_unsigned(0,current);if(selected.contains(candidate))candidate=current;selected.insert(candidate);indices.push_back(candidate);}for(std::uint64_tindex:indices){edges.push_back(decode_graph_edge(index,vertex_count,options));}returnedges;}std::vector<std::pair<int,int>>directed_graph(intvertex_count,intedge_count,boolallow_self_loops=false){RandomGraphOptionsoptions;options.allow_self_loops=allow_self_loops;returndirected_graph(vertex_count,edge_count,options);}std::vector<std::pair<int,int>>directed_graph(intvertex_count,intedge_count,RandomGraphOptionsoptions){options.directed=true;returngraph(vertex_count,edge_count,options);}// Returns a directed acyclic graph. Vertices are randomly permuted before// every sampled edge is directed forward in that topological order.std::vector<std::pair<int,int>>dag(intvertex_count,intedge_count,RandomGraphOptionsoptions={}){options.directed=false;options.allow_self_loops=false;std::vector<std::pair<int,int>>edges=graph(vertex_count,edge_count,options);std::vector<int>order=permutation(vertex_count);for(auto&[from,to]:edges){from=order[from];to=order[to];}returnedges;}template<std::integralWeight>requires(!std::same_as<std::remove_cv_t<Weight>,bool>)std::vector<std::tuple<int,int,Weight>>weighted_tree(intsize,Weightlower,Weightupper){std::vector<std::pair<int,int>>edges=tree(size);std::vector<Weight>weights=sequence(int(edges.size()),lower,upper);std::vector<std::tuple<int,int,Weight>>result;result.reserve(edges.size());for(intindex=0;index<int(edges.size());index++){result.emplace_back(edges[index].first,edges[index].second,weights[index]);}returnresult;}template<std::integralWeight>requires(!std::same_as<std::remove_cv_t<Weight>,bool>)std::vector<std::tuple<int,int,Weight>>weighted_graph(intvertex_count,intedge_count,Weightlower,Weightupper,RandomGraphOptionsoptions={}){std::vector<std::pair<int,int>>edges=graph(vertex_count,edge_count,options);std::vector<Weight>weights=sequence(int(edges.size()),lower,upper);std::vector<std::tuple<int,int,Weight>>result;result.reserve(edges.size());for(intindex=0;index<int(edges.size());index++){result.emplace_back(edges[index].first,edges[index].second,weights[index]);}returnresult;}template<std::integralWeight>requires(!std::same_as<std::remove_cv_t<Weight>,bool>)std::vector<std::tuple<int,int,Weight>>weighted_directed_graph(intvertex_count,intedge_count,Weightlower,Weightupper,boolallow_self_loops=false){RandomGraphOptionsoptions;options.allow_self_loops=allow_self_loops;returnweighted_directed_graph(vertex_count,edge_count,lower,upper,options);}template<std::integralWeight>requires(!std::same_as<std::remove_cv_t<Weight>,bool>)std::vector<std::tuple<int,int,Weight>>weighted_directed_graph(intvertex_count,intedge_count,Weightlower,Weightupper,RandomGraphOptionsoptions){options.directed=true;returnweighted_graph(vertex_count,edge_count,lower,upper,options);}template<std::integralWeight>requires(!std::same_as<std::remove_cv_t<Weight>,bool>)std::vector<std::tuple<int,int,Weight>>weighted_dag(intvertex_count,intedge_count,Weightlower,Weightupper,RandomGraphOptionsoptions={}){std::vector<std::pair<int,int>>edges=dag(vertex_count,edge_count,options);std::vector<Weight>weights=sequence(int(edges.size()),lower,upper);std::vector<std::tuple<int,int,Weight>>result;result.reserve(edges.size());for(intindex=0;index<int(edges.size());index++){result.emplace_back(edges[index].first,edges[index].second,weights[index]);}returnresult;}template<typenameT>voidshuffle(std::vector<T>&v){std::shuffle(v.begin(),v.end(),_engine);}template<typenameIterator>voidshuffle(Iteratorfirst,Iteratorlast){std::shuffle(first,last,_engine);}template<typenameT>constT&choice(conststd::vector<T>&v){returnv[uniform(0,static_cast<longlong>(v.size())-1)];}};}// namespace utilities}// namespace m1une#line 11 "verify/heuristic/simulated_annealing.test.cpp"
usingm1une::heuristic::AnnealingCooling;usingm1une::heuristic::AnnealingObjective;usingm1une::heuristic::SimulatedAnnealing;boolclose(doublefirst,doublesecond){returnstd::abs(first-second)<=1e-12*std::max(1.0,std::abs(second));}voidtest_temperature(){SimulatedAnnealingexponential(100.0,1.0);assert(close(exponential.temperature(0.0),100.0));assert(close(exponential.temperature(0.5),10.0));assert(close(exponential.temperature(1.0),1.0));SimulatedAnnealinglinear(100.0,0.0,AnnealingObjective::maximize,AnnealingCooling::linear);assert(close(linear.temperature(0.0),100.0));assert(close(linear.temperature(0.25),75.0));assert(close(linear.temperature(1.0),0.0));}voidtest_maximization(){SimulatedAnnealingannealing(10.0,10.0);assert(annealing.acceptance_probability(3,4,0.5)==1.0);assert(annealing.acceptance_probability(3,3,0.5)==1.0);assert(close(annealing.acceptance_probability(3,-7,0.5),std::exp(-1.0)));assert(annealing.accept(3,4,0.5,0.999999));assert(annealing.accept(3,-7,0.5,0.3));assert(!annealing.accept(3,-7,0.5,0.4));}voidtest_minimization(){SimulatedAnnealingannealing(2.0,2.0,AnnealingObjective::minimize);assert(annealing.acceptance_probability(5,4,0.0)==1.0);assert(close(annealing.acceptance_probability(5,7,0.0),std::exp(-1.0)));assert(annealing.accept_delta(-1.0,0.0,0.999999));assert(!annealing.accept_delta(2.0,0.0,0.4));}voidtest_zero_temperature_and_large_scores(){SimulatedAnnealinggreedy(1.0,0.0,AnnealingObjective::maximize,AnnealingCooling::linear);assert(greedy.acceptance_probability_delta(-1.0,1.0)==0.0);assert(!greedy.accept_delta(-1.0,1.0,0.0));assert(greedy.accept_delta(0.0,1.0,0.999999));longlonglow=std::numeric_limits<longlong>::min();longlonghigh=std::numeric_limits<longlong>::max();assert(greedy.acceptance_probability(low,high,1.0)==1.0);assert(greedy.acceptance_probability(high,low,1.0)==0.0);}voidtest_randomized_against_formula(){m1une::utilities::Randomrandom(0x51a7edULL);for(AnnealingObjectiveobjective:{AnnealingObjective::minimize,AnnealingObjective::maximize}){SimulatedAnnealingannealing(30.0,0.03,objective);for(inttrial=0;trial<10000;trial++){longlongcurrent=random.uniform(-1000000000,1000000000);longlongcandidate=random.uniform(-1000000000,1000000000);doubleprogress=random.real();doublerandom01=random.real();longdoubledelta=static_cast<longdouble>(candidate)-static_cast<longdouble>(current);longdoubleimprovement=objective==AnnealingObjective::maximize?delta:-delta;doubleexpected=1.0;if(improvement<0.0L){expected=std::exp(static_cast<double>(improvement/annealing.temperature(progress)));}assert(close(annealing.acceptance_probability(current,candidate,progress),expected));assert(annealing.accept(current,candidate,progress,random01)==(random01<expected));}}}intmain(){test_temperature();test_maximization();test_minimization();test_zero_temperature_and_large_scores();test_randomized_against_formula();longlonga,b;std::cin>>a>>b;std::cout<<a+b<<'\n';}