Problem: Polycarp likes numbers that are divisible by 3.

He has a huge number s. Polycarp wants to cut from it the maximum number of numbers that are divisible by 3. To do this, he makes an arbitrary number of vertical cuts between pairs of adjacent digits. As a result, after m such cuts, there will be m+1 parts in total. Polycarp analyzes each of the obtained numbers and finds the number of those that are divisible by 3.

For example, if the original number is s=3121, then Polycarp can cut it into three parts with two cuts: 3|1|21. As a result, he will get two numbers that are divisible by 3.

Polycarp can make an arbitrary number of vertical cuts, where each cut is made between a pair of adjacent digits. The resulting numbers cannot contain extra leading zeroes (that is, the number can begin with 0 if and only if this number is exactly one character '0'). For example, 007, 01 and 00099 are not valid numbers, but 90, 0 and 10001 are valid.

What is the maximum number of numbers divisible by 3 that Polycarp can obtain?

Input

The first line of the input contains a positive integer s. The number of digits of the number s is between 1 and 2⋅10^5, inclusive. The first (leftmost) digit is not equal to 0.

Output

Print the maximum number of numbers divisible by 3 that Polycarp can get by making vertical cuts in the given number s.

Examples

Input

3121


Output

2


Input

6


Output

1


Input

1000000000000000000000000000000000


Output

33


Input

201920181


Output

4

Note

In the first example, an example set of optimal cuts on the number is 3|1|21.

In the second example, you do not need to make any cuts. The specified number 6 forms one number that is divisible by 3.

In the third example, cuts must be made between each pair of digits. As a result, Polycarp gets one digit 1 and 33 digits 0. Each of the 33 digits 0 forms a number that is divisible by 3.

In the fourth example, an example set of optimal cuts is 2|0|1|9|201|81. The numbers 0, 9, 201 and 81 are divisible by 3.

Solution (in JAVA):

Solution:
import java.util.*;

public class Main {
	static int mod = 1000000007;
  static int size = 200000;
	static long[] fac = new long[size];
	static long[] finv = new long[size];
	static long[] inv = new long[size];
	static int INF = Integer.MAX_VALUE;

 	public static void main(String[] args){
		Scanner scanner = new Scanner(System.in);
		String s = scanner.next();
		int n = s.length();
		int[] a = new int[n+3];
		for(int i = 0; i < n; i++){
			a[i+1] = Character.getNumericValue(s.charAt(i));
			a[i+1] %= 3;
		}
		a[n+1] = 0;
		a[n+2] = 0;
		int count = 0;
		for(int i = 1; i <= n; i++){
			if(a[i] % 3 == 0){
				count++;
			}else if(a[i] % 3 != 0){
				if((a[i] == 1 && a[i+1] == 2) || (a[i] == 2 && a[i+1] == 1)){
					count++;
					i++;
				}else if(a[i] == 1 && a[i+1] == 1 && a[i+2] == 1){
					count++;
					i += 2;
				}else if(a[i] == 2 && a[i+1] == 2 && a[i+2] == 2){
					count++;
					i += 2;
				}
			}
		}
		System.out.println(count);
	}
	public static boolean isPrime(int n){
		if(n == 1) return false;
		if(n == 2 || n == 3) return true;
		for(int i = 2; i <= Math.sqrt(n); i++){
			if(n % i == 0) return false;
		}
		return true;
	}
	// tar の方が数字が大きいかどうか
	static boolean compare(String tar, String src) {
		if (src == null) return true;
		if (src.length() == tar.length()) {
			int len = tar.length();
			for (int i = 0; i < len; i++) {
				if (src.charAt(i) > tar.charAt(i)) {
					return false;
				} else if (src.charAt(i) < tar.charAt(i)) {
					return true;
				}
			}
			return tar.compareTo(src) > 0 ? true : false;
		} else if (src.length() < tar.length()) {
			return true;
		} else if (src.length() > tar.length()) {
			return false;
		}
		return false;
	}
	public static class Edge{
		int to;
		Edge(int to){
			this.to = to;
		}
	}
	public static void swap(long a, long b){
		long tmp = 0;
		if(a > b){
			tmp = a;
			a = b;
			b = tmp;
		}
	}
  static class Pair implements Comparable<Pair>{
    int first, second;
    Pair(int a, int b){
        first = a;
        second = b;
    }
    @Override
    public boolean equals(Object o){
        if (this == o) return true;
        if (!(o instanceof Pair)) return false;
        Pair p = (Pair) o;
        return first == p.first && second == p.second;
    }
    @Override
    public int compareTo(Pair p){
        return first == p.first ? second - p.second : first - p.first; //firstで昇順にソート
        //return (first == p.first ? second - p.second : first - p.first) * -1; //firstで降順にソート
        //return second == p.second ? first - p.first : second - p.second;//secondで昇順にソート
        //return (second == p.second ? first - p.first : second - p.second)*-1;//secondで降順にソート
    }
  }

  //繰り返し二乗法
  public static long pow(long x, long n){
    long ans = 1;
    while(n > 0){
      if((n & 1) == 1){
        ans = ans * x;
        ans %= mod;
      }
      x = x * x % mod;
      n >>= 1;
    }
    return ans;
  }

	public static long div(long x, long y){
		return (x*pow(y, mod-2))%mod;
	}

  //fac, inv, finvテーブルの初期化、これ使う場合はinitComb()で初期化必要
	public static  void initComb(){
		fac[0] = finv[0] = inv[0] = fac[1] = finv[1] = inv[1] = 1;
		for (int i = 2; i < size; ++i) {
			fac[i] = fac[i - 1] * i % mod;
			inv[i] = mod - (mod / i) * inv[(int) (mod % i)] % mod;
			finv[i] = finv[i - 1] * inv[i] % mod;
		}
	}

	//nCk % mod
	public static long comb(int n, int k){
		return fac[n] * finv[k] % mod * finv[n - k] % mod;
	}

	//n! % mod
	public static long fact(int n){
		return fac[n];
	}

	//(n!)^-1 with % mod
	public static long finv(int n){
		return finv[n];
	}

  static class UnionFind {
    int[] parent;
    public UnionFind(int size) {
      parent = new int[size];
      Arrays.fill(parent, -1);
    }
    public boolean unite(int x, int y) {
      x = root(x);
      y = root(y);
      if (x != y) {
        if (parent[y] < parent[x]) {
          int tmp = y;
          y = x;
          x = tmp;
        }
        parent[x] += parent[y];
        parent[y] = x;
        return true;
      }
      return false;
    }
    public boolean same(int x, int y) {
      return root(x) == root(y);
    }
    public int root(int x) {
      return parent[x] < 0 ? x : (parent[x] = root(parent[x]));
    }
    public int size(int x) {
      return -parent[root(x)];
    }
  }
	public static int upperBound(long[] array, long value) {
			 int low = 0;
			 int high = array.length;
			 int mid;
			 while( low < high ) {
					 mid = ((high - low) >>> 1) + low; // (high + low) / 2
					 if( array[mid] <= value ) {
							 low = mid + 1;
					 } else {
							 high = mid;
					 }
			 }
			 return low;
	 }
	 public static final int lowerBound(final int[] arr, final int value) {
    int low = 0;
    int high = arr.length;
    int mid;
    while (low < high) {
        mid = ((high - low) >>> 1) + low;    //(low + high) / 2 (オーバーフロー対策)
        if (arr[mid] < value) {
            low = mid + 1;
        } else {
            high = mid;
        }
    }
    return low;
}
  //n,mの最大公約数
  public static long gcd(long n, long m){
    if(m > n) return gcd(m,n);
    if(m == 0) return n;
    return gcd(m, n%m);
  }
	//3要素のソート
	private class Pair2 implements Comparable<Pair2> {
		String s;
		int p;
		int index;
		public Pair2(String s, int p, int index) {
				this.s = s;
				this.p = p;
				this.index = index;
		}

		public int compareTo(Pair2 other) {
				if (s.equals(other.s)) {
						return other.p - this.p;
				}
				return this.s.compareTo(other.s);
		}
	}
	//c -> intに変換
public static int c2i(char c){
	if('A' <= c && c <= 'Z'){
		return c - 'A';
	}else{
		return c - 'a' + 26;
	}
}
// int -> charに変換
public static char i2c(int i){
	if(0 <= i && i < 26){
			return (char)(i + 'A');
	}else{
			return (char)(i + 'a' - 26);
	}
}

}