const v: [char; 10] = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'];
fn main() {
    let n: usize = read();
    let mut cand: Vec<Vec<char>> = vec![vec!['a']];
    for i in 1..n {
        let mut newcand: Vec<Vec<char>> = vec![];
        for c in &mut cand {
            for j in 0..i + 1 {
                let mut next_c = c.clone();
                next_c.push(v[j]);
                newcand.push(next_c);
            }
        }
        cand = newcand;
    }
    cand.sort();
    for c in cand {
        println!("{}", c.into_iter().collect::<String>());
    }
}

// =========
#[allow(unused_imports)]
use std::cmp::{max, min};
#[allow(unused_imports)]
use std::collections::{HashMap, HashSet};
#[allow(unused_imports)]
use std::process::exit;

#[allow(dead_code)]
const MOD: usize = 1000000007;

fn read<T: std::str::FromStr>() -> T {
    use std::io::Read;
    let stdin = std::io::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")
}

// =========
