#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <stdlib.h>     /* srand, rand */
#include <time.h>       /* time */
#define mt make_tuple
#define ll long long
#define eb emplace_back
#define fi first
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define forn(i, n) for (int i = 0; i < (int)(n); ++i)
#define fore(i, a, b) for (int i = (int)(a); i <= (int)(b); ++i)
#define scanVec(vec , n) for(int i = 0; i < n ; i++){ cin>>vec[i];}
#define printVec(vec , n) for(int i = 0; i < n ; i++){ cout<<vec[i]<<" ";}
#define mod(a,b) ((a%b +b)%b)
#define bit(x,i) (x&(1<<i))  //select the bit of position i of x
#define lowbit(x) ((x)&((x)^((x)-1))) //get the lowest bit of x
#define hBit(msb,n) asm("bsrl %1,%0" : "=r"(msb) : "r"(n)) //get the highest bit of x, maybe the fastest
#define max(a,b) (a<b?b:a)
#define min(a,b) (a>b?b:a) 
#define error(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); }
#define IN(i,l,r) (l<i&&i<r)
#define LINR(i,l,r) (l<=i&&i<=r)
#define LIN(i,l,r) (l<=i&&i<r)
#define INR(i,l,r) (l<i&&i<=r)
#define lastEle(vec) vec[vec.size()-1] 
#define SZ(x) ((int)((x).size()))
#define FOREACH(i,t) for (typeof(t.begin()) i=t.begin(); i!=t.end(); i++) 
#define ll long long 
#define ull unsigned long long
#define ui unsigned int
#define us unsigned short
#define INF 1001001001
#define PI 3.1415926535897932384626
 
using namespace std;
 using namespace __gnu_pbds;
 template <typename T>
 using ordered_set =
    tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
 
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<pii> vpi;
typedef vector<vi> vvi;
 
void err(istream_iterator<string> it) {}
template<typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
    cerr << *it << " = " << a << endl;
    err(++it, args...);
}
 
//----------------------------------------------------------------------------------------------------------------------
  
  
void swap(char &a, char & b){
    char temp = a;
    a = b;
    b = temp;
}
 
const ll MOD = 998244353;
const int MAXN = 1e5 + 5;
 
//char grid[MAXN][MAXN];
 
void add_self(ll &a, ll b){
    a+= b;
    while(a > MOD){
        a-=MOD;
    }
}
 
 
ll inf = 1LL*1e18;
 
void no(){
    cout <<"No" << endl;
    exit(0);
}
 
void yes(){
    cout <<"Yes" << endl;
    exit(0);
}

ll getRem(ll add,ll c, ll curr){
    ll cntAll = (add + curr)/c;
    if(cntAll == 0) return curr;
    ll cntAdd = add/c;
    ll remAdd = add%c;
    cntAll -= cntAdd;
    curr = (cntAll-1)*curr - (c - remAdd);
    return curr;
}

// bool check( ll c, vector< ll > & arr,ll k){
//     vector< pair< ll,ll > > dp (arr.size());
//     dp[1] = {(arr[1]/c),(arr[1]%c)};
//     for(int i = 2;i < arr.size();i++){
//         if(i >= arr.size()) break;
//         pair< ll,ll > one = {dp[i-1].first + (arr[i] + dp[i-1].second)/c, getRem(dp[i-1].second,c,arr[i])};
//         pair< ll,ll > two = {dp[i-2].first + (arr[i] + arr[i-1])/c, getRem(arr[i-1],c,arr[i])};
//         if(one> two){
//             dp[i] = one;
//         }else{
//             dp[i] = two;
//         }
//         //dp[i] = max(dp[i-1] + (arr[i]/c),dp[i-2] + (arr[i] + arr[i-1])/c);
//     }
//     return dp[arr.size()-1].first >= k;
// }


bool check( ll c, vector< ll > & arr,ll k){
    ll ans = arr[1]/c;
    ll rem = arr[1]%c;
    for(int i = 2;i < arr.size();i++){
        ll cnt = (arr[i] + rem)/c;
        ans += cnt;
        if(arr[i] + rem < c){
            rem = arr[i];
        }else{
            rem = (arr[i] + rem)%c;
        }
    }
    return ans >= k;
}


int main(){
    //srand (time(NULL));
    int n;
    cin >> n;
    for(int i = 9;i >= 1;i--){
        if(n%i == 0 && n/i < 10){
            yes();
        }
    }
    no();
    return 0;
}

Measured memory_bytes: 256