// Arup Guha
// 4/30/2017
// Solution to 2017 NAIPC Problem F: Incremental Double Free Strings
// This is really ugly since I originally designed it to only work for k <= 6 and then "patched it up"
// until it worked. I should rewrite this whole thing since it's such a mess.

import java.util.*;

public class doublefree {

	final public static long MAXRANK = 1000000000000000000L;

	public static long[] memo;
	public static int k;
	public static int maxK;
	public static int targetLen;

	public static void main(String[] args) {

		Scanner stdin = new Scanner(System.in);
		int readk = stdin.nextInt();
		long n = stdin.nextLong();

		// I can only memoize my function up to 7.
		if (readk%2 == 1 || readk >=7)
			k = Math.min(readk, 7);
		else
			k = Math.min(readk, 6);
		maxK = k;

		// Evens are a special case for maxK.
		if (readk >= 8 && readk%2 == 0) maxK = 8;
		targetLen = maxK*(maxK+1)/2;

		int numBits = maxK == 8 ? 25 : 3*k+3;
		memo = new long[1<<numBits];
		Arrays.fill(memo, -1);
		memo[0] = 1;

		// Form mask for starting frequencies.
		int mask = 0;
		for (int i=1; i<=k; i++)
			mask |= (i<<(3*i));

		long res = solve(mask);

		// This case works with my old code, so keep it.
		if (readk <= 6) {

			for (int i=26; i>=26-k+1; i--)
				res *= i;

			if (res < n)
				System.out.println(-1);

			else {
				ArrayList<pair> list = new ArrayList<pair>();
				System.out.println(getRank("", list, n-1, 0));
			}
		}

		// Here I brute force some starting letters, downto either 7 or 8 letters left, but for these two cases,
		// I only partially place the letters, since a few of these end up moving sometimes.
		else {

			// Index 0 is one that uses all the letters, index 1 uses some of the letters and some need to be placed.
			String[] tmp = getAlt(readk);
			String prefix = tmp[0];
			String start = tmp[1];

			ArrayList<pair> list = new ArrayList<pair>();

			// Our starting letter.
			int startlet = readk%2 == 0 ? readk-8 : readk-7;

			// Our starting list of letters.
			if (maxK == 7) {
				list.add(new pair(start.charAt(0)-'a',2));
				list.add(new pair(start.charAt(1)-'a',1));
			}
			else {
				list.add(new pair(start.charAt(0)-'a',6));
				list.add(new pair(start.charAt(1)-'a',5));
			}

			// Call and output.
			System.out.println(prefix+getRank(start, list, n-1, startlet));
		}
	}

	// Builds forced letters (greedy) based on the original k.
	public static String[] getAlt(int origk) {

		String[] res = new String[2];
		res[0] = "";
		res[1] = "";
		int cur = 0;
		
		// Loop down until we're at 7 or 8.
		while (origk > 6) {

			// Figure out which of the two strings we're adding to.
			int iStr = origk > 8 ? 0 : 1;
			int iter = origk-1;
			if (origk == 7) iter = 1;
			if (origk == 8) iter = 5;

			// Alternate our characters.
			for (int i=0; i<iter; i++)
				res[iStr] = res[iStr] + (char)('a'+cur) + (char)('b'+cur);
			res[iStr] = res[iStr] + (char)('a'+cur);

			// We go by 2s.
			cur+=2;
			origk-=2;
		}

		return res;
	}

	public static String getRank(String cur, ArrayList<pair> freq, long n, int startLet) {

		// Filled in the whole string.
		if (cur.length() == targetLen) return cur;

		String retval = "";
		boolean found = false;

		// Try each letter next.
		for (int i=startLet; i<26; i++) {

			// Can't try previous letter.
			if (cur.length() > 0 && i == cur.charAt(cur.length()-1) - 'a') continue;

			// Add letter to frequency count.
			add(freq, i);

			// This letter works, go here.
			if (valid(freq)) {
				
				// See how many things we can form here,
				long cnt = getCount(freq, i, 26-startLet);
				
				// We still need to go farther, just subtract out of n.
				if (cnt <= n) n-=cnt;
				
				// This is the right letter, place it and recurse.
				else {
					retval = getRank(cur+(char)('a'+i), freq, n, startLet);
					found = true;
				}
			}

			// Undo adding this letter for next iterations.
			sub(freq, i);
			if (found) break;
		}

		return retval;
	}

	public static boolean valid(ArrayList<pair> freq) {

		// This is impossible, too many unique letters.
		if (freq.size() > maxK) return false;

		// Store all current frequencies.
		int[] myf = new int[freq.size()];
		for (int i=0; i<freq.size(); i++)
			myf[i] = freq.get(i).num;
		Arrays.sort(myf);

		// This is the most anything can be, if anything is too big, it's impossible.
		for (int i=maxK,j=myf.length-1; j>=0&&i>=0; i--,j--)
			if (myf[j] > i) return false;

		// If we get here, it's possible.
		return true;
	}

	public static void add(ArrayList<pair> freq, int letter) {

		// Find the letter in the current ones - if we do, just add 1 to its frequency.
		boolean flag = false;
		for (int i=0; i<freq.size(); i++) {
			if (freq.get(i).let == letter) {
				freq.get(i).num++;
				flag = true;
				break;
			}
		}

		// A new letter, just add it to the end.
		if (!flag) freq.add(new pair(letter, 1));
	}

	// Removes one copy of letter from freq.
	public static void sub(ArrayList<pair> freq, int letter) {
		for (int i=0;i<freq.size(); i++) {
			if (freq.get(i).let == letter) {
				freq.get(i).num--;
				if (freq.get(i).num == 0) freq.remove(i);
				break;
			}
		}
	}

	// Returns the number of combinations with this set of frequecies and the last letter last and letLeft of the last letter.
	public static long getCount(ArrayList<pair> freq, int last, int letLeft) {

		// Choices for unbound letters.
		long mult = 1;
		for (int i=freq.size(); i<maxK; i++)
			mult *= (letLeft-i);
	
		// It's a combination and this is the denominator.
		for (int i=1; i<=maxK-freq.size(); i++)
			mult /= i;

		// Call recursive function.
		boolean[] used = new boolean[maxK];
		int[] perm = new int[maxK];
		long res = getCountRec(perm, used, 0, freq, last);

		// To avoid overflow.
		if (MAXRANK/mult < res)
			return MAXRANK+1;
		else
			return res*mult;
	}

	public static long getCountRec(int[] perm, boolean[] used, int filled, ArrayList<pair> freq, int last) {

		if (filled == maxK) {

			// Full frequencies.
			int[] res = new int[k+1];
			for (int i=0; i<k; i++) res[i] = i+1;
			if (maxK == 8 && k == 7) {
				res[k] = k+1;
			}

			// Flip our permutation. When perm[i] = a, that means that item a in freq is in position i (i+1 copies).
			int[] flip = new int[maxK];
			for (int i=0; i<maxK; i++) flip[perm[i]] = i;

			// Subtract out the letters we've already used.
			int maplast = -1;
			for (int i=0; i<freq.size(); i++) {
				res[flip[i]] -= freq.get(i).num;
				if (freq.get(i).let == last)
					maplast = flip[i];
			}

			// Put in all copies except "last" letter copy.
			ArrayList<Integer> tmp = new ArrayList<Integer>();
			for (int i=0; i<res.length; i++)
				if (i != maplast)
					tmp.add(res[i]);
			Collections.sort(tmp);

			// First three bits store # of copies of last character still needed.
			int index = res[maplast];

			for (int i=0; i<tmp.size(); i++) {
				index |= (tmp.get(i) << (3*(i+1)));
			}

			// This is the number of permutations that fit this letter pattern.
			return solve(index);
		}

		long res = 0;
		
		// Try each unique letter here (slot filled) and add up the choices.
		for (int i=0; i<maxK; i++) {
			if (!used[i]) {
				if (i < freq.size() && freq.get(i).num > filled+1) continue;
				used[i] = true;
				perm[filled] = i;
				res += getCountRec(perm, used, filled+1, freq, last);
				used[i] = false;
			}
		}

		// This is our total.
		return res;
	}

	// Returns the overall # of "molds" for a particular mask divorcing which actual individual letters are involved.
	public static long solve(int mask) {

		int savemask = mask;

		// This means the only letter left to use is the previous one, so no solutions.
		if (mask > 0 && mask < 8) return 0;

		// We did this one before.
		if (memo[mask] != -1) return memo[mask];

		// Get letter frequencies left, including banned letter.
		int[] freq = new int[maxK+1];
		int cur = mask;
		for (int i=0; i<=k; i++) {
			int index = i < k ? cur&7 : cur;
			freq[index]++;
			cur >>= 3;
		}

		// Get rid of first, you can't use this letter next.
		mask >>= 3;

		long res = 0;

		// Now try each possible first letter.
		for (int i=0; i<k; i++) {
			int item = i<k-1 ? (mask&7) : mask;
			if (item == 0) {
				mask >>= 3;
				continue;
			}

			freq[item]--;

			int newm = item-1, shift = 3;

			// Store frequencies in sorted order from lsb to msb.
			for (int j=0; j<=maxK; j++) {
				for (int x=0; x<freq[j]; x++) {
					newm |= (j<<shift);
					shift += 3;
				}
			}

			// Add in these perms.
			res += solve(newm);

			// Update freq for next iteration.
			freq[item]++;

			// Go to next item.
			mask >>= 3;
		}

		// Store and return.
		memo[savemask] = res;
		return res;
	}
}

class pair implements Comparable<pair> {

	public int let;
	public int num;

	public pair(int ch, int n) {
		let = ch;
		num = n;
	}

	public int compareTo(pair other) {
		return this.num - other.num;
	}
}