Time Limit: 8 sec / Memory Limit: 64 MB





Example

Input

100
A=malloc(10)
B=clone(A)
free(A)


Output

0
#include <cstdio>
#include <cstdint>
#include <cassert>
#include <cctype>
#include <vector>
#include <algorithm>
#include <string>
#include <map>
#include <set>
#include <stdexcept>

class Memory {
  struct Allocator {
    intmax_t addr, size;
    Allocator(intmax_t a, intmax_t s): addr(a), size(s) {}
    bool null() const {
      return addr == -1;
    }
    bool initialized() const {
      return addr != -2;
    }
  };
  Allocator mem_NULL=Allocator(-1, 0), mem_XXX=Allocator(-2, 0);

  using Pointer = std::pair<char, Allocator>;
  std::map<char, Allocator> vars;
  intmax_t index=0;
  std::set<size_t> allocated;
  size_t leaked_=0;
  intmax_t remain;

  void mem_free(const std::string &s, size_t &i) {
    assert(s[1] == '(');
    i = 2;
    Pointer p=mem_expr(s, i);
    assert(s[i] == ')');

    if (p.second.null()) {
      // free(NULL) is safe
      return;
    } if (!p.second.initialized()) {
      // free(???) is unsafe
      throw std::logic_error("attempt to free un-alloc'd space");
    }

    {
      auto it=allocated.find(p.second.addr);
      if (it == allocated.end())
        throw std::logic_error("attempt to free un-alloc'd space");

      allocated.erase(it);
    }

    remain += p.second.size;

    if (!isupper(p.first)) {
      leaked_ -= p.second.size;
      return;
    }
    
    auto it=vars.find(p.first);
    if (it == vars.end())
      throw std::logic_error("attempt to use undefined pointer");

    vars.erase(it);
  }

  Pointer mem_expr(const std::string &s, size_t &i) {
    if (s[i] == '(') {
      // "(" <expr> ")"
      Pointer res=mem_expr(s, ++i);
      assert(s[i] == ')');
      ++i;
      return res;
    }
    if (s[i] == '$') {
      // "NULL"
      ++i;
      return {0, mem_NULL};
    }
    if (s[i] == 'm') {
      // <malloc>
      return {0, mem_malloc(s, i)};
    }
    if (s[i] == 'c') {
      // <clone>
      return {0, mem_clone(s, i)};
    }
    if (isupper(s[i])) {
      // <variable>
      char var=s[i++];
      if (s[i] != '=') {
        auto it=vars.find(var);
        if (it != vars.end()) return *it;
        return {var, mem_XXX};
      }

      // <variable> "=" <expr>
      return mem_assign(var, mem_expr(s, ++i));
    }
    __builtin_unreachable();
  }

  Allocator mem_malloc(const std::string &s, size_t &i) {
    // "malloc(" <number> ")"
    assert(s[i+1] == '(');
    i += 2;
    intmax_t size=s[i]-'0';
    while (++i < s.length() && isdigit(s[i]))
      size = size*10+s[i]-'0';

    if (size > remain) return mem_NULL;
    remain -= size;
    leaked_ += size;
    allocated.insert(index);
    return {index++, size};
  }

  Allocator mem_clone(const std::string &s, size_t &i) {
    // "clone(" <expr> ")"
    assert(s[i+1] == '(');
    i += 2;
    Pointer arg=mem_expr(s, i);

    if (!arg.second.initialized())
      throw std::logic_error("attempt to clone un-alloc'd space");
    if (arg.second.null()) return mem_NULL;
    if (arg.second.size > remain) return mem_NULL;
    remain -= arg.second.size;
    leaked_ += arg.second.size;
    allocated.insert(index);
    return Allocator(index++, arg.second.size);
  }

  Pointer mem_assign(char var, const Pointer &ptr) {
    auto it=vars.lower_bound(var);
    if (it != vars.end() && it->first == var) {
      if (it->second.size > 0) {
        leaked_ += it->second.size;
      }
      it->second = ptr.second;
    } else {
      vars.emplace_hint(it, var, ptr.second);
    }
    leaked_ -= ptr.second.size;
    return {var, ptr.second};
  }

public:
  Memory(intmax_t M): remain(M) {}

  void exec(const std::string &s) {
    size_t i=0;
    if (s[0] == 'f') {
      mem_free(s, i);
    } else {
      mem_expr(s, i);
    }
  }

  size_t leaked() const {
    return leaked_;
  }
};

void preprocess(std::string &s) {
  std::string t;
  for (size_t i=0; i<s.length(); ++i) {
    t += s[i];
    if (s[i] == 'm') {
      i += 5;  // "malloc"
    } else if (s[i] == 'f') {
      i += 3;  // "free"
    } else if (s[i] == 'c') {
      i += 4;  // "clone";
    } else if (s[i] == 'N' && i+1 < s.length() && s[i+1] == 'U') {
      i += 3;  // "NULL";
      t.back() = '$';
    }
  }
  s = std::move(t);
}

int main() {
  intmax_t M;
  scanf("%jd", &M);

  Memory mem(M);
  while (true) {
    char buf[384];
    if (scanf("%s", buf) == EOF) break;
    std::string s=buf;
    preprocess(s);
    try {
      mem.exec(s);
    } catch (std::logic_error &e) {
      // fprintf(stderr, "%s\n", e.what());
      printf("Error\n");
      return 0;
    }
  }

  printf("%zu\n", mem.leaked());
}

