**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).
{
private:
    UInt64 seed;
    MarkovModel markov_model;
public:
    StringModel(UInt64 seed_, MarkovModelParameters params_) : seed(seed_), markov_model(std::move(params_)) {}
    void train(const IColumn & column) override
    {
        const ColumnString & column_string = assert_cast<const ColumnString &>(column);
        size_t size = column_string.size();
        for (size_t i = 0; i < size; ++i)
        {
            StringRef string = column_string.getDataAt(i);
            markov_model.consume(string.data, string.size);
        }
    }
    void finalize() override