#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;

string tage[] = { "Sonntag", "Montag", "Dienstag",
                 "Mittwoch", "Donnerstag", "Freitag", "Samstag" };

// Monat mit zwei Komponenten, zweite K. ein int-Array der Laenge 2:
struct monat { string name; int n[2]; };

monat mon[] = {
  {"null",    {  0,  0}},
  {"Januar",  { 31, 31}},   {"Februar",   {59, 60}},  {"Maerz",    { 90, 91}},
  {"April",   {120,121}},   {"Mai",      {151,152}},  {"Juni",     {181,182}},
  {"Juli",    {212,213}},   {"August",   {243,244}},  {"September",{273,274}},
  {"Oktober", {304,305}},   {"November", {334,335}},  {"Dezember", {365,366}}
};

int schalt(int j) { /* gregorianisch */
  return  ( j % 4 == 0 &&  j % 100 != 0 || j % 400 == 0 );
}

int jahr_laenge(int j)  { return 365 + schalt(j);   }

class datum {
  int  t; int m; int j;  int n; // Tag, Monat, Jahr, Nummer des Tages im Jahr
public:
  // Drei Konstruktor-Funktionen
  datum() {}
  datum(int tag, int monat, int jahr) {
    t = tag; m = monat; j = jahr;

    if ( 1 <= m && m <= 12 && 1 <= t && t <= mon_laenge(*this) ) {
      n = t + mon[ m - 1 ].n[ schalt(j) ];  //  normalisieren.
    }
    else {
      cout << "Das Datum gibt es nicht : " << t << "." << m << "." << j <<"\n";
      exit(1);
    }
  }
  // Liefert zum Tag n >= 1 und Jahr j
  // das Datum des n-ten Tages ab und inklusive 1.1.j
  datum(int jj, int nn) {
    while( nn > jahr_laenge(jj) ) {
      nn -= jahr_laenge(jj);  jj++;
    }
    n = nn; j = jj;
    for (int i = 0;  mon[i].n[ schalt(j) ] < n  ; i++) {
      t = nn - mon[i].n[ schalt(j) ]; m = i+1;
    }
  }

  friend int mon_laenge(datum d) { /* braucht "zulaessiges" d.m */
    return mon[d.m].n[ schalt(d.j) ] - mon[d.m-1].n[ schalt(d.j) ];
  }

  friend ostream& operator<<(ostream& os, datum d) {
    os << d.t << ". " << mon[d.m].name << ", " << d.j << "\n";
    return os;
  }

  // Berechne u - v
  friend int operator-(datum u, datum v) {
    int n, i;
    if (u.j < v.j || (u.j == v.j && u.n < v.n ) ) return -(v-u);
    n = u.n;
    for(i = u.j - 1; i >= v.j; i--)
      n += jahr_laenge(i);
    n -=  v.n;
    return n;
  }

  // Liefert das Datum des folgenden Tages
  datum inc_tag() const { // nachgestelltes const, bezeichnet die Zusicherung,
    // dass das implizite Argument nicht veraendert wird
    return datum(j, n+1 );
  }

  friend datum operator+(datum u, int t) {
    if (t >= 0) {
      return datum(u.j, u.n + t);
    }
    cout << "Nicht implementiert (t negativ) : " << t << "\n" ;
    exit(1);
  }

  friend istream& operator>>(istream& is, datum& d) {
    cout << "Bitte Tag Monat Jahr eingeben : ";
    int t, m, j;
    is >> t >> m >> j;
    d = datum(t,m,j);
    return is;
  }

  int jahr() { return j;}
  int tag_im_jahr() { return n;}
};

int wochentag(datum d) {
  int jj = d.jahr() - 1;
  int w = (1 + 5*(jj%4) + 4*(jj%100) + 6*(jj%400)) % 7;
  return (w + d.tag_im_jahr() - 1) % 7;
}

int main() {
  int t; datum d, dd;

  while(1) {
    cin >> d;
    cout << "Das Datum ist : " << d ;
    cout << "Es ist der " <<
      d.tag_im_jahr() << "-te Tag im Jahr " << d.jahr()  << ".\n";
    cout << "Es ist ein " << tage[ wochentag(d) ] << ".\n";
    cout << "Der naechste Tag ist : " << d.inc_tag();
    cout << "wieviele Tage dazu ? "; cin >> t;
    dd = d + t;
    cout << dd;
    cout << "Unterschied nach diff : " << dd - d << "\n";
  }
}
