//最悪O(Q^2) 最短O(N+Q)
//番号→名簿番号(hashT[]から検索) 名簿番号→番号(meibo2[]から検索)
#include<iostream>
#include<vector>
using namespace std;
typedef pair<int,int> P;

struct Pos{
	int num,cnt;
};
int N,Q;
int hashT[1000001];
int meibo[100000],meibo2[100000],mcor = 0;	//mcor = 登録人数,meibo[] = cnt,meibo2[] = num;
vector<P> ans;

int main(){
	int i;
	Pos pos;
	cin >> N >> Q;
	for(i = 1;i <= N;i++){
		hashT[i] = -1;
	}
	//pos(ランキング1位)の初期化っぽいこと
	{
		int a,b;
		cin >> a >> b;
		hashT[a] = mcor;
		meibo[mcor] = b;
		meibo2[mcor] = a;
		pos.num = a;
		pos.cnt = b;
		ans.push_back(P(a,b));
		mcor++;
	}
	//2回目の大会から
	for(i = 1;i < Q;i++){
		int a,b;
		cin >> a >> b;
		//meiboに登録されていなければ登録
		if(hashT[a] == -1){
			hashT[a] = mcor;
			meibo[mcor] = b;
			meibo2[mcor] = a;
			mcor++;
		}
		//登録されていたら指定された所を更新
		else{
			meibo[hashT[a]] += b;
		}
		//現在の1位の魚の数の更新
		pos.cnt = meibo[hashT[pos.num]];
		//今の更新について
		//1位のキャッチ、1位以外のリリースなら順位はそのまま
		if((b > 0 && a == pos.num) || (b < 0 && a != pos.num))
			goto SAVEPOS;
		//1位以外のキャッチの場合
		else if(b > 0){
			//今キャッチした人と今の1位を比べる
			if((meibo[hashT[a]] > pos.cnt)||(a < pos.num && meibo[hashT[a]] == pos.cnt)){
				//最高記録の塗り替え
				pos.num = a;
				pos.cnt = meibo[hashT[a]];
			}
		}
		//1位のリリースの場合
		else if(b < 0){
			//最高記録を愚直に調べる。(記録を調べる順番は番号昇順でなくてもよいはず(任意のはず))
			for(int j = 0;j < mcor;j++){
				if((meibo[j] == pos.cnt && meibo2[j] < pos.cnt)||(meibo[j] > pos.cnt)){
					pos.num = meibo2[j];
					pos.cnt = meibo[j];
				}
			}
		}
SAVEPOS:
		ans.push_back(P(pos.num,pos.cnt));
	}
	int size = ans.size();
	for(i = 0;i < size;i++){
		cout << ans[i].first << " " << ans[i].second << endl;
	}
	return 0;
}