/*
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
using ll = long long;
const int N = 1505, M = 405, mod[3] = {998244353, 1004535809, 469762049}, G = 3, p = 1e9 + 7;
const ll mod01 = 1ll * mod[0] * mod[1];
int n, m, q, limit = 1, L, r[M];
int a[N][M][3], b[M][3], ans[M][3], Wn[M][3], INV[N][M][3];
int fastpow(int base, int p, const int &mod){
int res = 1;
while(p){
if(p & 1) res = 1ll * res * base % mod;
base = 1ll * base * base % mod;
p >>= 1;
}
return res;
}
const int inv[2] = {fastpow(mod[0], mod[1] - 2, mod[1]), fastpow(mod01 % mod[2], mod[2] - 2, mod[2])};
void NTT(int A[M][3], int type){
for(int i = 0; i < limit; i ++)
if(i < r[i])
for(int now = 0; now < 3; now ++)
swap(A[i][now], A[r[i]][now]);
for(int mid = 1; mid < limit; mid <<= 1){
int t = limit / mid >> 1;
for(int j = 0; j < limit; j += (mid << 1)){
for(int k = 0; k < mid; k ++){
for(int now = 0; now < 3; now ++){
int w = (type == 1 ? Wn[t * k][now] : Wn[limit - t * k][now]);
int x = A[j + k][now], y = 1ll * w * A[j + k + mid][now] % mod[now];
A[j + k][now] = (x + y) % mod[now], A[j + k + mid][now] = (x - y + mod[now]) % mod[now];
}
}
}
}
}
int main(){
ios::sync_with_stdio(0),cin.tie(0);
cin >> n >> m >> q;
while(limit <= m) limit <<= 1, L ++;
for(int i = 0; i < limit; i ++)
r[i] = (r[i >> 1] >> 1) | ((i & 1) << (L - 1));
int temp[3];
temp[0] = fastpow(G, (mod[0] - 1) / limit, mod[0]);
temp[1] = fastpow(G, (mod[1] - 1) / limit, mod[1]);
temp[2] = fastpow(G, (mod[2] - 1) / limit, mod[2]);
Wn[0][0] = Wn[0][1] = Wn[0][2] = 1;
for(int i = 1; i <= limit; i ++)
for(int now = 0; now < 3; now ++)
Wn[i][now] = 1ll * Wn[i - 1][now] * temp[now] % mod[now];
for(int i = m; ~i; i --){
cin >> b[i][0];
b[i][0] %= p;
b[i][1] = b[i][2] = b[i][0];
}
NTT(b, 1);
a[0][0][0] = a[0][0][1] = a[0][0][2] = 1;
NTT(a[0], 1);
for(int j = 0; j < limit; j ++){
for(int now = 0; now < 3; now ++)
INV[0][j][now] = fastpow(a[0][j][now], mod[now] - 2, mod[now]);
}
for(int i = 1; i <= n; i ++){
for(int j = 0; j <= m; j ++){
cin >> a[i][j][0];
a[i][j][0] %= p;
a[i][j][1] = a[i][j][2] = a[i][j][0];
}
NTT(a[i], 1);
for(int j = 0; j < limit; j ++){
for(int now = 0; now < 3; now ++){
a[i][j][now] = 1ll * a[i-1][j][now] * a[i][j][now] % mod[now];
INV[i][j][now] = fastpow(a[i][j][now], mod[now] - 2, mod[now]);
}
}
}
temp[0] = fastpow(limit, mod[0] - 2, mod[0]);
temp[1] = fastpow(limit, mod[1] - 2, mod[1]);
temp[2] = fastpow(limit, mod[2] - 2, mod[2]);
int l, r;
ll k0, k3, x3, res;
while(q --){
cin >> l >> r;
for(int j = 0; j < limit; j ++){
for(int now = 0; now < 3; now ++)
ans[j][now] = 1ll * a[r][j][now] * INV[l-1][j][now] % mod[now] * b[j][now] % mod[now];
}
NTT(ans, -1);
for(int now = 0; now < 3; now ++)
ans[m][now] = 1ll * ans[m][now] * temp[now] % mod[now];
k0 = 1ll * ((ans[m][1] - ans[m][0]) % mod[1] + mod[1]) % mod[1] * inv[0] % mod[1];
x3 = (ans[m][0] + k0 * mod[0]) % mod01;
k3 = 1ll * ((ans[m][2] - x3) % mod[2] + mod[2]) % mod[2] * inv[1] % mod[2];
res = (x3 + k3 * mod[0] % p * mod[1] % p) % p;
cout << res << '\n';
}
return 0;
}
*/
/*
3 3 3
4 3 2 1
0 1 0 1000000007
0 500000004 0 500000004
0 0 500000004 500000004
1 1
1 2
1 3
3 3 6
4 3 2 1
1000000007 0 1 0
1000000007 1 0 0
1000000007 0 1 0
1 1
1 2
1 3
2 2
2 3
3 3
*/
#include <bits/stdc++.h>
using namespace std;
#define SZ(x) ((int)((x).size()))
typedef long long ll;
namespace Polynomial {
const int Mod[] = {469762049, 998244353, 1004535809};
const int G = 3;
template<int mod>
class Modint {
private:
unsigned int x;
public:
Modint() = default;
Modint(unsigned int x): x(x) {}
unsigned int getx() { return x; }
friend istream& operator >> (istream& in, Modint& a) {return in >> a.x;}
friend ostream& operator << (ostream& out, Modint a) {return out << a.x;}
friend Modint operator + (Modint a, Modint b) {return (a.x + b.x) % mod;}
friend Modint operator - (Modint a, Modint b) {return (a.x - b.x + mod) % mod;}
friend Modint operator * (Modint a, Modint b) {return 1ULL * a.x * b.x % mod;}
friend Modint operator / (Modint a, Modint b) {return a * ~b;}
friend Modint operator ^ (Modint a, int b) {Modint ans = 1; for(; b; b >>= 1, a *= a) if(b & 1) ans *= a; return ans;}
friend Modint operator ~ (Modint a) {return a ^ (mod - 2);}
friend Modint operator - (Modint a) {return (mod - a.x) % mod;}
friend Modint& operator += (Modint& a, Modint b) {return a = a + b;}
friend Modint& operator -= (Modint& a, Modint b) {return a = a - b;}
friend Modint& operator *= (Modint& a, Modint b) {return a = a * b;}
friend Modint& operator /= (Modint& a, Modint b) {return a = a / b;}
friend Modint& operator ^= (Modint& a, int b) {return a = a ^ b;}
friend Modint& operator ++ (Modint& a) {return a += 1;}
friend Modint operator ++ (Modint& a, int) {Modint x = a; a += 1; return x;}
friend Modint& operator -- (Modint& a) {return a -= 1;}
friend Modint operator -- (Modint& a, int) {Modint x = a; a -= 1; return x;}
friend bool operator == (Modint a, Modint b) {return a.x == b.x;}
friend bool operator != (Modint a, Modint b) {return !(a == b);}
};
typedef Modint<469762049> mintp0;
typedef Modint<998244353> mintp1;
typedef Modint<1004535809> mintp2;
void init_convo(vector<int>& rev, int& lim, int n, int m) {
int s = 0;
for (lim = 1; lim <= n + m; lim <<= 1, s++);
rev.resize(lim);
for (int i = 0; i < lim; i++) {
rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (s - 1));
}
}
template <typename mint>
void NTT(vector<mint>& f, vector<int>& rev, int lim, int type, int mod) {
f.resize(lim, 0);
for (int i = 0; i < lim; i++) {
if (i < rev[i]) {
swap(f[i], f[rev[i]]);
}
}
for (int i = 1; i < lim; i <<= 1) {
mint mul = (mint)G ^ ((mod - 1) / (i << 1));
if (type == -1) {
mul = ~mul;
}
for (int j = 0; j < lim; j += (i << 1)) {
mint w = 1;
for (int k = 0; k < i; k++, w *= mul) {
mint x = f[j + k], y = w * f[j + k + i];
f[j + k] = x + y;
f[j + k + i] = x - y;
}
}
}
}
template <typename mint>
vector<mint> convolution(vector<mint> f, vector<mint> g, int mod) {
int n = SZ(f) - 1, m = SZ(g) - 1, lim;
vector<int> rev;
init_convo(rev, lim, n, m);
NTT(f, rev, lim, 1, mod);
NTT(g, rev, lim, 1, mod);
vector<mint> h(lim);
for (int i = 0; i < lim; i++) {
h[i] = f[i] * g[i];
}
NTT(h, rev, lim, -1, mod);
mint invlim = ~(mint)lim;
for (int i = 0; i < lim; i++) {
h[i] = h[i] * invlim;
}
h.resize(n + m + 1);
return h;
}
ll ksm(ll x, ll y, ll mod) {
ll res = 1;
while (y) {
if (y & 1) {
res = res * x % mod;
}
x = x * x % mod;
y >>= 1;
}
return res;
}
ll inv(ll x, ll mod) {
return ksm(x, mod - 2, mod);
}
ll mul(ll a, ll b, ll mod){
return (a * b - (ll)((long double)a / mod * b) * mod + mod) % mod;
}
vector<int> convolution(const vector<int>& f, const vector<int>& g, int mod) {
int n = SZ(f) - 1, m = SZ(g) - 1;
vector res(3, vector(n + m + 1, 0));
{
vector<mintp0> F, G;
F.resize(n + 1);
G.resize(m + 1);
for (int i = 0; i <= n; i++) {
F[i] = f[i];
}
for (int i = 0; i <= m; i++) {
G[i] = g[i];
}
auto cur = convolution(F, G, Mod[0]);
for (int i = 0; i <= n + m; i++) {
res[0][i] = cur[i].getx();
}
}
{
vector<mintp1> F, G;
F.resize(n + 1);
G.resize(m + 1);
for (int i = 0; i <= n; i++) {
F[i] = f[i];
}
for (int i = 0; i <= m; i++) {
G[i] = g[i];
}
auto cur = convolution(F, G, Mod[1]);
for (int i = 0; i <= n + m; i++) {
res[1][i] = cur[i].getx();
}
}
{
vector<mintp2> F, G;
F.resize(n + 1);
G.resize(m + 1);
for (int i = 0; i <= n; i++) {
F[i] = f[i];
}
for (int i = 0; i <= m; i++) {
G[i] = g[i];
}
auto cur = convolution(F, G, Mod[2]);
for (int i = 0; i <= n + m; i++) {
res[2][i] = cur[i].getx();
}
}
vector<int> h;
h.resize(n + m + 1);
ll p0 = Mod[0], p1 = Mod[1], p2 = Mod[2];
ll k0 = inv(p1, p0), k1 = inv(p0, p1);
ll ip0 = inv(p0, p2), ip1 = inv(p1, p2);
for (int i = 0; i <= n + m; i++) {
ll a0 = res[0][i], a1 = res[1][i], a2 = res[2][i];
ll m = p0 * p1;
ll a3 = (mul(a0, mul(k0, p1, m), m) + mul(a1, mul(k1, p0, m), m)) % m;
ll a4 = mul(mul(((a2 - a3) % p2 + p2) % p2, ip0, p2), ip1, p2);
h[i] = (mul(mul(a4, p0, mod), p1, mod) + a3) % mod;
}
return h;
}
}
using Polynomial::convolution;
using Polynomial::inv;
const int MAXN = 1510;
const int Mod = 1e9 + 7;
int cntx[MAXN];
vector<int> pre[MAXN], ipre[MAXN], preb[MAXN];
void solve() {
int n, m, q;
cin >> n >> m >> q;
vector b(m + 1, 0);
for (int i = 0; i <= m; i++) {
cin >> b[i];
}
vector p(n + 1, vector(m + 1, 0));
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= m; j++) {
cin >> p[i][j];
p[i][j] %= Mod;
}
}
pre[0].resize(m + 1, 0);
pre[0][0] = 1;
for (int i = 1; i <= n; i++) {
pre[i] = convolution(pre[i - 1], p[i], Mod);
pre[i].resize(m + 1);
int p = 0;
for (int j = 0; j <= m; j++) {
if (pre[i][j] == 0) {
p = j + 1;
}
else {
break;
}
}
for (int j = 0; j <= m - p; j++) {
pre[i][j] = pre[i][j + p];
}
for (int j = m - p + 1; j <= m; j++) {
pre[i][j] = 0;
}
cntx[i] = cntx[i - 1] + p;
}
reverse(b.begin(), b.end());
for (int i = 1; i <= n; i++) {
preb[i] = convolution(pre[i], b, Mod);
preb[i].resize(m + 1);
}
auto getinv = [&](vector<int> f) -> vector<int> {
vector g(m + 1, 0);
int if0 = inv(f[0], Mod);
g[0] = if0;
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= i; j++) {
g[i] = (g[i] + 1ll * f[j] * g[i - j]) % Mod;
}
g[i] = 1ll * (Mod - g[i]) * if0 % Mod;
}
return g;
};
for (int i = 0; i <= n; i++) {
ipre[i] = getinv(pre[i]);
}
while (q--) {
int l, r;
cin >> l >> r;
int res = 0;
int k = m - (cntx[r] - cntx[l - 1]);
for (int i = 0; i <= k; i++) {
res = (res + 1ll * preb[r][i] * ipre[l - 1][k - i]) % Mod;
}
cout << res << '\n';
}
}
int main() {
// freopen("data.in", "r", stdin);
// freopen("std.out", "w", stdout);
// clock_t st = clock();
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int T = 1;
while (T--) solve();
// cerr << clock() - st << '\n';
return 0;
}