#include <functional>
#include <iostream>
#include <string>
#include <unordered_set>
#include <vector>
#define loop(i, a, n) for (int i = (a); i < (n); i++)
#define rep(i, n) loop(i, 0, n)
template<typename A> using F = std::function<A>;
using namespace std;

template<typename T> struct ParseResult {
  bool succeeded;
  T object;
  int pos;
  ParseResult(const bool succeeded, T object, const int pos) : succeeded(succeeded), object(std::move(object)), pos(pos) {}
  friend std::ostream &operator<<(std::ostream &os, const ParseResult<T> &p) { return os << '{' << (p.succeeded ? "true" : "false") << ',' << p.object << ',' << p.pos << '}'; }
};

template<typename T> using Parser = std::function<ParseResult<T>(const std::string&, int)>;

Parser<std::string> token(std::string &&s) {
  const auto n = s.size();
  return[n = std::move(n), s = std::move(s)](const std::string &target, const int pos) {
    if (target.size() < n) return ParseResult<std::string>(false, {}, pos);
    return target.substr(pos, n) == s ? ParseResult<std::string>(true, s, pos + n) : ParseResult<std::string>(false, {}, pos);
  };
}

template<typename T> Parser<T> operator||(Parser<T> p1, Parser<T> p2) {
  return[p1 = std::move(p1), p2 = std::move(p2)](const std::string &target, const int pos) {
    auto r = p1(target, pos);
    if (r.succeeded) return r;
    r = p2(target, pos);
    if (r.succeeded) return r;
    return ParseResult<T>(false, {}, pos);
  };
}

template<typename T1, typename T2> Parser<std::pair<T1, T2>> operator+(Parser<T1> p1, Parser<T2> p2) {
  return[p1 = std::move(p1), p2 = std::move(p2)](const std::string &target, const int pos) {
    auto r1 = p1(target, pos);
    if (!r1.succeeded) return ParseResult<std::pair<T1, T2>>(false, {}, pos);
    auto r2 = p2(target, r1.pos);
    if (!r2.succeeded) return ParseResult<std::pair<T1, T2>>(false, {}, pos);
    return ParseResult<std::pair<T1, T2>>(true, { r1.object, r2.object }, r2.pos);
  };
}

template<typename T1, typename T2> Parser<T2> operator>>(Parser<T1> p1, Parser<T2> p2) {
  return[p1 = std::move(p1), p2 = std::move(p2)](const std::string &target, const int pos) {
    auto r1 = p1(target, pos);
    if (!r1.succeeded) return ParseResult<T2>(false, {}, pos);
    auto r2 = p2(target, r1.pos);
    if (!r2.succeeded) return ParseResult<T2>(false, {}, pos);
    return ParseResult<T2>(true, r2.object, r2.pos);
  };
}

template<typename T1, typename T2> Parser<T1> operator<<(Parser<T1> p1, Parser<T2> p2) {
  return[p1 = std::move(p1), p2 = std::move(p2)](const std::string &target, const int pos) {
    auto r1 = p1(target, pos);
    if (!r1.succeeded) return ParseResult<T1>(false, {}, pos);
    auto r2 = p2(target, r1.pos);
    if (!r2.succeeded) return ParseResult<T1>(false, {}, pos);
    return ParseResult<T1>(true, r1.object, r2.pos);
  };
}

Parser<char> oneOf(const std::string &s) {
  std::unordered_set<char> d;
  for (auto &c : s) d.insert(c);
  return[d = std::move(d)](const std::string &target, const int pos) {
    if (target.size() <= pos) return ParseResult<char>(false, {}, pos);
    char c = target[pos];
    return d.count(c) ? ParseResult<char>(true, c, pos + 1) : ParseResult<char>(false, {}, pos);
  };
}

template<typename T, typename S, typename F> Parser<S> fmap(Parser<T> p, F &&f) {
  return[p = std::move(p), f = std::forward<F>(f)](const std::string &target, const int pos) {
    auto r = p(target, pos);
    return r.succeeded ? ParseResult<S>(true, f(r.object), r.pos) : ParseResult<S>(false, {}, r.pos);
  };
}

template<typename T, typename F> Parser<T> lazy(F &&f) {
  static bool instantiated = false;
  static Parser<T> p;
  return[f = std::forward<F>(f)](const std::string &target, const int pos) {
    if (!instantiated) {
      p = f();
      instantiated = true;
    }
    return p(target, pos);
  };
}

struct SyntaxTree {
  string op;
  char value;
  vector<SyntaxTree> children;
  SyntaxTree() {}
  SyntaxTree(const string &op, const char value, const vector<SyntaxTree> &children) : op(op), value(value), children(children) {}
};

int main() {
  Parser<SyntaxTree> formulaP = lazy<SyntaxTree>([&]() {
    auto andP = fmap<pair<SyntaxTree, SyntaxTree>, SyntaxTree>((token("(") >> formulaP << token("*")) + (formulaP << token(")")), [](auto &o) { return SyntaxTree("*", {}, { o.first, o.second }); });
    auto orP = fmap<pair<SyntaxTree, SyntaxTree>, SyntaxTree>((token("(") >> formulaP << token("+")) + (formulaP << token(")")), [](auto &o) { return SyntaxTree("+", {}, { o.first, o.second }); });
    auto impP = fmap<pair<SyntaxTree, SyntaxTree>, SyntaxTree>((token("(") >> formulaP << token("->")) + (formulaP << token(")")), [](auto &o) { return SyntaxTree("->", {}, { o.first, o.second }); });
    auto notP = fmap<SyntaxTree, SyntaxTree>(token("-") >> formulaP, [](auto &o) { return SyntaxTree("-", {}, { o }); });
    auto valP = fmap<char, SyntaxTree>(oneOf("abcdefghijkTF"), [](char x) { return SyntaxTree({}, x, {}); });
    return andP || orP || impP || notP || valP;
  });
  auto equationP = (formulaP << token("=")) + formulaP;
  string s;
  while (cin >> s, s != "#") {
    auto r = equationP(s, 0);
    bool isValid = true;
    rep(i, 1 << 11) {
      auto toBool = [&](char c) -> bool {
        if (c == 'T') return true;
        if (c == 'F') return false;
        return i >> (c - 'a') & 1;
      };
      F<bool(const SyntaxTree&)> evalF = [&](const SyntaxTree &f) {
        switch (f.children.size()) {
        case 0: return toBool(f.value);
        case 1: return !evalF(f.children[0]);
        case 2:
          if (f.op == "*") return evalF(f.children[0]) && evalF(f.children[1]);
          if (f.op == "+") return evalF(f.children[0]) || evalF(f.children[1]);
          if (f.op == "->") return !evalF(f.children[0]) || evalF(f.children[1]);
        }
      };
      isValid &= evalF(r.object.first) == evalF(r.object.second);
    }
    cout << (isValid ? "YES" : "NO") << endl;
  }
}

Measured memory_bytes: 4708