There are n shovels in Polycarp's shop. The i-th shovel costs i burles, that is, the first shovel costs 1 burle, the second shovel costs 2 burles, the third shovel costs 3 burles, and so on. Polycarps wants to sell shovels in pairs.

Visitors are more likely to buy a pair of shovels if their total cost ends with several 9s. Because of this, Polycarp wants to choose a pair of shovels to sell in such a way that the sum of their costs ends with maximum possible number of nines. For example, if he chooses shovels with costs 12345 and 37454, their total cost is 49799, it ends with two nines.

You are to compute the number of pairs of shovels such that their total cost ends with maximum possible number of nines. Two pairs are considered different if there is a shovel presented in one pair, but not in the other.

Input

The first line contains a single integer n (2 ≤ n ≤ 109) — the number of shovels in Polycarp's shop.

Output

Print the number of pairs of shovels such that their total cost ends with maximum possible number of nines. 

Note that it is possible that the largest number of 9s at the end is 0, then you should count all such ways.

It is guaranteed that for every n ≤ 109 the answer doesn't exceed 2·109.

Examples

Input

7


Output

3


Input

14


Output

9


Input

50


Output

1

Note

In the first example the maximum possible number of nines at the end is one. Polycarp cah choose the following pairs of shovels for that purpose:

  * 2 and 7; 
  * 3 and 6; 
  * 4 and 5. 



In the second example the maximum number of nines at the end of total cost of two shovels is one. The following pairs of shovels suit Polycarp:

  * 1 and 8; 
  * 2 and 7; 
  * 3 and 6; 
  * 4 and 5; 
  * 5 and 14; 
  * 6 and 13; 
  * 7 and 12; 
  * 8 and 11; 
  * 9 and 10. 



In the third example it is necessary to choose shovels 49 and 50, because the sum of their cost is 99, that means that the total number of nines is equal to two, which is maximum possible for n = 50.
import java.io.*;
	import java.math.BigInteger;
	import java.math.RoundingMode;
	import java.text.DecimalFormat;
	import java.util.*;
	
	
	public class Solution
	{
	
		static double eps=(double)1e-6;
		static long mod=(long)(1e9+9);
		//static int arr[] =new int[1000001];
		//private static DecimalFormat df2 = new DecimalFormat(".##");
		public static void main(String args[]){
			InputReader sc = new InputReader(System.in);
			//Scanner sc=new Scanner(System.in);
			OutputStream outputStream = System.out;
			PrintWriter out = new PrintWriter(outputStream);
			//----------my code----------
			int t1=1;
			while(t1-->0)
			{
				long n=sc.nextLong();
				if(n==2)
					out.println("1");
				if(n==3)
					out.println("3");
				if(n==4)
					out.println("6");
				else if(n>=5 && n<50)
				{
					long temp=n%10;
					long d=n/10;
					long ans=5*d*d;
					if(temp<5)
						ans+=temp*d;
					else if(temp<9)
						ans+=temp*d+(temp%5+1);
					else
						ans+=temp*d+4;
					out.println(ans);
				}
				else if(n>=50 && n<500)
				{
					long temp=n%100;
					long d=n/100;
					long ans=50*d*d;
					if(temp<50)
					{
						ans+=temp*d;
					}
					else if(temp<99)
					{
						ans+=temp*d+(temp%50+1);
					}
					else
						ans+=temp*d+49;
					out.println(ans);
				}
				else if(n>=500 && n<5000)
				{
					long temp=n%(long)(1e3);
					long d=n/(long)1e3;
					long ans=500*d*d;
					if(temp<500)
					{
						ans+=temp*d;
					}
					else if(temp<999)
					{
						ans+=temp*d+(temp%500+1);
					}
					else
						ans+=temp*d+499;
					out.println(ans);
				}
				else if(n>=(5*(long)1e3) && n<(5*(long)1e4))
				{
					long temp=n%(long)(1e4);
					long d=n/(long)1e4;
					long ans=(5*(long)1e3)*d*d;
					if(temp<(5*(long)1e3))
					{
						ans+=temp*d;
					}
					else if(temp<(long)(1e4)-1)
					{
						ans+=temp*d+(temp%(5*(long)1e3)+1);
					}
					else
						ans+=temp*d+(5*(long)1e3)-1;
					out.println(ans);
				}
				else if(n>=(5*(long)1e4) && n<(5*(long)1e5))
				{
					long temp=n%(long)(1e5);
					long d=n/(long)1e5;
					long ans=(5*(long)1e4)*d*d;
					if(temp<(5*(long)1e4))
					{
						ans+=temp*d;
					}
					else if(temp<(long)(1e5)-1)
					{
						ans+=temp*d+(temp%(5*(long)1e4)+1);
					}
					else
						ans+=temp*d+(5*(long)1e4)-1;
					out.println(ans);
				}
				else if(n>=(5*(long)1e5) && n<(5*(long)1e6))
				{
					long temp=n%(long)(1e6);
					long d=n/(long)1e6;
					long ans=(5*(long)1e5)*d*d;
					if(temp<(5*(long)1e5))
					{
						ans+=temp*d;
					}
					else if(temp<(long)(1e6)-1)
					{
						ans+=temp*d+(temp%(5*(long)1e5)+1);
					}
					else
						ans+=temp*d+(5*(long)1e5)-1;
					out.println(ans);
				}
				else if(n>=(5*(long)1e6) && n<(5*(long)1e7))
				{
					long temp=n%(long)(1e7);
					long d=n/(long)1e7;
					long ans=(5*(long)1e6)*d*d;
					if(temp<(5*(long)1e6))
					{
						ans+=temp*d;
					}
					else if(temp<(long)(1e7)-1)
					{
						ans+=temp*d+(temp%(5*(long)1e6)+1);
					}
					else
						ans+=temp*d+(5*(long)1e6)-1;
					out.println(ans);
				}
				else if(n>=(5*(long)1e7) && n<(5*(long)1e8))
				{
					long temp=n%(long)(1e8);
					long d=n/(long)1e8;
					long ans=(5*(long)1e7)*d*d;
					if(temp<(5*(long)1e7))
					{
						ans+=temp*d;
					}
					else if(temp<(long)(1e8)-1)
					{
						ans+=temp*d+(temp%(5*(long)1e7)+1);
					}
					else
						ans+=temp*d+(5*(long)1e7)-1;
					out.println(ans);
				}
				else if(n>=(5*(long)1e8) && n<=((long)1e9))
				{
					long temp=n%(long)(1e9);
					long d=n/(long)1e9;
					long ans=(5*(long)1e8)*d*d;
					if(temp<(5*(long)1e8))
					{
						ans+=temp*d;
					}
					else if(temp<(long)(1e9)-1)
					{
						ans+=temp*d+(temp%(5*(long)1e8)+1);
					}
					else
						ans+=temp*d+(5*(long)1e8)-1;
					out.println(ans);
				}
			}
			//---------------------------------
			out.close();
		}
		
		static long modInverse(long A,long M)
		{
		    return modularExpon(A,M-2,M);
		}
		
		static long comb(int n,int r,long [][] c)
		{
			if(n<r)
				return 0;
			if(n-r < r) 
			{
				c[n][r]=comb(n,n-r,c);
				return c[n][r];
			}
		    if(r == 0)
		    {
		    	c[n][r]=1;
		    	return 1;
		   	}
		    if(c[n][r]!=0)
		    	return c[n][r];
		    else
		    {
		    	c[n][r]=(n*comb(n-1, r-1,c))/r;
		    	return c[n][r];
		    }
		}
		
		static long modularExpon(long x,long n,long M)
		{
		    long result=1;
		    while(n>0)
		    {
		        if(n % 2 ==1)
		            result=(result * x)%M;
		        x=(x*x)%M;
		        n=n/2;
		    }
		    return result%M;
		}
		
		static int IsPandigital(int n)
	    {
	        int digits = 0,temp=n; int count = 0; int tmp = 0;
	        int fr[]=new int[10];
	        for(int i=0;i<10;i++)
	        	fr[i]=0;
	        while(temp>0)
	        {
	        	int a=temp/10;
	        	//System.out.println(temp-a*10);
	        	fr[temp-a*10]++;
	        	temp=temp/10;
	        	digits++;
	        }
	        for(int i=1;i<=digits;i++)
	        {
	        	if(fr[i]==1)
	        	{
	        		tmp=1;
	        	}
	        	else
	        	{
	        		tmp=0;
	        		break;
	        	}
	        }
	        return tmp;
	    }
		
		static int Divisors(int n)
		{
			int sum=0;
		    for (int i=2; i*i<=n; i++)
		    {
		        if (n%i==0)
		        {
		            if (n/i == i)
		                {sum+=i;//System.out.println(sum+" "+i);
		                }
		 
		            else 
		                {sum+=i+(n/i);//System.out.println(sum+" "+i+" "+(n/i));
		                }
		        }
		    }
		    return sum;
		}
		
		static int findmax(int arr[], int n)
	    {
	        int incl = arr[0];
	        int excl = 0;
	        int excl_new;
	        int i;
	 
	        for (i = 1; i < n; i++)
	        {
	            excl_new = (incl > excl) ? incl : excl;
	            incl = excl + arr[i];
	            excl = excl_new;
	        }
	        return ((incl > excl) ? incl : excl);
	    }
		
		static long ce(long x)
		{
			if(x%2!=0)
				return x/2+1;
			return x/2;
		}
		static boolean isSubSequence(String str1, String str2, int m, int n)
		{
		   int j = 0;
		   for (int i=0; i<n&&j<m; i++)
		       if (str1.charAt(j) == str2.charAt(i))
		         j++;
		 
		   return (j==m);
		}
		
		static long fibo(long l) {
	        if (l < 0) {
	            throw new IllegalArgumentException("The fibo value cannot be negative");
	        }
	
	        if (l <= 1) return l;
	
	        long[][] result = {{1, 0}, {0, 1}}; // identity matrix.
	        long[][] fiboM = {{1, 1}, {1, 0}};
	
	        while (l > 0) {
	            if (l%2 == 1) {
	                multMatrix(result, fiboM);
	            }
	            l = l / 2;
	            multMatrix(fiboM, fiboM);
	        }
	
	        return result[1][0];
	    }
	
	    private static void multMatrix(long[][] result, long[][] fiboM) {
	        long a = (result[0][0]%mod * fiboM[0][0]%mod)%mod +  (result[0][1]%mod * fiboM[1][0]%mod)%mod;
	        long b = (result[0][0]%mod * fiboM[0][1]%mod)%mod + ( result[0][1]%mod * fiboM[1][1]%mod)%mod;
	        long c = (result[1][0]%mod * fiboM[0][0]%mod)%mod + ( result[1][1]%mod * fiboM[0][1]%mod)%mod;
	        long d = (result[1][0]%mod * fiboM[0][1]%mod)%mod +  (result[1][1]%mod * fiboM[1][1]%mod)%mod;
	
	        result[0][0] = a;
	        result[0][1] = b;
	        result[1][0] = c;
	        result[1][1] = d;
	    }
	    
	    static HashSet<Long> gr(int size)
	    {
	    	long range=mod;
	    	long m0=2017;
	    	long m1=2027;
	    	long ln=0;
	    	long sln=1;
	    	long mn=0;
	    	HashSet<Long> hs=new HashSet<Long>();
	    	for(int i=0;i<size;i++)
	    	{
	    		long nn=((((ln%mod)*m0)%mod+((sln%mod)*m1)%mod+mn)%mod)+1;
	    		sln=ln;
	    		ln=nn;
	    		mn=Math.max(mn, nn);
	    		hs.add(nn);
	    	}
	    	return hs;
	    }
	    
		static int[] sieve(int n,int[] arr)
		{
			arr[0]=1;
			arr[1]=1;
			for(int i=2;i*i<=n;i++)
			{
				if(arr[i]==0)
				{
					for(int j=i*2;j<=n;j+=i)
						arr[j]=1;
				}
			}
			return arr;
		}
		
		static int[] spfsieve(int arr[])
		{
			int n=5000000;
			arr[0]=1;
			arr[1]=1;
			for(int i=2;i<=n;i++)
				arr[i]=i;
			for(int i=4;i<=n;i+=2)
				arr[i]=2;
			for(int i=3;i*i<=n;i++)
			{
				if(arr[i]==i)
				{
					for(int j=i*i;j<=n;j+=i)
						if (arr[j]==j)
		                    arr[j] = i;
				}
			}
			return arr;
		}
		
		static boolean isPal(String s)
		{
			for(int i=0, j=s.length()-1;i<=j;i++,j--)
			{
				if(s.charAt(i)!=s.charAt(j)) return false;
			}
			return true;
		}
		public static String rev(String s)
		{
			StringBuilder sb=new StringBuilder(s);
			sb.reverse();
			return sb.toString();
		}
		    
		static long lcm(long a, long b)
		{
			long temp1=a,temp2=b;
		    return ((a * b) / gcd(temp1, temp2));
		}
		
		static long gcd(long a, long b)
		{
		    if (b==0)
		        return a;
		    return gcd(b, a%b);
		}
		static long modulo(long a,long b,long c) {
			long x=1;
			long y=a;
			while(b > 0){
				if(b%2 == 1){
					x=(x*y)%c;
				}
				y = (y*y)%c; // squaring the base
				b /= 2;
			}
			return  x%c;
		}
		public static void debug(Object... o) {
			System.out.println(Arrays.deepToString(o));
		}
		
		static class SegmentTree 
		{
		    long st[]; 
		    public SegmentTree(long arr[], int n)
		    {
		        int x = (int) (Math.ceil(Math.log(n) / Math.log(2)));
		 
		        int max_size = 2 * (int) Math.pow(2, x) - 1;
		 
		        st = new long[max_size];
		 
		        constructSTUtil(arr, 0, n - 1, 0);
		    }
		    int getMid(int s, int e) {
		        return s + (e - s) / 2;
		    }
		 
		    long getSumUtil(int ss, int se, int qs, int qe, int si)
		    {
		        if (qs <= ss && qe >= se)
		            return st[si];
		        if (se < qs || ss > qe)
		            return 0;
		        int mid = getMid(ss, se);
		        return getSumUtil(ss, mid, qs, qe, 2 * si + 1) +
		                getSumUtil(mid + 1, se, qs, qe, 2 * si + 2);
		    }
		 
		    void updateValueUtil(int ss, int se, int i, int diff, int si)
		    {
		        if (i < ss || i > se)
		            return;
		        st[si] = st[si] + diff;
		        if (se != ss) {
		            int mid = getMid(ss, se);
		            updateValueUtil(ss, mid, i, diff, 2 * si + 1);
		            updateValueUtil(mid + 1, se, i, diff, 2 * si + 2);
		        }
		    }
		 
		    void updateValue(int arr[], int n, int i, int new_val)
		    {
		        if (i < 0 || i > n - 1) {
		            System.out.println("Invalid Input");
		            return;
		        }
		 
		        // Get the difference between new value and old value
		        int diff = new_val - arr[i];
		 
		        // Update the value in array
		        arr[i] = new_val;
		 
		        // Update the values of nodes in segment tree
		        updateValueUtil(0, n - 1, i, diff, 0);
		    }
		    long getSum(int n, int qs, int qe)
		    {
		        if (qs < 0 || qe > n - 1 || qs > qe) {
		            System.out.println("Invalid Input");
		            return -1;
		        }
		        return getSumUtil(0, n - 1, qs, qe, 0);
		    }
		 
		    long constructSTUtil(long arr[], int ss, int se, int si)
		    {
		        if (ss == se) {
		            st[si] = arr[ss];
		            return arr[ss];
		        }
		        int mid = getMid(ss, se);
		        st[si] = constructSTUtil(arr, ss, mid, si * 2 + 1) +
		                 constructSTUtil(arr, mid + 1, se, si * 2 + 2);
		        return st[si];
		    }
		}
		static class Pair {
			long x;
			long y;
			/*Pair(int xx,int yy,int zz){
				x=xx;
				y=yy;
				z=zz;
			}*/
			public long getx()
			{
				return x;
			}
			public long gety()
			{
				return y;
			}
			public void setx(long xx)
			{
				x=xx;
			}
			public void sety(long yy)
			{
				y=yy;
			}
		}
		
		public final static Comparator<Pair> ORIGINAL = new Comparator<Pair>()
	    {
		public int compare(Pair p1,Pair p2)
		{
			if(p1.getx()<p2.getx())
				return -1;
			else if(p1.getx()==p2.getx() && p1.gety()<p2.gety())
				return -1;
			else //if(p1.getx()>p2.getx() || p1.gety()>p2.gety() || p1.getz()>p2.getz())
				return 1;
			/*else
			{
				if(p1.gety()<p2.gety())
					return -1;
				else if(p1.gety()>p2.gety())
					return 1;
				else
				{
					if(p1.getz()<p2.getz())
						return -1;
					else if(p1.getz()>p2.getz())
						return 1;
				}
			}*/
			//return 0;
		}
	    };
		
		static class InputReader {
			public BufferedReader reader;
			public StringTokenizer tokenizer;
	
			public InputReader(InputStream inputstream) {
				reader = new BufferedReader(new InputStreamReader(inputstream));
				tokenizer = null;
			}
	
			public String nextLine(){
				String fullLine=null;
				while (tokenizer == null || !tokenizer.hasMoreTokens()) {
					try {
						fullLine=reader.readLine();
					} catch (IOException e) {
						throw new RuntimeException(e);
					}
					return fullLine;
				}
				return fullLine;
			}
			public String next() {
				while (tokenizer == null || !tokenizer.hasMoreTokens()) {
					try {
						tokenizer = new StringTokenizer(reader.readLine());
					} catch (IOException e) {
						throw new RuntimeException(e);
					}
				}
				return tokenizer.nextToken();
			}
			public long nextLong() {
				return Long.parseLong(next());
			}
			public int nextInt() {
				return Integer.parseInt(next());
			}
		}
		
	}
	class Graph
	{
		int vertices;
		LinkedList<Integer> l[];
		Graph(int vertices)
		{
			this.vertices=vertices;
			l=new LinkedList[vertices];
			for(int i=0;i<vertices;i++)
			{
				l[i]=new LinkedList<Integer>();
			}
		}	
		void addEdge(int s,int v)
		{
			l[s].add(v);
		}
		
		void BFS(int s)
		{
			LinkedList<Integer> queue=new LinkedList<Integer>();
			boolean []visited=new boolean[vertices];
			visited[s]=true;
			queue.add(s);
			while(queue.size()>0)
			{
				int r=queue.poll();
				System.out.println(r+" ");
				for(int i=0;i<l[r].size();i++)
				{
					int temp=l[r].get(i);
					if(!visited[temp])
					{
						queue.add(temp);
						visited[temp]=true;
					}
				}
			}
		}
		
	}  