#include <bits/stdc++.h>
#include <cmath>
#include <unordered_map> 
using namespace std;
#define ll long long
#define lmin LONG_MIN
#define lmax LONG_MAX
#define imin ll_MIN
#define imax ll_MAX
#define ffor(i,a,b) for(ll i=a;i<b;i++)
#define bfor(i,a,b) for(ll i=a-1;i>=b;i--)
#define mset(f,a) memset(f,a,sizeof(f))
#define pb push_back
#define fastio ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define MAXN   10000001
#define level 18
ll M= 1e9+7;
ll fact[300000+7];

ll sieve[1000000+6];

ll power(ll x ,ll y)
{
    if(y==0)
        return 1;
    
    ll t=power(x, y/2);
    
    t=((t%M)*(t%M))%M;
    
    if(y%2==1)
        t=((t%M)*(x%M))%M;
    
    return t;
    
}
  
ll max(ll a, ll b)
{
    if(a>b)
        return a;
    
    return b;
}
 
ll min(ll a, ll b)
{
    if(a>b)
        return b;
    
    return a;
}
  
 
ll binarySearch(vector<ll> arr, ll l, ll r, ll x) 
{ 
    if (r >= l) { 
        ll mid = l + (r - l) / 2; 
  
        // If the element is present at the middle 
        // itself 
        if (arr[mid] == x) 
            return mid; 
  
        // If element is smaller than mid, then 
        // it can only be present in left subarray 
        if (arr[mid] > x) 
            return binarySearch(arr, l, mid - 1, x); 
  
        // Else the element can only be present 
        // in right subarray 
        return binarySearch(arr, mid + 1, r, x); 
    } 
  
    // We reach here when element is not 
    // present in array 
    return -1; 
}
 
ll gcd(ll a, ll b)
{
    if (b == 0)
        return a;
    return gcd(b, a % b);
      
}
 
ll phi(ll n)
{
    ll result = n;
    
    for (ll p = 2; p * p <= n; ++p)
    {
        if (n % p == 0) {
            while (n % p == 0)
                n /= p;
            result -= result / p;
        }
    }
    if (n > 1)
        result -= result / n;
    return result;
}
void dfs(ll source,ll visited[],vector<ll>graph[],ll l)
{
    visited[source]=l;
    ll i;
    
    for(i=0;i<graph[source].size();i++)
    {
        if(visited[graph[source][i]]==-1)
            dfs(graph[source][i], visited, graph, l);
    }
}

bool isPerfectSquare(long double x) 
{   
  
  long double sr = sqrt(x); 
 
  return ((sr - floor(sr)) == 0); 
} 

ll getMid(ll s, ll e) { return s + (e -s)/2; }  
  
/* A recursive function to get the sum of values in the given range  
    of the array. The following are parameters for this function.  
  
    st --> Poller to segment tree  
    si --> Index of current node in the segment tree. Initially  
            0 is passed as root is always at index 0  
    ss & se --> Starting and ending indexes of the segment represented  
                by current node, i.e., st[si]  
    qs & qe --> Starting and ending indexes of query range */
ll getSumUtil(ll *st, ll ss, ll se, ll qs, ll qe, ll si)  
{  
    // If segment of this node is a part of given range, then return  
    // the sum of the segment  
    if (qs <= ss && qe >= se)  
        return st[si];  
  
    // If segment of this node is outside the given range  
    if (se < qs || ss > qe)  
        return 0;  
  
    // If a part of this segment overlaps with the given range  
    ll mid = getMid(ss, se);  
    return getSumUtil(st, ss, mid, qs, qe, 2*si+1) +  
        getSumUtil(st, mid+1, se, qs, qe, 2*si+2);  
}  
  
/* A recursive function to update the nodes which have the given  
index in their range. The following are parameters  
    st, si, ss and se are same as getSumUtil()  
    i --> index of the element to be updated. This index is  
            in the input array.  
diff --> Value to be added to all nodes which have i in range */
void updateValueUtil(ll *st, ll ss, ll se, ll i, ll diff, ll si)  
{  
    // Base Case: If the input index lies outside the range of  
    // this segment  
    if (i < ss || i > se)  
        return;  
  
    // If the input index is in range of this node, then update  
    // the value of the node and its children  
    st[si] = st[si] + diff;  
    if (se != ss)  
    {  
        ll mid = getMid(ss, se);  
        updateValueUtil(st, ss, mid, i, diff, 2*si + 1);  
        updateValueUtil(st, mid+1, se, i, diff, 2*si + 2);  
    }  
}  
  
// The function to update a value in input array and segment tree.  
// It uses updateValueUtil() to update the value in segment tree  
void updateValue(ll arr[], ll *st, ll n, ll i, ll new_val)  
{  
    // Check for erroneous input index  
    if (i < 0 || i > n-1)  
    {  
        cout<<"Invalid Input";  
        return;  
    }  
  
    // Get the difference between new value and old value  
    ll diff = new_val - arr[i];  
  
    // Update the value in array  
    arr[i] = new_val;  
  
    // Update the values of nodes in segment tree  
    updateValueUtil(st, 0, n-1, i, diff, 0);  
}  
  
// Return sum of elements in range from index qs (quey start)  
// to qe (query end). It mainly uses getSumUtil()  
ll getSum(ll *st, ll n, ll qs, ll qe)  
{  
    // Check for erroneous input values  
    if (qs < 0 || qe > n-1 || qs > qe)  
    {  
        cout<<"Invalid Input";  
        return -1;  
    }  
  
    return getSumUtil(st, 0, n-1, qs, qe, 0);  
}  
  
// A recursive function that constructs Segment Tree for array[ss..se].  
// si is index of current node in segment tree st  
ll constructSTUtil(ll arr[], ll ss, ll se, ll *st, ll si)  
{  
    // If there is one element in array, store it in current node of  
    // segment tree and return  
    if (ss == se)  
    {  
        st[si] = arr[ss];  
        return arr[ss];  
    }  
  
    // If there are more than one elements, then recur for left and  
    // right subtrees and store the sum of values in this node  
    ll mid = getMid(ss, se);  
    st[si] = constructSTUtil(arr, ss, mid, st, si*2+1) +  
            constructSTUtil(arr, mid+1, se, st, si*2+2);  
    return st[si];  
}  
  
/* Function to construct segment tree from given array. This function  
allocates memory for segment tree and calls constructSTUtil() to  
fill the allocated memory */
ll *constructST(ll arr[], ll n)  
{  
    // Allocate memory for the segment tree  
  
    //Height of segment tree  
    ll x = (ll)(ceil(log2(n)));  
  
    //Maximum size of segment tree  
    ll max_size = 2*(ll)pow(2, x) - 1;  
  
    // Allocate memory  
    ll *st = new ll[max_size];  
  
    // Fill the allocated memory st  
    constructSTUtil(arr, 0, n-1, st, 0);  
  
    // Return the constructed segment tree  
    return st;  
}  
  

vector<ll> maxSubArraySum(ll a[], ll size) 
{ 
    ll max_so_far = lmin, max_ending_here = 0, 
       start =0, end = 0, s=0; 
  
    for (ll i=0; i< size; i++ ) 
    { 
        max_ending_here += a[i]; 
  
        if (max_so_far < max_ending_here) 
        { 
            max_so_far = max_ending_here; 
            start = s; 
            end = i; 
        } 
  
        if (max_ending_here < 0) 
        { 
            max_ending_here = 0; 
            s = i + 1; 
        } 
    } 
    
    vector<ll>v;
    v.pb(max_so_far);
    v.pb(start);
    v.pb(end);

   
    return v;
} 

vector<ll> smallestSumSubarr(ll arr[], ll n) 
{ 
    ll min_ending_here = 0; 
      
    ll min_so_far = lmax,start=0,end=0,s=0; 
      
    for (ll i=0; i<n; i++) 
    { 
        min_ending_here+=arr[i];

        if (min_so_far > min_ending_here) 
        { 
            min_so_far = min_ending_here; 
            start = s; 
            end = i; 
        }   

         if (min_ending_here > 0) 
        {    
            min_ending_here = 0; 
            s=i+1;
        }     
    } 
      
    vector<ll>v;
    v.pb(min_so_far);
    v.pb(start);
    v.pb(end);

    return v;
} 

void bfs(vector<ll>g[],ll dist[],bool v[],ll u) 
{ 
    queue<ll> q; 
  
    q.push(u); 
    v[u] = true; 
    dist[u]=0;

    while (!q.empty()) 
    { 
        ll f = q.front(); 
        q.pop(); 
  
        // Enqueue all adjacent of f and mark them visited  
        for (auto i = g[f].begin(); i != g[f].end(); i++) 
        { 
            if (!v[*i]) 
            { 
                q.push(*i); 
                v[*i] = true; 
                dist[*i]=dist[f]+1;
            } 
        } 
    } 
} 

class DisjSet { 
    ll *rank, *parent, *gc, n; 
  
public: 
    // Constructor to create and 
    // initialize sets of n items 
    DisjSet(ll n) 
    { 
        rank = new ll[n]; 
        parent = new ll[n]; 
        gc = new ll[n];
        this->n = n; 
        makeSet(); 
    } 
  
    // Creates n single item sets 
    void makeSet() 
    { 
        for (ll i = 0; i < n; i++) { 
            parent[i] = i; 
        } 

        for (ll i = 0; i < n; i++) { 
            rank[i] = i; 
            gc[i]=i;
        } 

    
    } 
    
    void initi(ll a[])
    {
        for(ll i=0;i<n;i++)
            gc[i]=a[i]%M;
    }
    // Finds set of given item x 
    ll find(ll x) 
    { 
        // Finds the representative of the set 
        // that x is an element of 
        if (parent[x] != x) { 
  
            // if x is not the parent of itself 
            // Then x is not the representative of 
            // his set, 
            parent[x] = find(parent[x]); 
  
            // so we recursively call Find on its parent 
            // and move i's node directly under the 
            // representative of this set 
        } 
  
        return parent[x]; 
    } 
  
    // Do union of two sets represented 
    // by x and y. 
    bool Union(ll x, ll y) 
    { 
        // Find current sets of x and y 
        ll xset = find(x); 
        ll yset = find(y); 
  
        // If they are already in same set 
        if (xset == yset) 
            return false; 
  
        // Put smaller ranked item under 
        // bigger ranked item if ranks are 
        // different 
        if (rank[xset] < rank[yset]) { 
            parent[xset] = yset; 
            gc[yset]=gcd(gc[yset],gc[xset])%M;
        } 
        else if (rank[xset] > rank[yset]) { 
            parent[yset] = xset; 
            gc[xset]=gcd(gc[yset],gc[xset])%M;
        } 
        // else { 
        //     parent[yset] = xset; 
        //     gc[xset]=(gcd(gc[yset],gc[xset]))%M;
        //     rank[xset] = rank[xset] + 1; 
        // } 
        // If ranks are same, then increment 
        // rank. 
        
    } 

    ll get(ll x)
    {
        return gc[x]%M;
    }
}; 
  
bool isPali(string s)
{
    ll st=0,ed=s.size()-1;

    while(st<=ed && s[st]==s[ed])
    {
        st++;
        ed--;
    }

    if(st>ed)
        return true;

    return false;
}


ll sp[MAXN]; 
  
// Calculating SPF (Smallest Prime Factor) for every 
// number till MAXN. 
// Time Complexity : O(nloglogn) 
void siev() 
{ 
    sp[1] = 1; 
    for (ll i=2; i<MAXN; i++) 
        sp[i] = i; 
  
    for (ll i=4; i<MAXN; i+=2) 
        sp[i] = 2; 
  
    for (ll i=3; i*i<MAXN; i++) 
    { 
        if (sp[i] == i) 
        { 
            // marking SPF for all numbers divisible by i 
            for (int j=i*i; j<MAXN; j+=i) 
  
                if (sp[j]==j) 
                    sp[j] = i; 
        } 
    } 

    

    
} 
  
// A O(log n) function returning primefactorization 
// by dividing by smallest prime factor at every step 

ll a[2][100009];

vector<ll> getFactorization(ll x) 
{ 
    vector<ll> ret; 
    
    while (x != 1) 
    { 
        ret.push_back(sp[x]); 
        x = x / sp[x]; 
    } 

    
    return ret; 
} 

ll findlcm(ll arr[], ll n) 
{ 
    // Initialize result 
    ll ans = arr[0]; 
  
    for (ll i = 1; i < n; i++) 
        ans = (((arr[i] * ans)) / 
                (gcd(arr[i], ans))); 
  
    return ans; 
} 
void bfs(vector<ll>v[],ll n,ll parent[])
{
    ll i;
    
    ll flg[200000+9]={0};
    
    queue<ll>q;
    q.push(n);
    parent[n]=-1;
    while(!q.empty())
    {
        ll u=q.front();
        q.pop();
        flg[u]=1;
        for(i=0;i<v[u].size();i++)
        {
            ll ve=v[u][i];
            
            if(flg[ve]==0)
            {
                q.push(ve);
                parent[ve]=u;
            }
        }
       // cout<<endl;
    }
    
    
}

ll spf[MAXN];

vector<ll> getFactor(ll n) 
{ 
    vector<ll>v;

    ll i;

    for(i=1;i*i<=n;i++)
    {
        if(n%i==0)
        {
            if(n/i!=i)
                v.pb(n/i);
            v.pb(i);
        }
    }

    return v;
} 


ll s;
ll poww[1000000+9];
ll c[1000000+9];

vector <ll> tree[200000+9]; 
ll depth[200000+9]; 
ll parent[200000+9][level]; 
  
// pre-compute the depth for each node and their 
// first parent(2^0th parent) 
// time complexity : O(n) 
void dfsUtil(vector<ll>v[], ll s,ll vis[],ll dis[]) 
{ 
    vis[s]=1;

    ll i;

    for(i=0;i<v[s].size();i++)
    {
         if(vis[v[s][i]]==0)
        {
            vis[v[s][i]]=1;
            dis[v[s][i]]=dis[s]+1;
            dfsUtil(v,v[s][i],vis,dis);
        }
    }
} 
  
// Dynamic Programming Sparse Matrix Approach 
// populating 2^i parent for each node 
// Time complexity : O(nlogn) 
ll dis[200009];
ll par[200009];
void dfs(ll cur, ll prev) 
{ 
    //cout<<"22\n";
    depth[cur] = depth[prev] + 1; 
    parent[cur][0] = prev; 
    //cout<<cur<<" "<<prev<<endl;
    for (ll i=0; i<tree[cur].size(); i++) 
    { 
        if (tree[cur][i] != prev) 
        {
            dis[tree[cur][i]]=dis[cur]+1;
            par[tree[cur][i]]=cur;
            dfs(tree[cur][i], cur); 
        }
    } 
} 
  

void precomputeSparseMatrix(ll n) 
{ 
    for (ll i=1; i<level; i++) 
    { 
        for (ll node = 1; node <= n; node++) 
        { 
            if (parent[node][i-1] != -1) 
                parent[node][i] = 
                    parent[parent[node][i-1]][i-1]; 
        } 
    } 
} 
  
// Returning the LCA of u and v 
// Time complexity : O(log n) 
ll lca(ll u, ll v) 
{ 
    if (depth[v] < depth[u]) 
        swap(u, v); 
  
    ll diff = depth[v] - depth[u]; 
  
    // Step 1 of the pseudocode 
    for (int i=0; i<level; i++) 
        if ((diff>>i)&1) 
            v = parent[v][i]; 
  
    // now depth[u] == depth[v] 
    if (u == v) 
        return u; 
  
    // Step 2 of the pseudocode 
    for (ll i=level-1; i>=0; i--) 
        if (parent[u][i] != parent[v][i]) 
        { 
            u = parent[u][i]; 
            v = parent[v][i]; 
        } 
  
    return parent[u][0]; 
} 

void dfs(vector<ll>v[],ll s, ll dis[],ll vis[],ll a[], ll su[],ll y)
{
    //cout<<s<<endl;
    
    if(su[s]==-1)
    {
        a[s]=0;
    }
    else
    {
        a[s]=su[s]-y;
    }

    y+=a[s];

    ll i;
    vis[s]=1;

    for(i=0;i<v[s].size();i++)
    {
        if(vis[v[s][i]]==0)
        {
            dis[v[s][i]]=dis[s]+1;
            dfs(v,v[s][i],dis,vis,a,su,y);
        }
    }

    y-=a[s];
}

void numberOfNodes(vector<ll>adj[],ll count1[],ll s, ll e) 
{ 
    vector<ll>::iterator u; 
    count1[s] = 1; 
    for (u = adj[s].begin(); u != adj[s].end(); u++) { 
          
        // condition to omit reverse path 
        // path from children to parent 
        if (*u == e) 
            continue; 
          
        // recursive call for DFS 
        numberOfNodes(adj,count1,*u, s); 
          
        // update count[] value of parent using  
        // its children 
        count1[s] += count1[*u]; 
    } 
} 


ll p[100000+9];
ll f[100000+9];

vector<ll> getBinary(ll x)
{
    vector<ll>v;

    while(x>0)
    {
        v.pb(x%2);
        x=x/2;
    }

    // reverse(v.begin(),v.end());
    
    return v;
}

ll max(ll a, ll b, ll c) { return max(max(a, b), c); } 
ll maxCrossingSum(ll arr[], ll l, ll m, ll h) 
{ 
    // Include elements on left of mid. 
    ll s1[m-l+1],s2[h-m];
    mset(s1,0);
    mset(s2,0);

    s1[m-l]=arr[m];
    ll le=m-l-1;
    ll i;

    ll mx1[m-l+1],mx2[h-m];
    mx1[m-l]=arr[m];

    for(i=m-1;i>=l;i--)
    {
        s1[le]=s1[le+1]+arr[i];
        //cout<<s1[le]<<" "<<s1[le+1]<<" "<<arr[i]<<endl;
        mx1[le]=max(mx1[le+1],arr[i]);
        le--;
    }

    s2[0]=arr[m+1];
    le=1;
    
    mx2[0]=arr[m+1];
    // cout<<s2[0]<<endl;
    for(i=m+2;i<=h;i++)
    {
        s2[le]=s2[le-1]+arr[i];
        mx2[le]=max(mx2[le-1],arr[i]);
        //cout<<s2[le]<<" "<<s2[le-1]<<" "<<arr[i]<<endl;
        le++;
    }

    
    ll j;
    i=0;j=h-m-1;
    ll maxi=0;

    while(i<=m-l && j>=0)
    {
        if(maxi<s1[i]+s2[j]-max(mx1[i],mx2[j]))
            maxi=s1[i]+s2[j]-max(mx1[i],mx2[j]);
        //cout<<s1[i]<<" "<<s2[j]<<endl;
        if(mx1[i]==max(mx1[i],mx2[j]))
            i++;
        else
            j--;

        cout<<maxi<<endl;
    }

    return maxi;
} 
  
// Returns sum of maxium sum subarray in aa[l..h] 
ll maxSubArraySum(ll arr[], ll l, ll h) 
{ 
   // Base Case: Only one element 
   if (l == h) 
     return 0; 
  
   // Find middle point 

   
   ll m = (l + h)/2; 
    // ll y1=*max_element(arr,arr+(m+1));
    // ll y2=*max_element(arr+(m+1),arr+(h+1));

//    cout<<y1<<" "<<y2<<endl;

    ll l1=maxSubArraySum(arr, l, m);
    ll l2=maxSubArraySum(arr, m+1, h);
    ll l3=maxCrossingSum(arr, l, m, h);


    cout<<l1<<" "<<l2<<" "<<l3<<" "<<l<<" "<<h<<endl;
   return max(l1,l2, l3); 
} 

ll Ni,Mi;
// #define double float

vector<ll> bfsM(ll s, vector<ll>v[], ll dis[], bool vis[],ll a[],ll b[],double rt)
{
    queue<ll>q;
    dis[s]=1;
    vector<ll>vt;
    q.push(s);
    vis[s]=true;
    //cout<<s<<endl;
    // cout<<rt<<endl;
    vt.pb(s);

    while(!q.empty())
    {
        ll u=q.front();
        q.pop();

        ll i;

        for(i=0;i<v[u].size();i++)
        {
            
            double d=(a[v[u][i]]/(double)b[v[u][i]]);
            
            if(!vis[v[u][i]] && d==rt)
            {
                //cout<<v[u][i]<<endl;
                q.push(v[u][i]);
                dis[v[u][i]]=dis[u]+1;
                vis[v[u][i]]=true;
                vt.pb(v[u][i]);
            }
        }
    }

    return vt;
}

pair<ll,ll>dfsUti(vector<ll>v[],ll s, ll a[], ll b[], ll c[], ll vis[],pair<ll,ll>p[])
{
    
    vis[s]=1;

    ll x=0,y=0;
    for(ll i=0;i<v[s].size();i++)
    {
        

        if(vis[v[s][i]]==0)
        {
            if(a[s]<a[v[s][i]])
                a[v[s][i]]=a[s];
            
            pair<ll,ll>p1=dfsUti(v,v[s][i],a,b,c,vis,p);
            x+=p1.first;
            y+=p1.second;
        }
    }

    if(b[s]==1 && c[s]==0)
        y++;
    else if(b[s]==0 && c[s]==1)
        x++;

    if(1)
    {
        ll d=min(x,y);
        x=x-d;
        y=y-d;
        p[s]=make_pair(d,d);
    }
   
    return make_pair(x,y);
}

void dfs(vector<ll>v[],ll s, ll a[], ll vis[],pair<ll,ll>p[],ll*cost,ll c)
{
    vis[s]=1;

    
    ll count=2*p[s].first;
    (*cost)=(*cost)+(a[s]*count);
    c=a[s];

    

    for(ll i=0;i<v[s].size();i++)
    {
        if(vis[v[s][i]]==0)
        {
            dfs(v,v[s][i],a,vis,p,cost,c);
        }
    }
}
ll ft;
bool compt(ll x, ll y)
{
    return (x%ft)<(y%ft);
}

ll findMex(ll b[], ll n)
{
    ll l=0;

    ll a[n];
    for(ll i=0;i<n;i++)
        a[i]=b[i];

    sort(a,a+n);

    for(ll i=0;i<n;i++)
    {
        if(a[i]!=l)
        {
            return l;
        }

        while(i<n && a[i]==l)
        {
            i++;
        }
        i--;
        l++;
    }

    return l;
}
void output()
{
    fastio
    
    ll n;
    cin>>n;

    if(n%1000==0)
    {
        cout<<"0\n";
    }
    else
    {
        cout<<(n/1000+1)*1000-n<<endl;
    }
}   

int main(int argc, const char * argv[]) {
    // insert code here...



    fastio
    #ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    #endif 
    //siev();

    

    int t;
    t=1;
   //cin>>t;
    
    p[0]=1;

    // for(ll i=1;i<=61;i++)
    //     p[i]=p[i-1]*2;
    
    // f[0]=1;

    // for(ll i=1;i<=100000;i++)
    //     f[i]=((f[i-1]%M)*(i%M))%M;
    
    
    while(t--)
        output();
        
    return 0;
}

Measured memory_bytes: 8344