Polycarpus loves lucky numbers. Everybody knows that lucky numbers are positive integers, whose decimal representation (without leading zeroes) contain only the lucky digits x and y. For example, if x = 4, and y = 7, then numbers 47, 744, 4 are lucky.

Let's call a positive integer a undoubtedly lucky, if there are such digits x and y (0 ≤ x, y ≤ 9), that the decimal representation of number a (without leading zeroes) contains only digits x and y.

Polycarpus has integer n. He wants to know how many positive integers that do not exceed n, are undoubtedly lucky. Help him, count this number.

Input

The first line contains a single integer n (1 ≤ n ≤ 109) — Polycarpus's number.

Output

Print a single integer that says, how many positive integers that do not exceed n are undoubtedly lucky.

Examples

Input

10


Output

10


Input

123


Output

113

Note

In the first test sample all numbers that do not exceed 10 are undoubtedly lucky.

In the second sample numbers 102, 103, 104, 105, 106, 107, 108, 109, 120, 123 are not undoubtedly lucky.
import java.io.*;
import java.math.BigInteger;
import java.util.*;


 public class Main {
	public static InputReader in;
    public static PrintWriter pw;



	public static void main(String args[]) {
		new Thread(null, new Runnable() {
            public void run() {
                try{
                    solve();
                }
                catch(Exception e){
                    e.printStackTrace();
                }
            }
        }, "1", 1 << 26).start();
    }
	//static HashSet<Integer> set;
	static ArrayList<Integer> g[];
	static ArrayList<Integer> h[];
	//static boolean visited[];
	static long edje=0;
    static boolean vis[];
	static int col[];
	static boolean[] visited;
	static int Parent[];
	static int Ans=0;
	static int min=Integer.MAX_VALUE;
	static boolean vis1[];
	static int degree[];
	static int f[];
	static  int size[];
	static int n;
	static int edjes=0;
	static int start=-1;
	static int end=-1;
	static boolean bool=false;
	static int Total=0;
	static int nums[];
	static int a[];
	static int fr[];
	static int min1=Integer.MAX_VALUE;
	static TreeSet<String> set;
	static int cnt=0;
	static TreeSet<Integer> don=new TreeSet<Integer>();
	public static void solve(){
	
		 in = new InputReader(System.in);
		 pw = new PrintWriter(System.out);
        int n=in.nextInt();
        for(int i=0;i<=9;i++)
        {
        	for(int j=i+1;j<=9;j++)
        	{
        		set=new TreeSet<String>();
        		String o=Integer.toString(i);
        		String p=Integer.toString(j);
        		set.add(o);
        		set.add(p);
        		Method(o,p);
        		set.clear();
        		cnt=0;
        	}
        }
      // System.out.println(don.size());
        //System.out.println(don.contains(111));
        int ans=0;
        don.add(1000000000);
        for(int x:don)
        {
        	if(x<=n)
        		ans++;
        }
        System.out.println(ans-1);
		 
	}
	

	 private static void Method(String one,String two) {
		TreeSet<String> tmp=new TreeSet<String>(); 
		if(cnt==8)
			return;
		for(String p:set)
		{
		don.add(Integer.parseInt(p+one));
		don.add(Integer.parseInt(p+two));
		tmp.add(p+one);
		tmp.add(p+two);
		}
		set=tmp;
		cnt++;
		Method(one,two);
	}


	public static void dfs(int curr)
	 {
		 edjes++;
		 fr[a[curr]]++;
		 visited[curr]=true;
		 min1=Math.min(min1,a[curr]);
		 for(int x:g[curr])
      	 {
			 if(!visited[x])
      			 dfs(x);
      	 }
	 }
	/*public static void dfs(int curr)
	{
		vis[curr]=true;
		int trees=0;
		for(int x:g[curr])
		{
			if(!vis[x]&&x!=1)
			{
			trees++;
			if(!s.contains(curr+" "+x))
				total+=cost[curr][x];
			dfs(x);
			}
	    }
		if(trees==0)
		{
			if(!s.contains(curr+" "+1))
				total+=cost[1][curr];
		}
	}
	public static void dfs1(int curr,int parent)
	{
	val[curr]=a[curr];
	for(int x:g[curr])
	{
	       if(x!=parent)
	       {
	    	   dfs1(x,curr);
	    	   val[curr]+=val[x];
	      }
	
	}
	}
	public static void dfs2(int curr,int parent)
	{
		f[curr]=val[curr];
		for(int x:g[curr])
		{
			if(x!=parent)
			{
				dfs2(x,curr);
				f[curr]+=f[x];
			}
		}
	}
	
	
	 
/*    public static void dfs2(int curr)
    {
    if(st[col[curr]].isEmpty())
    {
    ans[curr]=-1;	
    }
    else
    {
    	ans[curr]=st[col[curr]].peek();
    }
    st[col[curr]].push(curr);
    for(int x:g[curr])
    {
    	dfs2(x);
    }
    st[col[curr]].pop();
    	
    }
    
  
	public static void dfs1(int curr)
	{
		visited[curr]=true;
		for(int next:g[curr])
		{
			edje++;
			if(!visited[next])
				dfs1(next);
		}
	}
	
	public static void dfs(int curr,int prev)
		{
		val[curr]=1;
			for(int x:g[curr])
			{
				if(x!=prev)
				{
		            dfs(x,curr);
		            val[curr]+=val[x];
					
			    }
			}
		}*/
	
		public static long power(long a,long b)
		{
			long result=1;
			while(b>0)
			{
				if(b%2==1)
					result*=a;
				a=a*a;
				b/=2;
			}
			return result;
		}
				public static long pow(long n,long p,long m)
	{
		 long  result = 1;
		  if(p==0)
		    return 1;
		if (p==1)
		    return n;
		while(p!=0)
		{
		    if(p%2==1)
		        result *= n;
		    if(result>=m)
		    result%=m;
		    p >>=1;
		    n*=n;
		    if(n>=m)
		    n%=m;
		}
		return result;
	}
	static class Pair implements Comparable<Pair>{
	int ind;
		int dis;
		Pair(int mr,int i){
	     	ind=mr;
			dis=i;
			
		}
		@Override
		public int compareTo(Pair o) {
		        if(o.dis<this.dis)
		        	return 1;
		        else
		        	return -1;
			
			}
		
	}
	public static long gcd(long a, long b) {
		  if (b == 0) return a;
		  return gcd(b, a%b);
		}
	static class InputReader {
 
		private InputStream stream;
		private byte[] buf = new byte[8192];
		private int curChar, snumChars;
		private SpaceCharFilter filter;
 
		public InputReader(InputStream stream) {
			this.stream = stream;
		}
 
		public int snext() {
			if (snumChars == -1)
				throw new InputMismatchException();
			if (curChar >= snumChars) {
				curChar = 0;
				try {
					snumChars = stream.read(buf);
				} catch (IOException e) {
					throw new InputMismatchException();
				}
				if (snumChars <= 0)
					return -1;
			}
			return buf[curChar++];
		}
 
		public   int nextInt() {
			int c = snext();
			while (isSpaceChar(c))
				c = snext();
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = snext();
			}
			int res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}
 
		public long nextLong() {
			int c = snext();
			while (isSpaceChar(c))
				c = snext();
			int sgn = 1;
			if (c == '-') {
				sgn = -1;
				c = snext();
			}
			long res = 0;
			do {
				if (c < '0' || c > '9')
					throw new InputMismatchException();
				res *= 10;
				res += c - '0';
				c = snext();
			} while (!isSpaceChar(c));
			return res * sgn;
		}
 
		public int[] nextIntArray(int n) {
			int a[] = new int[n];
			for (int i = 0; i < n; i++)
				a[i] = nextInt();
			return a;
		}
 
		public String readString() {
			int c = snext();
			while (isSpaceChar(c))
				c = snext();
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = snext();
			} while (!isSpaceChar(c));
			return res.toString();
		}
 
		public boolean isSpaceChar(int c) {
			if (filter != null)
				return filter.isSpaceChar(c);
			return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
		}
 
		public interface SpaceCharFilter {
			public boolean isSpaceChar(int ch);
		}
	}
}
 