/* template {{{ */
#include <bits/stdc++.h>
using namespace std;
using namespace rel_ops;

#define GET_MACRO(a, b, c, d, NAME, ...) NAME
#define REP2(i, n) REP3(i, 0, n)
#define REP3(i, a, b) REP4(i, a, b, 1)
#define REP4(i, a, b, s) for (ll i = (a); i < (ll)(b); i += (s))
#define RREP2(i, n) RREP3(i, 0, n)
#define RREP3(i, a, b) for (ll i = (b) - 1; i >= (ll)(a); i--)

#define rep(...) GET_MACRO(__VA_ARGS__, REP4, REP3, REP2)(__VA_ARGS__)
#define rrep(...) GET_MACRO(__VA_ARGS__,, RREP3, RREP2)(__VA_ARGS__)

#define all(c) begin(c), end(c)
#define popcount(x) __builtin_popcountll(x)

using uint = unsigned;
using ll = long long;
using ull = unsigned long long;

const int dx[] = {-1, 0, 1, 0, -1, 1, 1, -1};
const int dy[] = {0, -1, 0, 1, -1, -1, 1, 1};

template<typename T>
inline T sq(T x){
	return x * x;
}

inline ll gcd(ll x, ll y){
	return __gcd(x, y);
}

inline ll lcm(ll x, ll y){
	return x / __gcd(x, y) * y;
}

template<typename T, typename U>
inline T& chmin(T &x, U y){
	if (x > y) x = y;
	return x;
}

template<typename T, typename U>
inline T& chmax(T &x, U y){
	if (x < y) x = y;
	return x;
}

template<typename T>
inline void sort(T &c){
	sort(all(c));
}

template<typename T, typename Comp>
inline void sort(T &c, Comp comp){
	sort(all(c), comp);
}

template<typename T>
inline void reverse(T &c){
	reverse(all(c));
}

template<typename T>
inline void unique(T &c){
	sort(all(c));
	c.erase(unique(all(c)), end(c));
}

template<typename T>
inline T sorted(const T &c){
	T t(c);
	sort(t);
	return move(t);
}

template<typename T, typename Comp>
inline T sorted(const T &c, Comp comp){
	T t(c);
	sort(t, comp);
	return move(t);
}

template<typename T>
inline T reverse(const T &c){
	T t(c);
	reverse(t);
	return move(t);
}

template<typename T>
inline size_t indexof(const vector<T> &c, T x){
	return upper_bound(all(c), x) - begin(c);
}

template<size_t N, typename ...T>
typename enable_if<(N >= sizeof...(T)), void>::type
input_tuple(istream&, tuple<T...>&){
}

template<size_t N, typename ...T>
typename enable_if<(N < sizeof...(T)), void>::type
input_tuple(istream &is, tuple<T...> &t){
	is >> get<N>(t);
	input_tuple<N + 1, T...>(is, t);
}

template<typename ...T>
istream& operator>>(istream &is, tuple<T...> &t){
	input_tuple<0, T...>(is, t);
	return is;
}

template<typename T, typename U>
istream& operator>>(istream &is, pair<T, U> &t){
	return is >> t.first >> t.second;
}

template<size_t N, typename ...T>
typename enable_if<(N >= sizeof...(T)), void>::type
output_tuple(ostream &, const tuple<T...> &){
}

template<size_t N, typename ...T>
typename enable_if<(N < sizeof...(T)), void>::type
output_tuple(ostream &os, const tuple<T...> &t){
	os << (N > 0 ? " " : "") << get<N>(t);
	output_tuple<N + 1, T...>(os, t);
}

template<typename ...T>
ostream& operator<<(ostream &os, const tuple<T...> &t){
	output_tuple<0, T...>(os, t);
	return os;
}

template<typename T, typename U>
ostream& operator<<(ostream &os, const pair<T, U> &t){
	return os << t.first << " " << t.second;
}
/* }}} */
/* segment_tree.cpp {{{ */
#include <vector>
#include <algorithm>
#include <limits>
#include <functional>
#include <iterator>

namespace ktlib {
namespace segtree {
/* SegmentTree {{{ */
template<typename Traits>
class SegmentTree {
public:
	using value_type = typename Traits::value_type;
	 
	SegmentTree(int n = 0, const Traits &traits = Traits()): traits(traits){
		for (size = 1; size < n; size <<= 1);
		value.assign(size * 2 - 1, this->traits.initial());
		index.resize(size * 2 - 1);
		build();
	}
	
	template<typename RandomAccessIterator>
	SegmentTree(RandomAccessIterator first, RandomAccessIterator last, const Traits &traits = Traits()): traits(traits){
		int n = std::distance(first, last);
		for (size = 1; size < n; size <<= 1);
		value.assign(size * 2, this->traits.initial());
		std::copy(first, last, std::next(std::begin(value), size - 1));
		index.resize(size * 2);
		build();
	}

	value_type query(int left, int right) const {
		return query(left, right, 0, 0, size);
	};

	int queryIndex(int left, int right) const {
		return queryIndex(left, right, 0, 0, size);
	}

	void update(int k, const value_type &x){
		k += size - 1;
		value[k] = x;
		while (k > 0){
			k = (k - 1) / 2;
			value[k] = traits.merge(value[k * 2 + 1], value[k * 2 + 2]);
			index[k] = traits.compare(value[k * 2 + 1], value[k * 2 + 2]) ? index[k * 2 + 1] : index[k * 2 + 2];
		}
	}

private:
	void build(){
		for (int i = 0; i <= size; i++) index[i + size - 1] = i;
		for (int i = size - 2; i >= 0; i--){
			value[i] = traits.merge(value[i * 2 + 1], value[i * 2 + 2]);
			index[i] = traits.compare(value[i * 2 + 1], value[i * 2 + 2]) ? index[i * 2 + 1] : index[i * 2 + 2];
		}
	}

	value_type query(int l, int r, int k, int a, int b) const {
		if (r <= a || b <= l) return traits.initial();
		if (l <= a && b <= r) return value[k];
		int m = (a + b) / 2;
		auto vl = query(l, r, k * 2 + 1, a, m);
		auto vr = query(l, r, k * 2 + 2, m, b);
		return traits.merge(vl, vr);
	}

	int queryIndex(int l, int r, int k, int a, int b) const {
		if (r <= a || b <= l) return index.back(); // nil
		if (l <= a && b <= r) return index[k];
		int m = (a + b) / 2;
		int vl = queryIndex(l, r, k * 2 + 1, a, m);
		int vr = queryIndex(l, r, k * 2 + 2, m, b);
		return traits.compare(value[vl + size - 1], value[vr + size - 1]) ? vl : vr;
	}

	Traits traits;
	int size;
	std::vector<value_type> value;
	std::vector<int> index;
};
/* }}} */
/* RangeMinimumTraits {{{ */
template<typename T, typename Compare = std::less<T>>
struct RangeMinimumTraits {
	using value_type = T;

	value_type initial() const {
		return 0;
		// return std::numeric_limits<T>::max() / 2;
	}

	value_type merge(const T &a, const T &b) const {
		return std::min(a, b, comp);
	}

	// operator <=
	bool compare(const T &a, const T &b) const {
		return !comp(b, a);
	}

private:
	Compare comp;
};
/* }}} */
/* RangeSumTraits {{{ */
template<typename T, typename Operator = std::plus<T>>
struct RangeSumTraits {
	using value_type = T;

	value_type initial() const {
		return 0;
	}

	value_type merge(const T &a, const T &b) const {
		return op(a, b);
	}

	// ?????¨?????????
	bool compare(const T &a, const T &b) const {
		return true;
	}

private:
	Operator op;
};
/* }}} */
} /* namespace segtree */
} /* namespace ktlib */
/* }}} */

signed main()
{
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	using namespace ktlib::segtree;

	int n, q;
	cin >> n >> q;
	vector<int> a(n, 0);
	SegmentTree<RangeMinimumTraits<int, greater<int>>> tr(begin(a), end(a));
	for (int i = 0; i < q; i++){
		int x, y;
		cin >> x >> y, x--;
		tr.update(x, a[x] += y);
		cout << tr.queryIndex(0, n) + 1 << " " << tr.query(0, n) << endl;
	}
}

Measured memory_bytes: 23208