#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <math.h>
#include <assert.h>
#include <vector>
#include <queue>
#include <string>
#include <map>
#include <set>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c) for (__typeof((c).begin())it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

typedef int Weight;
struct Edge {
  int src;
  int dest;
  Weight weight;
  Edge(int src, int dest, Weight weight) : src(src), dest(dest), weight(weight) {;}
  bool operator<(const Edge &rhs) const {
    if (weight != rhs.weight) { return weight > rhs.weight; }
    if (src != rhs.src) { return src < rhs.src; }
    return dest < rhs.dest;
  }
};
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
typedef vector<Weight> Array;
typedef vector<Array> Matrix;

void PrintMatrix(const Matrix &matrix) {
  for (int y = 0; y < (int)matrix.size(); y++) {
    for (int x = 0; x < (int)matrix[y].size(); x++) {
      printf("%d ", matrix[y][x]);
    }
    puts("");
  }
}


Weight Dijkstra(const Graph &g, int s, int t) {
  const int n = g.size();
  vector<bool> visit(n, false);
  Array dist(n, 2000000000LL);
  priority_queue<Edge> que;
  que.push(Edge(s, s, 0));
  Weight ans = -1;
  dist[s] = 0;
  while (!que.empty()) {
    Edge edge = que.top();
    que.pop();
    int from = edge.dest;
    if (visit[from]) { continue; }
    visit[from] = true;
    if (from == t) {
      ans = edge.weight;
      break;
    }   
    for (int i = 0; i < (int)g[from].size(); i++) {
      int to = g[from][i].dest;
      Weight ncost = edge.weight + g[from][i].weight;
      if (visit[to] || ncost >= dist[to]) { continue; }
      dist[to] = ncost;
      que.push(Edge(from, to, ncost));
    }   
  }
  return ans;
}

const int dx[4] = { 1, 0, -1, 0 };
const int dy[4] = { 0, 1, 0, -1 };
int ok[60][60][4];
int w, h, n;
int Calc(int s, int t) {
  Graph g(w * h);
  REP(y, h) {
    REP(x, w) {
      REP(dir, 4) {
        int nx = x + dx[dir];
        int ny = y + dy[dir];
        ok[y][x][dir] &= !(nx < 0 || nx >= w || ny < 0 || ny >= h);
        if (ok[y][x][dir]) {
          int from = y * w + x;
          int to = ny * w + nx;
          g[from].push_back(Edge(from, to, 1));
        }
      }
    }
  }
  return Dijkstra(g, s, t);
}


int main() {
  while (scanf("%d %d %d", &w, &h, &n) > 0) {
    MEMSET(ok, true);
    if ((w|h|n) == 0) { break; }
    Graph g(w * h);
    REP(i, n) {
      int x1, y1, x2, y2;
      scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
      x1 = min(w, max(0, x1));
      x2 = min(w, max(0, x2));
      y1 = min(h, max(0, y1));
      y2 = min(h, max(0, y2));
      if (x1 > x2) { swap(x1, x2); }
      if (y1 > y2) { swap(y1, y2); }
      if (x1 == x2 && y1 == y2) { continue; }
      if (x1 == x2) {
        FOR(i, y1, y2) {
          ok[i][x1 - 1][0] = false;
          ok[i][x1][2] = false;
        }
      } else {
        FOR(i, x1, x2) {
          ok[y1 - 1][i][1] = false;
          ok[y1][i][3] = false;
        }
      }
    }
    int ix, iy, ox, oy;
    scanf("%d %d %d %d", &ix, &iy, &ox, &oy);
    int s = iy * w + ix;
    int t = oy * w + ox;
    int initial = Calc(s, t);
    int best = initial;
    REP(y, h) REP(x, w) REP(dir, 4) {
      if (!ok[y][x][dir]) { continue; }
      ok[y][x][dir] = false;
      best = max(best, Calc(s, t));
      ok[y][x][dir] = true;
    }
    printf("%d\n", best - initial);
  }
}

Measured memory_bytes: 0