import java.util.*;
import java.io.*;
/**
 *
 * @author User
 */
public class JavaApplication37 {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        String s=in.next();
        int a[]=new int[3];
        int c=0; int b;
        for (int i = 0; i < s.length(); i++) {
            b=s.charAt(i)-'0';
            if(b%3==0){
                c++;
            }
            else{
                if(i+1<s.length()){
                if((s.charAt(i+1)-'0')%3==0){
                    c++; i++; continue;
                }
                else{
                    b=s.charAt(i)+s.charAt(i+1)-'0';
                    if(b%3==0){
                        c++;
                        i++; continue;
                    }
                    else{
                        c++;
                        i+=2; continue;

                    }
                    }
                }
            }
            }
        out.print(c);
        out.flush();
        }

}


import java.util.HashMap;
import java.util.Scanner;

/**
 * @Created by sbhowmik on 23/11/18
 */
public class Polycrap {

    static public int count(String s) { // divide by 3 means the elements sum will be divided by 3

        int modValue[] = new int[s.length()];

        for (int i = 0; i < s.length(); i++) {
            modValue[i] = (s.charAt(i) - '0')%3;
        }
        int count = 0;
        for (int i = 0; i < s.length(); i++) {
            if (modValue[i] == 0) {
                count++;
                modValue[i] = -1;
            }
            if(i+1 < s.length() && ((modValue[i] ==1 && modValue[i+1]==2) || (modValue[i] == 2 && modValue[i+1] == 1))) {
                count++;
                modValue[i] =-1;
                modValue[i+1]= -2;
            }
            if (i+2 < s.length() && (modValue[i] == 1 && modValue[i+1]==1 && modValue[i+2] ==1 || modValue[i] == 2 && modValue[i+1]==2 && modValue[i+2]==2 )){
                count++;
                modValue[i]=-1;
                modValue[i+1]=-1;
                modValue[i+2] = -1;
            }
        }
        return count;
    }
    public static void main(String []args) {

        Scanner scanner = new Scanner(System.in);

        HashMap<Integer, Integer> map = new HashMap<>();
        map.put(0, 1);

        int i = 0;
        String s = scanner.next();

        System.out.print(count(s));
    }
}


import java.util.HashMap;
import java.util.Scanner;

/**
 * @Created by sbhowmik on 23/11/18
 */
public class Polycrap {

    static public int count(String s) { // divide by 3 means the elements sum will be divided by 3

        int modValue[] = new int[s.length()];

        for (int i = 0; i < s.length(); i++) {
            modValue[i] = (s.charAt(i) - '0')%3;
        }
        int count = 0;
        for (int i = 0; i < s.length(); i++) {
            if (modValue[i] == 0) {
                count++;
                modValue[i] = -1;
            }
            if(modValue[i] ==1 && modValue[i+1]==2 || modValue[i] == 2 && modValue[i+1] == 1) {
                count++;
                modValue[i] =-1;
                modValue[i+1]= -2;
            }
            if (modValue[i] == 1 && modValue[i+1]==1 && modValue[i+2] ==1 || modValue[i] == 2 && modValue[i+1]==2 && modValue[i+2]==2 ){
                count++;
                modValue[i]=-1;
                modValue[i+1]=-1;
                modValue[i+2] = -1;
            }
        }
        return count;
    }
    public static void main(String []args) {

        Scanner scanner = new Scanner(System.in);

        HashMap<Integer, Integer> map = new HashMap<>();
        map.put(0, 1);

        int i = 0;
        String s = scanner.next();

        System.out.print(count(s));
    }
}


import java.util.HashMap;
import java.util.Scanner;

/**
 * @Created by sbhowmik on 23/11/18
 */
public class Polycrap {

    public static void main(String []args) {

        Scanner scanner = new Scanner(System.in);

        HashMap<Integer, Integer> map = new HashMap<>();
        map.put(0, 1);

        int i = 0;
        String s = scanner.next();
        int sum = 0;
        int count =0 ;
        for (i = 0; i < s.length(); i++) {
            sum = (sum + s.charAt(i) - '0')%3;
            if (map.get(sum)!=null) {
                count++;
                map = new HashMap<>();
            }
            map.put(sum, 1);
        }
        System.out.print(count);
    }
}


import java.util.*;
import java.io.*;

public class Main
{
	public static void main(String[] args)
	{
		FastReader reader = new FastReader();
		PrintWriter writer = new PrintWriter(System.out);

		String input = reader.nextLine();
		int[][] dp = new int[3][2];

		int temp = (int)input.charAt(0) - (int)'0';
		if (temp%3 == 0)
			dp[0][0]++;

		for (int i=1; i<input.length(); i++)
		{
			int got = (int)input.charAt(i) - (int)'0';

			for (int j=0; j<3; j++)
			{
				dp[(got+j)%3][1] = dp[j][0];

				if ((got+j)%3 == 0)
					dp[(got+j)%3][1] = Math.max(dp[0][0], dp[j][0]+1);
			}

			for (int j=0; j<3; j++)
			{
				//writer.print(dp[j][1] + " ");
				dp[j][0] = dp[j][1];
			}

			//writer.println();
		}

		writer.println(dp[0][0]);
		writer.close();
	}

	static class FastReader
	{
		BufferedReader br;
		StringTokenizer st;

		public FastReader()
		{
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		String next()
		{
			while (st == null || !st.hasMoreElements())
			{
				try
				{
					st = new StringTokenizer(br.readLine());
				}
				catch (IOException e)
				{
					e.printStackTrace();
				}
			}
			return st.nextToken();
		}

		int nextInt()
		{
			return Integer.parseInt(next());
		}

		long nextLong()
		{
			return Long.parseLong(next());
		}

		double nextDouble()
		{
			return Double.parseDouble(next());
		}

		String nextLine()
		{
			String str = "";
			try
			{
				str = br.readLine();
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}
			return str;
		}
	}
}


import java.util.*;
import java.io.*;

public class Main
{
	public static void main(String[] args)
	{
		FastReader reader = new FastReader();
		PrintWriter writer = new PrintWriter(System.out);

		String input = reader.nextLine();
		int[] last = {0, -1, -1};
		int n = input.length();
		int[] dp = new int[n+1];

		int sum = 0;
		for (int i=0; i<n; i++)
		{
			dp[i+1] = dp[i];

			sum += (int)input.charAt(i);
			sum %= 3;

			if (last[sum] != -1)
				dp[i+1] = Math.max(dp[i+1], dp[last[sum]]+1);

			last[sum] = i+1;
		}

		writer.println(dp[n]);
		writer.close();
	}

	static class FastReader
	{
		BufferedReader br;
		StringTokenizer st;

		public FastReader()
		{
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		String next()
		{
			while (st == null || !st.hasMoreElements())
			{
				try
				{
					st = new StringTokenizer(br.readLine());
				}
				catch (IOException e)
				{
					e.printStackTrace();
				}
			}
			return st.nextToken();
		}

		int nextInt()
		{
			return Integer.parseInt(next());
		}

		long nextLong()
		{
			return Long.parseLong(next());
		}

		double nextDouble()
		{
			return Double.parseDouble(next());
		}

		String nextLine()
		{
			String str = "";
			try
			{
				str = br.readLine();
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}
			return str;
		}
	}
}


import java.util.*;
import java.io.*;

public class Main
{
	public static void main(String[] args)
	{
		FastReader reader = new FastReader();
		PrintWriter writer = new PrintWriter(System.out);

		String input = reader.nextLine();
		int[][] dp = new int[3][2];

		int temp = (int)input.charAt(0) - (int)'0';
		if (temp%3 == 0)
			dp[0][0]++;

		/*for (int j=0; j<3; j++)
		{
			writer.print(dp[j][0] + " ");
			//dp[j][0] = dp[j][1];
		}*/

		//writer.println();

		for (int i=1; i<input.length(); i++)
		{
			int got = (int)input.charAt(i) - (int)'0';

			for (int j=0; j<3; j++)
			{
				dp[(got+j)%3][1] = dp[j][0];

				if ((got+j)%3==0 && i>1)
					dp[(got+j)%3][1] = Math.max(dp[0][0], dp[j][0]+1);
			}

			for (int j=0; j<3; j++)
			{
				//writer.print(dp[j][1] + " ");
				dp[j][0] = dp[j][1];
			}

			//.println();
		}

		writer.println(dp[0][0]);
		writer.close();
	}

	static class FastReader
	{
		BufferedReader br;
		StringTokenizer st;

		public FastReader()
		{
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		String next()
		{
			while (st == null || !st.hasMoreElements())
			{
				try
				{
					st = new StringTokenizer(br.readLine());
				}
				catch (IOException e)
				{
					e.printStackTrace();
				}
			}
			return st.nextToken();
		}

		int nextInt()
		{
			return Integer.parseInt(next());
		}

		long nextLong()
		{
			return Long.parseLong(next());
		}

		double nextDouble()
		{
			return Double.parseDouble(next());
		}

		String nextLine()
		{
			String str = "";
			try
			{
				str = br.readLine();
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}
			return str;
		}
	}
}


import java.util.*;
import java.io.*;

public class Main {
    public static void main(String[] args) throws Exception {
        FastScanner sc = new FastScanner(System.in);
        PrintWriter pw = new PrintWriter(System.out);
        StringBuilder sb = new StringBuilder();
        char[] s = sc.next().toCharArray();
        int ans = 0;
        int cum = 0;
        for(char c : s){
            int now = c - '0';
            if(now % 3 == 0){
                ans++;
                cum = 0;
            }else{
                cum += now;
                if(cum % 3 == 0){
                    ans++;
                    cum = 0;
                }
            }
        }
        pw.println(ans);
        pw.flush();
    }

    static class GeekInteger {
        public static void save_sort(int[] array) {
            shuffle(array);
            Arrays.sort(array);
        }

        public static int[] shuffle(int[] array) {
            int n = array.length;
            Random random = new Random();
            for (int i = 0, j; i < n; i++) {
                j = i + random.nextInt(n - i);
                int randomElement = array[j];
                array[j] = array[i];
                array[i] = randomElement;
            }
            return array;
        }

    }
}

class FastScanner {
    private BufferedReader reader = null;
    private StringTokenizer tokenizer = null;
    public FastScanner(InputStream in) {
        reader = new BufferedReader(new InputStreamReader(in));
        tokenizer = null;
    }

    public String next() {
        if (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public String nextLine() {
        if (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                return reader.readLine();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken("\n");
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    public double nextDouble() {
         return Double.parseDouble(next());
    }

    public String[] nextArray(int n) {
        String[] a = new String[n];
        for (int i = 0; i < n; i++)
            a[i] = next();
        return a;
    }

    public int[] nextIntArray(int n) {
        int[] a = new int[n];
        for (int i = 0; i < n; i++)
            a[i] = nextInt();
        return a;
    }

    public long[] nextLongArray(int n) {
        long[] a = new long[n];
        for (int i = 0; i < n; i++)
            a[i] = nextLong();
        return a;
    }
}


import java.util.*;
import java.io.*;

public class Main {
    public static void main(String[] args) throws Exception {
        FastScanner sc = new FastScanner(System.in);
        PrintWriter pw = new PrintWriter(System.out);
        StringBuilder sb = new StringBuilder();
        char[] s = sc.next().toCharArray();
        int ans = 0;
        int chain = 0;
        int mod = -1;
        for(char c : s){
            int now = c - '0';
            now %= 3;
            if(now == 0){
                ans++;
                chain = 0;
                mod = -1;
            }else{

                if(mod == -1){
                    mod = now;
                    chain = 1;
                }else if(mod == now){
                    chain++;
                    if(chain == 3){
                        ans++;
                        chain = 0;
                        mod = -1;
                    }
                }else{
                    ans++;
                    chain = 0;
                    mod = -1;
                }
            }
        }
        pw.println(ans);
        pw.flush();
    }

    static class GeekInteger {
        public static void save_sort(int[] array) {
            shuffle(array);
            Arrays.sort(array);
        }

        public static int[] shuffle(int[] array) {
            int n = array.length;
            Random random = new Random();
            for (int i = 0, j; i < n; i++) {
                j = i + random.nextInt(n - i);
                int randomElement = array[j];
                array[j] = array[i];
                array[i] = randomElement;
            }
            return array;
        }

    }
}

class FastScanner {
    private BufferedReader reader = null;
    private StringTokenizer tokenizer = null;
    public FastScanner(InputStream in) {
        reader = new BufferedReader(new InputStreamReader(in));
        tokenizer = null;
    }

    public String next() {
        if (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public String nextLine() {
        if (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                return reader.readLine();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken("\n");
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    public double nextDouble() {
         return Double.parseDouble(next());
    }

    public String[] nextArray(int n) {
        String[] a = new String[n];
        for (int i = 0; i < n; i++)
            a[i] = next();
        return a;
    }

    public int[] nextIntArray(int n) {
        int[] a = new int[n];
        for (int i = 0; i < n; i++)
            a[i] = nextInt();
        return a;
    }

    public long[] nextLongArray(int n) {
        long[] a = new long[n];
        for (int i = 0; i < n; i++)
            a[i] = nextLong();
        return a;
    }
}


import java.util.*;
import java.io.*;

public class Main {
    public static void main(String[] args) throws Exception {
        FastScanner sc = new FastScanner(System.in);
        PrintWriter pw = new PrintWriter(System.out);
        StringBuilder sb = new StringBuilder();
        char[] s = sc.next().toCharArray();
        int ans = 0;
        int chain = 0;
        int mod = -1;
        for(char c : s){
            int now = c - '0';
            if(now % 3 == 0){
                ans++;
                chain = 0;
                mod = -1;
            }else{
                if(mod == -1){
                    mod = now;
                    chain = 1;
                }else if(mod == now){
                    chain++;
                    if(chain == 3){
                        ans++;
                        chain = 0;
                        mod = -1;
                    }
                }else{
                    ans++;
                    chain = 0;
                    mod = -1;
                }
            }
        }
        pw.println(ans);
        pw.flush();
    }

    static class GeekInteger {
        public static void save_sort(int[] array) {
            shuffle(array);
            Arrays.sort(array);
        }

        public static int[] shuffle(int[] array) {
            int n = array.length;
            Random random = new Random();
            for (int i = 0, j; i < n; i++) {
                j = i + random.nextInt(n - i);
                int randomElement = array[j];
                array[j] = array[i];
                array[i] = randomElement;
            }
            return array;
        }

    }
}

class FastScanner {
    private BufferedReader reader = null;
    private StringTokenizer tokenizer = null;
    public FastScanner(InputStream in) {
        reader = new BufferedReader(new InputStreamReader(in));
        tokenizer = null;
    }

    public String next() {
        if (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public String nextLine() {
        if (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                return reader.readLine();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken("\n");
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    public double nextDouble() {
         return Double.parseDouble(next());
    }

    public String[] nextArray(int n) {
        String[] a = new String[n];
        for (int i = 0; i < n; i++)
            a[i] = next();
        return a;
    }

    public int[] nextIntArray(int n) {
        int[] a = new int[n];
        for (int i = 0; i < n; i++)
            a[i] = nextInt();
        return a;
    }

    public long[] nextLongArray(int n) {
        long[] a = new long[n];
        for (int i = 0; i < n; i++)
            a[i] = nextLong();
        return a;
    }
}


import java.awt.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Tester {
	static int ans=0;
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner s=new Scanner(System.in);
		String st=s.nextLine();
		int cnt=0;
		String tmp="";
		int sum=0,tm;
		for(int j=0;j<st.length();j++)
		{
			tm=Integer.parseInt(""+st.charAt(j));
			tmp+=Integer.toString(tm%3);
		}
		int j=0;
		while(j<st.length())
		{
			tm=Integer.parseInt(""+tmp.charAt(j));

			if(tm%3==0)
			{
				cnt++;
				j++;
			}
			else if(tm%3==1)
			{
				if(j+2<st.length() && st.charAt(j+1)=='1' && st.charAt(j+2)=='1')
				{
					cnt++;
					j=j+3;
				}
				else if(j+1<st.length() && st.charAt(j+1)=='2')
				{
					cnt++;
					j=j+2;
				}
			}
			else
			{
			    if(j+1<st.length() && st.charAt(j+1)=='1')
				{
					cnt++;
					j=j+2;
				}
			}

		}
		System.out.println(cnt);

	}

}


import java.awt.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Tester {
	static int ans=0;
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner s=new Scanner(System.in);
		String st=s.nextLine();
		int cnt=0;
		String tmp="";
		int sum=0,tm;
		for(int j=0;j<st.length();j++)
		{
			tm=Integer.parseInt(""+st.charAt(j));
			if(tm%3==0)
			{
				cnt++;
				sum=0;
				continue;
			}
			else
			{
				sum+=tm;
			}
			if(sum%3==0)
			{
				cnt++;
				sum=0;
			}
		}
		System.out.println(cnt);

	}

}


import java.awt.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Tester {
	static int ans=0;
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner s=new Scanner(System.in);
		String st=s.nextLine();
		int cnt=0;
		StringBuilder tmp=new StringBuilder("");
		int sum=0,tm;
		for(int j=0;j<st.length();j++)
		{
			tm=Integer.parseInt(""+st.charAt(j));
			tmp.append(Integer.toString(tm%3));
		}
		int j=0;
		while(j<st.length())
		{
			tm=Integer.parseInt(""+tmp.charAt(j));

			if(tm%3==0)
			{
				cnt++;
				j++;
			}
			else if(tm%3==1)
			{
				if(j+2<st.length() && st.charAt(j+1)=='1' && st.charAt(j+2)=='1')
				{
					cnt++;
					j=j+3;
				}
				else if(j+1<st.length() && st.charAt(j+1)=='2')
				{
					cnt++;
					j=j+2;
				}
				else
					j++;
			}
			else
			{
			    if(j+1<st.length() && st.charAt(j+1)=='1')
				{
					cnt++;
					j=j+2;
				}
			    else if(j+2<st.length() && st.charAt(j+1)=='2' && st.charAt(j+2)=='2')
				{
					cnt++;
					j=j+3;
				}
			    else
			    	j++;
			}

		}
		System.out.println(cnt);

	}

}


import java.awt.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Tester {
	static int ans=0;
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner s=new Scanner(System.in);
		String st=s.nextLine();
		int cnt=0;
		StringBuilder tmp=new StringBuilder("");
		int sum=0,tm;
		for(int j=0;j<st.length();j++)
		{
			tm=Integer.parseInt(""+st.charAt(j));
			tmp.append(Integer.toString(tm%3));
		}
		int j=0;
		while(j<st.length())
		{
			tm=Integer.parseInt(""+tmp.charAt(j));

			if(tm%3==0)
			{
				cnt++;
				j++;
			}
			else if(tm%3==1)
			{
				if(j+2<st.length() && st.charAt(j+1)=='1' && st.charAt(j+2)=='1')
				{
					cnt++;
					j=j+3;
				}
				else if(j+1<st.length() && st.charAt(j+1)=='2')
				{
					cnt++;
					j=j+2;
				}
				else
					j++;
			}
			else
			{
			    if(j+1<st.length() && st.charAt(j+1)=='1')
				{
					cnt++;
					j=j+2;
				}
			    else
			    	j++;
			}

		}
		System.out.println(cnt);

	}

}


import java.awt.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Tester {
	static int ans=0;
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner s=new Scanner(System.in);
		String st=s.nextLine();
		int cnt=0;
		String tmp="";
		int sum=0,tm;
		for(int j=0;j<st.length();j++)
		{
			tm=Integer.parseInt(""+st.charAt(j));
			tmp+=Integer.toString(tm%3);
		}
		int j=0;
		while(j<st.length())
		{
			tm=Integer.parseInt(""+tmp.charAt(j));

			if(tm%3==0)
			{
				cnt++;
				j++;
			}
			else if(tm%3==1)
			{
				if(j+2<st.length() && st.charAt(j+1)=='1' && st.charAt(j+2)=='1')
				{
					cnt++;
					j=j+3;
				}
				else if(j+1<st.length() && st.charAt(j+1)=='2')
				{
					cnt++;
					j=j+2;
				}
				else
					j++;
			}
			else
			{
			    if(j+1<st.length() && st.charAt(j+1)=='1')
				{
					cnt++;
					j=j+2;
				}
			    else
			    	j++;
			}

		}
		System.out.println(cnt);

	}

}


import java.awt.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class Tester {
	static int ans=0;
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner s=new Scanner(System.in);
		String st=s.nextLine();
		int cnt=0;
		StringBuilder tmp=new StringBuilder("");
		int sum=0,tm;
		for(int j=0;j<st.length();j++)
		{
			tm=Integer.parseInt(""+st.charAt(j));
			tmp.append(Integer.toString(tm%3));
		}
		int j=0;
		while(j<st.length())
		{
			tm=Integer.parseInt(""+tmp.charAt(j));

			if(tm%3==0)
			{
				cnt++;
				j++;
			}
			else if(tm%3==1)
			{
				if(j+2<st.length() && tmp.charAt(j+1)=='1' && tmp.charAt(j+2)=='1')
				{
					cnt++;
					j=j+3;
				}
				else if(j+1<st.length() && tmp.charAt(j+1)=='2')
				{
					cnt++;
					j=j+2;
				}
				else
					j++;
			}
			else
			{
			    if(j+1<st.length() && tmp.charAt(j+1)=='1')
				{
					cnt++;
					j=j+2;
				}
			    else if(j+2<st.length() && tmp.charAt(j+1)=='2' && tmp.charAt(j+2)=='2')
				{
					cnt++;
					j=j+3;
				}
			    else
			    	j++;
			}

		}
		System.out.println(cnt);

	}

}


import java.io.*;
import java.util.*;
public class D
{
BufferedReader br;
BufferedWriter bw;
public static void main(String args[]) throws IOException
{
  (new D()).run();
}

void run() throws IOException
{
  br =new BufferedReader(new InputStreamReader(System.in));
  bw =new BufferedWriter(new OutputStreamWriter(System.out));
  // code starts here
  char num[]=line().toCharArray();
  int n=num.length;
  long cnt1=0;
  long sum=0;
  int i;
  HashSet<Integer> set=new HashSet<Integer>();
  for(i=0;i<n;i++)
  {
      sum+=num[i]-'0';
      if((num[i]-'0')%3==0)
      {
          cnt1++;
          sum=0;
          set.clear();
      }
      else if(sum%3==0)
      {
          cnt1++;
          sum=0;
          set.clear();
      }
      else
      {
          int rem=(int)(sum%3);
          if(set.contains(rem))
          {
              cnt1++;
              sum=0;
              set.clear();
          }
          else
          set.add(rem);
      }
  }
  /*long cnt2=0;
  sum=0;
  for(i=n-1;i>=0;i--)
  {
      sum+=num[i]-'0';
      if((num[i]-'0')%3==0)
      {
          cnt2++;
          sum=0;
      }
      else if(sum%3==0)
      {
          cnt2++;
          sum=0;
      }
  }*/

  System.out.println(cnt1);
 bw.flush();
}

String line() throws IOException
{
return br.readLine();
}
int[] na() throws IOException
{
String s[]=line().split(" ");
int len=s.length;
int ar[]=new int[len];
for(int i=0;i<len;i++)
ar[i]=toInt(s[i]);
return ar;
}

int[][] matrix(int n,int m) throws IOException
{
int ar[][]=new int[n][m];
for(int i=0;i<n;i++)
ar[i]=na();
return ar;
}
int toInt(String s) throws IOException
{
return Integer.parseInt(s);
}
long toLong(String s) throws IOException
{
return Long.parseLong(s);
}
double toDouble(String s) throws IOException
{
return Double.parseDouble(s);
}
private void tr(Object... o) { System.out.println(Arrays.deepToString(o)); }
}


import java.io.*;
import java.util.*;
public class D
{
BufferedReader br;
BufferedWriter bw;
public static void main(String args[]) throws IOException
{
  (new D()).run();
}

void run() throws IOException
{
  br =new BufferedReader(new InputStreamReader(System.in));
  bw =new BufferedWriter(new OutputStreamWriter(System.out));
  // code starts here
  char num[]=line().toCharArray();
  int n=num.length;
  long cnt1=0;
  long sum=0;
  int i;
  for(i=0;i<n;i++)
  {
      sum+=num[i]-'0';
      if((num[i]-'0')%3==0)
      {
          cnt1++;
          sum=0;
      }
      else if(sum%3==0)
      {
          cnt1++;
          sum=0;
      }
  }
  long cnt2=0;
  sum=0;
  for(i=n-1;i>=0;i--)
  {
      sum+=num[i]-'0';
      if((num[i]-'0')%3==0)
      {
          cnt2++;
          sum=0;
      }
      else if(sum%3==0)
      {
          cnt2++;
          sum=0;
      }
  }

  System.out.println(Math.max(cnt1,cnt2));
 bw.flush();
}

String line() throws IOException
{
return br.readLine();
}
int[] na() throws IOException
{
String s[]=line().split(" ");
int len=s.length;
int ar[]=new int[len];
for(int i=0;i<len;i++)
ar[i]=toInt(s[i]);
return ar;
}

int[][] matrix(int n,int m) throws IOException
{
int ar[][]=new int[n][m];
for(int i=0;i<n;i++)
ar[i]=na();
return ar;
}
int toInt(String s) throws IOException
{
return Integer.parseInt(s);
}
long toLong(String s) throws IOException
{
return Long.parseLong(s);
}
double toDouble(String s) throws IOException
{
return Double.parseDouble(s);
}
private void tr(Object... o) { System.out.println(Arrays.deepToString(o)); }
}


import java.io.*;
import java.util.*;
public class D
{
BufferedReader br;
BufferedWriter bw;
public static void main(String args[]) throws IOException
{
  (new D()).run();
}

void run() throws IOException
{
  br =new BufferedReader(new InputStreamReader(System.in));
  bw =new BufferedWriter(new OutputStreamWriter(System.out));
  // code starts here
  char num[]=line().toCharArray();
  int n=num.length;
  long cnt1=0;
  long sum=0;
  int i;
  HashSet<Integer> set=new HashSet<Integer>();
  for(i=0;i<n;i++)
  {
      sum+=num[i]-'0';
      if((num[i]-'0')%3==0)
      {
          cnt1++;
          sum=0;
      }
      else if(sum%3==0)
      {
          cnt1++;
          sum=0;
      }
      else
      {
          int rem=(int)(sum%3);
          if(set.contains(rem))
          {
              cnt1++;
              sum=0;
              set.clear();
          }
          else
          set.add(rem);
      }
  }
  long cnt2=0;
  sum=0;
  for(i=n-1;i>=0;i--)
  {
      sum+=num[i]-'0';
      if((num[i]-'0')%3==0)
      {
          cnt2++;
          sum=0;
      }
      else if(sum%3==0)
      {
          cnt2++;
          sum=0;
      }
  }

  System.out.println(Math.max(cnt1,cnt2));
 bw.flush();
}

String line() throws IOException
{
return br.readLine();
}
int[] na() throws IOException
{
String s[]=line().split(" ");
int len=s.length;
int ar[]=new int[len];
for(int i=0;i<len;i++)
ar[i]=toInt(s[i]);
return ar;
}

int[][] matrix(int n,int m) throws IOException
{
int ar[][]=new int[n][m];
for(int i=0;i<n;i++)
ar[i]=na();
return ar;
}
int toInt(String s) throws IOException
{
return Integer.parseInt(s);
}
long toLong(String s) throws IOException
{
return Long.parseLong(s);
}
double toDouble(String s) throws IOException
{
return Double.parseDouble(s);
}
private void tr(Object... o) { System.out.println(Arrays.deepToString(o)); }
}


//package ;
import java.io.*;
import java.util.*;

public class C {
	static int n,dp[][];
	static char[]s;
	static int dp(int i,int sum) {
		if(i==n) return sum==0?1:0;
		if(dp[i][sum]!=-1) return dp[i][sum];
		int sumtake = (sum+s[i]-'0')%3;
		int take = dp(i+1,sumtake);
		int stop = sum==0?1+dp(i+1,(s[i]-'0')%3):dp(i+1,(s[i]-'0')%3);
		return dp[i][sum]=Math.max(take, stop);
	}
	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner();
		PrintWriter pw = new PrintWriter(System.out);
		s=sc.nextCharArray();
		n=s.length;
		dp=new int[n][3];
		for(int i=0;i<n;i++)
			Arrays.fill(dp[i], -1);
		pw.print(dp(1,(s[0]-'0')%3));
		pw.close();
	}

	static class Scanner {
		BufferedReader br;
		StringTokenizer st;

		Scanner() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		String next() throws IOException {
			while (st == null || !st.hasMoreTokens()) {
				st = new StringTokenizer(br.readLine());
			}
			return st.nextToken();
		}

		int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		double nextDouble() throws IOException {
			return Double.parseDouble(next());
		}

		String nextLine() throws IOException {
			return br.readLine();
		}

		boolean hasnext() throws IOException {
			return br.ready();
		}

		public int[] nextIntArray(int n) throws IOException {
			int[] a = new int[n];
			for (int i = 0; i < n; i++)
				a[i] = nextInt();
			return a;
		}

		public Integer[] nextIntegerArray(int n) throws IOException {
			Integer[] a = new Integer[n];
			for (int i = 0; i < n; i++)
				a[i] = nextInt();
			return a;
		}

		char[] nextCharArray() throws IOException {
			return br.readLine().toCharArray();
		}

		public double[] nextDoubleArray(int n) throws IOException {
			double[] ans = new double[n];
			for (int i = 0; i < n; i++)
				ans[i] = nextDouble();
			return ans;
		}

	}
}


//package ;
import java.io.*;
import java.util.*;

public class C {
	static int n,dp[][];
	static char[]s;
//	static int dp(int i,int sum) {
//		if(i==n) return sum==0?1:0;
//		if(dp[i][sum]!=-1) return dp[i][sum];
//		int sumtake = (sum+s[i]-'0')%3;
//		int take = dp(i+1,sumtake);
//		int stop = sum==0?1+dp(i+1,0):dp(i+1,0);
//		return dp[i][sum]=Math.max(take, stop);
//	}
	static int dp(int i,int sum) {
		if(i==n+1) return 0;
		if(i==n) return sum==0?1:0;
		if(dp[i][sum]!=-1) return dp[i][sum];
		int sumtake = (sum+s[i]-'0')%3;
		int take = dp(i+1,sumtake);
		int stop = sum == 0?1:0;
		stop+=dp(i+1,(s[i]-'0')%3);
		return dp[i][sum]=Math.max(take, stop);
	}
	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner();
		PrintWriter pw = new PrintWriter(System.out);
		s=sc.nextCharArray();
		n=s.length;
		dp=new int[n][3];
		for(int i=0;i<n;i++)
			Arrays.fill(dp[i], -1);
		pw.print(dp(1,(s[0]-'0')%3));
		pw.close();
	}

	static class Scanner {
		BufferedReader br;
		StringTokenizer st;

		Scanner() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		String next() throws IOException {
			while (st == null || !st.hasMoreTokens()) {
				st = new StringTokenizer(br.readLine());
			}
			return st.nextToken();
		}

		int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		double nextDouble() throws IOException {
			return Double.parseDouble(next());
		}

		String nextLine() throws IOException {
			return br.readLine();
		}

		boolean hasnext() throws IOException {
			return br.ready();
		}

		public int[] nextIntArray(int n) throws IOException {
			int[] a = new int[n];
			for (int i = 0; i < n; i++)
				a[i] = nextInt();
			return a;
		}

		public Integer[] nextIntegerArray(int n) throws IOException {
			Integer[] a = new Integer[n];
			for (int i = 0; i < n; i++)
				a[i] = nextInt();
			return a;
		}

		char[] nextCharArray() throws IOException {
			return br.readLine().toCharArray();
		}

		public double[] nextDoubleArray(int n) throws IOException {
			double[] ans = new double[n];
			for (int i = 0; i < n; i++)
				ans[i] = nextDouble();
			return ans;
		}

	}
}


import java.io.*;
import java.util.*;

public class Test
{
     public static void main(String args[] ) throws Exception
    {
       Scanner sc= new Scanner(System.in);
        char arr[]=sc.next().toCharArray();
        int fin[]=new int[3];
        Arrays.fill(fin,-1);
        fin[0]=0;
        int r=0;
        int n=arr.length;
        int z[]=new int[n+1];
        for(int i=1;i<=n;i++){
            r = (r+arr[i-1]-'0')%3;
            z[i] = z[i-1];
           if(fin[r]!=-1){
               z[i]=Math.max(z[i],z[fin[r]]+1);
               }
           fin[r]=i;
        }
        System.out.println(z[n]);
    }
}


import java.io.*;
import java.util.*;

public class Test
{
     public static void main(String args[] ) throws Exception
    {
       Scanner sc= new Scanner(System.in);
        char arr[]=sc.next().toCharArray();
        int fin[]=new int[3];
        fin[0]=0;
        int r=0;
        int n=arr.length;
        int z[]=new int[n+1];
        for(int i=1;i<=n;i++){
            r = (r+arr[i-1]-'0')%3;
            z[i] = z[i-1];
           if(fin[r]!=-1){
               z[i]=Math.max(z[i],z[fin[r]]+1);
               }
           fin[r]=i;
        }
        System.out.println(z[n]);
    }
}


import java.io.*;
import java.util.*;

public class Test
{
     public static void main(String args[] ) throws Exception
    {
       Scanner sc= new Scanner(System.in);
        char arr[]=sc.next().toCharArray();
        int fin[]=new int[3];
        fin[0]=0;
        int r=0;
        int n=arr.length;
        int z[]=new int[n+1];
        for(int i=1;i<=n;i++){
            r = (r+arr[i-1]-'0')%3;
            z[i] = z[i-1];
           if(fin[r]!=-1){
               z[i]=Math.max(z[i],z[fin[r]]+1);
               fin[r]=i;
           }
        }
        System.out.println(z[n]);
    }
}


import java.io.*;
import java.util.StringTokenizer;

public class D_1005 {

    public static void main(String[] args) throws IOException {
        MyScanner sc = new MyScanner();

        String s = sc.next();
        int len = s.length();

        int[] counts = new int[len];
        boolean[] flags = new boolean[len];
        flags[0] = false;

        int count = 0;
        for (int i = 0; i < len; i++) {
            int cur = s.charAt(i) - '0';

            if (cur % 3 == 0) {
                count++;
                counts[i] = count;
                flags[i] = true;
                continue;
            } else {
                // find the first false element after last true
                if (i == 0) continue;

                int j = i - 1;
                while (j >= 0 && flags[j] == false) {
                    j--;
                }

                j++;
                if (i == j) {
                    counts[i] = count;
                    flags[i] = false;
                    continue;
                }

                // copy string from j to i and try to div it for 3
                //Long subNum = Long.parseLong(s.substring(j, i + 1));
                String subStr = s.substring(j, i + 1);

                long sum = 0;
                for (int k = 0; k < subStr.length(); k++) {
                    sum += subStr.charAt(k);
                }

                if (sum % 3 == 0) {
                    count++;
                    counts[i] = count;
                    flags[i] = true;
                } else {
                    counts[i] = count;
                    flags[i] = false;
                }
            }
        }

        print(count);
        exit();
    }

    static PrintWriter pr = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));

    static void println(Object o) {
        pr.println(o);
    }

    static void print(Object o) {
        pr.print(o);
    }

    static void exit() throws IOException {
        pr.close();
        System.exit(0);
    }

    public static class MyScanner {
        BufferedReader br;
        StringTokenizer st;

        public MyScanner() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

    }
}


import java.io.*;
import java.util.StringTokenizer;

public class D_1005 {

    public static void main(String[] args) throws IOException {
        MyScanner sc = new MyScanner();

        String s = sc.next();
        int len = s.length();

        int[] counts = new int[len];
        boolean[] flags = new boolean[len];
        flags[0] = false;

        int count = 0;
        for (int i = 0; i < len; i++) {
            int cur = Integer.parseInt(s.substring(i, i + 1));

            if (cur % 3 == 0) {
                count++;
                counts[i] = count;
                flags[i] = true;
                continue;
            } else {
                // find the first false element after last true
                if (i == 0) continue;

                int j = i - 1;
                while (j >= 0 && flags[j] == false) {
                    j--;
                }

                j++;
                if (i == j) {
                    counts[i] = count;
                    flags[i] = false;
                    continue;
                }

                // copy string from j to i and try to div it for 3
                int subNum = Integer.parseInt(s.substring(j, i + 1));
                if (subNum % 3 == 0) {
                    count++;
                    counts[i] = count;
                    flags[i] = true;
                } else {
                    counts[i] = count;
                    flags[i] = false;
                }
            }
        }

        print(count);
        exit();
    }

    static PrintWriter pr = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));

    static void println(Object o) {
        pr.println(o);
    }

    static void print(Object o) {
        pr.print(o);
    }

    static void exit() throws IOException {
        pr.close();
        System.exit(0);
    }

    public static class MyScanner {
        BufferedReader br;
        StringTokenizer st;

        public MyScanner() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

    }
}


import java.io.*;
import java.util.StringTokenizer;

public class D_1005 {

    public static void main(String[] args) throws IOException {
        MyScanner sc = new MyScanner();

        String s = sc.next();
        int len = s.length();

        int[] counts = new int[len];
        boolean[] flags = new boolean[len];
        flags[0] = false;

        int count = 0;
        for (int i = 0; i < len; i++) {
            int cur = s.charAt(i) - '0';

            if (cur % 3 == 0) {
                count++;
                counts[i] = count;
                flags[i] = true;
                continue;
            } else {
                // find the first false element after last true
                if (i == 0) continue;

                int j = i - 1;
                while (j >= 0 && flags[j] == false) {
                    j--;
                }

                j++;
                if (i == j) {
                    counts[i] = count;
                    flags[i] = false;
                    continue;
                }

                // copy string from j to i and try to div it for 3
                Long subNum = Long.parseLong(s.substring(j, i + 1));
                if (subNum % 3 == 0) {
                    count++;
                    counts[i] = count;
                    flags[i] = true;
                } else {
                    counts[i] = count;
                    flags[i] = false;
                }
            }
        }

        print(count);
        exit();
    }

    static PrintWriter pr = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));

    static void println(Object o) {
        pr.println(o);
    }

    static void print(Object o) {
        pr.print(o);
    }

    static void exit() throws IOException {
        pr.close();
        System.exit(0);
    }

    public static class MyScanner {
        BufferedReader br;
        StringTokenizer st;

        public MyScanner() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

    }
}


import java.io.*;
import java.util.StringTokenizer;

public class D_1005 {

    public static void main(String[] args) throws IOException {
        MyScanner sc = new MyScanner();

        String s = sc.next();
        int len = s.length();

        int[] counts = new int[len];
        boolean[] flags = new boolean[len];
        flags[0] = false;

        int count = 0;
        for (int i = 0; i < len; i++) {
            int cur = s.charAt(i) - '0';

            if (cur % 3 == 0) {
                count++;
                counts[i] = count;
                flags[i] = true;
                continue;
            } else {
                // find the first false element after last true
                if (i == 0) continue;

                int j = i - 1;
                while (j >= 0 && flags[j] == false) {
                    j--;
                }

                j++;
                if (i == j) {
                    counts[i] = count;
                    flags[i] = false;
                    continue;
                }

                // copy string from j to i and try to div it for 3
                //Long subNum = Long.parseLong(s.substring(j, i + 1));
                String subStr = s.substring(j, i + 1);

                long sum = 0;
                boolean flag = false;
                for (int k = 0; k < subStr.length(); k++) {
                    sum += subStr.charAt(k);
                    if (sum % 3 == 0) {
                        flag = true;
                        break;
                    }
                }

                if (flag) {
                    count++;
                    counts[i] = count;
                    flags[i] = true;
                } else {
                    counts[i] = count;
                    flags[i] = false;
                }
            }
        }

        print(count);
        exit();
    }

    static PrintWriter pr = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));

    static void println(Object o) {
        pr.println(o);
    }

    static void print(Object o) {
        pr.print(o);
    }

    static void exit() throws IOException {
        pr.close();
        System.exit(0);
    }

    public static class MyScanner {
        BufferedReader br;
        StringTokenizer st;

        public MyScanner() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

    }
}


import java.io.*;
import java.util.StringTokenizer;

public class D_1005 {

    public static void main(String[] args) throws IOException {
        MyScanner sc = new MyScanner();

        String s = sc.next();
        int len = s.length();

        int count = 0;
        int start = 0;

        for (int i = 0; i < len; i++) {
            String subStr = s.substring(start, i + 1);
            boolean flag = false;
            for (int j = 0; j < subStr.length(); j++) {
                String sub = subStr.substring(j);
                if (Long.parseLong(sub) % 3 == 0) {
                    flag = true;
                    break;
                }
            }

            if (flag) {
                start = i + 1;
                count++;
            }
        }

        print(count);
        exit();
    }

    static PrintWriter pr = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));

    static void println(Object o) {
        pr.println(o);
    }

    static void print(Object o) {
        pr.print(o);
    }

    static void exit() throws IOException {
        pr.close();
        System.exit(0);
    }

    public static class MyScanner {
        BufferedReader br;
        StringTokenizer st;

        public MyScanner() {
            br = new BufferedReader(new InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

    }
}


import java.util.Scanner;

public class PolycarpandDiv3 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String s=in.next();
        long count=0,sum=0;
        boolean ok=true;
        for (int i = 0; i < s.length(); i++) {
              sum+=(s.charAt(i)-'0');
            if((s.charAt(i)-'0')%3==0||sum%3==0){
                count++;
                sum=0;
                ok=false;
                continue;
            }

            if(i==0)
                continue;
            if((((s.charAt(i)-'0')+((s.charAt(i-1)-'0')*10))%3==0)&&ok){
                count++;
                sum=0;
                ok=false;
                continue;
            }
                ok=true;
        }
        System.out.println(count);
    }//psvm

}


import java.math.BigInteger;
import java.util.Scanner;

public class PolycarpandDiv3 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String s=in.next();
        int count=0,sum=0;
//        StringBuilder sb = new StringBuilder();
//        BigInteger bi=new BigInteger("");
        for (int i = 0; i < s.length(); i++) {
//            sb.append(s.charAt(i));
              sum+=(s.charAt(i)-'0');
            if((s.charAt(i)-'0')%3==0){
                count++;
//                System.out.println(s.charAt(i));
//                sb=new StringBuilder("");
                sum=0;
                continue;
            }
            if(sum%3==0){
                count++;
//                System.out.println(sum);
                sum=0;
//                sb=new StringBuilder("");
            }

        }
        System.out.println(count);

    }//psvm

}


import java.util.Scanner;

public class PolycarpandDiv3 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String s=in.next();
        int count=0;
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < s.length(); i++) {
            sb.append(s.charAt(i));
            if(Integer.parseInt(s.charAt(i)+"")%3==0){
                count++;
//                System.out.println(s.charAt(i));
                sb=new StringBuilder("");
                continue;
            }
            if(Integer.parseInt(sb+"")%3==0){
                count++;
//                System.out.println(sb);
                sb=new StringBuilder("");
            }

        }
        System.out.println(count);

    }//psvm

}


import java.util.Scanner;

public class PolycarpandDiv3 {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        String s=in.next();
        long count=0,sum=0;
        for (int i = 0; i < s.length(); i++) {
              sum+=(s.charAt(i)-'0');
            if((s.charAt(i)-'0')%3==0){
                count++;
                sum=0;
                continue;
            }
            if(sum%3==0){
                count++;
                sum=0;
            }

        }
        System.out.println(count);

    }//psvm

}


import java.util.*;
public class HelloWorld{

     public static void main(String []args){
        Scanner input = new Scanner(System.in);
        String s = input.nextLine();
        int count =0;
        int k =0;
        int sum =0;
        for(int i =0;i<s.length();i++){
            sum = (sum + s.charAt(i)-'0')%3;
            int t = (s.charAt(i)-'0')%3;
            k++;
            if(t == 0 || sum == 0 || k == 3){
                count++;
                k=0;
                sum =0;
            }
        }
        System.out.println(count);
     }
}


import java.util.*;
public class HelloWorld{

     public static void main(String []args){
        Scanner input = new Scanner(System.in);
        String s = input.nextLine();
        int count =0;
        int k =0;
        int sum =0;
        for(int i =0;i<s.length();i++){
            sum = (sum + s.charAt(i)-'0')%3;
            int t = (s.charAt(i)-'0')%3;
            if(t == 0 || sum == 0 || k == 3){
                count++;
                k=0;
                sum =0;
            }
        }
        System.out.println(count);
     }
}


import java.util.*;
public class HelloWorld{

     public static void main(String []args){
        Scanner input = new Scanner(System.in);
        String s = input.nextLine();
        int count =0;
        int k =0;
        int sum =0;
        for(int i =0;i<s.length();i++){
            sum = (sum + s.charAt(i)-'0')%3;
            int t = (s.charAt(i)-'0')%3;
            if(t == 0 || sum == 0 || k == 3){
                count++;
                k=0;
            }
        }
        System.out.println(count);
     }
}


import java.util.*;
public class HelloWorld{

     public static void main(String []args){
        Scanner input = new Scanner(System.in);
        String s = input.nextLine();
        int count =0;
        int k =0;
        int sum =0;
        for(int i =0;i<s.length();i++){
            sum = (sum + s.charAt(i)-'0')%3;
            int t = (s.charAt(i)-'0')%3;
            k++;
            if(t == 0 || sum == 0 || k == 3){
                count++;
                k=0;
            }
        }
        System.out.println(count);
     }
}


//package aug;

import java.io.*;
import java.util.*;

public class Rnd496
{
    InputStream is;
    PrintWriter out;
    String INPUT = "";
    //boolean codechef=false;
    boolean codechef=true;

	void solve()
	{
		char[] a=ns().toCharArray();
		int n=a.length;
		int[] dp=new int[n];
		if((a[0]-'0')%3==0)dp[0]=1;
		int[] pre=new int[n];
		pre[0]=a[0]-'0';
		for(int i=1;i<n;i++)
		{
			pre[i]=pre[i-1]+a[0]-'0';
		}
		int last=-1;
		if(dp[0]!=0)last=0;
		for(int i=1;i<n;i++)
		{
			int sum=0;
			for(int j=i;j>last;j--)
			{
				sum+=a[j]-'0';
				if(sum%3==0)
				{
					dp[i]=Math.max(dp[i], j==0?1:dp[j-1]+1);
					last=i;
					break;
				}
			}
			//System.out.println(dp[i]);
			dp[i]=Math.max(dp[i], dp[i-1]);
		}
		System.out.println(dp[n-1]);
	}

	static void dfs(int[][] g,int u,int[] vis,int p)
	{
		vis[u]=p;
		for(int v:g[u])
		{
			if(vis[v]==0)dfs(g,v,vis,u);
		}
	}

	static long fnc(long a,long b)
	{
		return a+(1000000007)*b;
	}

	static int[][] packD(int n, int[] from, int[] to) {
		int[][] g = new int[n][];
		int[] p = new int[n];
		for (int f : from)
			p[f]++;
		for (int i = 0; i < n; i++)
			g[i] = new int[p[i]];
		for (int i = 0; i < from.length; i++) {
			g[from[i]][--p[from[i]]] = to[i];
		}
		return g;
	}

    static class Pair
    {
        int a,b;
        public Pair(int a,int b)
        {
            this.a=a;
            this.b=b;
        }
    }

    static long lcm(int a,int b)
    {
        long val=a;
        val*=b;
        return (val/gcd(a,b));
    }

    static long gcd(long a,long b)
    {
        if(a==0)return b;
        return gcd(b%a,a);
    }

    static int pow(int a, int b, int p)
    {
        long ans = 1, base = a;
        while (b!=0)
        {
            if ((b & 1)!=0)
            {
                ans *= base;
                ans%= p;
            }
            base *= base;
            base%= p;
            b >>= 1;
        }
        return (int)ans;
    }

    static int inv(int x, int p)
    {
        return pow(x, p - 2, p);
    }

    void run() throws Exception
    {
        if(codechef)oj=true;
        is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        out = new PrintWriter(System.out);

        long s = System.currentTimeMillis();
        solve();
        out.flush();
        tr(System.currentTimeMillis()-s+"ms");
    }

    public static void main(String[] args) throws Exception {new Rnd496().run();}

    private byte[] inbuf = new byte[1024];
    public int lenbuf = 0, ptrbuf = 0;

    private int readByte()
    {
        if(lenbuf == -1)throw new InputMismatchException();
        if(ptrbuf >= lenbuf){
            ptrbuf = 0;
            try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
            if(lenbuf <= 0)return -1;
        }
        return inbuf[ptrbuf++];
    }

    private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
    private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

    private double nd() { return Double.parseDouble(ns()); }
    private char nc() { return (char)skip(); }

    private String ns()
    {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private char[] ns(int n)
    {
        char[] buf = new char[n];
        int b = skip(), p = 0;
        while(p < n && !(isSpaceChar(b))){
            buf[p++] = (char)b;
            b = readByte();
        }
        return n == p ? buf : Arrays.copyOf(buf, p);
    }

    private char[][] nm(int n, int m)
    {
        char[][] map = new char[n][];
        for(int i = 0;i < n;i++)map[i] = ns(m);
        return map;
    }

    private int[] na(int n)
    {
        int[] a = new int[n];
        for(int i = 0;i < n;i++)a[i] = ni();
        return a;
    }

    private int ni()
    {
        int num = 0, b;
        boolean minus = false;
        while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
        if(b == '-'){
            minus = true;
            b = readByte();
        }

        while(true){
            if(b >= '0' && b <= '9'){
                num = num * 10 + (b - '0');
            }else{
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private long nl()
    {
        long num = 0;
        int b;
        boolean minus = false;
        while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
        if(b == '-'){
            minus = true;
            b = readByte();
        }

        while(true){
            if(b >= '0' && b <= '9'){
                num = num * 10 + (b - '0');
            }else{
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
    private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}


//package aug;

import java.io.*;
import java.util.*;

public class Rnd496
{
    InputStream is;
    PrintWriter out;
    String INPUT = "";
    //boolean codechef=false;
    boolean codechef=true;

	void solve()
	{
		char[] a=ns().toCharArray();
		int n=a.length;
		int[] dp=new int[n];
		if((a[0]-'0')%3==0)dp[0]=1;
		for(int i=1;i<n;i++)
		{
			int sum=0;
			for(int j=i;j>=0;j--)
			{
				sum+=a[j]-'0';
				if(sum%3==0)
				{
					dp[i]=Math.max(dp[i], j==0?1:dp[j-1]+1);
				}
			}
			//System.out.println(dp[i]);
			dp[i]=Math.max(dp[i], dp[i-1]);
		}
		System.out.println(dp[n-1]);
	}

	static void dfs(int[][] g,int u,int[] vis,int p)
	{
		vis[u]=p;
		for(int v:g[u])
		{
			if(vis[v]==0)dfs(g,v,vis,u);
		}
	}

	static long fnc(long a,long b)
	{
		return a+(1000000007)*b;
	}

	static int[][] packD(int n, int[] from, int[] to) {
		int[][] g = new int[n][];
		int[] p = new int[n];
		for (int f : from)
			p[f]++;
		for (int i = 0; i < n; i++)
			g[i] = new int[p[i]];
		for (int i = 0; i < from.length; i++) {
			g[from[i]][--p[from[i]]] = to[i];
		}
		return g;
	}

    static class Pair
    {
        int a,b;
        public Pair(int a,int b)
        {
            this.a=a;
            this.b=b;
        }
    }

    static long lcm(int a,int b)
    {
        long val=a;
        val*=b;
        return (val/gcd(a,b));
    }

    static long gcd(long a,long b)
    {
        if(a==0)return b;
        return gcd(b%a,a);
    }

    static int pow(int a, int b, int p)
    {
        long ans = 1, base = a;
        while (b!=0)
        {
            if ((b & 1)!=0)
            {
                ans *= base;
                ans%= p;
            }
            base *= base;
            base%= p;
            b >>= 1;
        }
        return (int)ans;
    }

    static int inv(int x, int p)
    {
        return pow(x, p - 2, p);
    }

    void run() throws Exception
    {
        if(codechef)oj=true;
        is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        out = new PrintWriter(System.out);

        long s = System.currentTimeMillis();
        solve();
        out.flush();
        tr(System.currentTimeMillis()-s+"ms");
    }

    public static void main(String[] args) throws Exception {new Rnd496().run();}

    private byte[] inbuf = new byte[1024];
    public int lenbuf = 0, ptrbuf = 0;

    private int readByte()
    {
        if(lenbuf == -1)throw new InputMismatchException();
        if(ptrbuf >= lenbuf){
            ptrbuf = 0;
            try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
            if(lenbuf <= 0)return -1;
        }
        return inbuf[ptrbuf++];
    }

    private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
    private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

    private double nd() { return Double.parseDouble(ns()); }
    private char nc() { return (char)skip(); }

    private String ns()
    {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private char[] ns(int n)
    {
        char[] buf = new char[n];
        int b = skip(), p = 0;
        while(p < n && !(isSpaceChar(b))){
            buf[p++] = (char)b;
            b = readByte();
        }
        return n == p ? buf : Arrays.copyOf(buf, p);
    }

    private char[][] nm(int n, int m)
    {
        char[][] map = new char[n][];
        for(int i = 0;i < n;i++)map[i] = ns(m);
        return map;
    }

    private int[] na(int n)
    {
        int[] a = new int[n];
        for(int i = 0;i < n;i++)a[i] = ni();
        return a;
    }

    private int ni()
    {
        int num = 0, b;
        boolean minus = false;
        while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
        if(b == '-'){
            minus = true;
            b = readByte();
        }

        while(true){
            if(b >= '0' && b <= '9'){
                num = num * 10 + (b - '0');
            }else{
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private long nl()
    {
        long num = 0;
        int b;
        boolean minus = false;
        while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
        if(b == '-'){
            minus = true;
            b = readByte();
        }

        while(true){
            if(b >= '0' && b <= '9'){
                num = num * 10 + (b - '0');
            }else{
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
    private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}


//package aug;

import java.io.*;
import java.util.*;

public class Rnd496
{
    InputStream is;
    PrintWriter out;
    String INPUT = "";
    //boolean codechef=false;
    boolean codechef=true;

	void solve()
	{
		char[] a=ns().toCharArray();
		int n=a.length;
		int[] dp=new int[n];
		if((a[0]-'0')%3==0)dp[0]=1;
		for(int i=1;i<n;i++)
		{
			int sum=0;
			for(int j=i;j>0;j--)
			{
				sum+=a[j]-'0';
				if(sum%3==0)
				{
					dp[i]=Math.max(dp[i], dp[j-1]+1);
				}
			}
			dp[i]=Math.max(dp[i], dp[i-1]);
		}
		System.out.println(dp[n-1]);
	}

	static void dfs(int[][] g,int u,int[] vis,int p)
	{
		vis[u]=p;
		for(int v:g[u])
		{
			if(vis[v]==0)dfs(g,v,vis,u);
		}
	}

	static long fnc(long a,long b)
	{
		return a+(1000000007)*b;
	}

	static int[][] packD(int n, int[] from, int[] to) {
		int[][] g = new int[n][];
		int[] p = new int[n];
		for (int f : from)
			p[f]++;
		for (int i = 0; i < n; i++)
			g[i] = new int[p[i]];
		for (int i = 0; i < from.length; i++) {
			g[from[i]][--p[from[i]]] = to[i];
		}
		return g;
	}

    static class Pair
    {
        int a,b;
        public Pair(int a,int b)
        {
            this.a=a;
            this.b=b;
        }
    }

    static long lcm(int a,int b)
    {
        long val=a;
        val*=b;
        return (val/gcd(a,b));
    }

    static long gcd(long a,long b)
    {
        if(a==0)return b;
        return gcd(b%a,a);
    }

    static int pow(int a, int b, int p)
    {
        long ans = 1, base = a;
        while (b!=0)
        {
            if ((b & 1)!=0)
            {
                ans *= base;
                ans%= p;
            }
            base *= base;
            base%= p;
            b >>= 1;
        }
        return (int)ans;
    }

    static int inv(int x, int p)
    {
        return pow(x, p - 2, p);
    }

    void run() throws Exception
    {
        if(codechef)oj=true;
        is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
        out = new PrintWriter(System.out);

        long s = System.currentTimeMillis();
        solve();
        out.flush();
        tr(System.currentTimeMillis()-s+"ms");
    }

    public static void main(String[] args) throws Exception {new Rnd496().run();}

    private byte[] inbuf = new byte[1024];
    public int lenbuf = 0, ptrbuf = 0;

    private int readByte()
    {
        if(lenbuf == -1)throw new InputMismatchException();
        if(ptrbuf >= lenbuf){
            ptrbuf = 0;
            try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
            if(lenbuf <= 0)return -1;
        }
        return inbuf[ptrbuf++];
    }

    private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
    private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

    private double nd() { return Double.parseDouble(ns()); }
    private char nc() { return (char)skip(); }

    private String ns()
    {
        int b = skip();
        StringBuilder sb = new StringBuilder();
        while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }

    private char[] ns(int n)
    {
        char[] buf = new char[n];
        int b = skip(), p = 0;
        while(p < n && !(isSpaceChar(b))){
            buf[p++] = (char)b;
            b = readByte();
        }
        return n == p ? buf : Arrays.copyOf(buf, p);
    }

    private char[][] nm(int n, int m)
    {
        char[][] map = new char[n][];
        for(int i = 0;i < n;i++)map[i] = ns(m);
        return map;
    }

    private int[] na(int n)
    {
        int[] a = new int[n];
        for(int i = 0;i < n;i++)a[i] = ni();
        return a;
    }

    private int ni()
    {
        int num = 0, b;
        boolean minus = false;
        while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
        if(b == '-'){
            minus = true;
            b = readByte();
        }

        while(true){
            if(b >= '0' && b <= '9'){
                num = num * 10 + (b - '0');
            }else{
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private long nl()
    {
        long num = 0;
        int b;
        boolean minus = false;
        while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
        if(b == '-'){
            minus = true;
            b = readByte();
        }

        while(true){
            if(b >= '0' && b <= '9'){
                num = num * 10 + (b - '0');
            }else{
                return minus ? -num : num;
            }
            b = readByte();
        }
    }

    private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
    private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}


import java.io.*;
import java.util.*;
public class tr1 {
	static PrintWriter out;
	static StringBuilder sb;
	static int inf = (int) 1e9;
	static int mod = (int) 1e9 + 7;
	static int[] si;
	static ArrayList<Integer> primes;
	static HashSet<Integer> pr;
	static int n;
	static boolean[] in;
	static HashMap<Integer, Integer> factors;
	static HashSet<Integer> f;
    static long []fac;
    static int []l,r;
    static int [][]memo;
    static int []a;
    static HashMap<Integer,Integer> hm;
	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		out = new PrintWriter(System.out);
		String s=sc.nextLine();
		n=s.length();
		a=new int [s.length()];
		for(int i=0;i<s.length();i++)
			a[i]=Integer.parseInt(""+s.charAt(i));
		memo=new int [n+1][2];
		for(int []aa:memo)
			Arrays.fill(aa, -1);
		out.println(dp(0,0,1));
		out.flush();
	}
	public static int dp(int i,int val,int st) {
		if(i==n-1) {
			int y=0;
			if((val+a[i])%3==0)
				y++;
			return y;
		}
		if(memo[i][st]!=-1) {
	 	return memo[i][st];
		}
		int y=0;
		if((val+a[i])%3==0)
			y++;
		int take= y+dp(i+1,0,1);
		int leave=dp(i+1,val+a[i],0);
	//	System.out.println(i+" "+val+" "+take+" "+leave+" "+st+" "+y);
		return memo[i][st]=Math.max(take, leave);
	}
	public int [] merge(int []d,int st,int e) {
		if(st>e)
			return null;
		if(e==st) {
			int []ans= {d[e]};
			return ans;
		}
		int mid=(st+e)/2;
		int []ans=new int[e-st+1];
		int []ll=merge(d,st,mid);
		int []rr=merge(d,mid+1,e);
		if(ll==null)
			return rr;
		if(rr==null)
			return ll;
		int iver=0;
		int idxl=0;
		int idxr=0;
		for(int i=st;i<=e;i++) {
		    if(ll[idxl]<rr[idxr]) {

		    }
		}
		return ans;
	}
	public static class pair1 implements Comparable<pair1>{
		int a;
		int idx;
		pair1(int a,int i){
			this.a=a;
			idx=i;
		}
		public String toString() {
			return a+" "+idx;
		}
		@Override
		public int compareTo(pair1 o) {
			return o.a-a;
		}
	}
	public static class pair2 implements Comparable<pair2>{
		int a;
		int idx;
		pair2(int a,int i){
			this.a=a;
			idx=i;
		}
		public String toString() {
			return a+" "+idx;
		}
		@Override
		public int compareTo(pair2 o) {
			// TODO Auto-generated method stub
			return idx-o.idx;
		}
	}
	static int inver(long x) {
		int a = (int) x;
		int e = (mod - 2);
		int res = 1;
		while (e > 0) {
			if ((e & 1) == 1) {
				// System.out.println(res*a);
				res = (int) ((1l * res * a) % mod);
			}
			a = (int) ((1l * a * a) % mod);
			e >>= 1;
		}
		// out.println(res+" "+x);
		return res % mod;
	}
	static int atMostSum(int arr[], int n, int k)
	{
	    int sum = 0;
	    int cnt = 0, maxcnt = 0;

	    for (int i = 0; i < n; i++) {

	        // If adding current element doesn't
	        // cross limit add it to current window
	        if ((sum + arr[i]) <= k) {
	            sum += arr[i];
	            cnt++;
	        }

	        // Else, remove first element of current
	        // window and add the current element
	        else if(sum!=0)
	        {
	            sum = sum - arr[i - cnt] + arr[i];
	        }

	        // keep track of max length.
	        maxcnt = Math.max(cnt, maxcnt);
	    }
	    return maxcnt;
	}
	public static int[] longestSubarray(int[] inp) {
		// array containing prefix sums up to a certain index i
		int[] p = new int[inp.length];
		p[0] = inp[0];
		for (int i = 1; i < inp.length; i++) {
			p[i] = p[i - 1] + inp[i];
		}

		// array Q from the description below
		int[] q = new int[inp.length];
		q[inp.length - 1] = p[inp.length - 1];
		for (int i = inp.length - 2; i >= 0; i--) {
			q[i] = Math.max(q[i + 1], p[i]);
		}
		int a = 0;
		int b = 0;
		int maxLen = 0;
		int curr;
		int[] res = new int[] { -1, -1 };
		while (b < inp.length) {
			curr = a > 0 ? q[b] - p[a - 1] : q[b];
			if (curr >= 0) {
				if (b - a > maxLen) {
					maxLen = b - a;
					res = new int[] { a, b };
				}
				b++;
			} else {
				a++;
			}
		}
		return res;
	}

	static void factor(int n) {
		if (si[n] == n) {
			f.add(n);
			return;
		}
		f.add(si[n]);
		factor(n / si[n]);
	}

	static void seive() {
		si = new int[1000001];
		primes = new ArrayList<>();
		int N = 1000001;
		pr = new HashSet<>();
		si[1] = 1;
		for (int i = 2; i < N; i++) {
			if (si[i] == 0) {
				si[i] = i;
				primes.add(i);
				pr.add(i);
			}
			for (int j = 0; j < primes.size() && primes.get(j) <= si[i] && (i * primes.get(j)) < N; j++)
				si[primes.get(j) * i] = primes.get(j);

		}
	}

	static public class SegmentTree { // 1-based DS, OOP

		int N; // the number of elements in the array as a power of 2 (i.e. after padding)
		int[] array, sTree, lazy;

		SegmentTree(int[] in) {
			array = in;
			N = in.length - 1;
			sTree = new int[N << 1]; // no. of nodes = 2*N - 1, we add one to cross out index zero
			lazy = new int[N << 1];
			build(1, 1, N);
		}
         public String toString() {
        	 return Arrays.toString(sTree);
         }
		void build(int node, int b, int e) // O(n)
		{
			if (b == e)
				sTree[node] = array[b];
			else {
				int mid = b + e >> 1;
				build(node << 1, b, mid);
				build(node << 1 | 1, mid + 1, e);
				sTree[node] = gcd(sTree[node << 1] , sTree[node << 1 | 1]);
			}
		}

		void update_point(int index, int val) // O(log n)
		{
			index += N - 1;
			sTree[index] += val;
			while (index > 1) {
				index >>= 1;
				sTree[index] = sTree[index << 1] + sTree[index << 1 | 1];
			}
		}

		void update_range(int i, int j, int val) // O(log n)
		{
			update_range(1, 1, N, i, j, val);
		}

		void update_range(int node, int b, int e, int i, int j, int val) {
			if (i > e || j < b)
				return;
			if (b >= i && e <= j) {
				sTree[node] += (e - b + 1) * val;
				lazy[node] += val;
			} else {
				int mid = b + e >> 1;
				propagate(node, b, mid, e);
				update_range(node << 1, b, mid, i, j, val);
				update_range(node << 1 | 1, mid + 1, e, i, j, val);
				sTree[node] = sTree[node << 1] + sTree[node << 1 | 1];
			}

		}

		void propagate(int node, int b, int mid, int e) {
			lazy[node << 1] += lazy[node];
			lazy[node << 1 | 1] += lazy[node];
			sTree[node << 1] += (mid - b + 1) * lazy[node];
			sTree[node << 1 | 1] += (e - mid) * lazy[node];
			lazy[node] = 0;
		}

		int query(int i, int j) {
			return query(1, 1, N, i, j);
		}

		int query(int node, int b, int e, int i, int j) // O(log n)
		{
			if (i > e || j < b)
				return 0;
			if (b >= i && e <= j)
				return sTree[node];
			int mid = b + e >> 1;
			//propagate(node, b, mid, e);
			int q1 = query(node << 1, b, mid, i, j);
			int q2 = query(node << 1 | 1, mid + 1, e, i, j);
			return gcd(q1 , q2);
		}
	}

	static int gcd(int a, int b) {

		if (b == 0) {
			return a;
		}
		return gcd(b, a % b);
	}

	static class unionfind {
		int[] p;
		int[] size;

		unionfind(int n) {
			p = new int[n];
			size = new int[n];

			for (int i = 0; i < n; i++) {
				p[i] = i;
			}
			Arrays.fill(size, 1);
		}

		int findSet(int v) {
			if (v == p[v])
				return v;
			return p[v] = findSet(p[v]);
		}

		boolean sameSet(int a, int b) {
			a = findSet(a);
			b = findSet(b);
			if (a == b)
				return true;
			return false;
		}

		int max() {
			int max = 0;
			for (int i = 0; i < size.length; i++)
				if (size[i] > max)
					max = size[i];
			return max;
		}

		void combine(int a, int b) {
			a = findSet(a);
			b = findSet(b);
			if (a == b)
				return;
			if (size[a] > size[b]) {
				p[b] = a;
				size[a] += size[b];

			} else {
				p[a] = b;
				size[b] += size[a];
			}
		}
	}

	static class Scanner {
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream system) {
			br = new BufferedReader(new InputStreamReader(system));
		}

		public Scanner(String file) throws Exception {
			br = new BufferedReader(new FileReader(file));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public String nextLine() throws IOException {
			return br.readLine();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public double nextDouble() throws IOException {
			return Double.parseDouble(next());
		}

		public char nextChar() throws IOException {
			return next().charAt(0);
		}

		public Long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public boolean ready() throws IOException {
			return br.ready();
		}

		public void waitForInput() throws InterruptedException {
			Thread.sleep(3000);
		}
	}
}


import java.io.*;
import java.util.*;
public class tr1 {
	static PrintWriter out;
	static StringBuilder sb;
	static int inf = (int) 1e9;
	static int mod = (int) 1e9 + 7;
	static int[] si;
	static ArrayList<Integer> primes;
	static HashSet<Integer> pr;
	static int n;
	static boolean[] in;
	static HashMap<Integer, Integer> factors;
	static HashSet<Integer> f;
    static long []fac;
    static int []l,r;
    static int [][][]memo;
    static int []a;
    static HashMap<Integer,Integer> hm;
	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		out = new PrintWriter(System.out);
		String s=sc.nextLine();
		n=s.length();
		a=new int [s.length()];
		for(int i=0;i<s.length();i++)
			a[i]=Integer.parseInt(""+s.charAt(i));
		memo=new int [n][2][3];
		for(int [][]memo1:memo)
		  for(int []aa:memo1)
			Arrays.fill(aa,-1);
		out.println(dp(0,0,1));
		out.flush();
	}
	public static int dp(int i,int val,int st) {
		if(i==n-1) {
			int y=0;
			if((val+a[i])%3==0)
				y++;
		//	System.out.println((val+a[i])+" "+y);
			return y;
		}
		if(memo[i][st][val]!=-1) {
	 	return memo[i][st][val];
		}
		int y=0;
		if((val+a[i])%3==0)
			y++;
		int take= y+dp(i+1,0,1);
		int leave=dp(i+1,(val+a[i])%3,0);
		//System.out.println(i+" "+st+" "+take+" "+leave);
		return memo[i][st][val]=Math.max(take, leave);
	}
	public int [] merge(int []d,int st,int e) {
		if(st>e)
			return null;
		if(e==st) {
			int []ans= {d[e]};
			return ans;
		}
		int mid=(st+e)/2;
		int []ans=new int[e-st+1];
		int []ll=merge(d,st,mid);
		int []rr=merge(d,mid+1,e);
		if(ll==null)
			return rr;
		if(rr==null)
			return ll;
		int iver=0;
		int idxl=0;
		int idxr=0;
		for(int i=st;i<=e;i++) {
		    if(ll[idxl]<rr[idxr]) {

		    }
		}
		return ans;
	}
	public static class pair1 implements Comparable<pair1>{
		int a;
		int idx;
		pair1(int a,int i){
			this.a=a;
			idx=i;
		}
		public String toString() {
			return a+" "+idx;
		}
		@Override
		public int compareTo(pair1 o) {
			return o.a-a;
		}
	}
	public static class pair2 implements Comparable<pair2>{
		int a;
		int idx;
		pair2(int a,int i){
			this.a=a;
			idx=i;
		}
		public String toString() {
			return a+" "+idx;
		}
		@Override
		public int compareTo(pair2 o) {
			// TODO Auto-generated method stub
			return idx-o.idx;
		}
	}
	static int inver(long x) {
		int a = (int) x;
		int e = (mod - 2);
		int res = 1;
		while (e > 0) {
			if ((e & 1) == 1) {
				// System.out.println(res*a);
				res = (int) ((1l * res * a) % mod);
			}
			a = (int) ((1l * a * a) % mod);
			e >>= 1;
		}
		// out.println(res+" "+x);
		return res % mod;
	}
	static int atMostSum(int arr[], int n, int k)
	{
	    int sum = 0;
	    int cnt = 0, maxcnt = 0;

	    for (int i = 0; i < n; i++) {

	        // If adding current element doesn't
	        // cross limit add it to current window
	        if ((sum + arr[i]) <= k) {
	            sum += arr[i];
	            cnt++;
	        }

	        // Else, remove first element of current
	        // window and add the current element
	        else if(sum!=0)
	        {
	            sum = sum - arr[i - cnt] + arr[i];
	        }

	        // keep track of max length.
	        maxcnt = Math.max(cnt, maxcnt);
	    }
	    return maxcnt;
	}
	public static int[] longestSubarray(int[] inp) {
		// array containing prefix sums up to a certain index i
		int[] p = new int[inp.length];
		p[0] = inp[0];
		for (int i = 1; i < inp.length; i++) {
			p[i] = p[i - 1] + inp[i];
		}

		// array Q from the description below
		int[] q = new int[inp.length];
		q[inp.length - 1] = p[inp.length - 1];
		for (int i = inp.length - 2; i >= 0; i--) {
			q[i] = Math.max(q[i + 1], p[i]);
		}
		int a = 0;
		int b = 0;
		int maxLen = 0;
		int curr;
		int[] res = new int[] { -1, -1 };
		while (b < inp.length) {
			curr = a > 0 ? q[b] - p[a - 1] : q[b];
			if (curr >= 0) {
				if (b - a > maxLen) {
					maxLen = b - a;
					res = new int[] { a, b };
				}
				b++;
			} else {
				a++;
			}
		}
		return res;
	}

	static void factor(int n) {
		if (si[n] == n) {
			f.add(n);
			return;
		}
		f.add(si[n]);
		factor(n / si[n]);
	}

	static void seive() {
		si = new int[1000001];
		primes = new ArrayList<>();
		int N = 1000001;
		pr = new HashSet<>();
		si[1] = 1;
		for (int i = 2; i < N; i++) {
			if (si[i] == 0) {
				si[i] = i;
				primes.add(i);
				pr.add(i);
			}
			for (int j = 0; j < primes.size() && primes.get(j) <= si[i] && (i * primes.get(j)) < N; j++)
				si[primes.get(j) * i] = primes.get(j);

		}
	}

	static public class SegmentTree { // 1-based DS, OOP

		int N; // the number of elements in the array as a power of 2 (i.e. after padding)
		int[] array, sTree, lazy;

		SegmentTree(int[] in) {
			array = in;
			N = in.length - 1;
			sTree = new int[N << 1]; // no. of nodes = 2*N - 1, we add one to cross out index zero
			lazy = new int[N << 1];
			build(1, 1, N);
		}
         public String toString() {
        	 return Arrays.toString(sTree);
         }
		void build(int node, int b, int e) // O(n)
		{
			if (b == e)
				sTree[node] = array[b];
			else {
				int mid = b + e >> 1;
				build(node << 1, b, mid);
				build(node << 1 | 1, mid + 1, e);
				sTree[node] = gcd(sTree[node << 1] , sTree[node << 1 | 1]);
			}
		}

		void update_point(int index, int val) // O(log n)
		{
			index += N - 1;
			sTree[index] += val;
			while (index > 1) {
				index >>= 1;
				sTree[index] = sTree[index << 1] + sTree[index << 1 | 1];
			}
		}

		void update_range(int i, int j, int val) // O(log n)
		{
			update_range(1, 1, N, i, j, val);
		}

		void update_range(int node, int b, int e, int i, int j, int val) {
			if (i > e || j < b)
				return;
			if (b >= i && e <= j) {
				sTree[node] += (e - b + 1) * val;
				lazy[node] += val;
			} else {
				int mid = b + e >> 1;
				propagate(node, b, mid, e);
				update_range(node << 1, b, mid, i, j, val);
				update_range(node << 1 | 1, mid + 1, e, i, j, val);
				sTree[node] = sTree[node << 1] + sTree[node << 1 | 1];
			}

		}

		void propagate(int node, int b, int mid, int e) {
			lazy[node << 1] += lazy[node];
			lazy[node << 1 | 1] += lazy[node];
			sTree[node << 1] += (mid - b + 1) * lazy[node];
			sTree[node << 1 | 1] += (e - mid) * lazy[node];
			lazy[node] = 0;
		}

		int query(int i, int j) {
			return query(1, 1, N, i, j);
		}

		int query(int node, int b, int e, int i, int j) // O(log n)
		{
			if (i > e || j < b)
				return 0;
			if (b >= i && e <= j)
				return sTree[node];
			int mid = b + e >> 1;
			//propagate(node, b, mid, e);
			int q1 = query(node << 1, b, mid, i, j);
			int q2 = query(node << 1 | 1, mid + 1, e, i, j);
			return gcd(q1 , q2);
		}
	}

	static int gcd(int a, int b) {

		if (b == 0) {
			return a;
		}
		return gcd(b, a % b);
	}

	static class unionfind {
		int[] p;
		int[] size;

		unionfind(int n) {
			p = new int[n];
			size = new int[n];

			for (int i = 0; i < n; i++) {
				p[i] = i;
			}
			Arrays.fill(size, 1);
		}

		int findSet(int v) {
			if (v == p[v])
				return v;
			return p[v] = findSet(p[v]);
		}

		boolean sameSet(int a, int b) {
			a = findSet(a);
			b = findSet(b);
			if (a == b)
				return true;
			return false;
		}

		int max() {
			int max = 0;
			for (int i = 0; i < size.length; i++)
				if (size[i] > max)
					max = size[i];
			return max;
		}

		void combine(int a, int b) {
			a = findSet(a);
			b = findSet(b);
			if (a == b)
				return;
			if (size[a] > size[b]) {
				p[b] = a;
				size[a] += size[b];

			} else {
				p[a] = b;
				size[b] += size[a];
			}
		}
	}

	static class Scanner {
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream system) {
			br = new BufferedReader(new InputStreamReader(system));
		}

		public Scanner(String file) throws Exception {
			br = new BufferedReader(new FileReader(file));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public String nextLine() throws IOException {
			return br.readLine();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public double nextDouble() throws IOException {
			return Double.parseDouble(next());
		}

		public char nextChar() throws IOException {
			return next().charAt(0);
		}

		public Long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public boolean ready() throws IOException {
			return br.ready();
		}

		public void waitForInput() throws InterruptedException {
			Thread.sleep(3000);
		}
	}
}


import java.io.*;
import java.util.*;
public class tr1 {
	static PrintWriter out;
	static StringBuilder sb;
	static int inf = (int) 1e9;
	static int mod = (int) 1e9 + 7;
	static int[] si;
	static ArrayList<Integer> primes;
	static HashSet<Integer> pr;
	static int n;
	static boolean[] in;
	static HashMap<Integer, Integer> factors;
	static HashSet<Integer> f;
    static long []fac;
    static int []l,r;
    static int [][][]memo;
    static int []a;
    static HashMap<Integer,Integer> hm;
	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		out = new PrintWriter(System.out);
		String s=sc.nextLine();
		n=s.length();
		a=new int [s.length()];
		for(int i=0;i<s.length();i++)
			a[i]=Integer.parseInt(""+s.charAt(i));
		memo=new int [n][2][1001];
		for(int [][]memo1:memo)
		for(int []aa:memo1)
			Arrays.fill(aa, -1);
		out.println(dp(0,0,1));
//		for(int []aa:memo)
	//		System.out.println(Arrays.toString(aa));
		out.flush();
	}
	public static int dp(int i,int val,int st) {
		if(i==n-1) {
			int y=0;
			if((val+a[i])%3==0)
				y++;
			return y;
		}
		if(memo[i][st][val]!=-1) {
	 	return memo[i][st][val];
		}
		int y=0;
		if((val+a[i])%3==0)
			y++;
		int take= y+dp(i+1,0,1);
		int leave=dp(i+1,val+a[i],0);
		//System.out.println(i+" "+st+" "+take+" "+leave);
		return memo[i][st][val]=Math.max(take, leave);
	}
	public int [] merge(int []d,int st,int e) {
		if(st>e)
			return null;
		if(e==st) {
			int []ans= {d[e]};
			return ans;
		}
		int mid=(st+e)/2;
		int []ans=new int[e-st+1];
		int []ll=merge(d,st,mid);
		int []rr=merge(d,mid+1,e);
		if(ll==null)
			return rr;
		if(rr==null)
			return ll;
		int iver=0;
		int idxl=0;
		int idxr=0;
		for(int i=st;i<=e;i++) {
		    if(ll[idxl]<rr[idxr]) {

		    }
		}
		return ans;
	}
	public static class pair1 implements Comparable<pair1>{
		int a;
		int idx;
		pair1(int a,int i){
			this.a=a;
			idx=i;
		}
		public String toString() {
			return a+" "+idx;
		}
		@Override
		public int compareTo(pair1 o) {
			return o.a-a;
		}
	}
	public static class pair2 implements Comparable<pair2>{
		int a;
		int idx;
		pair2(int a,int i){
			this.a=a;
			idx=i;
		}
		public String toString() {
			return a+" "+idx;
		}
		@Override
		public int compareTo(pair2 o) {
			// TODO Auto-generated method stub
			return idx-o.idx;
		}
	}
	static int inver(long x) {
		int a = (int) x;
		int e = (mod - 2);
		int res = 1;
		while (e > 0) {
			if ((e & 1) == 1) {
				// System.out.println(res*a);
				res = (int) ((1l * res * a) % mod);
			}
			a = (int) ((1l * a * a) % mod);
			e >>= 1;
		}
		// out.println(res+" "+x);
		return res % mod;
	}
	static int atMostSum(int arr[], int n, int k)
	{
	    int sum = 0;
	    int cnt = 0, maxcnt = 0;

	    for (int i = 0; i < n; i++) {

	        // If adding current element doesn't
	        // cross limit add it to current window
	        if ((sum + arr[i]) <= k) {
	            sum += arr[i];
	            cnt++;
	        }

	        // Else, remove first element of current
	        // window and add the current element
	        else if(sum!=0)
	        {
	            sum = sum - arr[i - cnt] + arr[i];
	        }

	        // keep track of max length.
	        maxcnt = Math.max(cnt, maxcnt);
	    }
	    return maxcnt;
	}
	public static int[] longestSubarray(int[] inp) {
		// array containing prefix sums up to a certain index i
		int[] p = new int[inp.length];
		p[0] = inp[0];
		for (int i = 1; i < inp.length; i++) {
			p[i] = p[i - 1] + inp[i];
		}

		// array Q from the description below
		int[] q = new int[inp.length];
		q[inp.length - 1] = p[inp.length - 1];
		for (int i = inp.length - 2; i >= 0; i--) {
			q[i] = Math.max(q[i + 1], p[i]);
		}
		int a = 0;
		int b = 0;
		int maxLen = 0;
		int curr;
		int[] res = new int[] { -1, -1 };
		while (b < inp.length) {
			curr = a > 0 ? q[b] - p[a - 1] : q[b];
			if (curr >= 0) {
				if (b - a > maxLen) {
					maxLen = b - a;
					res = new int[] { a, b };
				}
				b++;
			} else {
				a++;
			}
		}
		return res;
	}

	static void factor(int n) {
		if (si[n] == n) {
			f.add(n);
			return;
		}
		f.add(si[n]);
		factor(n / si[n]);
	}

	static void seive() {
		si = new int[1000001];
		primes = new ArrayList<>();
		int N = 1000001;
		pr = new HashSet<>();
		si[1] = 1;
		for (int i = 2; i < N; i++) {
			if (si[i] == 0) {
				si[i] = i;
				primes.add(i);
				pr.add(i);
			}
			for (int j = 0; j < primes.size() && primes.get(j) <= si[i] && (i * primes.get(j)) < N; j++)
				si[primes.get(j) * i] = primes.get(j);

		}
	}

	static public class SegmentTree { // 1-based DS, OOP

		int N; // the number of elements in the array as a power of 2 (i.e. after padding)
		int[] array, sTree, lazy;

		SegmentTree(int[] in) {
			array = in;
			N = in.length - 1;
			sTree = new int[N << 1]; // no. of nodes = 2*N - 1, we add one to cross out index zero
			lazy = new int[N << 1];
			build(1, 1, N);
		}
         public String toString() {
        	 return Arrays.toString(sTree);
         }
		void build(int node, int b, int e) // O(n)
		{
			if (b == e)
				sTree[node] = array[b];
			else {
				int mid = b + e >> 1;
				build(node << 1, b, mid);
				build(node << 1 | 1, mid + 1, e);
				sTree[node] = gcd(sTree[node << 1] , sTree[node << 1 | 1]);
			}
		}

		void update_point(int index, int val) // O(log n)
		{
			index += N - 1;
			sTree[index] += val;
			while (index > 1) {
				index >>= 1;
				sTree[index] = sTree[index << 1] + sTree[index << 1 | 1];
			}
		}

		void update_range(int i, int j, int val) // O(log n)
		{
			update_range(1, 1, N, i, j, val);
		}

		void update_range(int node, int b, int e, int i, int j, int val) {
			if (i > e || j < b)
				return;
			if (b >= i && e <= j) {
				sTree[node] += (e - b + 1) * val;
				lazy[node] += val;
			} else {
				int mid = b + e >> 1;
				propagate(node, b, mid, e);
				update_range(node << 1, b, mid, i, j, val);
				update_range(node << 1 | 1, mid + 1, e, i, j, val);
				sTree[node] = sTree[node << 1] + sTree[node << 1 | 1];
			}

		}

		void propagate(int node, int b, int mid, int e) {
			lazy[node << 1] += lazy[node];
			lazy[node << 1 | 1] += lazy[node];
			sTree[node << 1] += (mid - b + 1) * lazy[node];
			sTree[node << 1 | 1] += (e - mid) * lazy[node];
			lazy[node] = 0;
		}

		int query(int i, int j) {
			return query(1, 1, N, i, j);
		}

		int query(int node, int b, int e, int i, int j) // O(log n)
		{
			if (i > e || j < b)
				return 0;
			if (b >= i && e <= j)
				return sTree[node];
			int mid = b + e >> 1;
			//propagate(node, b, mid, e);
			int q1 = query(node << 1, b, mid, i, j);
			int q2 = query(node << 1 | 1, mid + 1, e, i, j);
			return gcd(q1 , q2);
		}
	}

	static int gcd(int a, int b) {

		if (b == 0) {
			return a;
		}
		return gcd(b, a % b);
	}

	static class unionfind {
		int[] p;
		int[] size;

		unionfind(int n) {
			p = new int[n];
			size = new int[n];

			for (int i = 0; i < n; i++) {
				p[i] = i;
			}
			Arrays.fill(size, 1);
		}

		int findSet(int v) {
			if (v == p[v])
				return v;
			return p[v] = findSet(p[v]);
		}

		boolean sameSet(int a, int b) {
			a = findSet(a);
			b = findSet(b);
			if (a == b)
				return true;
			return false;
		}

		int max() {
			int max = 0;
			for (int i = 0; i < size.length; i++)
				if (size[i] > max)
					max = size[i];
			return max;
		}

		void combine(int a, int b) {
			a = findSet(a);
			b = findSet(b);
			if (a == b)
				return;
			if (size[a] > size[b]) {
				p[b] = a;
				size[a] += size[b];

			} else {
				p[a] = b;
				size[b] += size[a];
			}
		}
	}

	static class Scanner {
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream system) {
			br = new BufferedReader(new InputStreamReader(system));
		}

		public Scanner(String file) throws Exception {
			br = new BufferedReader(new FileReader(file));
		}

		public String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public String nextLine() throws IOException {
			return br.readLine();
		}

		public int nextInt() throws IOException {
			return Integer.parseInt(next());
		}

		public double nextDouble() throws IOException {
			return Double.parseDouble(next());
		}

		public char nextChar() throws IOException {
			return next().charAt(0);
		}

		public Long nextLong() throws IOException {
			return Long.parseLong(next());
		}

		public boolean ready() throws IOException {
			return br.ready();
		}

		public void waitForInput() throws InterruptedException {
			Thread.sleep(3000);
		}
	}
}