/*
一棵二叉树 用三种颜色染色 相邻必须不同 且 若有两个子节点 三点互不相同
dp[u][0/1/2] u染成0/1/2 u的子树中绿色最多有几个
f[u][0/1/2] u染成0/1/2 u的子树中绿色最少有几个
->1son
dp[u][0]=max(dp[v][1],dp[v][2])+1;
dp[u][1]=max(dp[v][0],dp[v][2]);
dp[u][2]=max(dp[v][0],dp[v][1]);
->2son
dp[u][0]=max(dp[v1][1]+dp[v2][2],)+1;
dp[u][1]=
dp[u][2]=
*/
/*
1122002010
5 2
*/
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<string.h>
#include<queue>
#include<vector>
#include<bits/stdc++.h>
#define ll long long
#define ddd printf("-----------------------\n");
using namespace std;
const int maxn=5e5 +10;
const int mod=998244353;
const int inf=0x3f3f3f3f;
char s[maxn];
int f[maxn][4],dp[maxn][4],cnt;
void dfs(int x)
{
if(s[x]=='0'){
dp[x][0]=f[x][0]=1;
return;
}
dfs(++cnt);
if(s[x]=='1')
{
dp[x][0]=max(dp[x+1][1],dp[x+1][2])+1;
dp[x][1]=max(dp[x+1][0],dp[x+1][2]);
dp[x][2]=max(dp[x+1][1],dp[x+1][0]);
f[x][0]=min(f[x+1][1],f[x+1][2])+1;
f[x][1]=min(f[x+1][0],f[x+1][2]);
f[x][2]=min(f[x+1][1],f[x+1][0]);
}
else
{
int k=++cnt;
dfs(k);
dp[x][0]=max(dp[x+1][1]+dp[k][2],dp[x+1][2]+dp[k][1])+1;
dp[x][1]=max(dp[x+1][0]+dp[k][2],dp[x+1][2]+dp[k][0]);
dp[x][2]=max(dp[x+1][0]+dp[k][1],dp[x+1][1]+dp[k][0]);
f[x][0]=min(f[x+1][1]+f[k][2],f[x+1][2]+f[k][1])+1;
f[x][1]=min(f[x+1][0]+f[k][2],f[x+1][2]+f[k][0]);
f[x][2]=min(f[x+1][0]+f[k][1],f[x+1][1]+f[k][0]);
}
}
int main()
{
ios::sync_with_stdio(false);
cin>>s+1;
dfs(++cnt);
cout<<max(dp[1][0],max(dp[1][1],dp[1][2]))<<" "<<min(f[1][0],min(f[1][1],f[1][2]))<<'\n';
return 0;
}