# include <stdio.h>
const long int MAXN = 110;
const long int MAXK = 10000;
const long int GATE = 2;
const long int FINISH = 3;
const long int START = 4;
const long int vx[5] = {0,-1,0,1,0};
const long int vy[5] = {0,0,1,0,-1};
long int n,m,k;
typedef long int TIMETABLE[MAXN + 1][MAXN + 1];
typedef int (*FUNCTIE)(const void *p);
TIMETABLE map,nogate,startgate,finishgate,nogatecount,startgatecount,finishgatecount;
typedef struct NOD{
long int x,y;
} NOD;
typedef struct COADA{
long int prim,ultim;
NOD v[MAXN*MAXN + 1];
} COADA;
COADA c;
NOD poarta[MAXK + 1];
void push(COADA &c, long int x, long int y)
{
c.ultim ++;
c.v[c.ultim].x = x;
c.v[c.ultim].y = y;
}
NOD pop(COADA &c)
{
c.prim ++;
return c.v[c.prim - 1];
}
int allowed_no_gate(const void *p)
{
NOD a = *((NOD*)p);
if (a.x <= 0 || a.y <= 0 || a.x > n || a.y > m || map[a.x][a.y] == START)
return 0;
return 1;
}
int allowed_yes_gate(const void *p)
{
NOD a = *((NOD*)p);
if (a.x <= 0 || a.y <= 0 || a.x > n || a.y > m || map[a.x][a.y] == FINISH || map[a.x][a.y] == START)
return 0;
return 1;
}
void scrie(long int ii, long int jj, TIMETABLE &a, char *sir)
{
long int i,j;
printf("%s\n",sir);
for (i = 1;i <= ii;i ++){
for (j = 1;j <= jj;j ++)
printf("%ld ",a[i][j]);
printf("\n");
}
fflush(stdin);
getchar();
}
void fill(long int xi, long int yi, long int DEST, TIMETABLE &time, TIMETABLE &count,FUNCTIE allowed_condition)
{
c.prim = 1;
c.ultim = 0;
NOD nod,nou;
push(c,xi,yi);
count[xi][yi] = 1;
long int timer = 0,dir;
do{
nod = pop(c);
if (timer && time[nod.x][nod.y] == timer)
break;
for (dir = 1;dir <= 4;dir ++){
nou.x = nod.x + vx[dir];
nou.y = nod.y + vy[dir];
if (allowed_condition(&nou))
if (time[nou.x][nou.y] == 0){
time[nou.x][nou.y] = time[nod.x][nod.y] + 1;
count[nou.x][nou.y] = count[nod.x][nod.y];
push(c,nou.x,nou.y);
if (timer == 0 && map[nou.x][nou.y] == DEST)
timer = time[nou.x][nou.y];
}
else if (time[nou.x][nou.y] == time[nod.x][nod.y] + 1){
count[nou.x][nou.y] += count[nod.x][nod.y];
count[nou.x][nou.y] %= 997;
}
}
}while (1);
}
int main()
{
FILE *f = fopen("poarta.in","r");
fscanf(f,"%ld%ld%ld",&n,&m,&k);
long int xi,yi,xf,yf;
fscanf(f,"%ld%ld",&xi,&yi);
map[xi][yi] = START;
fscanf(f,"%ld%ld",&xf,&yf);
map[xf][yf] = FINISH;
long int i;
for (i = 1;i <= k;i ++){
fscanf(f,"%ld%ld",&poarta[i].x,&poarta[i].y);
map[poarta[i].x][poarta[i].y] = GATE;
}
fill(xi,yi,FINISH,nogate,nogatecount,allowed_no_gate);
if (k){
startgate[xi][yi] = 1;
fill(xi,yi,GATE,startgate,startgatecount,allowed_yes_gate);
fill(xf,yf,GATE,finishgate,finishgatecount,allowed_yes_gate);
}
/*consideram solutia cea fara porti*/
long int dmin,nrdmin,dminsg,nrdminsg,dminfg,nrdminfg;
nrdminsg = 0;
nrdminfg = 0;
/*acest comentariu
* este pe
* mai multe
* liniii si contine spatii
*/
dmin = nogate[xf][yf];
nrdmin = nogatecount[xf][yf];
if (k){
for (i = 1;i <= k;i ++){
if (startgate[poarta[i].x][poarta[i].y]){
dminsg = startgate[poarta[i].x][poarta[i].y];
nrdminsg += startgatecount[poarta[i].x][poarta[i].y];
}
if (finishgate[poarta[i].x][poarta[i].y]){
dminfg = finishgate[poarta[i].x][poarta[i].y];
nrdminfg += finishgatecount[poarta[i].x][poarta[i].y];
}
}
if (dminsg + dminfg<dmin){
dmin = dminsg + dminfg;
nrdmin = (nrdminsg * nrdminfg) % 997;
}
else if (dminsg + dminfg == dmin){
nrdmin += nrdminsg * nrdminfg;
nrdmin %= 997;
}
}
FILE *g = fopen("poarta.out","w");
fprintf(g,"%ld\n%ld\n",dmin,nrdmin);
fclose(f);
fclose(g);
return 0;
}