## A Hitch-hikers Guide to Uniqueness-based Solving Techniques

Advanced methods and approaches for solving Sudoku puzzles

### A Hitch-hikers Guide to Uniqueness-based Solving Techniques

This is an attempt to consolidate the knowledge about Uniqueness-based solving techniques into a single thread, similar to the successful Ultimate Fish Guide. Feel free to point out any errors, suggest better terms and other improvements as you see fit.

Unique Solution Premise

A valid Sudoku puzzle has a unique solution. Uniqueness-based solving techniques should only be used on valid Sudoku puzzles. *)

From the POV of the puzzle setter: In a valid Sudoku puzzle each unavoidable set is covered by at least one given value.

From the POV of the player: A valid Sudoku puzzle either has been validated (by some software) or comes from a trusted source. The latter is not 100% proof, so in this case we speak of Uniqueness Assumption.

Uniqueness-based solving techniques can never be used to prove that a Sudoku puzzle is valid.

*) (pseudo-)Puzzles with multiple solutions will contain deadly patterns with no escape (DP+0). Avoiding such a pattern using uniqueness-based techniques will reduce the number of solutions by a factor equal to the number of solutions to this pattern. In the end you with either find 0 or 1 solution.

Unavoidable Sets

Unavoidable sets exist in a solution grid. An unavoidable set is a group of cells which can be changed in such a way that another valid solution can be formed by only altering the cells inside this set.

The smallest unavoidable set has 4 cells. The largest unavoidable set has 81 cells. Any two rows or columns in a single chute form an unavoidable set of 18 cells. The combined cells for any pair of numbers also form an unavoidable set of 18 cells.

An unavoidable set can be a subset of one or more larger unavoidable sets. For example: A bivalue rectangle located in a single chute is both a subset of the unavoidable set for the 2 lines in that chute and of the unavoidable set for all 18 cells holding these two numbers.

Observation: Each unavoidable set has a complementary unavoidable set in each of its parents. This complementary set contains all the remaining cells in this parent.

Unavoidable sets can also intersect with other unavoidable sets. The union of these sets can be seen as unavoidable sets by themselves, but their constituent sets are not true subsets, since their complements are not unavoidable sets.

As stated above, in a valid Sudoku puzzle each unavoidable set is covered with at least one given value. As a result, a valid Sudoku puzzle does not contain unavoidable sets in which none of the cells contains a given value.

An deadly pattern is a set of candidates which is a subset of the combined candidate space of an unavoidable set and all its alternative solutions, which contains no given numbers. The pattern may contain solved cells, but the solved values must belong to the same candidate space.

A little lateral thinking is required here. We know that a valid Sudoku does not contain unavoidable sets without given values, so how can we find any of them in the PM grid? The answer is best illustrated with an example:

Code: Select all
` +-----------------------+ | 1 . . | 2 . . | . . . | | 2 . . | 1 . . | . . . | | . . . | . . . | . . . | |-------+-------+-------|`

The cells r12c14 form an unavoidable set.
The alternative solution to these 4 cells is also an unavoidable set:
Code: Select all
` +-----------------------+ | 2 . . | 1 . . | . . . | | 1 . . | 2 . . | . . . | | . . . | . . . | . . . | |-------+-------+-------|`

The combined candidate space is this set. If none of these 4 cells contains a given number, any subset of this set qualifies as a deadly pattern:
Code: Select all
` +--------------------------------+ | 12 .  .  | 12 .  .  | .  .  .  | | 12 .  .  | 12 .  .  | .  .  .  | | .  .  .  | .  .  .  | .  .  .  | |----------+----------+----------|`

Here is the candidate space for two intersecting bivalue rectangles:
Code: Select all
` +--------------------------------+ | 12 .  .  | 12 .  .  | .  .  .  | | 12 .  .  | 123.  .  | 13 .  .  | | .  .  .  | 13 .  .  | 13 .  .  | |----------+----------+----------|`

It has 3 solutions (each of them is an unavoidable set):
Code: Select all
` +-----------------------+ | 1 . . | 2 . . | . . . | | 2 . . | 1 . . | 3 . . | | . . . | 3 . . | 1 . . | |-------+-------+-------| +-----------------------+ | 2 . . | 1 . . | . . . | | 1 . . | 2 . . | 3 . . | | . . . | 3 . . | 1 . . | |-------+-------+-------| +-----------------------+ | 1 . . | 2 . . | . . . | | 2 . . | 3 . . | 1 . . | | . . . | 1 . . | 3 . . | |-------+-------+-------|`

This pattern is also covered by this trivalue set, but it is not a true subset, since the remaining cells do not form a complementary set.
Code: Select all
` +-----------------------------------+ | 123 .  .  | 123 .  .  | 123 .  .  | | 123 .  .  | 123 .  .  | 123 .  .  | | 123 .  .  | 123 .  .  | 123 .  .  | |-----------+-----------+-----------|`

In a valid Sudoku, there must be at least one additional candidate in the cells belonging to a deadly pattern. Additional candidates are known as surplus candidates. Also, there must be at least one additional candidate in 3 of the unit constraints covered by the pattern. Together, these are the 4 escapes that must accompany the deadly pattern.

An example:
Code: Select all
` +--------------------------------+ | 12 .  .  | 12 .  .  | .  .  .  | | 12 .  .  | 12 .  .  | .  .  .  | | .  .  .  | .  .  .  | .  .  .  | |----------+----------+----------|`

To escape this deadly pattern:
- at least one of the cells must have a candidate for a number other than 1 or 2;
- at least one of the rows 1 & 2 must have a candidate 1 or 2 not in columns 1 and 4;
- at least one of the boxes must have a candidate for number 1 or 2 outside these 4 cells;
- at least one of the columns must also have an additional candidate for number 1 or 2.

Each of these 4 conditions can be used in the definition of uniqueness-based solving techniques.

Bivalue vs. Multivalue deadly patterns

An deadly pattern is a bivalue pattern when all the cells have exactly 2 candidates. All other deadly patterns are multivalue patterns. For specific cases, we can use terms like trivalue. These names are useful to identify multivalue patterns which appear more frequent and are easy to recognize.

Complete vs. Partial deadly patterns

A complete deadly pattern contains all unsolved cells in the grid. A BUG is an example of a complete (bivalue) deadly pattern. An partial deadly pattern only contains a part of the unsolved cells. UR and BUG-Lite are examples of partial deadly patterns.

Any (combination of) move(s) which would result in a deadly pattern which does not have all 4 escapes is an invalid (combination of) move(s). Blocking a single escape is sufficient to enforce the deadly pattern. Therefore, for any set of surplus candidates in each the 4 constraint sets we can deduce:
- If there is a single surplus candidate, it can be placed.
- If all candidates belong to a single cell or unit constraint, the candidates in the intersection of this constraint and the deadly pattern can be eliminated.
- If there are two surplus candidates, they are strongly linked.
- If there are two groups of candidates in 2 constraints, these groups are strongly linked.

It is also possible to establish a link between escapes in different constraint types.
I'm using the following symbols:
Code: Select all
` * : One or more candidates belonging to the deadly pattern / : One or more candidates not found in the deadly pattern . : anything (given, solved, any group of candidates) A,B,C : A candidate that provides an escape in a row, column or box x,y,z : A candidate that provides an escape in a cell belonging to the deadly pattern`

Code: Select all
` +--------------------------------+ | */ /  /  | */ /  /  | A/ /  /  | | *x .  .  | *  .  .  | .  .  .  | | .  .  .  | .  .  .  | .  .  .  | |----------+----------+----------|`

In this example, A is the only surplus candidate in row 1. x is the only surplus candidate in the 2 cells that belong to row 2. Either r1c6=A or r2c1=x.

Lexicon of known Deadly Patterns

I will complete this section later. It will contain a canonicalized representative of each type of pattern.

Code: Select all
` Unique Rectangle (UR): 4 cells, bivalue, partial +-----------------------------------------+ | 12  12  .   | .   .   .   | .   .   .   | | .   .   .   | .   .   .   | .   .   .   | | .   .   .   | .   .   .   | .   .   .   | |-------------+-------------+-------------| | 12  12  .   | .   .   .   | .   .   .   | | .   .   .   | .   .   .   | .   .   .   | | .   .   .   | .   .   .   | .   .   .   | |-------------+-------------+-------------| | .   .   .   | .   .   .   | .   .   .   | | .   .   .   | .   .   .   | .   .   .   | | .   .   .   | .   .   .   | .   .   .   | +-----------------------------------------+`

Lexicon of known Escape Routes

Another section to be completed. When the previous material has passed the scrutiny of the experts, we can start a list of known solving techniques which can be seen as escape routes from a deadly pattern.

References
Thanks to Mike Barker for keeping up his invaluable index.
Last edited by Ruud on Sun Sep 30, 2007 4:16 pm, edited 1 time in total.
Ruud

Posts: 664
Joined: 28 October 2005

Ruud,

This looks interesting!

I think you need to cover the issue of an initial value (clue) as part of a deadly pattern in your introduction.

For example:

Code: Select all
` +--------------------------------+ | 1  .  .  | 12 .  .  | .  .  .  | | 12 .  .  | 12 .  .  | .  .  .  | | .  .  .  | .  .  .  | .  .  .  | |----------+----------+----------|`

If R1C1 <1> is given as an initial clue,
Code: Select all
` +--------------------------------+ | 1  .  .  | 2  .  .  | .  .  .  | | 2  .  .  | 1  .  .  | .  .  .  | | .  .  .  | .  .  .  | .  .  .  | |----------+----------+----------|`

is perfectly valid in the solution.

Keith
keith
2017 Supporter

Posts: 215
Joined: 03 April 2006

While everyone is working on the grand picture, I have a more basic question to ask.

In the example below, I'm pretty sure that using cell [r5c1] as part of an elimination chain isn't going to be acceptable. What is the scope of the cells that can be used to resolve a bivalue deadly pattern?

Code: Select all
` *-----------------------------------* |  .  .  .  |  .  .  .  |  .  .  .  | |  .  .  .  | 12  . 125 |  .  .  .  | |  .  .  .  |  .  .  .  |  .  .  .  | |-----------+-----------+-----------| |  .  .  .  |  .  .  .  |  .  .  .  | |  .  .  .  |  .  .  .  |  .  .  .  | |  .  .  .  |  .  .  .  |  .  .  .  | |-----------+-----------+-----------| |  .  .  .  |  .  .  .  |  .  .  .  | |  .  .  .  | 126 . 12  |  .  .  .  | |  .  .  .  |  .  .  .  |  .  .  .  | *-----------------------------------*`

I'm currently limiting UR elimination chains to cells in [r28], [c46], and [b28] for this example.
daj95376
2014 Supporter

Posts: 2624
Joined: 15 May 2006

daj95376 wrote:While everyone is working on the grand picture, I have a more basic question to ask.

In the example below, I'm pretty sure that using cell [r5c1] as part of an elimination chain isn't going to be acceptable. What is the scope of the cells that can be used to resolve a bivalue deadly pattern?

Code: Select all
` *-----------------------------------* |  .  .  .  |  .  .  .  |  .  .  .  | |  .  .  .  | 12  . 125 |  .  .  .  | |  .  .  .  |  .  .  .  |  .  .  .  | |-----------+-----------+-----------| |  .  .  .  |  .  .  .  |  .  .  .  | |  .  .  .  |  .  .  .  |  .  .  .  | |  .  .  .  |  .  .  .  |  .  .  .  | |-----------+-----------+-----------| |  .  .  .  |  .  .  .  |  .  .  .  | |  .  .  .  | 126 . 12  |  .  .  .  | |  .  .  .  |  .  .  .  |  .  .  .  | *-----------------------------------*`

I'm currently limiting UR elimination chains to cells in [r28], [c46], and [b28] for this example.

I am not sure what you mean by "acceptable as part of an elimination chain".

In this case, either R2C6 is <5> and / or R8C4 is <6>. You can use any chain to explore the implications. For example, suppose you have:
Code: Select all
` *-----------------------------------* |  .  .  .  |  .  .  .  |  .  .  .  | |  .  .  .  | 12  . 125 |  .  .  .  | |  .  .  .  |  .  .  .  |  .  .  .  | |-----------+-----------+-----------| |  .  .  .  |  .  .  .  |  .  .  .  | |  .  .  .  |  .  .  .  |  .  .  .  | |  .  .  .  |  .  .  .  |  .  .  .  | |-----------+-----------+-----------| |  .  .  .  |  .  .  .  |  .  .  .  | |  .  .  .  | 126 . 12  |  .  .  .  | |  .  .  .  |  .  . 25  |  .  .  .  | *-----------------------------------*`

then R8C4 must be <6>.

Or, you may have
Code: Select all
` *-----------------------------------* |  .  .  .  |  .  .  #  |  .  .  .  | |  .  .  .  | 12  . 125 |  .  .  .  | |  .  .  .  |  .  .  #  |  .  .  .  | |-----------+-----------+-----------| |  .  .  .  |  .  .  #  |  .  .  .  | |  .  .  .  |  .  .  #  |  .  .  .  | |  .  .  .  |  .  .  #  |  .  .  .  | |-----------+-----------+-----------| |  .  .  .  |  @  @ @#  |  .  .  .  | |  .  .  .  | 126 @ 12  |  .  .  .  | |  .  .  .  |  @  @ 56  |  .  .  .  | *-----------------------------------*`

You can eliminate <6> in all the cells marked @, and <5> from all the cells marked #.

You may also have strong links on the UR itself. For example, suppose the UR is also an X-wing on <1>. Then the diagonal cells R2C4 and R8C6 must be <1>.

I don't have these things classified as patterns - I prefer to argue them on a case-by-case basis.

Keith
keith
2017 Supporter

Posts: 215
Joined: 03 April 2006

keith wrote:You can use any chain to explore the implications.

Code: Select all
`So, [@]<>5,[#]<>6,[*]<>7 because of UR in [r28c46] *-----------------------------------* |  .  .  .  |  .  .  @  |  .  .  .  | |  .  .  .  | 12  . 125 |  .  .  .  | |  .  .  .  |  .  .  @  |  .  .  .  | |-----------+-----------+-----------| |  .  .  .  |  .  .  @  |  .  .  .  | | 34  .  .  |  .  . 35  |  .  .  .  | |  .  .  .  |  .  .  @  |  .  .  .  | |-----------+-----------+-----------| | 47  *  *  |  *  *  *@ |  *  * 78  | |  #  #  #  | 126 # 12  |  #  # 68  | |  .  .  .  |  .  .  @  |  .  .  .  | *-----------------------------------*`
Last edited by daj95376 on Sun Sep 30, 2007 11:56 am, edited 1 time in total.
daj95376
2014 Supporter

Posts: 2624
Joined: 15 May 2006

Amazing how quickly these things change!

Your (edited again) chain is a correct continuous loop:
Code: Select all
`- (7=4)r7c1 - (4=3)r5c1 - (3=5)r5c6 - (5)r2c6 [UR(12)r28c46] = (6)r8c4 - (6=8)r8c9 - (8=7)r7c9 - `

Ruud
Last edited by Ruud on Sun Sep 30, 2007 1:22 pm, edited 1 time in total.
Ruud

Posts: 664
Joined: 28 October 2005

### Re: The Hitch-hikers Guide to Uniqueness-based Solving Techn

Ruud wrote:Unique Solution Premise

Uniqueness-based solving techniques can only be used on valid Sudoku puzzles.

I'm not entirely happy with this as it implies that you could make an elimination that gives zero solutions from a puzzle with multiple solutions.

I'd prefer it to be a caveat such as "using Uniqueness-based solving techniques on invalid puzzles might remove equally valid solutions".

I used "might" because sometimes an alternate method would make the same elimination.

Alternately, changing "can" to "should" would work for me!
wintder

Posts: 297
Joined: 24 April 2007

### Re: The Hitch-hikers Guide to Uniqueness-based Solving Techn

wintder wrote:
Ruud wrote:Unique Solution Premise

Uniqueness-based solving techniques can only be used on valid Sudoku puzzles.

I'm not entirely happy with this as it implies that you could make an elimination that gives zero solutions from a puzzle with multiple solutions.
[...]
Alternately, changing "can" to "should" would work for me!

When combined with the immediate prior sentence ... in the same paragraph ... it's very clear IMO. With my underlining added ...
Ruud wrote:A valid Sudoku puzzle has a unique solution. Uniqueness-based solving techniques can only be used on valid Sudoku puzzles.
ronk
2012 Supporter

Posts: 4764
Joined: 02 November 2005
Location: Southeastern USA

Here's how I see it:
Code: Select all
` *--------------------------* | . . . | .  .  . | . .  . | | . . . |12  . 125| . .  . | | . . . | .  .  . | . .  . | |-------+---------+--------| | . . . | .  .  . | . .  . | |34 . . | .  . 35 | . .  . | | . . . | .  .  . | . .  . | |-------+---------+--------| |47 . . | .  .  . | . . 78 | | . . . |126 . 12 | . . 68 | | . . . | .  .  . | . .  . | *--------------------------*`

The conclusion from the UR is:

R2C5 is <5> AND/OR R8C4 is <6>.

They are not necessarily both true, but they may be!
Code: Select all
`If R2C5 = <5> *--------------------------* | . . . | .  .  . | . .  . | | . . . |12  .  5 | . .  . | | . . . | .  .  . | . .  . | |-------+---------+--------| | . . . | .  .  . | . .  . | | 4 . . | .  .  3 | . .  . | | . . . | .  .  . | . .  . | |-------+---------+--------| | 7 . . | .  .  . | . .  8 | | . . . |12  . 12 | . .  6 | | . . . | .  .  . | . .  . | *--------------------------*`

Code: Select all
`If R8C4 = <6> *--------------------------* | . . . | .  .  . | . .  . | | . . . |12  . 12 | . .  . | | . . . | .  .  . | . .  . | |-------+---------+--------| | . . . | .  .  . | . .  . | | 3 . . | .  .  5 | . .  . | | . . . | .  .  . | . .  . | |-------+---------+--------| | 4 . . | .  .  . | . .  7 | | . . . | 6  . 12 | . .  8 | | . . . | .  .  . | . .  . | *--------------------------*`

Code: Select all
`If R2C5 = <5> and R8C4 = <6> *--------------------------* | . . . | .  .  . | . .  . | | . . . |12  .  5 | . .  . | | . . . | .  .  . | . .  . | |-------+---------+--------| | . . . | .  .  . | . .  . | | 4 . . | .  .  3 | . .  . | | . . . | .  .  . | . .  . | |-------+---------+--------| |7? . . | .  .  . | . . 7? | | . . . | 6  . 12 | . .  8 | | . . . | .  .  . | . .  . | *--------------------------*`

The example does not satisfy the AND condition!

This one does:
Code: Select all
` *--------------------------* | . . . | .  .  . | . .  . | | . . . |12  . 125| . .  . | | . . . | .  .  . | . .  . | |-------+---------+--------| | . . . | .  .  . | . .  . | |34 . . | .  . 35 | . .  . | | . . . | .  .  . | . .  . | |-------+---------+--------| |47 . . | .  .  . | . . 78 | | . . . |126 . 12 | . . 17 | | . . . | .  .  . | . .  . | *--------------------------*`

The only conclusion in this last example is, I think, R8C4 is <6>

Keith
keith
2017 Supporter

Posts: 215
Joined: 03 April 2006

Keith wrote:They are not necessarily both true, but they may be!

In this case, the continuous loop eliminates the AND option.

Code: Select all
` *--------------------------*  | . . . | .  .  . | . .  . |  | . . . |12  . 125| . .  . |  | . . . | .  .  . | . .  . |  |-------+---------+--------|  | . . . | .  .  . | . .  . |  |34 . . | .  . 35 | . .  . |  | . . . | .  .  . | . .  . |  |-------+---------+--------|  |47 . . | .  .  . | . . 78 |  | . . . |126 . 12 | . . 17 |  | . . . | .  .  . | . .  . |  *--------------------------*`

The only conclusion in this last example is, I think, R8C4 is <6>

This "solution" is valid, IMO:
Code: Select all
` *--------------------------*  | . . . | .  .  . | . .  . |  | . . . |12  .  5 | . .  . |  | . . . | .  .  . | . .  . |  |-------+---------+--------|  | . . . | .  .  . | . .  . |  | 4 . . | .  .  3 | . .  . |  | . . . | .  .  . | . .  . |  |-------+---------+--------|  | 7 . . | .  .  . | . .  8 |  | . . . |12  . 12 | . .  7 |  | . . . | .  .  . | . .  . |  *--------------------------*`

Ruud
Ruud

Posts: 664
Joined: 28 October 2005

ronk wrote:
wintder wrote:
Ruud wrote:Unique Solution Premise

Uniqueness-based solving techniques can only be used on valid Sudoku puzzles.

I'm not entirely happy with this as it implies that you could make an elimination that gives zero solutions
from a puzzle with multiple solutions.
[...]
Alternately, changing "can" to "should" would work for me!

When combined with the immediate prior sentence ... in the same paragraph ... it's very clear IMO.
With my underlining added ...
Ruud wrote:A valid Sudoku puzzle has a unique solution. Uniqueness-based solving techniques
can only be used on valid Sudoku puzzles.

I would have thought that:
Ruud wrote:"Uniqueness-based solving techniques can never be used to prove that a Sudoku puzzle is valid."
is the germane part.

The trouble is it does not explain itself. My poor prose points out the danger in using Uniqueness,
which gives more information than just saying don't use it.

If a puzzle with more than one solution has 4 distinct deadly sets but two of them are covered
uniqueness can be used on two of them reliably. Which two? Ahh! The crux.

Should not be used, yes, cannot be used is untrue.

The difference between [Uniqueness and T&E and guessing] and [most other methods] is that
the former can eliminate possible "valid" solutions and yet still produce answers no less valid than the other methods.

If this thread is to be definitive I believe the dangers should be listed as well as the benefits.
wintder

Posts: 297
Joined: 24 April 2007

wintder wrote:Should not be used, yes, cannot be used is untrue.

The difference between [Uniqueness and T&E and guessing] and [most other methods] is that
the former can eliminate possible "valid" solutions and yet still produce answers no less valid than the other methods.

Wintder, you have obviously missed the logic behind uniqueness technique. The basic logic for all uniqueness based eliminations is: "If this puzzle has only one solution, then cell C<>X." Now please tell me, how could you possibly use a technique like this in a puzzle with multiple solutions? The very definition of the technique does not allow you to use it in a puzzle with multiple solutions, therefore "cannot be used" is true.

RW

PS. Very nice thread initiative, Ruud! I'll try to contribute if I can find some spare time.
RW
2010 Supporter

Posts: 1000
Joined: 16 March 2006

Ruud wrote:
Keith wrote:They are not necessarily both true, but they may be!

In this case, the continuous loop eliminates the AND option.

Code: Select all
` *--------------------------*  | . . . | .  .  . | . .  . |  | . . . |12  . 125| . .  . |  | . . . | .  .  . | . .  . |  |-------+---------+--------|  | . . . | .  .  . | . .  . |  |34 . . | .  . 35 | . .  . |  | . . . | .  .  . | . .  . |  |-------+---------+--------|  |47 . . | .  .  . | . . 78 |  | . . . |126 . 12 | . . 17 |  | . . . | .  .  . | . .  . |  *--------------------------*`

The only conclusion in this last example is, I think, R8C4 is <6>

This "solution" is valid, IMO:
Code: Select all
` *--------------------------*  | . . . | .  .  . | . .  . |  | . . . |12  .  5 | . .  . |  | . . . | .  .  . | . .  . |  |-------+---------+--------|  | . . . | .  .  . | . .  . |  | 4 . . | .  .  3 | . .  . |  | . . . | .  .  . | . .  . |  |-------+---------+--------|  | 7 . . | .  .  . | . .  8 |  | . . . |12  . 12 | . .  7 |  | . . . | .  .  . | . .  . |  *--------------------------*`

Ruud

Ruud,

I can be educated! In my example, I think the UR says:

R8C4 is <6> and / or R2C5 is <5>.

Options:

1. R8C4 is <6>.

2. R2C5 is <5>, the chain results in R8C4 is <6>.

Either way, R8C4 is <6>.

If R8C4 is <6>, I do not see how you conclude that R2C5 is <5>.

Keith
keith
2017 Supporter

Posts: 215
Joined: 03 April 2006

Wintder, I appreciate your concerns. I've changed the wording and added a footnote.

Ruud
Ruud

Posts: 664
Joined: 28 October 2005

### I vote "Yes"!

Do we, the "Sudoku Community", accept that "valid" puzzles have only a single solution?

If so, this discussion is moot.

In my opinion, multiple-solution puzzles are very valuable. They help us to discover new non-unique patterns and techniques.

As a side benefit, they can be contributed to Mike's "Sudokus of shame".

If you do like to solve puzzles with multiple solutions, here is my contribution:

Code: Select all
` *-------------------------* | 1 . . | .  .  . | . . . | | . . . | .  .  . | . . . | | . . . | .  .  . | . . . | |-------+---------+-------| | . . . | .  .  . | . . . | | . . . | .  .  . | . . . | | . . . | .  .  . | . . . | |-------+---------+-------| | . . . | .  .  . | . . . | | . . . | .  .  . | . . . | | . . . | .  .  . | . . . | *-------------------------*`

Keith.
keith
2017 Supporter

Posts: 215
Joined: 03 April 2006

Next