2 import java
.io
.FileNotFoundException
;
3 import java
.io
.PrintWriter
;
4 import java
.util
.ArrayList
;
5 import java
.util
.Arrays
;
6 import java
.util
.Collections
;
7 import java
.util
.HashMap
;
10 import java
.util
.Scanner
;
11 import java
.util
.TreeMap
;
13 public class database_gk_generic
{
14 static final int MAX_N
= 10000;
15 static final int MAX_M
= 100;
17 static interface Type
<V
> {
18 Pair
<Integer
, Integer
> solve(V
[] col1
, V
[] col2
);
21 static interface Generator
<V
, T
> {
22 T
key(V value1
, V value2
);
25 static class HashType
<V
, T
> implements Type
<V
> {
26 Generator
<V
, T
> generator
;
28 public HashType(Generator
<V
, T
> generator
) {
29 this.generator
= generator
;
33 public Pair
<Integer
, Integer
> solve(V
[] col1
, V
[] col2
) {
34 Map
<T
, Integer
> map
= new HashMap
<T
, Integer
>();
35 for (int r1
= 0; r1
< col1
.length
; r1
++) {
36 Integer r2
= map
.put(generator
.key(col1
[r1
], col2
[r1
]), r1
);
38 return new Pair
<Integer
, Integer
>(r1
, r2
);
45 static class TreeType
<V
, T
> implements Type
<V
> {
46 Generator
<V
, T
> generator
;
48 public TreeType(Generator
<V
, T
> generator
) {
49 this.generator
= generator
;
53 public Pair
<Integer
, Integer
> solve(V
[] col1
, V
[] col2
) {
54 Map
<T
, Integer
> map
= new TreeMap
<T
, Integer
>();
55 for (int r1
= 0; r1
< col1
.length
; r1
++) {
56 Integer r2
= map
.put(generator
.key(col1
[r1
], col2
[r1
]), r1
);
58 return new Pair
<Integer
, Integer
>(r1
, r2
);
65 static class SortType
<V
, T
extends Comparable
<T
>> implements Type
<V
> {
66 Generator
<V
, T
> generator
;
68 public SortType(Generator
<V
, T
> generator
) {
69 this.generator
= generator
;
73 public Pair
<Integer
, Integer
> solve(V
[] col1
, V
[] col2
) {
74 List
<Pair
<T
, Integer
>> pairs
= new ArrayList
<Pair
<T
, Integer
>>();
75 for (int r
= 0; r
< col1
.length
; r
++) {
76 pairs
.add(new Pair
<T
, Integer
>(generator
.key(col1
[r
], col2
[r
]), r
));
78 Collections
.sort(pairs
);
79 for (int i
= 0; i
< pairs
.size() - 1; i
++) {
80 if (pairs
.get(i
).f
.compareTo(pairs
.get(i
+ 1).f
) == 0) {
81 return new Pair
<Integer
, Integer
>(pairs
.get(i
).s
, pairs
.get(i
+ 1).s
);
88 static final Generator
<String
, String
> CONCAT_GENERATOR
= new Generator
<String
, String
>() {
90 public String
key(String value1
, String value2
) {
91 return value1
+ "," + value2
;
95 static final Generator
<String
, String
> CONCAT_ERROR_GENERATOR
= new Generator
<String
, String
>() {
97 public String
key(String value1
, String value2
) {
98 return value1
+ value2
;
102 static final Generator
<Object
, Pair
<Object
, Object
>> PAIR_GENERATOR
= new Generator
<Object
, Pair
<Object
, Object
>>() {
104 public Pair
<Object
, Object
> key(Object value1
, Object value2
) {
105 return new Pair
<Object
, Object
>(value1
, value2
);
109 static final Type
<String
> HASH_CONCAT
= new HashType
<String
, String
>(CONCAT_GENERATOR
);
110 static final Type
<String
> HASH_CONCAT_ERROR
= new HashType
<String
, String
>(CONCAT_ERROR_GENERATOR
);
111 static final Type
<?
> HASH_PAIR
= new HashType
<Object
, Pair
<Object
, Object
>>(PAIR_GENERATOR
);
112 static final Type
<?
> TREE_PAIR
= new TreeType
<Object
, Pair
<Object
, Object
>>(PAIR_GENERATOR
);
113 static final Type
<String
> SORT_CONCAT
= new SortType
<String
, String
>(CONCAT_GENERATOR
);
114 static final Type
<?
> SORT_PAIR
= new SortType
<Object
, Pair
<Object
, Object
>>(PAIR_GENERATOR
);
115 static final Type
<?
> HASH_NESTED
= new Type
<Object
>(){
117 public Pair
<Integer
, Integer
> solve(Object
[] col1
, Object
[] col2
) {
118 Map
<Object
, Map
<Object
, Integer
>> outter
= new HashMap
<Object
, Map
<Object
, Integer
>>();
119 for (int r1
= 0; r1
< col1
.length
; r1
++) {
120 Map
<Object
, Integer
> inner
= outter
.get(col1
[r1
]);
122 inner
= new HashMap
<Object
, Integer
>();
123 outter
.put(col1
[r1
], inner
);
125 Integer r2
= inner
.put(col2
[r1
], r1
);
127 return new Pair
<Integer
, Integer
>(r1
, r2
);
133 static final Type
<Integer
> PACK_LONG
= new Type
<Integer
>(){
135 public Pair
<Integer
, Integer
> solve(Integer
[] col1
, Integer
[] col2
) {
137 long[] pairs
= new long[n
];
138 for (int r
= 0; r
< n
; r
++) {
139 pairs
[r
] = ((long) col1
[r
] * MAX_N
* MAX_M
+ col2
[r
]) * n
+ r
;
142 for (int i
= 0; i
< n
- 1; i
++) {
143 if (pairs
[i
] / n
== pairs
[i
+ 1] / n
) {
144 return new Pair
<Integer
, Integer
>((int) (pairs
[i
] % n
), (int) (pairs
[i
+ 1] % n
));
152 static PrintWriter out
;
155 final boolean compact
;
160 database_gk_generic(Type
<?
> type
, boolean compact
) {
162 this.compact
= compact
;
165 static class Pair
<F
, S
> implements Comparable
<Pair
<F
, S
>> {
175 @SuppressWarnings("unchecked")
176 public int compareTo(Pair
<F
, S
> that
) {
177 int f
= ((Comparable
) this.f
).compareTo(that
.f
);
178 return f
!= 0 ? f
: ((Comparable
) this.s
).compareTo(that
.s
);
182 public boolean equals(Object o
) {
183 @SuppressWarnings("unchecked")
184 Pair
<F
, S
> that
= (Pair
<F
, S
>) o
;
185 return this.f
.equals(that
.f
) && this.s
.equals(that
.s
);
189 public int hashCode() {
190 return f
.hashCode() * 31 + s
.hashCode();
199 String
[][] values
= new String
[m
][n
];
200 for (int i
= 0; i
< n
; i
++) {
201 String
[] parts
= in
.nextLine().split(",");
202 for (int j
= 0; j
< m
; j
++) {
203 values
[j
][i
] = parts
[j
];
208 Map
<String
, Integer
> intern
= new HashMap
<String
, Integer
>();
209 Integer
[][] indices
= new Integer
[m
][n
];
211 for (int j
= 0; j
< m
; j
++) {
212 for (int i
= 0; i
< n
; i
++) {
213 String value
= values
[j
][i
];
214 Integer index
= intern
.get(value
);
217 intern
.put(value
, index
);
219 indices
[j
][i
] = index
;
223 @SuppressWarnings("unchecked")
224 Type
<Integer
> type
= (Type
<Integer
>) this.type
;
225 for (int c1
= 0; c1
< m
; c1
++) {
226 for (int c2
= c1
+ 1; c2
< m
; c2
++) {
227 Pair
<Integer
, Integer
> result
= type
.solve(indices
[c1
], indices
[c2
]);
228 if (result
!= null) {
230 out
.println(((int) result
.f
+ 1) + " " + ((int) result
.s
+ 1));
231 out
.println((c1
+ 1) + " " + (c2
+ 1));
237 @SuppressWarnings("unchecked")
238 Type
<String
> type
= (Type
<String
>) this.type
;
239 for (int c1
= 0; c1
< m
; c1
++) {
240 for (int c2
= c1
+ 1; c2
< m
; c2
++) {
241 Pair
<Integer
, Integer
> result
= type
.solve(values
[c1
], values
[c2
]);
242 if (result
!= null) {
244 out
.println(((int) result
.f
+ 1) + " " + ((int) result
.s
+ 1));
245 out
.println((c1
+ 1) + " " + (c2
+ 1));
254 static void run(Type
<?
> type
, boolean compact
) throws FileNotFoundException
{
255 in
= new Scanner(new File("database.in"));
256 out
= new PrintWriter("database.out");
258 new database_gk_generic(type
, compact
).run();