#include <iostream>
#include <memory>
#include <string>
#include <vector>

struct figura {
   virtual ~figura( ) = default;
   virtual std::string nombre( ) const = 0;
   virtual double perimetro( ) const = 0;
};

struct circulo : figura {
   double diametro;

   circulo(double d)
   : diametro(d) {
   }

   std::string nombre( ) const {
      return "circulo";
   }

   double perimetro( ) const {
      return 3.1416 * diametro;
   }
};

struct cuadrado : figura {
   double lado;

   cuadrado(double d)
   : lado(d) {
   }

   std::string nombre( ) const {
      return "cuadrado";
   }

   double perimetro( ) const {
      return 4 * lado;
   }
};

struct rectangulo : figura {
   double base, altura;

   rectangulo(double b, double a)
   : base(b), altura(a) {
   }

   std::string nombre( ) const {
      return "rectangulo";
   }

   double perimetro( ) const {
      return 2 * base + 2 * altura;
   }
};

int main( ) {
   int n;
   std::cin >> n;

   std::vector<std::shared_ptr<figura>> v;
   for (int i = 0; i < n; ++i) {
      char opcion;
      std::cin >> opcion;

      if (opcion == 'C') {
         double diametro;
         std::cin >> diametro;
         v.push_back(std::make_shared<circulo>(diametro));     // std::make_shared se encarga de llamar a new, crear el objeto y devolver el std::shared_ptr
      } else if (opcion == 'S') {
         double lado;
         std::cin >> lado;
         v.push_back(std::make_shared<cuadrado>(lado));
      } else if (opcion == 'R') {
         double base, altura;
         std::cin >> base >> altura;
         v.push_back(std::make_shared<rectangulo>(base, altura));
      }
   }

   for (std::shared_ptr<figura> p : v) {
      std::cout << p->nombre( ) << " " << p->perimetro( ) << "\n";
                                                            // ¿la figura realmente es de tipo circulo?
      circulo* checar = dynamic_cast<circulo*>(p.get( ));   // p.get( ) obtiene figura* (dynamic_cast requiere un T*, no un std::shared_ptr<T>)
      if (checar != nullptr) {                              // si sí entonces checar es válido; si no entonces checar es nulo
         std::cout << "   diametro " << checar->diametro << "\n";
      }
   }
}                                                           // existe std::dynamic_pointer_cast que puede tomar directamente un std::shared_ptr<T> (y devuelve otro std::shared_ptr)

/* Ejemplo de entrada:
5
C 1.2
S 3.4
R 5.6 7.8
C 9.1
S 2.3
*/
