#include <algorithm>
#include <bits/stdc++.h>
#include <cmath>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <iostream>
#include <iterator>
#include <vector>

// lib/square.hpp
#ifndef SQUARE_HPP
#define SQUARE_HPP

/*
usage:

tools::square(5) => 25
*/

namespace tools {
  template <typename T>
  constexpr T square(const T x) {
    return x * x;
  }
}

#endif

// lib/util.hpp
#ifndef UTIL_HPP
#define UTIL_HPP


typedef std::int_fast64_t i64;
typedef std::uint_fast64_t u64;
typedef std::int_fast32_t i32;
typedef std::uint_fast32_t u32;

namespace tools {
  template <typename T>
  void read(std::vector<T>& vector, const typename std::vector<T>::size_type size) {
    vector.reserve(size);
    std::copy_n(std::istream_iterator<T>(std::cin), size, std::back_inserter(vector));
  }

  template <typename T, std::size_t N>
  void read(std::array<T, N>& array) {
    std::copy_n(std::istream_iterator<T>(std::cin), N, array.begin());
  }
}

#endif

// lib/prime_sieve.hpp
#ifndef PRIME_SIEVE_HPP
#define PRIME_SIEVE_HPP


/*
// primes are all primes less than or equal to 100
std::vector<std::int_fast64_t> primes = tools::prime_sieve<std::int_fast64_t>(100);
*/

namespace tools {
  template <typename T>
  std::vector<T> prime_sieve(const T n) {
    std::vector<bool> is_prime(n + 1, true);
    is_prime[0] = false;
    is_prime[1] = false;

    const T max = static_cast<T>(std::sqrt(n));
    for (T i = 2; i <= max; ++i) {
      if (is_prime[i]) {
        for (T j = i * 2; j <= n; j += i) {
          is_prime[j] = false;
        }
      }
    }

    std::vector<T> result;
    for (T i = 0; i <= n; ++i) {
      if (is_prime[i]) {
        result.push_back(i);
      }
    }
    return result;
  }
}

#endif

// lib/cumsum.hpp
#ifndef CUMSUM_HPP
#define CUMSUM_HPP


/*
usage:

std::vector<std::vector<std::int_fast64_t>> a;
const auto cumsum = tools::cumsum(a);
cumsum(0, 2);
*/

namespace tools {
  namespace detail {
    namespace cumsum {
      template <typename T>
      class result1d {
      private:
        std::vector<T> cumsum;
        std::function<T(T, T)> inv_op;

      public:
        result1d(const std::vector<T>& source, const T& init, const std::function<T(T, T)>& op, const std::function<T(T, T)>& inv_op) :
          cumsum({init}),
          inv_op(inv_op) {
          this->cumsum.reserve(source.size() + 1);
          for (const T& x : source) {
            this->cumsum.push_back(op(this->cumsum.back(), x));
          }
        }

        T operator()(const std::size_t l, const std::size_t r) const {
          return this->inv_op(this->cumsum[r], this->cumsum[l]);
        }
      };

      template <typename T>
      class result2d {
      private:
        std::vector<std::vector<T>> cumsum;
        std::function<T(T, T)> op;
        std::function<T(T, T)> inv_op;

      public:
        result2d(const std::vector<std::vector<T>>& source, const T& init, const std::function<T(T, T)>& op, const std::function<T(T, T)>& inv_op) :
          cumsum(source.size() + 1, std::vector<T>((source.empty() ? 0 : source.front().size()) + 1, init)),
          op(op),
          inv_op(inv_op) {
          const std::size_t n1 = source.size();
          const std::size_t n2 = source.empty() ? 0 : source.front().size();
          for (std::size_t i = 0; i < n1; ++i) {
            for (std::size_t j = 0; j < n2; ++j) {
              this->cumsum[i + 1][j + 1] = op(this->cumsum[i + 1][j], source[i][j]);
            }
          }
          for (std::size_t j = 0; j < n2; ++j) {
            for (std::size_t i = 0; i < n1; ++i) {
              this->cumsum[i + 1][j + 1] = op(this->cumsum[i][j + 1], this->cumsum[i + 1][j + 1]);
            }
          }
        }

        T operator()(const std::size_t x1, const std::size_t y1, const std::size_t x2, const std::size_t y2) const {
          return this->op(this->inv_op(this->inv_op(this->cumsum[x2][y2], this->cumsum[x1][y2]), this->cumsum[x2][y1]), this->cumsum[x1][y1]);
        }
      };
    }
  }

  template <typename T>
  std::function<T(std::size_t, std::size_t)> cumsum(
    const std::vector<T>& source,
    const T& init,
    const std::function<T(T, T)>& op,
    const std::function<T(T, T)>& inv_op
  ) {
    return detail::cumsum::result1d<T>(source, init, op, inv_op);
  }

  template <typename T>
  std::function<T(std::size_t, std::size_t)> cumsum(const std::vector<T>& source) {
    return cumsum<T>(source, static_cast<T>(0), std::plus<T>(), std::minus<T>());
  }

  template <typename T>
  std::function<T(std::size_t, std::size_t, std::size_t, std::size_t)> cumsum(
    const std::vector<std::vector<T>>& source,
    const T& init,
    const std::function<T(T, T)>& op,
    const std::function<T(T, T)>& inv_op
  ) {
    return detail::cumsum::result2d<T>(source, init, op, inv_op);
  }

  template <typename T>
  std::function<T(std::size_t, std::size_t, std::size_t, std::size_t)> cumsum(const std::vector<std::vector<T>>& source) {
    return cumsum<T>(source, static_cast<T>(0), std::plus<T>(), std::minus<T>());
  }
}

#endif

// lib/pow.hpp
#ifndef POW_H
#define POW_H


/*
usage:

tools::pow(2, 5) => 32
*/

namespace tools {
  template <typename T>
  constexpr T pow(const T base, const T exponent) {
    return exponent == 0
      ? 1
      : exponent % 2 == 0
        ? square(pow(base, exponent / 2))
        : pow(base, exponent - 1) * base;
  }
}

#endif

// main.cpp

// N!に素因数pが出現する回数
i64 calc_occurrence(const i64 N, const i64 p) {
  i64 occurrence = 0;
  for (i64 i = 1; tools::pow(p, i) <= N; ++i) {
    occurrence += N / tools::pow(p, i);
  }
  return occurrence;
}

int main() {
  i64 N;
  std::cin >> N;

  // N!に出現する回数別の素因数の個数
  std::vector<i64> prime_factor_counts(calc_occurrence(N, 2) + 1, 0);
  for (const i64& p : tools::prime_sieve(N)) {
    ++prime_factor_counts[calc_occurrence(N, p)];
  }

  const auto cumsum = tools::cumsum(prime_factor_counts);
  const i64 max = prime_factor_counts.size();

  // N!に[l, r)回出現する素因数の個数
  const auto prime_factor_count_range = [&cumsum, &max](const i64 l, const i64 r) {
    return cumsum(std::min(l, max), std::min(r, max));
  };

  // 七五数は必ず以下のいずれかの形になる。
  // 1) p^74（pは素数）
  // 2) p^24 * q^2（p, qは相異なる素数）
  // 3) p^14 * q^4（p, qは相異なる素数）
  // 4) p^4 * q^4 * r^2（p, q, rは相異なる素数）
  i64 answer = 0;

  // 1) p^74（pは素数）
  {
    // N!に[74, ∞)回出現する素因数の個数
    const i64 a = prime_factor_count_range(74, max);

    answer += a;
  }

  // 2) p^24 * q^2（p, qは相異なる素数）
  {
    // 以下の2グループの素因数について考える。
    // Aグループ: N!に[24, ∞)回出現する素因数
    // Bグループ: N!に[2, 24)回出現する素因数

    // Aグループの個数
    const i64 a = prime_factor_count_range(24, max);

    // Bグループの個数
    const i64 b = prime_factor_count_range(2, 24);

    // 以下の2パターンの組み合わせ総数を求める。
    // 2-1) p, q共にAグループの素因数
    // 2-2) pはAグループの素因数で、qはBグループの素因数
    answer += a * (a - 1) + a * b;
  }

  // 3) p^14 * q^4（p, qは相異なる素数）
  {
    // 以下の2グループの素因数について考える。
    // Aグループ: N!に[14, ∞)回出現する素因数
    // Bグループ: N!に[4, 14)回出現する素因数

    // Aグループの個数
    const i64 a = prime_factor_count_range(14, max);

    // Bグループの個数
    const i64 b = prime_factor_count_range(4, 14);

    // 以下の2パターンの組み合わせ総数を求める。
    // 3-1) p, q共にAグループの素因数
    // 3-2) pはAグループの素因数で、qはBグループの素因数
    answer += a * (a - 1) + a * b;
  }

  // 4) p^4 * q^4 * r^2（p, q, rは相異なる素数）
  {
    // 以下の2グループの素因数について考える。
    // Aグループ: N!に[4, ∞)回出現する素因数
    // Bグループ: N!に[2, 4)回出現する素因数

    // Aグループの個数
    const i64 a = prime_factor_count_range(4, max);

    // Bグループの個数
    const i64 b = prime_factor_count_range(2, 4);

    // 以下の2パターンの組み合わせ総数を求める。
    // 4-1) p, q, rがすべてAグループの素因数
    // 4-2) p, q共にAグループの素因数で、rはBグループの素因数
    // pとqは同じ4乗の因数なので、順番が区別されないことに注意する。
    answer += a * (a - 1) * (a - 2) / 2 + a * (a - 1) * b / 2;
  }

  std::cout << answer << std::endl;
  return 0;
}

Measured memory_bytes: 256