#include <iostream>
#include <array>
#include <vector>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <algorithm>
#include <math.h>
#include <string>
#include <climits>
#include <assert.h>
#include <iomanip>
#include <bitset>
#include <queue>
#include <deque>
#include <stack>
#include <functional>

#define FOR(i,a,n) for(int i=(a);i<(n); ++i)
#define FOE(i,a) for(auto i : a)
#define ALL(c) (c).begin(), (c).end()
#define RALL(c) (c).rbegin(), (c).rend()
#define SUM(x) std::accumulate(ALL(x), 0LL)
#define MIN(v) *std::min_element(v.begin(), v.end())
#define MAX(v) *std::max_element(v.begin(), v.end())
#define EXIST(v,x) (std::find(v.begin(), v.end(), x) != v.end())
#define IS_BIT_ON(bit, i) (bit & (1 << i))
#define BIT_ON(bit, i) (bit |= (1 << i))
#define BIT_OFF(bit, i) (bit &= ~(1 << i))
#define BIT_COUNT(bit) (__builtin_popcount(bit))

typedef long long LL;
template<typename T> std::vector<T> make_v(size_t a){return std::vector<T>(a);}
template<typename T,typename... Ts> auto make_v(size_t a, Ts... ts){ return std::vector<decltype(make_v<T>(ts...))>(a,make_v<T>(ts...));}    // C++14
template<typename T,typename V> typename std::enable_if<std::is_class<T>::value==0>::type fill_v(T &t,const V &v){t=v;}
template<typename T,typename V> typename std::enable_if<std::is_class<T>::value!=0>::type fill_v(T &t,const V &v){for(auto &e:t) fill_v(e,v);}
template<class T> inline T ceil(T a, T b) { return (a + b - 1) / b; }
void print() { std::cout << std::endl; }
template <class Head, class... Tail> void print(Head&& head, Tail&&... tail) { std::cout << head; if (sizeof...(tail) != 0) {std::cout << " ";} print(std::forward<Tail>(tail)...); }
template <class T> void print(std::vector<T> &v) {for (auto& a : v) { std::cout << a; if (&a != &v.back()) {std::cout << " ";} }std::cout << std::endl;}
template <class T> void print(std::vector<std::vector<T>> &vv) { for (auto& v : vv) { print(v); }}
void debug() { std::cerr << std::endl; }
template <class Head, class... Tail> void debug(Head&& head, Tail&&... tail) { std::cerr << head; if (sizeof...(tail) != 0) {std::cerr << " ";} print(std::forward<Tail>(tail)...); }
template <class T> void debug(std::vector<T> &v) {for (auto& a : v) { std::cerr << a; if (&a != &v.back()) {std::cerr << " ";} }std::cerr << std::endl;}
template <class T> void debug(std::vector<std::vector<T>> &vv) { for (auto& v : vv) { print(v); }}
inline bool inside(long long y, long long x, long long H, long long W) {return 0 <= y and y < H and 0 <= x and x < W; }
template<class T> inline double euclidean_distance(T y1, T x1, T y2, T x2) { return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); }
template<class T> inline double manhattan_distance(T y1, T x1, T y2, T x2) { return abs(x1 - x2) + abs(y1 - y2); }
template<typename T> T &chmin(T &a, const T &b) { return a = std::min(a, b); }
template<typename T> T &chmax(T &a, const T &b) { return a = std::max(a, b); }

template<class T> inline std::vector<T> unique(std::vector<T> v) {
    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()), v.end());
    return v;
}
// 初項s, 交差dのn個の数列の和
long long sum_of_arithmetic_progression(long long s, long long d, long long n) {
    return n * (2 * s + (n - 1) * d) / 2;
}

// 2のべき乗数かどうか
bool is_power_of_two(long long x) {
    return !(x & (x - 1));
}

// aとbの最大公約数 O(log min(a, b))
long long gcd(long long a, long long b) {
    if (b == 0) { return a; }
    return gcd(b, a % b);
}

// 数列vの最大公約数 O(N log d)
long long gcd(std::vector<long long> &v) {
    long long ans = v[0];
    for (int i = 1; i < (int)v.size(); ++i) {
        ans = gcd(ans, v[i]);
    }
    return ans;
}

// aとbの最小公倍数 O(log min(a, b))
long long lcm(long long a, long long b) {
    long long g = gcd(a, b);
    return a / g * b;
}

const int INF = 1u << 30u;
const long long LINF = 1ull << 58u;
const double EPS = 1e-9;
const long double PI = acos(-1.0);
const std::vector<int> dy2 = {0, 1}, dx2 = {1, 0};  // 右，下
const std::vector<int> dy4 = {0, 1, 0, -1}, dx4 = {1, 0, -1, 0};    // 右，下，左，上
const std::vector<int> dy8 = { 0, -1, 0, 1, 1, -1, -1, 1 }, dx8 = { 1, 0, -1, 0, 1, 1, -1, -1 };

using namespace std;
class CoPrime {
    std::vector<int> smallest_prime_factor; // 一番小さい因数
    bool done = false;

public:
    CoPrime() {}

    // O(n log n)
    void build(long long n) {
        this->done = true;
        this->smallest_prime_factor.resize(n + 1, 0);
        sieve_of_eratosthenes(n);
    }

    // [1, n]にあるnと互いに素の自然数の個数
    // O(log n)
    // 先にbuildすること
    int totient(long long n) {
        assert(done);

        unordered_map<int, int> prime_factors;
        while (n > 1) {
            int s = smallest_prime_factor[n];
            if (s == 0) {
                break;
            }
            ++prime_factors[s];
            n /= s;
        }

        int ans = 1;
        for (auto &q: prime_factors) {
            int p = q.first;
            int e = q.second;
            int a = p - 1;
            for (int i = 0; i < e - 1; ++i) {
                a *= p;
            }
            ans *= a;
        }

        return ans;
    }

    // [1, n]にあるnと互いに素の自然数の個数
    // O(sqrt(n)) + O(log n)
    int totient_online(long long n) {
        auto prime_factors = prime_factor_decomposition(n);

        int ans = 1;
        for (auto &q: prime_factors) {
            int p = q.first;
            int e = q.second;
            int a = p - 1;
            for (int i = 0; i < e - 1; ++i) {
                a *= p;
            }
            ans *= a;
        }

        return ans;
    }

    // [1, y]にあるxと互いに素の自然数の個数
    // xの素因数の個数がnのときO(n * 2^n)
    // 2 * 3 * 5 * 7 * 11 * 13 * 17 * 19 = 9699690
    // 先にbuildすること
    long long num_co_prime(long long x, long long y) {
        assert(this->done);

        vector<int> prime_factor;
        unordered_set<int> memo;
        while (x > 1) {
            int s = smallest_prime_factor[x];
            if (s == 0) {
                break;
            }
            if (memo.find(s) == memo.end()) {
                prime_factor.emplace_back(s);
                memo.insert(s);
            }
            x /= s;
        }

        long long ans = 0;
        int n = (int)prime_factor.size();
        for (int bit = 0; bit < (1 << n); ++bit) {
            long long mul = 1;
            for (int j = 0; j < n; j++) {
                if (bit & (1 << j)) {
                    mul *= prime_factor[j];
                }
            }
            ans += (y / mul) * (__builtin_popcount(bit) % 2 ? (-1) : (+1));
        }
        return ans;
    }

private:
    // エラトステネスの篩で最小の素因数をメモする
    // O(n log n)
    void sieve_of_eratosthenes(const long long n) {
        for (long long i = 2; i <= n; ++i) {
            this->smallest_prime_factor[i] = i;
        }

        for (long long i = 2; i * i <= n; ++i) {
            if (this->smallest_prime_factor[i] == i) {
                for (int j = i * i; j <= n; j += i) {
                    this->smallest_prime_factor[j] = i;
                }
            }
        }
    }


    // nを素因数分解する(O(n^(1/2)))
    // prime_factor_decomposition(12) : {2:2, 3:1}
    unordered_map<int, int> prime_factor_decomposition(long long n) {
        unordered_map<int, int> m;
        while (n > 1) {
            bool findFactor = false;
            for(long long i = 2; i * i <= n; ++i) {
                if (n % i == 0) {
                    m[i]++;
                    n /= i;
                    findFactor = true;
                    break;
                }
            }
            if (not findFactor) {
                m[n]++;
                break;
            }
        }
        return m;
    }
};



int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);

    CoPrime cp;

    LL N;
    cin >> N;
    print(cp.totient_online(N));

    return 0;
}


Measured memory_bytes: 3204