#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
using pll=pair<ll,ll>;
#define all(v) v.begin(), v.end()
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define rep2(i,l,r) for(ll i = (l); i <= (ll)(r); i++)
#define rep3(i,l,r) for(ll i = (l); i >= (ll)(r); i--)
#define dup(x,y) (((x)+(y)-1)/(y)) //a/bの除算の切り上げ
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
const int inf = 1001001001;
const ll INF = 1LL << 60;
const ll mod = 1000000007;
const ld pi = acos(-1);
 
//xor演算
//a^b=b^a
//a^(b^c)=(a^b)^c
//a^a=0
//a+b=a^b + 2(a&b)
//(4a)^(4a+1)^(4a+2)^(4a+3)=0
 
// union by size + path having
// 最初にUnionFind a(n);で宣言
class UnionFind {
public:
   vector <ll> par; // 各元の親を表す配列
   vector <ll> siz; // 素集合のサイズを表す配列(1 で初期化)
 
   // Constructor
   UnionFind(ll sz_): par(sz_),siz(sz_, 1LL){
       for (ll i=0; i<sz_; i++) par[i]=i; // 初期では親は自分自身
   }
   void init(ll sz_){
       par.resize(sz_);
       siz.assign(sz_, 1LL);  // resize だとなぜか初期化されなかった
       for (ll i=0; i<sz_; i++) par[i]=i; // 初期では親は自分自身
  }
 
   // Member Function
   // Find
   ll root(ll x){ // 根の検索
      while (par[x]!=x){
           x=par[x]=par[par[x]]; // x の親の親を x の親とする
       }
       return x;
  }
 
   // Union(Unite, Merge)
   bool unite(ll x, ll y){
       x=root(x);
       y=root(y);
       if (x==y) return false;
       // merge technique（データ構造をマージするテク．小を大にくっつける)
       if (siz[x]<siz[y]) swap(x, y);
       siz[x]+=siz[y];
       par[y]=x;
       return true;
  }
 
  bool same(ll x, ll y){ // 連結判定
       return root(x)==root(y);
  }
 
  ll size(ll x){ // 素集合のサイズ
      return siz[root(x)];
  }
};
 
//セグメント木
//全て添字で扱うこと
// seg.build(配列名, 単位元)で宣言
// segment_tree seg;
// seg.build(a,0);
 
struct segment_tree{
ll n; //vの要素数
ll m; //葉の数
vector<ll> v; //セグ木本体．ただの配列を使う
ll id_e; //単位元 区間の和なら0、区間の積なら1、最大値なら-1とか、最小値ならINF、最大公約数なら0
 
//二項演算
ll binary_op(ll a,ll b){
return a+b;//処理 区間の和ならa+b、区間の積ならa*b、最大値ならmax(a,b)、最初値ならmin(a,b)、最大公約数ならgcd(a,b)
}
 
//初期化関数．数列と単位元を受け取って初期化
void build(vector<ll> a,ll b){
  id_e = b;
  m = 1;
  while (m<a.size()) m*=2; //aの項数以上の2べきのうち最小のものを求める
  n = 2*m-1;
  v.resize(n);
  for (ll i=0; i<a.size(); i++) v[m-1+i]=a[i]; //葉(1段目)の値
  for (ll i=a.size(); i<m; i++) v[m-1+i]=id_e; //葉(1段目)の右端の0埋め
  for (ll i=m-2; i>=0; i--){ //2段目以降を順番に埋めていく
  v[i]=binary_op(v[2*i+1],v[2*i+2]);
  }
}
 
//ある項の値をbに書き換え
void update(ll a,ll b) {
  a+=(m-1);
  v[a]=b; //葉(1段目)を書き換え
  while((a-1)/2 != a){ //2段目以降を順番に書き換え
    a=(a-1)/2;
    v[a]=binary_op(v[2*a+1],v[2*a+2]);
  }
}
 
//区間和の補助関数
//cur:今見ている頂点の，配列vでの添字
//[l, r]:v[cur]がカバーする区間
ll seg_sub(ll a,ll b,ll cur,ll l,ll r){
  if (a<=l && r<=b) return v[cur]; //今見ている頂点のカバーする区間が，[a,b]に完全に収まっている場合
  if (r<a || b<l) return id_e; //今見ている頂点のカバーする区間が，[a,b]と全く被っていない場合
  return binary_op( //今見ている頂点のカバーする区間が，[a,b]と一部被っている場合
    seg_sub(a,b,2*cur+1,l,(l+r)/2),
    seg_sub(a,b,2*cur+2,(l+r)/2+1,r)
    );
}
 
//区間[a, b]の和
//最上段の頂点から子へ再帰していく
ll partial_sum(ll a,ll b){return seg_sub(a,b,0,0,m-1);}
};
 
ll modpow(ll x,ll n){
   x=x%mod;
   if(n==0) return 1;
   else if(n%2==1){
       return (x*modpow(x,n-1))%mod;
   }
   else return modpow((x*x)%mod,n/2)%mod;
}
 
ll com(ll n,ll k){
   ll x=1;
   for(int i=n-k+1; i<=n; i++){
      x=x*i%mod;
   }
   ll y=1;
   for(int i=1; i<=k; i++){
       y=y*i%mod;
   }
   y=modpow(y,mod-2);
   return x*y%mod;
}
 
bool is_prime(const unsigned n){
   switch(n){
       case 0: // fall-through
       case 1: return false;
       case 2: // fall-through
       case 3: return true;
  }
   if(n%2==0 || n%3==0) return false;
   for(unsigned i = 5; i*i<=n; i+=6) {
       if(n%i==0) return false;
       if(n%(i+2)==0) return false;
   }
   return true;
}
 
int digsum(int n){
   int res=0;
   while(n > 0) {
       res+=n%10; //ここをres++;に変えたら桁数を求める関数になる,res+=n%10;なら格桁の和
       n/=10;
   }
   return res;
}
vector<ll> divisor(ll n){
   vector<ll> ret;
   for(ll i=1; i*i<=n; i++){
       if(n%i==0){
           ret.push_back(i);
           if(i*i!=n) ret.push_back(n/i);
       }
   }
   sort(ret.begin(),ret.end());
   return ret;
}
 
vector<ll> yakusuu_cnt(ll n){
   vector<ll> cnt(n);
   for(ll i=1; i<=n; i++){
       for(ll j=i; j<=n; j+=i){
           cnt[j]++;
       }
   }
   return cnt;
}
 
int main(){

    ll n;
    cin >> n;
    ll ans=0;
    ll cnt=0;
    if(n==1){
        cout << 1 << endl;
        return 0;
    }
    rep2(i,1,n){
        ll x=i;
        ll y=0;
        if(x%2!=0) continue;
        while(x%2==0){
            x/=2;
            y++;
        }
        if(y>cnt){
            cnt=y;
            ans=i;
        }

        
    }

    cout << ans << endl;
    
}

Measured memory_bytes: 3604