package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

const (
	initialBufSize = 1e4
	maxBufSize     = 1e6 + 7
)

var buf []byte = make([]byte, maxBufSize)
var sc = bufio.NewScanner(os.Stdin)

func init() {
	sc.Split(bufio.ScanWords)
	sc.Buffer(buf, maxBufSize)
}

func main() {
	N := nextInt()
	// var digits int
	// an := make([]int, 0)
	ans := ""
	if N <= 26 {
		fmt.Println(numToAlphabet(N))
		return
	}
	for N > 0 {
		N--
		// if N%26 == 0 {
		// 	an = append(an, 26)
		// } else {
		// 	an = append(an, N%26)
		// }
		ans += string(N%26 + 'a')
		N /= 26
	}
	// for i := N - 1; i > 0; i /= 26 {
	// 	// fmt.Println(digits)
	// 	// if i%26 == 0 {
	// 	// 	an = append(an, 26)
	// 	// } else {
	// 	// 	an = append(an, i%26)
	// 	// 	if an[len(an)-1] == 26 {
	// 	// 		an[len(an)]--
	// 	// 	}
	// 	// }
	// 	an = append(an, i%26)
	// 	digits++
	// 	// fmt.Println(i, digits)
	// }
	// fmt.Println(an, digits)
	// ans := make([]rune, len(an))
	// ans2 := make([]string, len(an))
	// for i := 0; i < len(an); i++ {
	// 	ans[len(ans)-1-i] = rune(an[i] + 'a' - 1)
	// 	// ans2[len(ans2)-1-i] = numToAlphabet(an[i])
	// }
	// if digits != len(ans2) {
	// fmt.Println(string(ans[2:]), strings.Join(ans2[2:], ""))
	// fmt.Println(strings.Join(ans2[2:], ""))
	// } else {
	// fmt.Println(strings.Join(ans2, ""))
	// }
	// fmt.Println(string(ans))
	fmt.Println(Reverse(ans))
	// fmt.Println(string(ans), strings.Join(ans2, ""))
	// fmt.Println(strings.Join(ans2, ""))
}

func numToAlphabet(n int) string {
	var s string
	switch n {
	case 1:
		s = "a"
	case 2:
		s = "b"
	case 3:
		s = "c"
	case 4:
		s = "d"
	case 5:
		s = "e"
	case 6:
		s = "f"
	case 7:
		s = "g"
	case 8:
		s = "h"
	case 9:
		s = "i"
	case 10:
		s = "j"
	case 11:
		s = "k"
	case 12:
		s = "l"
	case 13:
		s = "m"
	case 14:
		s = "n"
	case 15:
		s = "o"
	case 16:
		s = "p"
	case 17:
		s = "q"
	case 18:
		s = "r"
	case 19:
		s = "s"
	case 20:
		s = "t"
	case 21:
		s = "u"
	case 22:
		s = "v"
	case 23:
		s = "w"
	case 24:
		s = "x"
	case 25:
		s = "y"
	case 26:
		s = "z"
	}
	return s
}

func nextLine() string {
	sc.Scan()
	return sc.Text()
}

func nextInt() int {
	sc.Scan()
	i, e := strconv.Atoi(sc.Text())
	if e != nil {
		panic(e)
	}
	return i
}

func abs(a int) int {
	if a > 0 {
		return a
	} else {
		return -a
	}
}

func pow(p, q int) int {
	res := p
	if q == 0 {
		return 1
	}
	for i := 0; i < q-1; i++ {
		res *= p
	}
	return res
}

func MinOf(vars ...int) int {
	min := vars[0]
	for _, i := range vars {
		if min > i {
			min = i
		}
	}
	return min
}

func MaxOf(vars ...int) int {
	max := vars[0]
	for _, i := range vars {
		if max < i {
			max = i
		}
	}
	return max
}

func gcdof2numbers(a int, b int) int {
	if b == 0 {
		return a
	}
	return gcdof2numbers(b, a%b)
}

func lcmof2numbers(a int, b int) int {
	return a / gcdof2numbers(a, b) * b
}

// マイナスの場合は考慮していない
func fuctorial(a int) int {
	if a == 1 || a == 0 {
		return 1
	} else {
		return fuctorial(a-1) * a
	}
}

func NextPermutation(x sort.Interface) bool {
	n := x.Len() - 1
	if n < 1 {
		return false
	}
	j := n - 1
	for ; !x.Less(j, j+1); j-- {
		if j == 0 {
			return false
		}
	}
	l := n
	for !x.Less(j, l) {
		l--
	}
	x.Swap(j, l)
	for k, l := j+1, n; k < l; {
		x.Swap(k, l)
		k++
		l--
	}
	return true
}

// 素因数分解したmapを返す
func primeFuctorize(n int) map[int]int {
	pf := map[int]int{}
	for i := 2; i*i <= n; i++ {
		for n%i == 0 {
			pf[i]++
			n /= i
		}
	}
	if n != 1 {
		pf[n]++
	}
	return pf
}

func Reverse(s string) string {
	runes := []rune(s)
	for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
		runes[i], runes[j] = runes[j], runes[i]
	}
	return string(runes)
}


Measured memory_bytes: 1808