diff --git a/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h
index 687deced223d6008b8c7b836180269a9e05a30d3..7a07174427df0b3f43205dbefdfe8c7d7c9375c5 100644
--- a/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h
+++ b/alib2algo/src/automaton/simplify/UnreachableStatesRemover.h
@@ -52,60 +52,47 @@ namespace simplify {
 class UnreachableStatesRemover {
 public:
 	/**
-	 * Removes unreachable states from an automaton.
+	 * Removes unreachable states from a finite automaton.
 	 *
 	 * @tparam T type of a finite automaton
 	 *
-	 * @param automaton automaton to trim
+	 * @param fsm automaton to remove unreachable states from
 	 *
-	 * @return @p automaton without unreachable states
+	 * @return @p fsm without unreachable states
 	 */
 	template < class T >
-	static T remove( const T & fsm );
+	static ext::require < isDFA < T > || isNFA < T > || isEpsilonNFA < T > || isCompactNFA < T > || isExtendedNFA < T >, T > remove ( const T & fsm );
 
 	/**
-	 * @overload
-	 * @tparam SymbolType Type for input symbols.
-	 * @tparam StateType Type for states.
-	 */
-	template < class SymbolType, class StateType >
-	static automaton::MultiInitialStateNFA < SymbolType, StateType > remove( const automaton::MultiInitialStateNFA < SymbolType, StateType > & fsm );
-
-	/**
-	 * Removes unreachable states from a deterministic finite tree automaton.
-	 *
 	 * @overload
 	 *
 	 * @tparam SymbolType Type for input symbols.
-	 * @tparam RankType Type for rank (arity) in ranked alphabet.
 	 * @tparam StateType Type for states.
 	 *
-	 * @param dfta automaton to trim
+	 * @param fsm automaton to remove unreachable states from
 	 *
-	 * @return @p autoamton without unreachable states
+	 * @return @p fsm without unreachable states
 	 */
 	template < class SymbolType, class StateType >
-	static automaton::DFTA < SymbolType, StateType > remove( const automaton::DFTA < SymbolType, StateType > & fta );
+	static automaton::MultiInitialStateNFA < SymbolType, StateType > remove( const automaton::MultiInitialStateNFA < SymbolType, StateType > & fsm );
 
 	/**
-	 * Removes unreachable states from a deterministic finite tree automaton.
+	 * Removes unreachable states from a finite tree automaton.
 	 *
 	 * @overload
 	 *
-	 * @tparam SymbolType Type for input symbols.
-	 * @tparam RankType Type for rank (arity) in ranked alphabet.
-	 * @tparam StateType Type for states.
+	 * @tparam T type of a finite tree automaton
 	 *
-	 * @param dfta automaton to trim
+	 * @param fta automaton to remove unreachable states from
 	 *
-	 * @return @p autoamton without unreachable states
+	 * @return @p fta without unreachable states
 	 */
-	template < class SymbolType, class StateType >
-	static automaton::NFTA < SymbolType, StateType > remove( const automaton::NFTA < SymbolType, StateType > & fta );
+	template < class T >
+	static ext::require < isDFTA < T > || isNFTA < T >, T > remove ( const T & fta );
 };
 
 template < class T >
-T UnreachableStatesRemover::remove ( const T & fsm ) {
+ext::require < isDFA < T > || isNFA < T > || isEpsilonNFA < T > || isCompactNFA < T > || isExtendedNFA < T >, T > UnreachableStatesRemover::remove ( const T & fsm ) {
 	using StateType = typename T::StateType;
 
 	// 1a
@@ -114,20 +101,16 @@ T UnreachableStatesRemover::remove ( const T & fsm ) {
 	// 2
 	T M(fsm.getInitialState());
 
-	for( const auto & q : Qa )
-		M.addState( q );
-
-	for( const auto & a : fsm.getInputAlphabet( ) )
-		M.addInputSymbol( a );
+	M.setStates( Qa );
+	M.setInputAlphabet( fsm.getInputAlphabet( ) );
 
 	for( const auto & transition : fsm.getTransitions( ) )
 		if( Qa.count( transition.first.first ) )
 			M.addTransition( transition.first.first, transition.first.second, transition.second );
 
-	ext::set<StateType> intersect;
-	std::set_intersection( fsm.getFinalStates( ).begin(), fsm.getFinalStates( ).end(), Qa.begin( ), Qa.end( ), std::inserter( intersect, intersect.begin( ) ) );
-	for( auto const & state : intersect )
-		M.addFinalState( state );
+	ext::set<StateType> finalStates;
+	std::set_intersection( fsm.getFinalStates( ).begin(), fsm.getFinalStates( ).end(), Qa.begin( ), Qa.end( ), std::inserter( finalStates, finalStates.begin( ) ) );
+	M.setFinalStates( finalStates );
 
 	return M;
 }
@@ -140,74 +123,41 @@ automaton::MultiInitialStateNFA < SymbolType, StateType > UnreachableStatesRemov
 	// 2
 	automaton::MultiInitialStateNFA < SymbolType, StateType > M;
 
-	for( const auto & q : Qa )
-		M.addState( q );
-
+	M.setStates( Qa );
 	M.setInitialStates( fsm.getInitialStates() );
-
-	for( const auto & a : fsm.getInputAlphabet( ) )
-		M.addInputSymbol( a );
+	M.setInputAlphabet( fsm.getInputAlphabet( ) );
 
 	for( const auto & transition : fsm.getTransitions( ) )
 		if( Qa.count( transition.first.first ) )
 			M.addTransition( transition.first.first, transition.first.second, transition.second );
 
-	ext::set<StateType> intersect;
-	std::set_intersection( fsm.getFinalStates( ).begin(), fsm.getFinalStates( ).end(), Qa.begin( ), Qa.end( ), std::inserter( intersect, intersect.begin( ) ) );
-	for( auto const & state : intersect )
-		M.addFinalState( state );
+	ext::set<StateType> finalStates;
+	std::set_intersection( fsm.getFinalStates( ).begin(), fsm.getFinalStates( ).end(), Qa.begin( ), Qa.end( ), std::inserter( finalStates, finalStates.begin( ) ) );
+	M.setFinalStates( finalStates );
 
 	return M;
 }
 
-template < class SymbolType, class StateType >
-automaton::DFTA < SymbolType, StateType > UnreachableStatesRemover::remove( const automaton::DFTA < SymbolType, StateType > & fta ) {
-	// 1a
-	ext::set<StateType> Qa = automaton::properties::ReachableStates::reachableStates( fta );
-
-	// 2
-	automaton::DFTA < SymbolType, StateType > M;
-
-	for( const auto & q : Qa )
-		M.addState( q );
-
-	for( const auto & a : fta.getInputAlphabet( ) )
-		M.addInputSymbol( a );
-
-	for( const auto & transition : fta.getTransitions( ) )
-		if( std::all_of ( transition.first.second.begin ( ), transition.first.second.end ( ), [ & ] ( const StateType & state ) { return Qa.count ( state ); } ) )
-			M.addTransition ( transition.first.first, transition.first.second, transition.second );
-
-	ext::set<StateType> intersect;
-	std::set_intersection( fta.getFinalStates( ).begin(), fta.getFinalStates( ).end(), Qa.begin( ), Qa.end( ), std::inserter( intersect, intersect.begin( ) ) );
-	for( auto const & state : intersect )
-		M.addFinalState( state );
-
-	return M;
-}
+template < class T >
+ext::require < isDFTA < T > || isNFTA < T >, T >  UnreachableStatesRemover::remove( const T & fta ) {
+	using StateType = typename T::StateType;
 
-template < class SymbolType, class StateType >
-automaton::NFTA < SymbolType, StateType > UnreachableStatesRemover::remove( const automaton::NFTA < SymbolType, StateType > & fta ) {
 	// 1a
 	ext::set<StateType> Qa = automaton::properties::ReachableStates::reachableStates( fta );
 
 	// 2
-	automaton::NFTA < SymbolType, StateType > M;
-
-	for( const auto & q : Qa )
-		M.addState( q );
+	T M;
 
-	for( const auto & a : fta.getInputAlphabet( ) )
-		M.addInputSymbol( a );
+	M.setStates( Qa );
+	M.setInputAlphabet( fta.getInputAlphabet( ) );
 
 	for( const auto & transition : fta.getTransitions( ) )
 		if( std::all_of ( transition.first.second.begin ( ), transition.first.second.end ( ), [ & ] ( const StateType & state ) { return Qa.count ( state ); } ) )
 			M.addTransition ( transition.first.first, transition.first.second, transition.second );
 
-	ext::set<StateType> intersect;
-	std::set_intersection( fta.getFinalStates( ).begin(), fta.getFinalStates( ).end(), Qa.begin( ), Qa.end( ), std::inserter( intersect, intersect.begin( ) ) );
-	for( auto const & state : intersect )
-		M.addFinalState( state );
+	ext::set<StateType> finalStates;
+	std::set_intersection( fta.getFinalStates( ).begin(), fta.getFinalStates( ).end(), Qa.begin( ), Qa.end( ), std::inserter( finalStates, finalStates.begin( ) ) );
+	M.setFinalStates( std::move ( finalStates ) );
 
 	return M;
 }