#include<iostream>
#include<string>



class Exception {
  std::string _msg;  
protected:
  explicit Exception(std::string msg):_msg(msg) {};
public:  
  virtual std::string what() {return _msg;}
  virtual ~Exception(){};
};

class Numeric : public Exception {
protected:
  explicit Numeric(std::string msg):Exception(msg) {};
public:

};

class Overflow : public Numeric {
public:
  Overflow(std::string msg): Numeric(msg) {};
  virtual std::string what() {return "overflow " + Exception::what();}
};

class Underflow : public Numeric {
public:
  Underflow(std::string msg): Numeric(msg) {};
  virtual std::string what() {return "underflow " + Exception::what();}
};

class Range_error: public Exception {
public:
  Range_error(std::string msg):Exception(msg) {};
  virtual std::string what() {return "range error " + Exception::what();}
};


main() {

  try {
    throw Range_error("test");
  }
  catch(Numeric &e) {
    std::cerr<<"caught numeric error\n"<<e.what()<<"\n";
  }
  catch(Range_error &e ) {
    std::cerr<<"caught range error\n"<<e.what()<<"\n";
  }
  

}