#include <bits/stdc++.h>
using namespace std;
const long long dx[] = {1, 0, -1, 0};
const long long dy[] = {0, 1, 0, -1};
const long long ddx[] = {1, 1, 0, -1, -1, -1, 0, 1};
const long long ddy[] = {0, 1, 1, 1, 0, -1, -1, -1};
long long gcd(long long a, long long b) {
  if (b == 0) return a;
  return gcd(b, a % b);
}
long long extgcd(long long a, long long b, long long &x, long long &y) {
  long long d = a;
  if (b != 0) {
    d = extgcd(b, a % b, y, x);
    y -= (a / b) * x;
  } else {
    x = 1;
    y = 0;
  }
  return d;
}
long long inv(long long a, long long mod) {
  long long x, y;
  extgcd(a, mod, x, y);
  return (x + mod) % mod;
}
long long pow(long long x, long long n) {
  long long res = 1;
  while (n > 0) {
    if (n & 1) res *= x;
    x *= x;
    n >>= 1;
  }
  return res;
}
template <long long mod>
struct modint {
  long long val;
  modint() { val = 0; }
  modint(long long _val) {
    if (_val < 0) _val += mod * (-_val / mod + 1);
    val = _val % mod;
  }
  modint &operator=(const modint &x) {
    val = x.val;
    return *this;
  }
  bool operator==(const modint &rhs) const { return val == rhs.val; }
  bool operator<(const modint &rhs) const { return val < rhs.val; }
  bool operator>(const modint &rhs) const { return val > rhs.val; }
  bool operator<=(const modint &rhs) const { return val <= rhs.val; }
  bool operator>=(const modint &rhs) const { return val >= rhs.val; }
  bool operator!=(const modint &rhs) const { return val != rhs.val; }
  modint operator+(const modint &rhs) const {
    return modint<mod>(val + rhs.val);
  }
  modint operator-(const modint &rhs) const {
    return modint<mod>(val - rhs.val);
  }
  modint operator*(const modint &rhs) const {
    return modint<mod>((long long)((long long)val * rhs.val % mod));
  }
  modint operator/(const modint &rhs) const {
    return modint<mod>((long long)((long long)val * inv(rhs.val, mod) % mod));
  }
  modint &operator+=(const modint &rhs) {
    val = modint<mod>(val + rhs.val).val;
    return *this;
  }
  modint &operator-=(const modint &rhs) {
    val = modint<mod>(val - rhs.val).val;
    return *this;
  }
  modint &operator*=(const modint &rhs) {
    val = (long long)((long long)val * rhs.val % mod);
    return *this;
  }
  modint &operator/=(const modint &rhs) {
    val = (long long)((long long)val * inv(rhs.val, mod) % mod);
    return *this;
  }
  modint &operator++() {
    val = (val + 1) % mod;
    return *this;
  }
  modint operator++(signed) {
    modint<mod> m = *this;
    val = (val + 1) % mod;
    return m;
  }
  modint &operator--() {
    val = (val + mod - 1) % mod;
    return *this;
  }
  modint operator--(signed) {
    modint<mod> m = *this;
    val = (val + mod - 1) % mod;
    return m;
  }
};
struct unitree {
  long long *par, *rank, *sz;
  unitree(long long n) {
    par = new long long[n];
    rank = new long long[n];
    sz = new long long[n];
    for (long long i = 0; i < n; i++) {
      par[i] = i;
      rank[i] = 0;
      sz[i] = 1;
    }
  }
  long long root(long long x) {
    if (par[x] == x)
      return x;
    else
      return par[x] = root(par[x]);
  }
  void merge(long long x, long long y) {
    x = root(x);
    y = root(y);
    if (x == y) return;
    if (rank[x] < rank[y]) {
      par[x] = y;
      sz[y] += sz[x];
    } else {
      par[y] = x;
      if (rank[x] == rank[y]) rank[x]++;
      sz[x] += sz[y];
    }
  }
  bool same(long long x, long long y) { return root(x) == root(y); }
  long long siz(long long x) { return sz[root(x)]; }
};
struct vect {
  long long x, y;
  vect() {
    x = 0;
    y = 0;
  }
  vect(long long x, long long y) {
    this->x = x;
    this->y = y;
  }
  long long posi() const {
    if (x == 0 && y == 0) exit(1);
    if (x > 0 && y == 0) return 0;
    if (x > 0 && y > 0) return 1;
    if (x == 0 && y > 0) return 2;
    if (x < 0 && y > 0) return 3;
    if (x < 0 && y == 0) return 4;
    if (x < 0 && y < 0) return 5;
    if (x == 0 && y < 0) return 6;
    if (x > 0 && y < 0) return 7;
  }
  long long posi(const vect &v) const {
    long long s = x * v.y - y * v.x;
    long long c = x * v.x + y * v.y;
    if (s == 0 && c == 0) exit(1);
    if (s == 0 && c > 0) return 0;
    if (s > 0 && c > 0) return 1;
    if (s > 0 && c == 0) return 2;
    if (s > 0 && c < 0) return 3;
    if (s == 0 && c < 0) return 4;
    if (s < 0 && c < 0) return 5;
    if (s < 0 && c == 0) return 6;
    if (s < 0 && c > 0) return 7;
  }
  bool operator<(const vect &rhs) {
    long long p1 = posi();
    long long p2 = rhs.posi();
    if (p1 != p2) return p1 < p2;
    return rhs.x * y < x * rhs.y;
  }
};
struct segtree {
  long long n, *dat;
  segtree(long long _n, string str) {
    n = 1;
    while (n < _n) n *= 2;
    dat = new long long[n * 2 + 1];
    for (long long i = 0; i < (long long)(_n); i++)
      dat[n - 1 + i] = 1 << (str[i] - 'a');
    fill(dat + n - 1 + _n, dat + n * 2 - 1, 0);
    for (long long i = n - 2; i >= 0; i--) {
      dat[i] = dat[i * 2 + 1] | dat[i * 2 + 2];
    }
  }
  void update(long long k, char c) {
    k += n - 1;
    dat[k] = 1 << (c - 'a');
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = dat[k * 2 + 1] | dat[k * 2 + 2];
    }
  }
  long long _query(long long a, long long b, long long k, long long l,
                   long long r) {
    if (r <= a || b <= l) return 0;
    if (a <= l && r <= b) return dat[k];
    long long vl = _query(a, b, k * 2 + 1, l, (l + r) / 2);
    long long vr = _query(a, b, k * 2 + 2, (l + r) / 2, r);
    return vl | vr;
  }
  long long query(long long a, long long b) {
    long long res = _query(a, b, 0, 0, n);
    long long ans = 0;
    while (res) {
      if (res & 1) ans++;
      res >>= 1;
    }
    return ans;
  }
};
signed main() {
  string str =
      "1, 1, 1, 2, 1, 2, 1, 5, 2, 2, 1, 5, 1, 2, 1, 14, 1, 5, 1, 5, 2, 2, 1, "
      "15, 2, 2, 5, 4, 1, 4, 1, 51";
  long long k;
  cin >> k;
  if (k == 1) {
    cout << (1) << endl;
    return 0;
  }
  for (long long i = 0; i < str.length(); i++) {
    if (str[i] == ' ') k--;
    if (k == 1) {
      cout << (str[i + 1]) << endl;
      return 0;
    }
  }
}
