#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <deque>
#include <ctime>
#include <cassert>
#include <cmath>

#pragma comment(linker, "/STACK:256000000")

using namespace std;

typedef long long int ll;
typedef long double ld;
const int MAX_N = 400 * 1000 + 5;

struct point
{
	ll x;
	ll y;
	int number;
	pair<ll, ll> answer;

	point()
	{
		x = 0;
		y = 0;
	}

	point(ll _x, ll _y)
	{
		x = _x;
		y = _y;
	}
};

bool operator< (const point &a, const point &b)
{
	return a.x < b.x;
}

point operator+ (const point &a, const point &b)
{
	return point(a.x + b.x, a.y + b.y);
}

point operator- (const point &a, const point &b)
{
	return point(a.x - b.x, a.y - b.y);
}

ll operator* (const point &a, const point &b)
{
	return a.x*b.y - a.y*b.x;
}

ll operator% (const point &a, const point &b)
{
	return a.x*b.x + a.y*b.y;
}

int n, q;
point arr[MAX_N];
point asks[MAX_N];
set<ll> at_x;
set<ll> at_y;
vector<int> more;
vector<point> gg;

void get_ans(point p)
{
	int ptr = upper_bound(arr, arr + n, p) - arr;
	
	int l = ptr - 1;
	int r = ptr;

	if (arr[r].x == p.x)
	{
		++r;
	}

	point p1, p2;
	while (r < n - 1)
	{
		p1 = arr[r] - p;
		p2 = arr[r + 1] - p;
		if (p1*p2 < 0)
		{
			break;
		}
		++r;
	}
	while (l > 0)
	{
		p1 = arr[l] - p;
		p2 = arr[l - 1] - p;
		if (p1*p2 > 0)
		{
			break;
		}
		--l;
	}
	//cout << l << " " << r << endl;
	printf("%lld %lld\n", arr[max(l, 0)].x, arr[min(r, n - 1)].x);
}

int ll1, rr;
void get_ans2(point &p)
{
	//int ptr = upper_bound(arr, arr + n, p) - arr;

	//int l = ptr - 1;
	//int r = ptr;

	//if (arr[r].x == p.x)
	//{
	//	++r;
	//}

	point p1, p2;
	while (rr < n - 1)
	{
		p1 = arr[rr] - p;
		p2 = arr[rr + 1] - p;
		if (p1*p2 < 0)
		{
			break;
		}
		++rr;
	}
	while (ll1 > 0)
	{
		p1 = arr[ll1] - p;
		p2 = arr[ll1 - 1] - p;
		if (p1*p2 > 0)
		{
			break;
		}
		--ll1;
	}

	p.answer.first = arr[max(ll1, 0)].x;
	p.answer.second = arr[min(rr, n - 1)].x;
}

void get_ans3(point &p)
{
	int ptr = upper_bound(arr, arr + n, p) - arr;

	int l = ptr - 1;
	int r = ptr;

	if (arr[r].x == p.x)
	{
		++r;
	}

	ll1 = l;
	rr = r;// max(rr, r);

	point p1, p2;
	while (rr < n - 1)
	{
		p1 = arr[rr] - p;
		p2 = arr[rr + 1] - p;
		if (p1*p2 < 0)
		{
			break;
		}
		++rr;
	}
	while (ll1 > 0)
	{
		p1 = arr[ll1] - p;
		p2 = arr[ll1 - 1] - p;
		if (p1*p2 > 0)
		{
			break;
		}
		--ll1;
	}

	p.answer.first = arr[max(ll1, 0)].x;
	p.answer.second = arr[min(rr, n - 1)].x;
}

bool cmp1(const point &a, const point &b)
{
	return a.y < b.y;
}

bool cmp2(const point &a, const point &b)
{
	return a.number < b.number;
}


int main()
{
	freopen("mountain.in", "r", stdin);
	freopen("mountain.out", "w", stdout);

	scanf("%d %d", &n, &q);

	ll d, k;
	arr[0].x = 0;
	arr[0].y = 0;

	for (int i = 0; i < n; ++i)
	{
		scanf("%lld %lld", &d, &k);
		arr[i + 1].x = arr[i].x + d;
		arr[i + 1].y = arr[i].y + d*k;
	}

	++n;


	point now;
	for (int i = 0; i < q; ++i)
	{
		scanf("%lld %lld", &asks[i].x, &asks[i].y);
		asks[i].number = i;
		//get_ans(now);
		at_x.insert(asks[i].x);
		at_y.insert(asks[i].y);
	}

	if (at_x.size() == 1)
	{
		int ptr = upper_bound(arr, arr + n, asks[0]) - arr;

		ll1 = ptr - 1;
		rr = ptr;

		if (arr[rr].x == asks[0].x)
		{
			++rr;
		}
		sort(asks, asks + q, cmp1);
		for (int i = 0; i < q; ++i)
		{
			get_ans2(asks[i]);
		}
		sort(asks, asks + q, cmp2);
		for (int i = 0; i < q; ++i)
		{
			printf("%lld %lld\n", asks[i].answer.first, asks[i].answer.second);
		}
	}
	else if (at_y.size() == 1)
	{
		//for (int i = 0; i < q; ++i)
		//{
		//	get_ans(asks[i]);
		//}
		
		for (int i = 0; i < n; ++i)
		{
			if (arr[i].y >= asks[0].y)
			{
				more.push_back(i);
			}
			if (more.size() >= 2)
			{
				if (more[(int)more.size() - 2] == more[(int)more.size() - 1] - 1)
				{
					if (arr[more[(int)more.size() - 2]].y == arr[more[(int)more.size() - 1]].y)
					{
						//swap(more[(int)more.size() - 2], more[(int)more.size() - 1]);
						more.pop_back();
					}
				}
			}
		}

		for (int i = 0; i < more.size(); ++i)
		{
			gg.push_back(arr[more[i]]);
		}

		sort(asks, asks + q);

		int ptr = upper_bound(arr, arr + n, asks[0]) - arr;

		ll1 = ptr - 1;
		rr = ptr;

		if (arr[rr].x == asks[0].x)
		{
			++rr;
		}

		for (int i = 0; i < q; ++i)
		{
			get_ans3(asks[i]);
		}
		sort(asks, asks + q, cmp2);
		for (int i = 0; i < q; ++i)
		{
			printf("%lld %lld\n", asks[i].answer.first, asks[i].answer.second);
		}
	}
	else
	{
		for (int i = 0; i < q; ++i)
		{
			get_ans(asks[i]);
		}
	}

	fclose(stdin);
	fclose(stdout);

	return 0;
}