#include <bits/stdc++.h>
        using namespace std;
        #define rep(i,a,b) for(ll i =a; i<b;++i)
        #define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
        #define endl "\n"
        #define pb push_back
        #define F first
        #define S second
        #define print(a)       for(auto x : a) cout << x << " "; cout << endl
        #define print1(a)      for(auto x : a) cout << x.F << " " << x.S << endl
        #define print2(a,x,y)  for(int i = x; i < y; i++) cout<< a[i]<< " "; cout << endl
        #define mk(x,y)  make_pair(x,y)
        typedef  long long  int ll;
        const int N = ( 1e6 + 5 );
        const int mod = 1e9+7;
        ll n,m,p;
        vector <ll > g[N],g_tr[N];
ll pow_mod_m(ll a , ll n)
{
    if(!n)
        return 1;
    ll pt =  pow_mod_m(a,n/2);
    pt *= pt ; pt %= mod;
    if(n&1)
        pt *= a , pt %= mod;
    return pt;
}

struct LCA
{
    vector <int> height , euler , first , segtree;
    vector <bool > visited;
    int n;
    LCA(vector <vector<int>> &adj , int root  = 0)
    {
        n = adj.size();
        height.resize(n);
        first.resize(n);
        euler.reserve(2*n);
        visited.assign(n,false);
        dfs(adj,root);
        int m = euler.size();
        segtree.resize(4*m);
        build(1 , 0 , m-1);
    }
    void dfs(vector < vector <int>> &adj , int node , int h = 0)
    {
        visited[node]  = 1;
        height[node]  =h;
        first[node] = euler.size();
        euler.pb(node);
        for(auto to : adj[node])
        {
            if(!visited[to]){
                 dfs(adj ,to , h+1);
                 euler.pb(node);
            }
        }
    }
    void build(int node ,int b ,int e)
    {
        if(b == e)
            segtree[node]  = euler[b];
        else
        {
            int m = (b+e)>>1;
            build(node <<1 ,b ,m);
            build(node <<1 | 1 , m+1 , e);
            int l  =segtree[node <<1] ,r = segtree[node <<1 | 1 ] ;
            segtree[node] = ( height[l] < height[r] ) ? l  : r;
        }
    }

int query(int node , int b , int e,int L ,int R)
{
    if( b > R  || e<L)
        return -1;
    if( b >= L and e <= R )
        return segtree[node];
    int mid = ( b + e ) >> 1;
    int left  = query(node <<1 , b , mid , L ,R);
    int right = query(node <<1 |1 , mid+1,e, L,R);
    if(left == -1) return right;
    if(right == -1) return left;
    return (height[left] < height[right]) ? left : right ;
}

int lca(int u,int v)
{
    int left = first[u] , right = first[v];
    if(left > right) swap(left,right);
    return query( 1 , 0 , euler.size() -1 ,left ,right) ;
}
};

using cd = complex<double>;
const double PI = acos(-1);

void fft(vector<cd> & a, bool invert) {
    int n = a.size();
    if (n == 1)
        return;

    vector<cd> a0(n / 2), a1(n / 2);
    for (int i = 0; 2 * i < n; i++) {
        a0[i] = a[2*i];
        a1[i] = a[2*i+1];
    }
    fft(a0, invert);
    fft(a1, invert);

    double ang = 2 * PI / n * (invert ? -1 : 1);
    cd w(1), wn(cos(ang), sin(ang));
    for (int i = 0; 2 * i < n; i++) {
        a[i] = a0[i] + w * a1[i];
        a[i + n/2] = a0[i] - w * a1[i];
        if (invert) {
            a[i] /= 2;
            a[i + n/2] /= 2;
        }
        w *= wn;
    }
}

vector<int> multiply(vector<int> const& a, vector<int> const& b) {
    vector<cd> fa(a.begin(), a.end()), fb(b.begin(), b.end());
    int n = 1;
    while (n < a.size() + b.size())
        n <<= 1;
    fa.resize(n);
    fb.resize(n);

    fft(fa, false);
    fft(fb, false);
    for (int i = 0; i < n; i++)
        fa[i] *= fb[i];
    fft(fa, true);

    vector<int> result(n);
    for (int i = 0; i < n; i++)
        result[i] = round(fa[i].real());
    return result;
}

int main()
{
     IOS;
 //    freopen("a_example (2).txt","r",stdin);
 //   freopen("c.txt","w",stdout);
    int ts =1;
  //  cin>>ts;
	while( ts-- )
    {
        cin >> n ;
        cout<< (n%2 == 0 ? n/2 : n/2 +1) <<endl;
    }
	return 0;
}


Measured memory_bytes: 47104