#include<bits/stdc++.h>
#define L t[u].ls
#define R t[u].rs
using namespace std;
const int mxn=10010;
inline int read(){
int r=0,f=1;char c=getchar();
while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();}
while(c>=‘0‘&&c<=‘9‘){r=r*10+c-‘0‘;c=getchar();}
return r*f;
}
int n,c=1;
char s[mxn];
struct Node{
int ls,rs;
}t[mxn];
void dfs1(int u){
if(s[u]==‘0‘){
t[u].ls=t[u].rs=-1;
}
else if(s[u]==‘1‘){
c++;t[u].ls=c;
dfs1(c);
t[u].rs=-1;
}
else{
c++;t[u].ls=c;
dfs1(c);
c++;t[u].rs=c;
dfs1(c);
}
}
void init(){
scanf("%s",s+1);
n=strlen(s+1);
dfs1(1);
}
int f[mxn][3],g[mxn][3];
void dfs2(int u){
f[u][0]=g[u][0]=1;
f[u][1]=g[u][1]=0;
f[u][2]=g[u][2]=0;
if(s[u]==‘0‘)return;
dfs2(L);
if(!~R){
f[u][0]+=max(f[L][1],f[L][2]);
f[u][1]+=max(f[L][0],f[L][2]);
f[u][2]+=max(f[L][0],f[L][1]);
g[u][0]+=min(g[L][1],g[L][2]);
g[u][1]+=min(g[L][0],g[L][2]);
g[u][2]+=min(g[L][0],g[L][1]);
}
else{
dfs2(R);
f[u][0]+=max(f[L][1]+f[R][2],f[L][2]+f[R][1]);
f[u][1]+=max(f[L][0]+f[R][2],f[L][2]+f[R][0]);
f[u][2]+=max(f[L][0]+f[R][1],f[L][1]+f[R][0]);
g[u][0]+=min(g[L][1]+g[R][2],g[L][2]+g[R][1]);
g[u][1]+=min(g[L][0]+g[R][2],g[L][2]+g[R][0]);
g[u][2]+=min(g[L][0]+g[R][1],g[L][1]+g[R][0]);
}
}
int main(){
init();
dfs2(1);
cout<<max(f[1][0],max(f[1][1],f[1][2]))<<‘ ‘<<min(g[1][0],min(g[1][1],g[1][2]));
}