import std.algorithm;
import std.array;
import std.ascii;
import std.container;
import std.conv;
import std.math;
import std.numeric;
import std.range;
import std.stdio;
import std.string;
import std.typecons;
import core.stdc.stdlib;
import core.stdc.string;
void log(A...)(A arg) { stderr.writeln(arg); }
int size(T)(in T s) { return cast(int)s.length; }

struct R {
    int x;
    void set(int mask, bool res) {
        if (res) x |= 1 << mask;
        else x &= ~(1 << mask);
    }
    void set(bool a, bool b, bool c, bool d, bool res) {
        int mask = (a << 3) | (b << 2) | (c << 1) | d;
        set(mask, res);
    }
    bool get(int mask) {
        return (x & (1 << mask)) != 0;
    }
    bool get(bool a, bool b, bool c, bool d) {
        int mask = (a << 3) | (b << 2) | (c << 1) | d;
        return get(mask);
    }
}

bool eval(in string s, bool a, bool b, bool c, bool d) {
    int i = 0;
    bool expr() {
        switch (s[i++]) {
            case '0': return false;
            case '1': return true;
            case 'a': return a;
            case 'b': return b;
            case 'c': return c;
            case 'd': return d;
            case '-': return !expr();
            case '(':
                auto l = expr();
                char op = s[i++];
                assert(op == '*' || op == '^');
                auto r = expr();
                assert(s[i] == ')');
                i++;
                return (op == '*' ? l & r : l ^ r);
            default:
                assert(false);
        } 
    }
    return expr();
}

void main() {
    auto dp = new int[1<<16];
    const huge = 35;
    dp[] = huge;

    // 0
    dp[0] = 1;

    // 1
    {
        R r;
        for (int mask = 0; mask < 16; mask++) { r.set(mask, true); }
        dp[r.x] = 1;
    }

    // a, b, c, d
    {
        auto bs = [false, true];
        R A, B, C, D;
        foreach (a; bs) {
            foreach (b; bs) {
                foreach (c; bs) {
                    foreach (d; bs) {
                        A.set(a, b, c, d, a);
                        B.set(a, b, c, d, b);
                        C.set(a, b, c, d, c);
                        D.set(a, b, c, d, d);
                    }
                }
            }
        }
        dp[A.x] = dp[B.x] = dp[C.x] = dp[D.x] = 1;
    }

    bool updated = true;
    auto idx = iota(0, 1<<16, 1).array;
    while (updated) {
        updated = false;
        idx.sort!((i, j) => dp[i] < dp[j]);
        for (int i = 0; i < (1<<16); i++) {
            auto x = dp[i];
            if (x == huge) continue;
            if (dp[~i & (1<<16) - 1] > x + 1) {
                dp[~i & (1<<16) - 1] = x + 1;
                updated = true;
            }
            for (int k = 0; k < (1<<16); k++) {
                int j = idx[k];
                auto y = dp[j];
                if (x + y + 3 >= huge) break;
                if (dp[i ^ j] > x + y + 3) {
                    dp[i ^ j] = x + y + 3;
                    updated = true;
                }
                if (dp[i & j] > x + y + 3) {
                    dp[i & j] = x + y + 3;
                    updated = true;
                }
            }
        }
    }

    string s;
    bool input() {
        s = readln.chomp;
        if (s == ".") return false;
        return true;
    }
    void solve() {
        R r;
        const bs = [false, true];
        foreach (a; bs) {
            foreach (b; bs) {
                foreach (c; bs) {
                    foreach (d; bs) {
                        r.set(a, b, c, d, eval(s, a, b, c, d));
                    }
                }
            }
        }
        writeln(dp[r.x]);
    }
    while (input()) solve();
}