#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const ll MOD = 1e9 + 7;
const ll INF = 1e13;

struct Node {
    char type;
    vector<Node> child;
    Node(char _type) {
        type = _type;
    }
    void trav(string ind) {
        cout << ind << type << endl;
        for(Node node : child)
            node.trav(ind + " ");
    }
    int need0() {
        if(type == '&') {
            return min(child[0].need1() + child[1].need0(), child[0].need0());
        } else if(type == '|') {
            return child[0].need0() + child[1].need0();
        } else {
            return 1;
        }
    }
    int need1() {
        if(type == '|') {
            return min(child[0].need0() + child[1].need1(), child[0].need1());
        } else if(type == '&') {
            return child[0].need1() + child[1].need1();
        } else {
            return 1;
        }
    }
};

int main() {
    string S;
    cin >> S;
    stack<char> st;
    vector<Node> nodes;
    for(int i = 0; i < S.size(); ++i) {
        char c = S[i];
        if(c == '&') {
            while(!st.empty() && st.top() == '&') {
                nodes.push_back(Node('&'));
                st.pop();
            }
            st.push('&');
        } else if(c == '|') {
            while(!st.empty() && st.top() != '(') {
                nodes.push_back(Node(st.top()));
                st.pop();
            }
            st.push('|');
        } else if(c == '?') {
            nodes.push_back(Node(c));
        } else if(c == '(') {
            st.push('(');
        } else {
            while(!st.empty() && st.top() != '(') {
                nodes.push_back(Node(st.top()));
                st.pop();
            }
            st.pop();
        }
    }
    while(!st.empty()) {
        nodes.push_back(Node(st.top()));
        st.pop();
    }
    stack<Node> nst;
    for(int i = 0; i < nodes.size(); ++i) {
        Node node = nodes[i];
        if(node.type == '?') {
            nst.push(node);
        } else if(node.type == '&') {
            Node n2 = nst.top();
            nst.pop();
            Node n1 = nst.top();
            nst.pop();
            node.child.push_back(n1);
            node.child.push_back(n2);
            nst.push(node);
        } else {
            Node n2 = nst.top();
            nst.pop();
            Node n1 = nst.top();
            nst.pop();
            node.child.push_back(n1);
            node.child.push_back(n2);
            nst.push(node);
        }
    }
    Node root = nst.top();
    cout << root.need0() << " " << root.need1() << endl;
    return 0;
}
