Problem:
Score : 300 points

Problem Statement

Gotou just received a dictionary. However, he doesn't recognize the language used in the dictionary. He did some analysis on the dictionary and realizes that the dictionary contains all possible diverse words in lexicographical order.

A word is called diverse if and only if it is a nonempty string of English lowercase letters and all letters in the word are distinct. For example, atcoder, zscoder and agc are diverse words while gotou and connect aren't diverse words.

Given a diverse word S, determine the next word that appears after S in the dictionary, i.e. the lexicographically smallest diverse word that is lexicographically larger than S, or determine that it doesn't exist.

Let X = x_{1}x_{2}...x_{n} and Y = y_{1}y_{2}...y_{m} be two distinct strings. X is lexicographically larger than Y if and only if Y is a prefix of X or x_{j} > y_{j} where j is the smallest integer such that x_{j} \neq y_{j}.

Constraints

1 \leq |S| \leq 26

S is a diverse word.

Input

Input is given from Standard Input in the following format:

S

Output

Print the next word that appears after S in the dictionary, or -1 if it doesn't exist.

Sample Input 1

atcoder

Sample Output 1

atcoderb

atcoderb is the lexicographically smallest diverse word that is lexicographically larger than atcoder. Note that atcoderb is lexicographically smaller than b.

Sample Input 2

abc

Sample Output 2

abcd

Sample Input 3

zyxwvutsrqponmlkjihgfedcba

Sample Output 3

-1

This is the lexicographically largest diverse word, so the answer is -1.

Sample Input 4

abcdefghijklmnopqrstuvwzyx

Sample Output 4

abcdefghijklmnopqrstuvx

Solution in Rust (1.42.0) (judge verdict: Accepted)

use std::io::*;
use std::str::FromStr;

//https://docs.rs/permutohedron/0.2.4/src/permutohedron/lexical.rs.html#23-30
pub trait LexicalPermutation {
    /// Return `true` if the slice was permuted, `false` if it is already
    /// at the last ordered permutation.
    fn next_permutation(&mut self) -> bool;
}
 
impl<T> LexicalPermutation for [T]
where
    T: Ord,
{
    /// Original author in Rust: Thomas Backman <serenity@exscape.org>
    fn next_permutation(&mut self) -> bool {
        // These cases only have 1 permutation each, so we can't do anything.
        if self.len() < 2 {
            return false;
        }
 
        // Step 1: Identify the longest, rightmost weakly decreasing part of the vector
        let mut i = self.len() - 1;
        while i > 0 && self[i - 1] >= self[i] {
            i -= 1;
        }
 
        // If that is the entire vector, this is the last-ordered permutation.
        if i == 0 {
            return false;
        }
 
        // Step 2: Find the rightmost element larger than the pivot (i-1)
        let mut j = self.len() - 1;
        //while j >= i && self[j] <= self[i - 1] {
        while self[j] <= self[i - 1] {
            j -= 1;
        }
 
        // Step 3: Swap that element with the pivot
        self.swap(i -1 , j);
 
        // Step 4: Reverse the (previously) weakly decreasing part
        self[i..].reverse();
 
        true
    }
}

//https://onlinejudge.u-aizu.ac.jp/solutions/problem/ALDS1_5_B/review/2709881/arsenic28/Rust
trait Joinable {
    fn join(self, sep: &str) -> String;
}

impl<U: ToString, T: Iterator<Item = U>> Joinable for T {
    fn join(self, sep: &str) -> String {
        self.map(|x| x.to_string()).collect::<Vec<_>>().join(sep)
    }
}

//https://qiita.com/tubo28/items/e6076e9040da57368845
fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let token: String = stdin
        .bytes()
        .map(|c| c.expect("failed to read char") as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().expect("failed to parse token")
}

//https://atcoder.jp/contests/agc022/submissions/14854736
//https://iloveconviniboshi.hatenablog.com/entry/2019/11/19/013117
fn main() {
    let mut s: Vec<char> = read::<String>().chars().collect();

    //25字以下のとき
	//与えられた文字列 + ( a ~ zで入力に存在しない文字の最小の文字）
    if s.len() < 26 {
        //文字aからzまでの順番にsにその文字が使われているかチェック
        //未使用であるならばvecに追加していき、unuseに格納される。
        let unuse = (b'a'..=b'z').map(char::from).filter(|c| !s.contains(c)).collect::<Vec<_>>();
        s.push(unuse[0]);
        println!("{}",s.iter().join(""));
        return;
    }
    //26字のとき
    let mut next_s = s.clone();
    //辞書順で次の単語を得る
    let has_next = next_s.next_permutation();

    //終端の場合は-1
    if !has_next {
        println!("-1");
        return;
    }

    let mut ans:Vec<char> = Vec::new();

    //辞書順の次の単語と文字列sを比較して違う文字が出てくるところまでをansに追加する
    //zipで２つのiteratorをペアにして回す
    for (n, o) in next_s.iter().zip(s.iter()){
        ans.push(*n);
        if n != o {
            break;
        }
    }
    
    /*for i in 0..26{
        ans.push(next_s[i]);
        if next_s[i] != s[i] {
            break;
        }
    }*/
    println!("{}",ans.iter().join(""));


}