#define	_CRT_SECURE_NO_WARNINGS
#define	_USE_MATH_DEFINES
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <cassert>
#include <cstdio>
#include <ctime>
#include <iostream>
#include <utility>
#include <string>
#include <algorithm>
#include <functional>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <deque>
#include <vector>

#define	mp	make_pair

using namespace std;

typedef	long long int	ll;
typedef	long double		ld;
typedef	pair<int, int>	ii;
typedef	vector<int>		vi;
typedef	vector<ii>		vii;

const int MAXN = 200000;
const int INF = 1000000010;

int N, Q;
ll D[MAXN], K[MAXN];
ll X[MAXN], Y[MAXN];
ll U[MAXN], V[MAXN];
set<pair<ll, int>> s;
pair<ll, ll> ans[MAXN];
int lb[MAXN], rb[MAXN];
int lib[MAXN], rib[MAXN];
int stn = 0;
int st[MAXN];

int id[MAXN];

bool cmp(int idl, int idr) {
	return X[idl] < X[idr];
}

ll t[4 * MAXN];
ll tp[4 * MAXN];

void build_tree(int v = 0, int l = 0, int r = Q - 1) {
	tp[v] = -INF;

	if (l == r) {
		t[v] = X[id[l]];
	}
	else {
		build_tree(2 * v + 1, l, (l + r) / 2);
		build_tree(2 * v + 2, (l + r) / 2 + 1, r);
		t[v] = min(t[2 * v + 1], t[2 * v + 2]);
	}
}

void make_push(int v, ll val) {
	t[v] = min(t[v], val);
	if (tp[v] == -INF)
		tp[v] = val;
	else
		tp[v] = min(tp[v], val);
}

void update(int ql, int qr, ll qv, int v = 0, int l = 0, int r = Q - 1) {
	if (qr < l || r < ql)
		return;

	if (tp[v] != -INF) {
		if (l != r) {
			make_push(2 * v + 1, tp[v]);
			make_push(2 * v + 2, tp[v]);
		}

		tp[v] = -INF;
	}

	if (ql <= l && r <= qr) {
		make_push(v, qv);
	}
	else {
		update(ql, qr, qv, 2 * v + 1, l, (l + r) / 2);
		update(ql, qr, qv, 2 * v + 2, (l + r) / 2 + 1, r);
		t[v] = min(t[2 * v + 1], t[2 * v + 2]);
	}
}

ll get_ans(int pos, int v = 0, int l = 0, int r = Q-1) {
	if (pos < l || r < pos)
		return INF;

	if (pos <= l && r <= pos) {
		return t[v];
	}
	else {
		return min(get_ans(pos, 2 * v + 1, l, (l + r) / 2),
			get_ans(pos, 2 * v + 2, (l + r) / 2 + 1, r));
	}
}

inline int cross(ll vx, ll vy, ll ux, ll uy) {
	return vx*uy - vy*ux;
}

int main() {
#ifdef FILE_IO
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#else
	freopen("mountain.in", "r", stdin);
	freopen("mountain.out", "w", stdout);
#endif // FILE_IO

	scanf("%d %d", &N, &Q);
	X[0] = Y[0] = 0;

	for (int i = 0; i < N; i++) {
		scanf("%lld %lld", &D[i], &K[i]);
		X[i + 1] = X[i] + D[i];
		Y[i + 1] = Y[i] + D[i] * K[i];
	}

	bool flag = true;
	bool flag2 = true;
	for (int i = 0; i < Q; i++) {
		scanf("%lld %lld", &U[i], &V[i]);
		if (i && U[i] != U[i - 1])
			flag = false;
		if (i && V[i] != V[i - 1])
			flag2 = false;
	}

	if (N <= 3000 && Q <= 3000) {
		ll ui, vi;
		int ptrr, ptrl;
		for (int i = 0; i < Q; i++) {
			ui = U[i], vi = V[i];

			ptrl = ptrr = lower_bound(X, X + N + 1, ui) - X;
			if (X[ptrl] > ui)
				ptrl--;

			while (ptrr < N) {
				if (Y[ptrr] - vi > K[ptrr] * (X[ptrr] - ui))
					break;
				ptrr++;
			}

			while (ptrl > 0) {
				if (K[ptrl - 1] * (ui - X[ptrl]) > vi - Y[ptrl])
					break;
				ptrl--;
			}

			printf("%lld %lld\n", X[ptrl], X[ptrr]);
		}

#ifdef FILE_IO
		puts("");
#else
		return 0;
#endif // FILE_IO
	}

	if (flag) {
		ll ui = U[0];
		int ptrl, ptrr;
		ptrl = ptrr = lower_bound(X, X + N + 1, ui) - X;
		if (X[ptrl] > ui)
			ptrl--;

		for (int i = 0; i < Q; i++)
			s.insert(mp(V[i], i));

		while (ptrr < N) {
			while (!s.empty() && Y[ptrr] - s.begin()->first > K[ptrr] * (X[ptrr] - ui)) {
				ans[s.begin()->second].second = X[ptrr];
				s.erase(s.begin());
			}
			ptrr++;
		}

		while (!s.empty()) {
			ans[s.begin()->second].second = X[N];
			s.erase(s.begin());
		}

		for (int i = 0; i < Q; i++)
			s.insert(mp(V[i], i));

		while (ptrl > 0) {
			while (!s.empty() && K[ptrl - 1] * (ui - X[ptrl]) > s.begin()->first - Y[ptrl]) {
				ans[s.begin()->second].first = X[ptrl];
				s.erase(s.begin());
			}
			ptrl--;
		}

		while (!s.empty()) {
			ans[s.begin()->second].first = X[0];
			s.erase(s.begin());
		}

		for (int i = 0; i < Q; i++)
			printf("%lld %lld\n", ans[i].first, ans[i].second);

#ifdef FILE_IO
		puts("");
#else
		return 0;
#endif // FILE_IO
	}

	if (flag2) {
		memset(lb, -1, sizeof(lb));
		memset(rb, -1, sizeof(rb));

		for (int i = 0; i < Q; i++)
			id[i] = i;
		sort(id, id + Q);

		for (int i = 0; i <= N; i++) {
			while (stn >= 2 && cross(X[i] - X[st[stn-2]], Y[i] - Y[st[stn-2]], X[st[stn - 1]] - X[st[stn-2]], Y[st[stn - 1]] - Y[st[stn-2]]) < 0) {
				stn--;
			}
			if (stn)
				lb[i] = st[stn - 1];
			st[stn++] = i;
		}

		stn = 0;
		for (int i = 0; i <= N; i++) {
			while (stn >= 2 && cross(X[i] - X[st[stn - 2]], Y[i] - Y[st[stn - 2]], X[st[stn - 1]] - X[st[stn - 2]], Y[st[stn - 1]] - Y[st[stn - 2]]) > 0) {
				stn--;
			}
			if (stn)
				lb[i] = st[stn - 1];
			st[stn++] = i;
		}

		build_tree();
		int l, r, md;
		for (int i = 0; i <= N; i++) {
			l = 0, r = Q - 1;
			if (i == 0) {
				lib[i] = 0;
			}
			else {
				while (lb < rb) {
					md = (l + r) / 2;
					if (cross(X[lb[i]] - X[i], Y[lb[i]] - Y[i], U[id[md]] - X[i], V[id[md]] - Y[i]) <= 0)
						r = md;
					else
						l = md + 1;
				}
				lib[i] = l;
			}

			if (i == N) {
				rib[i] = Q-1;
			}
			else {
				while (lb < rb) {
					md = (l + r + 1) / 2;

					if (cross(X[lb[i]] - X[i], Y[lb[i]] - Y[i], U[id[md]] - X[i], V[id[md]] - Y[i]) >= 0)
						l = md;
					else
						r = md - 1;
				}
				rib[i] = l;
			}

			if (lib[i] <= rib[i])
				update(lib[i], rib[i], X[i]);
		}

		for (int i = 0; i < Q; i++) {
			ans[id[i]].first = get_ans(i);
			X[id[i]] = -X[id[i]];
		}

		sort(id, id + Q);

		build_tree();
		for (int i = 0; i <= N; i++) {
			if (lib[i] <= rib[i])
				update(lib[i], rib[i], -X[i]);
		}

		for (int i = 0; i < Q; i++) {
			ans[id[i]].second = -get_ans(i);
		}

		for (int i = 0; i < Q; i++)
			printf("%lld %lld\n", ans[i].first, ans[i].second);

		return 0;
	}
	
	assert(1 == 0);

	return 0;
}
