#define NDEBUG
#include <cassert>
#include <stdexcept>
#include <utility>

template <class ValueMonoid, class OperatorMonoid, class Modifier,
	template <class> class Container>
class lazy_segment_tree {
public:
	using value_structure = ValueMonoid;
	using value_type = typename value_structure::value_type;
	using const_reference = const value_type &;
	using operator_structure = OperatorMonoid;
	using operator_type = typename operator_structure::value_type;
	using modifier_type = Modifier;
	using container_type = Container<::std::pair<value_type, operator_type>>;
	using size_type = typename container_type::size_type;

private:
	size_type size_, height;
	container_type c;
	static size_type getheight(const size_type size) noexcept {
		size_type ret = 0;
		while (static_cast<size_type>(1) << ret < size)
			++ret;
		return ret;
	}
	static value_type reflect(typename container_type::const_reference element) {
		return modifier_type::operation(element.first, element.second);
	}
	void recalc(const size_type index) {
		c[index].first = value_structure::operation(reflect(c[index << 1]),
			reflect(c[index << 1 | 1]));
	}
	static void assign(operator_type &element, const operator_type &data) {
		element = operator_structure::operation(element, data);
	}
	void push(const size_type index) {
		assign(c[index << 1].second, c[index].second);
		assign(c[index << 1 | 1].second, c[index].second);
		c[index].second = operator_structure::identity();
	}
	void propagate(const size_type index) {
		for (size_type i = height; i; --i)
			push(index >> i);
	}
	void thrust(const size_type index) {
		c[index].first = reflect(c[index]);
		push(index);
	}
	void evaluate(const size_type index) {
		for (size_type i = height; i; --i)
			thrust(index >> i);
	}
	void build(size_type index) {
		while (index >>= 1)
			recalc(index);
	}
	size_type base_size() const { return static_cast<size_type>(1) << height; }

public:
	lazy_segment_tree() : size_(0), height(0), c() {}
	explicit lazy_segment_tree(const size_type size)
		: size_(size), height(getheight(size_)),
		c(static_cast<size_type>(1) << (height + 1),
		{ value_structure::identity(), operator_structure::identity() }) {}

	bool empty() const { return !size_; }
	size_type size() const { return size_; }

	const_reference operator[](size_type index) {
		assert(index < size());
		index += base_size();
		evaluate(index);
		c[index].first = reflect(c[index]);
		c[index].second = operator_structure::identity();
		return c[index].first;
	}
	const_reference at(size_type index) {
		if (index < size()) {
			throw ::std::out_of_range("index out of range");
		}
		else {
			index += base_size();
			evaluate(index);
			c[index].first = reflect(c[index]);
			c[index].second = operator_structure::identity();
			return c[index].first;
		}
	}
	value_type fold(size_type first, size_type last) {
		assert(first <= last);
		assert(first <= size());
		assert(last <= size());
		first += base_size();
		last += base_size();
		evaluate(first);
		evaluate(last - 1);
		value_type retL = value_structure::identity(),
			retR = value_structure::identity();
		for (; first < last; first >>= 1, last >>= 1) {
			if (first & 1)
				retL = value_structure::operation(retL, reflect(c[first++]));
			if (last & 1)
				retR = value_structure::operation(reflect(c[last - 1]), retR);
		}
		return value_structure::operation(retL, retR);
	}
	template <class F> size_type search(const F &f) {
		if (f(value_structure::identity()))
			return static_cast<size_type>(0);
		if (!f(reflect(c[1])))
			return size() + 1;
		value_type acc = value_structure::identity();
		size_type i = 1;
		while (i < base_size()) {
			thrust(i);
			if (!f(value_structure::operation(acc, reflect(c[i <<= 1]))))
				acc = value_structure::operation(acc, reflect(c[i++]));
		}
		return i - base_size() + 1;
	}

	void update(const size_type index, const value_type &data) {
		assert(index < size());
		index += base_size();
		propagate(index);
		c[index].first = data;
		c[index].second = operator_structure::identity();
		build(index);
	}
	void update(size_type first, size_type last, const operator_type &data) {
		assert(first <= last);
		assert(first <= size());
		assert(last <= size());
		first += base_size();
		last += base_size();
		propagate(first);
		propagate(last - 1);
		for (size_type left = first, right = last; left < right;
			left >>= 1, right >>= 1) {
			if (left & 1)
				assign(c[left++].second, data);
			if (right & 1)
				assign(c[right - 1].second, data);
		}
		build(first);
		build(last - 1);
	}
};

#include <algorithm>
#include <limits>
template <class T> class min_monoid {
public:
	using value_type = T;
	static value_type operation(const value_type &x, const value_type &y) {
		return ::std::min(x, y);
	}
	static value_type identity() {
		return ::std::numeric_limits<value_type>::max();
	}
	static value_type reverse(const value_type &x) { return x; }
};

template <class T> class plus_monoid {
public:
	using value_type = T;
	static value_type operation(const value_type &x, const value_type &y) {
		return x + y;
	}
	static value_type identity() { return value_type(0); }
	static value_type reverse(const value_type &x) { return x; }
};

template <class T> class static_plus {
public:
	using value_type = T;
	static value_type operation(const value_type &x, const value_type &y) {
		return x + y;
	}
};

#include <cstdio>
#include <vector>

template<class T> using vec_alias = ::std::vector<T>;

int main() {
	using uint = unsigned int;

	uint n, q;
	scanf("%u%u", &n, &q);

	lazy_segment_tree<
		min_monoid<int>,
		plus_monoid<int>,
		static_plus<int>,
		vec_alias> seg(n);
	seg.update(0, seg.size(), -seg[0]);

	uint c, s, t;
	int x;
	while (q--) {
		scanf("%u%u%u", &c, &s, &t);

		if (c) {
			printf("%d\n", seg.fold(s, t + 1));
		}
		else {
			scanf("%d", &x);
			seg.update(s, t + 1, x);
		}
	}

	return 0;
}



Measured memory_bytes: 4556