#include <iostream>
#include <cstdio>
using namespace std;

class Carrier;
class BigInt;
class Decimal;

class Carrier {
	friend class Decimal;
protected:
	struct Four {
		Four *upper = NULL;
		Four *under = NULL;
		unsigned long value = 0;
	};
	Four *most  = NULL;
	Four *least = NULL;
    void release();
    Four* carry();
	Carrier();
	~Carrier();
};

class BigInt : public virtual Carrier
{
	friend class Decimal;
private:
	static const unsigned long UNIT = 0xFFFF;
	static const unsigned long SHIFT = 16;
public:
	BigInt();
	BigInt(unsigned long value);
	BigInt& add(const BigInt& value);
//	BigInt& copy(const BitInt& value);
};

class Decimal : public virtual Carrier
{
private:
	static const unsigned long UNIT = 10000;
public:
    Decimal();
    Decimal(unsigned long value);
    Decimal(const Decimal& value);
    Decimal(const Decimal *value);
    Decimal(const BigInt& value);
    Decimal& add(const Decimal& value);
    Decimal& mul(const Decimal& value);
    Decimal& copy(const Decimal& value);
    Decimal& copy(const Decimal *value);
    Decimal& swap(Decimal& value);
    Decimal& operator ++ ();
    Decimal& operator = (const Decimal& value);
    Decimal& operator += (const Decimal& value);
    Decimal& operator *= (const Decimal& value);
    Decimal operator + (const Decimal& value);
    Decimal operator * (const Decimal& value);
    void print() const;
    void println() const;
    
};

Carrier::Carrier() { most = least = new Four; }
Carrier::~Carrier() { release(); }
void Carrier::release() {
	Four *temp;
	while (most != NULL) {
		temp = most->under;
		delete most;
		most = temp;
	}
	most = least = NULL;
}
Carrier::Four* Carrier::carry() {
	Four *temp = new Four;
	temp->under = most;
	most->upper = temp;
	most = temp;
	return most;
}

BigInt::BigInt() {}
BigInt::BigInt(unsigned long value) {
	Four *temp = least;
	while (value > 0) {
		if (temp == NULL) {
			temp = carry();
		}
		temp->value = value & UNIT;
		value >>= SHIFT;
		temp = temp->upper;
	}
}
BigInt& BigInt::add(const BigInt& value) {
	unsigned long flow = 0;
	Four *me = least;
	Four *he = value.least;
	while (he != NULL) {
		if (me == NULL) {
			me = carry();
		}
		me->value += he->value + flow;
		flow = me->value >> SHIFT;
		me->value &= UNIT;
		me = me->upper;
		he = he->upper;
	}
	while (flow > 0) {
		if (me == NULL) {
			me = carry();
		}
		me->value += flow;
		flow = me->value >> SHIFT;
		me->value &= UNIT;
		me = me->upper;
	}
	return *this;
}


Decimal::Decimal() {}
Decimal::Decimal(unsigned long value) {
	Four *temp = least;
	while (value > 0) {
		if (temp == NULL) {
			temp = carry();
		}
		temp->value = value % UNIT;
		value /= UNIT;
		temp = temp->upper;
	}
}
Decimal::Decimal(const Decimal& value) { copy(value); }
Decimal::Decimal(const Decimal *value) { copy(value); }
Decimal::Decimal(const BigInt& value) {
	const Decimal temp(BigInt::UNIT + 1);
	Four *cur = value.most;
	while (cur != NULL) {
		mul(temp);
		add(Decimal(cur->value));
		cur = cur->under;
	}
}
Decimal& Decimal::add(const Decimal& value) {
	unsigned long flow = 0;
	Four *me = least;
	Four *he = value.least;
	while (he != NULL) {
		if (me == NULL) {
			me = carry();
		}
		me->value += he->value + flow;
		flow = me->value / UNIT;
		me->value %= UNIT;
		me = me->upper;
		he = he->upper;
	}
	while (flow > 0) {
		if (me == NULL) {
			me = carry();
		}
		me->value += flow;
		flow = me->value / UNIT;
		me->value %= UNIT;
		me = me->upper;
	}
	return *this;
}
Decimal& Decimal::mul(const Decimal& value) {
	Decimal temp;
	swap(temp);
	Four *me = least;
	Four *he = value.least;
	Four *she, *who;
	unsigned long flow1, flow2, product;
	while (he != NULL) {
		if (me == NULL) {
			me = carry();
		}
		she = temp.least;
		who = me;
		flow1 = flow2 = 0;
		while (she != NULL) {
			if (who == NULL) {
				who = carry();
			}
			product = he->value * she->value;
			flow2 = product / UNIT;
			who->value += product % UNIT;
			flow2 += who->value / UNIT;
			who->value %= UNIT;
			who->value += flow1;
			flow1 = flow2 + (who->value / UNIT);
			who->value %= UNIT;
			who = who->upper;
			she = she->upper;
		}
		while (flow1 > 0) {
			if (who == NULL) {
				who = carry();
			}
			who->value += flow1;
			flow1 = who->value / UNIT;
			who->value %= UNIT;
			who = who->upper;
		}
		me = me->upper;
		he = he->upper;
	}
	return *this;
}
Decimal& Decimal::copy(const Decimal& value) {
	Four *me = least;
	Four *he = value.least;
	while (he != NULL) {
		if (me == NULL) {
			me = carry();
		}
		me->value = he->value;
		me = me->upper;
		he = he->upper;
	}
	while (me != NULL) {
		me->value = 0;
		me = me->upper;
	}
	return *this;
}
Decimal& Decimal::copy(const Decimal *value) { if (value != NULL) { copy(*value); } return *this; }
Decimal& Decimal::swap(Decimal& value) {
	Four *temp_most = most;
	Four *temp_least = least;
	most = value.most;
	least = value.least;
	value.most = temp_most;
	value.least = temp_least;
	return *this;
}
void Decimal::print() const {
	Four *temp = most;
	int f = 0;
	while (temp != NULL) {
		if (f == 0) {
			if (temp->value != 0) {
				printf("%d", temp->value);
				f = 1;
			}
		} else {
			printf("%04d", temp->value);
		}
		temp = temp->under;
	}
	if (f == 0) {
		putchar('0');
	}
}
void Decimal::println() const { print(); putchar('\n'); }
Decimal& Decimal::operator ++ () { return add(Decimal(1)); }
Decimal& Decimal::operator += (const Decimal& value) { return add(value); }
Decimal Decimal::operator + (const Decimal& value) { Decimal sum(value); return sum.add(*this); }
Decimal& Decimal::operator *= (const Decimal& value) { return mul(value); }
Decimal Decimal::operator * (const Decimal& value) { Decimal product(value); return product.mul(*this); }
Decimal& Decimal::operator = (const Decimal& value) { return copy(value); }


int main() {
	
	BigInt val1(12340);
	BigInt val2(90060);
	
	BigInt val(1234567);
	Decimal dec1(1111111);
	Decimal dec2(7);
	Decimal dec3(val1.add(val2));
	
	dec2 *= dec1;
	dec2 += dec2;
	dec2 += dec2;

	dec1.println();
	dec2.println();
	dec3.println();
	
	return 0;
}