#include <cstdio>
#include <cstdint>
#include <cassert>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <algorithm>
#include <random>
#include <functional>

class Parser {
  std::vector<int> assoc, preced;
  std::map<std::string, intmax_t> vars;
  char open, close;
  int max_preced;

  intmax_t apply(intmax_t lhs, char op, intmax_t rhs) const {
    switch (op) {
      case '^': return lhs ^ rhs;
      case '*': return lhs & rhs;
      default: assert(false);
    }
  }

  intmax_t literal(const std::string &s, size_t &i) const {
    assert(isalnum(s[i]));
    std::string param(1, s[i++]);
    return vars.at(param);
  }

  intmax_t parse(const std::string &s, size_t &i, int level) const {
    /* tsurai parser */
    if (level == max_preced) {
      if (s[i] == open) {
        intmax_t tmp=parse(s, ++i, 0);
        assert(s[i] == close);
        ++i;
        return tmp;
      } else if (s[i] == '-') {
        return ((1<<16)-1)&~parse(s, ++i, level);
      }

      return literal(s, i);
    }

    intmax_t lhs=parse(s, i, level+1);
    while (i < s.length()) {
      int op=s[i];
      if (op == close || preced[op] != level) break;
      if (assoc[op] == '>') {
        intmax_t rhs=parse(s, ++i, level+1);
        lhs = apply(lhs, op, rhs);
      } else /* if (assoc[op] == '<') */ {
        lhs = apply(lhs, op, parse(s, ++i, level));
      }
    }
    return lhs;
  }

public:
  Parser(const std::vector<std::string> &opss, const std::string &paren="()"):
      assoc(128), preced(128), open(paren[0]), close(paren[1]),
      max_preced(opss.size())
  {
    for (size_t i=0; i<opss.size(); ++i) {
      int a=opss[i][0];  // '<' or '>'; means associativity
      for (size_t j=1; j<opss[i].size(); ++j) {
        int op=opss[i][j];
        assoc[op] = a;
        preced[op] = i;
      }
    }
  }

  intmax_t parse(const std::string &s) const {
    size_t i=0;
    return parse(s, i, 0);
  }

  void add_var(const std::string &param, intmax_t value) {
    vars[param] = value;
  }
};

int main() {
  std::queue<std::string> q;
  std::vector<std::string> ss[15];
  ss[0] = {"0", "1", "a", "b", "c", "d"};

  Parser p({">^*"});
  p.add_var("0", 0x0000);
  p.add_var("1", 0xFFFF);
  p.add_var("a", 0xFF00);
  p.add_var("b", 0xF0F0);
  p.add_var("c", 0xCCCC);
  p.add_var("d", 0xAAAA);

  std::vector<size_t> res(1<<16, 20);
  // std::vector<std::string> debug(1<<16);

  for (const auto &s: ss[0]) {
    size_t val=p.parse(s);
    res[val] = 1;
    // debug[val] = s;
  }

  for (size_t i=1; i<6; ++i) {
    for (const std::string &s: ss[i-1]) {
      std::string t="-"+s;
      if (t.length() > 16) continue;
      size_t val=p.parse(t);
      if (res[val] > t.length()) {
        ss[i].emplace_back(t);
        res[val] = t.length();
        // debug[val] = t;
      }
    }

    for (const std::string &s1: ss[i-1]) {
      for (size_t j=0; j<i; ++j) {
        for (const std::string &s2: ss[j]) {
          std::string t="("+s1+"^"+s2+")";
          if (t.length() > 16) continue;
          std::string u="("+s1+"*"+s2+")";
          {
            size_t val=p.parse(t);
            if (res[val] > t.length()) {
              ss[i].emplace_back(t);
              res[val] = t.length();
              // debug[val] = t;
            }
          }
          {
            size_t val=p.parse(u);
            if (res[val] > u.length()) {
              ss[i].emplace_back(u);
              res[val] = u.length();
              // debug[val] = u;
            }
          }
        }
      }
    }

    // for (const std::string &s: ss[i])
    //   fprintf(stderr, "%zu: %s\n", i, s.c_str());
  }

  while (true) {
    char s[32];
    scanf("%s", s);
    if (s[0] == '.') return 0;
    printf("%zu\n", res[p.parse(s)]);
  }
}



Measured memory_bytes: 3424