**Use case**

Generate models once and reuse them.

**Describe the solution you'd like**

Add command line options:
```
--save file - write serialized models on disk after training and before generating the data; the user can set --limit to 0 to only train the models and save them without proceeding to data generation;
--load file - instead of training the models, load the prepared models from the file and start generating the data.
```

Serialization format: one byte for version (equals to 0), then simple binary serialization of all the models; the whole file is compressed with ZSTD level 1 using CompressedWriteBuffer (no need to allow any compression options to choose).
{
public:
    
    virtual void train(const IColumn & column) = 0;
    
    virtual void finalize() = 0;
    
    virtual ColumnPtr generate(const IColumn & column) = 0;
    
    virtual void updateSeed() = 0;
    virtual ~IModel() = default;
};
using ModelPtr = std::unique_ptr<IModel>;
template <typename... Ts>
UInt64 hash(Ts... xs)
{
    SipHash hash;
    (hash.update(xs), ...);
    return hash.get64();
}
static UInt64 maskBits(UInt64 x, size_t num_bits)
{
    return x & ((1ULL << num_bits) - 1);
}
static UInt64 feistelRound(UInt64 x, size_t num_bits, UInt64 seed, size_t round)