Problem:
Problem B: Left Hand Rule

The left-hand rule, which is also known as the wall follower, is a well-known strategy that solves a two-
dimensional maze. The strategy can be stated as follows: once you have entered the maze, walk around
with keeping your left hand in contact with the wall until you reach the goal. In fact, it is proven that this
strategy solves some kind of mazes.

Your task is to write a program that determines whether the given maze is solvable by using the left-hand
rule and (if the maze is solvable) the number of steps to reach the exit. Moving to a cell from the entrance
or the adjacent (north, south, east or west) cell is counted as a step.

In this problem, the maze is represented by a collection of walls placed on the two-dimensional grid.
We use an ordinary Cartesian coordinate system; the positive x-axis points right and the positive y-axis
points up. Each wall is represented by a line segment which is parallel to the x-axis or the y-axis, such
that both ends of each wall are located on integer coordinates. The size of the maze is given by W and H
that indicate the width and the height of the maze, respectively. A rectangle whose vertices are on (0, 0),
(W, 0), (W, H) and (0, H) forms the outside boundary of the maze. The outside of the maze is always
surrounded by walls except for the entrance of the maze. The entrance is represented by a line segment
whose ends are (xE, yE) and (xE', yE'). The entrance has a unit length and is located somewhere on one
edge of the boundary. The exit is a unit square whose bottom left corner is located on (xX, yX).

A few examples of mazes are illustrated in the figure below. They correspond to the datasets in the sample
input.

Figure 1: Example Mazes (shaded squares indicate the exits)

Input

The input consists of multiple datasets.

Each dataset is formatted as follows:

W H N
x1 y1 x1' y1'
x2 y2 x2' y2'
...
xN yN xN' yN'
xE yE xE' yE' xX yX

W and H (0 < W, H ≤ 100) indicate the size of the maze. N is the number of walls inside the maze.
The next N lines give the positions of the walls, where (xi, yi) and (xi', yi') denote two ends of each wall
(1 ≤ i ≤ N). The last line gives the positions of the entrance and the exit. You can assume that all the
coordinates given in the input are integer coordinates and located inside the boundary of the maze. You
can also assume that the wall description is not redundant, i.e. an endpoint of a wall is not shared by any
other wall that is parallel to it.

The input is terminated by a line with three zeros.

Output

For each dataset, print a line that contains the number of steps required to reach the exit. If the given
maze is unsolvable, print “Impossible” instead of the number of steps.

Sample Input

3 3 3
1 0 1 2
1 2 2 2
2 2 2 1
0 0 1 0 1 1
3 3 4
1 0 1 2
1 2 2 2
2 2 2 1
2 1 1 1
0 0 1 0 1 1
3 3 0
0 0 1 0 1 1
0 0 0

Output for the Sample Input

9
Impossible
Impossible

Solution in Rust (judge verdict: Accepted)

extern crate core;

use std::fmt;
use ::Direction::{North, East, South, West};
use std::ops::{Add, Sub};
use std::convert::From;
use std::cmp::min;


macro_rules! read_line{
    () => {{
        let mut line = String::new();
        std::io::stdin().read_line(&mut line).ok();
        line
    }};
    (delimiter: ' ') => {
        read_line!().split_whitespace().map(|x|x.to_string()).collect::<Vec<_>>()
    };
    (delimiter: $p:expr) => {
        read_line!().split($p).map(|x|x.to_string()).collect::<Vec<_>>()
    };
    (' ') => {
        read_line!(delimiter: ' ')
    };
    ($delimiter:expr) => {
        read_line!(delimiter: $delimiter)
    };
    (' '; $ty:ty) => {
        read_line!().split_whitespace().map(|x|x.parse::<$ty>().ok().unwrap()).collect::<Vec<$ty>>()
    };
    ($delimiter:expr; $ty:ty) => {
        read_line!($delimiter).into_iter().map(|x|x.parse::<$ty>().ok().unwrap()).collect::<Vec<$ty>>()
    };
}
macro_rules! let_all {
    ($($n:ident:$t:ty),*) => {
        let line = read_line!(delimiter: ' ');
        let mut iter = line.iter();
        $(let $n:$t = iter.next().unwrap().parse().ok().unwrap();)*
    };
}

#[derive(Ord, PartialOrd, PartialEq, Eq, Copy, Clone)]
struct Point{
    x: i32, y: i32
}
impl Add for Point {
    type Output = Point;
    fn add(self, rhs: Self) -> Self::Output {
        Point{x: self.x + rhs.x, y: self.y + rhs.y}
    }
}
impl Sub for Point {
    type Output = Point;
    fn sub(self, rhs: Self) -> Self::Output {
        Point{x: self.x - rhs.x, y: self.y - rhs.y}
    }
}
#[derive(Eq, PartialEq, Copy, Clone)]
pub struct State {
    state: usize
}
impl State {
    fn new() -> State {
        State{state: 0}
    }
    fn add_wall(&mut self, wall: Direction) -> () {
        self.state |= (1 << wall as usize)
    }
    fn exist_wall(&self, wall: Direction) -> bool {
        self.state & (1 << wall as usize) != 0
    }
    fn no_wall(&self, wall: Direction) -> bool {
        !self.exist_wall(wall)
    }
}
impl Default for State {
    fn default() -> Self {
        State{state:0}
    }
}
#[derive(Eq, PartialEq, Clone, Copy)]
enum Direction {
    North,
    East,
    South,
    West
}
impl Direction {
    fn clockwise_next(&self) -> Direction {
        Direction::from(((usize::from(*self) + 1) % 4))
    }
    fn counter_clockwise_next(&self) -> Direction {
        Direction::from(((usize::from(*self) + 3) % 4))
    }
}
impl From<usize> for Direction {
    fn from(i: usize) -> Self {
        match i % 4 {
            0 => North,
            1 => East,
            2 => South,
            3 => West,
            _ => unreachable!()
        }
    }
}
impl From<Direction> for usize {
    fn from(wall: Direction) -> Self {
        match wall {
            North => 0,
            East => 1,
            South => 2,
            West => 3
        }
    }
}
#[derive(Eq, PartialEq, Copy, Clone)]
enum Face {
    Forward, Right, Back, Left
}
#[derive(Eq, PartialEq, Copy, Clone)]
struct Person {
    position: Point,
    direction: Direction
}
impl Person {
    fn move_forward(&self) -> Person {
        let diff = match self.direction {
            North => Point{x: 0, y: 1},
            East => Point{x: 1, y: 0},
            South => Point{x: 0, y: -1},
            West => Point{x: -1, y: 0}
        };
        Person{position: self.position + diff, direction: self.direction}
    }
    fn turn_right(&self) -> Person {
        Person{position: self.position, direction: self.direction.clockwise_next()}
    }
    fn turn_left(&self) -> Person {
        Person{position: self.position, direction: self.direction.counter_clockwise_next()}
    }
    fn left(&self) -> Direction {
        self.direction.counter_clockwise_next()
    }
    fn forward(&self) -> Direction {
        self.direction
    }
    fn right(&self) -> Direction {
        self.direction.clockwise_next()
    }
}
fn set_wall(maze: &mut Vec<Vec<State>>, from: Point, to: Point) -> () {
    match to - from {
        Point{x: 0, y} if y >= 0 => {
            for y in from.y .. to.y {
                maze[y as usize][from.x as usize].add_wall(West);
                if from.x > 0 {
                    maze[y as usize][(from.x - 1) as usize].add_wall(East);
                }
            }
        },
        Point{x: 0, y} if y < 0 => {
            for y in to.y .. from.y {
                maze[y as usize][from.x as usize].add_wall(West);
                if from.x > 0 {
                    maze[y as usize][(from.x - 1) as usize].add_wall(East);
                }
            }
        },
        Point{x, y: 0} if x >= 0 => {
            for x in from.x .. to.x {
                maze[from.y as usize][x as usize].add_wall(South);
                if from.y > 0 {
                    maze[(from.y - 1) as usize][x as usize].add_wall(North);
                }
            }
        },
        Point{x, y: 0} if x < 0 => {
            for x in to.x .. from.x {
                maze[from.y as usize][x as usize].add_wall(South);
                if from.y > 0 {
                    maze[(from.y - 1) as usize][x as usize].add_wall(North);
                }
            }
        }
        _ => unreachable!()
    }
}
fn main() {
    loop {
        let_all!(w: usize, h: usize, n: usize);
        if w == 0 && h == 0 && n == 0 {
            return
        }
        let mut maze = vec![vec![State::default(); w]; h];
        for x in 0 .. w {
            maze[0][x].add_wall(South);
            if h > 0 {
                maze[(h - 1) as usize][x].add_wall(North)
            }
        }
        for y in 0 .. h {
            maze[y][0].add_wall(West);
            if w > 0 {
                maze[y][(w - 1) as usize].add_wall(East);
            }
        }
        for _ in 0 .. n {
            let_all!(fx: i32, fy: i32, tx: i32, ty: i32);
            set_wall(&mut maze, Point{x: fx, y:fy}, Point{x: tx, y: ty});
        }
        let mut person: Person;
        let mut goal: Point;
        let_all!(fx: i32, fy: i32, tx: i32, ty: i32, gx:i32, gy:i32);
        person = if fx == tx {
            if fx == 0 {
                Person{position: Point{x: - 1, y: min(fy, ty)}, direction: East}
            }else {
                Person{position: Point{x: w as i32, y: min(fy, ty)}, direction: West}
            }
        }else {
            if fy == 0 {
                Person{position: Point{x: min(fx, tx), y: -1}, direction: North}
            }else {
                Person{position: Point{x: min(fx, tx), y: h as i32}, direction: South}
            }
        }.move_forward();
        goal = Point{x: gx, y: gy};
        let mut is_visit = vec![vec![vec![false; w]; h];4];
        let mut count = 1;
        loop {
            if person.position.x < 0 || person.position.x >= w as i32 || person.position.y < 0 || person.position.y >= h as i32 || is_visit[usize::from(person.direction)][person.position.y as usize][person.position.x as usize] || person.position == goal {
                break
            }
            is_visit[usize::from(person.direction)][person.position.y as usize][person.position.x as usize] = true;
            if maze[person.position.y as usize][person.position.x as usize].exist_wall(person.left()) {
                person = person.turn_right()
            }else {
                count += 1;
                person = person.turn_left().move_forward();
            }
        }
        if person.position == goal {
            println!("{}", count);
        }else {
            println!("Impossible");
        }
    }
}