#include <unordered_set> 
#include <string> 
#include <vector> 
#include <climits> 
#include <cstddef> 
#include <queue> 
 
 
namespace  word_ladder { 
 
	[ [ nodiscard] ]  auto  generate( std:: string  const  &  from,
	                            std:: string  const  &  to,
	                            std:: unordered_set < std:: string >  const  &  lexicon) 
	   - >  std:: vector < std:: vector < std:: string >>  { 
		std:: vector < std:: vector < std:: string >>  answer; 
 
		std:: unordered_set < std:: string >  words; 
		words.insert ( lexicon.cbegin ( ) , lexicon.cend ( ) ) ; 
 
		std:: queue < std:: vector < std:: string >>  paths; 
		paths.push ( { from} ) ; 
 
		std:: size_t  level =  1 ; 
		std:: size_t  minLevel =  INT_MAX ; 
 
		std:: unordered_set < std:: string >  visited; 
 
		while  ( ! paths.empty ( ) )  { 
			std:: vector < std:: string >  path =  paths.front ( ) ; 
			paths.pop ( ) ; 
			if  ( path.size ( )  >  level)  { 
				for  ( std:: string  w :  visited)  { 
					words.erase ( w) ; 
				} 
				visited.clear ( ) ; 
				if  ( path.size ( )  >  minLevel)  { 
					break ; 
				} 
				else  { 
					level =  path.size ( ) ; 
				} 
			} 
 
			std:: string  last =  path.back ( ) ; 
			for  ( std:: size_t  i =  0 ;  i <  last.size ( ) ;  ++ i)  { 
				std:: string  news =  last; 
				for  ( char  c =  'a' ;  c <=  'z' ;  ++ c)  { 
					news[ i]  =  c; 
					if  ( words.find ( news)  ! =  words.end ( ) )  { 
						std:: vector < std:: string >  newpath =  path; 
						newpath.push_back ( news) ; 
						visited.insert ( news) ; 
						if  ( news ==  to)  { 
							minLevel =  level; 
							answer.push_back ( newpath) ; 
						} 
						else  { 
							paths.push ( newpath) ; 
						} 
					} 
				} 
			} 
		} 
		return  answer; 
	} 
 
} 
 
				I2luY2x1ZGUgPHVub3JkZXJlZF9zZXQ+CiNpbmNsdWRlIDxzdHJpbmc+CiNpbmNsdWRlIDx2ZWN0b3I+CiNpbmNsdWRlIDxjbGltaXRzPgojaW5jbHVkZSA8Y3N0ZGRlZj4KI2luY2x1ZGUgPHF1ZXVlPgoKCm5hbWVzcGFjZSB3b3JkX2xhZGRlciB7CgoJW1tub2Rpc2NhcmRdXSBhdXRvIGdlbmVyYXRlKHN0ZDo6c3RyaW5nIGNvbnN0ICYgZnJvbSwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OnN0cmluZyBjb25zdCAmIHRvLAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZDo6dW5vcmRlcmVkX3NldDxzdGQ6OnN0cmluZz4gY29uc3QgJiBsZXhpY29uKQoJICAgLT4gc3RkOjp2ZWN0b3I8c3RkOjp2ZWN0b3I8c3RkOjpzdHJpbmc+PiB7CgkJc3RkOjp2ZWN0b3I8c3RkOjp2ZWN0b3I8c3RkOjpzdHJpbmc+PiBhbnN3ZXI7CgoJCXN0ZDo6dW5vcmRlcmVkX3NldDxzdGQ6OnN0cmluZz4gd29yZHM7CgkJd29yZHMuaW5zZXJ0KGxleGljb24uY2JlZ2luKCksIGxleGljb24uY2VuZCgpKTsKCgkJc3RkOjpxdWV1ZTxzdGQ6OnZlY3RvcjxzdGQ6OnN0cmluZz4+IHBhdGhzOwoJCXBhdGhzLnB1c2goe2Zyb219KTsKCgkJc3RkOjpzaXplX3QgbGV2ZWwgPSAxOwoJCXN0ZDo6c2l6ZV90IG1pbkxldmVsID0gSU5UX01BWDsKCgkJc3RkOjp1bm9yZGVyZWRfc2V0PHN0ZDo6c3RyaW5nPiB2aXNpdGVkOwoKCQl3aGlsZSAoIXBhdGhzLmVtcHR5KCkpIHsKCQkJc3RkOjp2ZWN0b3I8c3RkOjpzdHJpbmc+IHBhdGggPSBwYXRocy5mcm9udCgpOwoJCQlwYXRocy5wb3AoKTsKCQkJaWYgKHBhdGguc2l6ZSgpID4gbGV2ZWwpIHsKCQkJCWZvciAoc3RkOjpzdHJpbmcgdyA6IHZpc2l0ZWQpIHsKCQkJCQl3b3Jkcy5lcmFzZSh3KTsKCQkJCX0KCQkJCXZpc2l0ZWQuY2xlYXIoKTsKCQkJCWlmIChwYXRoLnNpemUoKSA+IG1pbkxldmVsKSB7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQllbHNlIHsKCQkJCQlsZXZlbCA9IHBhdGguc2l6ZSgpOwoJCQkJfQoJCQl9CgoJCQlzdGQ6OnN0cmluZyBsYXN0ID0gcGF0aC5iYWNrKCk7CgkJCWZvciAoc3RkOjpzaXplX3QgaSA9IDA7IGkgPCBsYXN0LnNpemUoKTsgKytpKSB7CgkJCQlzdGQ6OnN0cmluZyBuZXdzID0gbGFzdDsKCQkJCWZvciAoY2hhciBjID0gJ2EnOyBjIDw9ICd6JzsgKytjKSB7CgkJCQkJbmV3c1tpXSA9IGM7CgkJCQkJaWYgKHdvcmRzLmZpbmQobmV3cykgIT0gd29yZHMuZW5kKCkpIHsKCQkJCQkJc3RkOjp2ZWN0b3I8c3RkOjpzdHJpbmc+IG5ld3BhdGggPSBwYXRoOwoJCQkJCQluZXdwYXRoLnB1c2hfYmFjayhuZXdzKTsKCQkJCQkJdmlzaXRlZC5pbnNlcnQobmV3cyk7CgkJCQkJCWlmIChuZXdzID09IHRvKSB7CgkJCQkJCQltaW5MZXZlbCA9IGxldmVsOwoJCQkJCQkJYW5zd2VyLnB1c2hfYmFjayhuZXdwYXRoKTsKCQkJCQkJfQoJCQkJCQllbHNlIHsKCQkJCQkJCXBhdGhzLnB1c2gobmV3cGF0aCk7CgkJCQkJCX0KCQkJCQl9CgkJCQl9CgkJCX0KCQl9CgkJcmV0dXJuIGFuc3dlcjsKCX0KCn0=