├── input ├── p1.png ├── p1 ├── p1.dot └── p9 ├── doc ├── make_clean.out ├── make_test.out └── make_build.out ├── src ├── Makefile ├── fms │ ├── utest.awk │ ├── utest.sh │ ├── Makefile │ ├── ad_lib_fms.h │ ├── ad_fms.c │ └── ad_lib_fms.c ├── pfm │ ├── utest.awk │ ├── Makefile │ ├── utest.sh │ ├── ad_lib_pfm.h │ ├── ad_pfm.c │ └── ad_lib_pfm.c ├── plm │ ├── utest.awk │ ├── Makefile │ ├── utest.sh │ ├── ad_lib_plm.h │ ├── ad_plm.c │ └── ad_lib_plm.c └── share │ ├── ad_fileio.h │ ├── ad_random.h │ ├── ad_fileio.c │ ├── ad_partition.h │ ├── ad_readinput.h │ ├── ad_random.c │ ├── Makefile │ ├── ad_bucketio.h │ ├── ad_print.h │ ├── ad_lib.h │ ├── ad_defs.h │ ├── ad_readinput.c │ ├── ad_bucketio.c │ ├── ad_partition.c │ ├── ad_print.c │ └── ad_lib.c └── README.md /input/p1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alidasdan/graph-partitioning-algorithms/HEAD/input/p1.png -------------------------------------------------------------------------------- /input/p1: -------------------------------------------------------------------------------- 1 | 6 2 | 7 3 | 1 2 0 1 4 | 1 2 1 2 5 | 1 2 2 0 6 | 1 2 3 4 7 | 1 2 4 5 8 | 1 2 5 3 9 | 1 2 0 3 10 | 1 11 | 1 12 | 1 13 | 1 14 | 1 15 | 1 16 | -------------------------------------------------------------------------------- /doc/make_clean.out: -------------------------------------------------------------------------------- 1 | make -C share clean 2 | rm -f *.o *~ core *.x 3 | make -C fms clean 4 | rm -f *.o *~ core *.x 5 | make -C plm clean 6 | rm -f *.o *~ core *.x 7 | make -C pfm clean 8 | rm -f *.o *~ core *.x 9 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | make -C share all 3 | make -C fms all 4 | make -C plm all 5 | make -C pfm all 6 | 7 | test: 8 | make -C fms test 9 | make -C plm test 10 | make -C pfm test 11 | 12 | clean: 13 | make -C share clean 14 | make -C fms clean 15 | make -C plm clean 16 | make -C pfm clean 17 | -------------------------------------------------------------------------------- /src/fms/utest.awk: -------------------------------------------------------------------------------- 1 | # Awk program called in utest.sh 2 | { 3 | # c = current cutsize 4 | # l = target cutsize 5 | c = $7 6 | s = "program=" p ": cutsize=" c " target=" t 7 | if (c == t) { 8 | print "Passed:", s; 9 | } else { 10 | print "Failed:", s; 11 | } 12 | } 13 | 14 | # EOF 15 | -------------------------------------------------------------------------------- /src/pfm/utest.awk: -------------------------------------------------------------------------------- 1 | # Awk program called in utest.sh 2 | { 3 | # c = current cutsize 4 | # l = target cutsize 5 | c = $7 6 | s = "program=" p ": cutsize=" c " target=" t 7 | if (c == t) { 8 | print "Passed:", s; 9 | } else { 10 | print "Failed:", s; 11 | } 12 | } 13 | 14 | # EOF 15 | -------------------------------------------------------------------------------- /src/plm/utest.awk: -------------------------------------------------------------------------------- 1 | # Awk program called in utest.sh 2 | { 3 | # c = current cutsize 4 | # l = target cutsize 5 | c = $7 6 | s = "program=" p ": cutsize=" c " target=" t 7 | if (c == t) { 8 | print "Passed:", s; 9 | } else { 10 | print "Failed:", s; 11 | } 12 | } 13 | 14 | # EOF 15 | -------------------------------------------------------------------------------- /src/share/ad_fileio.h: -------------------------------------------------------------------------------- 1 | #ifndef AD_FILEIO_INCLUDED 2 | #define AD_FILEIO_INCLUDED 3 | 4 | /* COPYRIGHT C 1991- Ali Dasdan */ 5 | 6 | #include 7 | 8 | /* open file fp with filename = fname and mode = mode */ 9 | void open_file(FILE **fp, 10 | char *fname, 11 | char *mode); 12 | 13 | /* close file fp */ 14 | void close_file(FILE **fp); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /input/p1.dot: -------------------------------------------------------------------------------- 1 | digraph p1 { 2 | label="(name=p1,n=6,m=7)"; 3 | 0 -> 1 [label="(w=1)"]; 4 | 1 -> 2 [label="(w=1)"]; 5 | 2 -> 0 [label="(w=1)"]; 6 | 3 -> 4 [label="(w=1)"]; 7 | 4 -> 5 [label="(w=1)"]; 8 | 5 -> 3 [label="(w=1)"]; 9 | 0 -> 3 [label="(w=1)"]; 10 | 0 [label="0 (w=1)"]; 11 | 1 [label="1 (w=1)"]; 12 | 2 [label="2 (w=1)"]; 13 | 3 [label="3 (w=1)"]; 14 | 4 [label="4 (w=1)"]; 15 | 5 [label="5 (w=1)"]; 16 | } 17 | -------------------------------------------------------------------------------- /src/fms/utest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # testing each executable using input/p1 4 | 5 | ./ad_fms.x ../../input/p1 2 123456 | grep Final | awk -v p="ad_fms p1 2" -v t=1 -f utest.awk 6 | 7 | # testing each executable using input/p9 8 | 9 | ./ad_fms.x ../../input/p9 2 123456 | grep Final | awk -v p="ad_fms p9 2" -v t=85 -f utest.awk 10 | ./ad_fms.x ../../input/p9 3 123456 | grep Final | awk -v p="ad_fms p9 3" -v t=201 -f utest.awk 11 | 12 | # EOF 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/share/ad_random.h: -------------------------------------------------------------------------------- 1 | #ifndef AD_RANDOM_INCLUDED 2 | #define AD_RANDOM_INCLUDED 3 | 4 | /* COPYRIGHT C 1991- Ali Dasdan */ 5 | 6 | #include 7 | 8 | /* These two lines of code are TERRIBLY necessary */ 9 | double drand48(); 10 | void srand48(); 11 | 12 | /* initializes random number generator with seed or */ 13 | /* with any value if seed = -1 */ 14 | long randomize(long seed); 15 | 16 | /* generates a float random number in [0, 1) */ 17 | float rand01(); 18 | 19 | /* generates a int random number in [min, max] */ 20 | /* if int output is needed, prms are true min & max */ 21 | int irandom(int min, int max); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/share/ad_fileio.c: -------------------------------------------------------------------------------- 1 | 2 | /* COPYRIGHT C 1991- Ali Dasdan */ 3 | 4 | #include 5 | #include 6 | #include 7 | #include "ad_fileio.h" 8 | 9 | /* open file fp with filename = fname and mode = mode */ 10 | void open_file(FILE **fp, 11 | char *fname, 12 | char *mode) 13 | { 14 | if ((*fp = fopen(fname, mode)) == NULL) { 15 | printf("Error: File %s can NOT be opened with mode %s: errno= %d error= %s\n", 16 | fname, mode, errno, strerror(errno)); 17 | exit(1); 18 | } 19 | } /* open_file */ 20 | 21 | /* close file fp */ 22 | void close_file(FILE **fp) 23 | { 24 | if (fclose(*fp) != 0) { 25 | printf("Error: Cannot close file: errno= %d error= %s\n", errno, strerror(errno)); 26 | exit(1); 27 | } 28 | } /* close_file */ 29 | 30 | /* EOF */ 31 | -------------------------------------------------------------------------------- /src/share/ad_partition.h: -------------------------------------------------------------------------------- 1 | #ifndef AD_PARTITION_INCLUDED 2 | #define AD_PARTITION_INCLUDED 3 | 4 | /* COPYRIGHT C 1991- Ali Dasdan */ 5 | 6 | /* create initial partition */ 7 | int create_partition(int nocells, 8 | int noparts, 9 | int totsize, 10 | cells_t cells[], 11 | ind_t *ind); 12 | 13 | /* copy partition properties to parts_info for temporary use */ 14 | void copy_partition(int noparts, 15 | parts_info_t parts_info[], 16 | ind_t *ind); 17 | 18 | /* read a partition prepared beforehand */ 19 | int read_partition(FILE *fp, 20 | char *filename, 21 | int noparts, 22 | ind_t *ind); 23 | 24 | /* write a partition */ 25 | void write_partition(FILE *fp, 26 | char *filename, 27 | int nocells, 28 | int noparts, 29 | ind_t *ind); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /src/fms/Makefile: -------------------------------------------------------------------------------- 1 | CC0 = gcc 2 | CC = $(CC0) 3 | LD = $(CC0) 4 | FLAGS1 = -O3 5 | FLAGS2 = -lm 6 | FLAGS3 = -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow 7 | DIR_H = ../share 8 | FLAGS = $(FLAGS1) $(FLAGS3) -I$(DIR_H) 9 | 10 | DEPS_SHARE = $(DIR_H)/ad_bucketio.h \ 11 | $(DIR_H)/ad_fileio.h \ 12 | $(DIR_H)/ad_lib.h \ 13 | $(DIR_H)/ad_partition.h \ 14 | $(DIR_H)/ad_print.h \ 15 | $(DIR_H)/ad_random.h \ 16 | $(DIR_H)/ad_readinput.h 17 | DEPS_FMS = ad_lib_fms.h $(DIR_H)/ad_defs.h $(DEPS_SHARE) 18 | OBJS = $(patsubst %.h,%.o,$(DEPS_SHARE)) 19 | OBJS_FMS = $(OBJS) ad_lib_fms.o 20 | 21 | all: ad_fms 22 | 23 | ad_lib_fms.o: ad_lib_fms.c ad_lib_fms.h $(DIR_H)/ad_lib.h $(DIR_H)/ad_bucketio.h $(DIR_H)/ad_defs.h 24 | $(CC) $(FLAGS) -c -o $@ $< 25 | 26 | ad_fms: ad_fms.c $(DEPS_FMS) $(OBJS_FMS) 27 | $(CC) $(FLAGS) -o $@.x $< $(OBJS_FMS) 28 | 29 | # Testing: 30 | test: 31 | ./utest.sh 32 | 33 | # Cleaning: 34 | clean c cl cle clea: 35 | rm -f *.o *~ core *.x 36 | cleano: 37 | rm -f *.o *~ core 38 | 39 | # End of file 40 | -------------------------------------------------------------------------------- /src/plm/Makefile: -------------------------------------------------------------------------------- 1 | CC0 = gcc 2 | CC = $(CC0) 3 | LD = $(CC0) 4 | FLAGS1 = -O3 5 | FLAGS2 = -lm 6 | FLAGS3 = -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow 7 | DIR_H = ../share 8 | FLAGS = $(FLAGS1) $(FLAGS3) -I$(DIR_H) 9 | 10 | DEPS_SHARE = $(DIR_H)/ad_bucketio.h \ 11 | $(DIR_H)/ad_fileio.h \ 12 | $(DIR_H)/ad_lib.h \ 13 | $(DIR_H)/ad_partition.h \ 14 | $(DIR_H)/ad_print.h \ 15 | $(DIR_H)/ad_random.h \ 16 | $(DIR_H)/ad_readinput.h 17 | DEPS_PLM = ad_lib_plm.h $(DIR_H)/ad_defs.h $(DEPS_SHARE) 18 | OBJS = $(patsubst %.h,%.o,$(DEPS_SHARE)) 19 | OBJS_PLM = $(OBJS) ad_lib_plm.o 20 | 21 | all: ad_plm 22 | 23 | ad_lib_plm.o: ad_lib_plm.c ad_lib_plm.h $(DIR_H)/ad_lib.h $(DIR_H)/ad_bucketio.h $(DIR_H)/ad_defs.h 24 | $(CC) $(FLAGS) -c -o $@ $< 25 | 26 | ad_plm: ad_plm.c $(DEPS_PLM) $(OBJS_PLM) 27 | $(CC) $(FLAGS) -o $@.x $< $(OBJS_PLM) 28 | 29 | # Testing: 30 | test: 31 | ./utest.sh 32 | 33 | # Cleaning: 34 | clean c cl cle clea: 35 | rm -f *.o *~ core *.x 36 | cleano: 37 | rm -f *.o *~ core 38 | 39 | # End of file 40 | -------------------------------------------------------------------------------- /src/pfm/Makefile: -------------------------------------------------------------------------------- 1 | CC0 = gcc 2 | CC = $(CC0) 3 | LD = $(CC0) 4 | FLAGS1 = -O3 5 | FLAGS2 = -lm 6 | FLAGS3 = -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow 7 | DIR_H = ../share 8 | FLAGS = $(FLAGS1) $(FLAGS3) -I$(DIR_H) 9 | 10 | DEPS_SHARE = $(DIR_H)/ad_bucketio.h \ 11 | $(DIR_H)/ad_fileio.h \ 12 | $(DIR_H)/ad_lib.h \ 13 | $(DIR_H)/ad_partition.h \ 14 | $(DIR_H)/ad_print.h \ 15 | $(DIR_H)/ad_random.h \ 16 | $(DIR_H)/ad_readinput.h 17 | DEPS_PFM = ad_lib_pfm.h $(DIR_H)/ad_defs.h $(DEPS_SHARE) 18 | OBJS = $(patsubst %.h,%.o,$(DEPS_SHARE)) 19 | OBJS_PFM = $(OBJS) ad_lib_pfm.o 20 | 21 | all: ad_pfm 22 | 23 | ad_lib_pfm.o: ad_lib_pfm.c ad_lib_pfm.h $(DIR_H)/ad_lib.h $(DIR_H)/ad_bucketio.h $(DIR_H)/ad_defs.h 24 | $(CC) $(FLAGS) -c -o $@ $< $(FLAGS2) 25 | 26 | ad_pfm: ad_pfm.c $(DEPS_PFM) $(OBJS_PFM) 27 | $(CC) $(FLAGS) -o $@.x $< $(OBJS_PFM) $(FLAGS2) 28 | 29 | # Testing: 30 | test: 31 | ./utest.sh 32 | 33 | # Cleaning: 34 | clean c cl cle clea: 35 | rm -f *.o *~ core *.x 36 | cleano: 37 | rm -f *.o *~ core 38 | 39 | # End of file 40 | -------------------------------------------------------------------------------- /src/pfm/utest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # testing each executable using input/p1 4 | 5 | ./ad_pfm.x ../../input/p1 2 1 1 123456 | grep Final | awk -v p="ad_pfm p1 2 1 1" -v t=1 -f utest.awk 6 | ./ad_pfm.x ../../input/p1 2 2 1 123456 | grep Final | awk -v p="ad_pfm p1 2 2 1" -v t=1 -f utest.awk 7 | ./ad_pfm.x ../../input/p1 2 3 1 123456 | grep Final | awk -v p="ad_pfm p1 2 3 1" -v t=1 -f utest.awk 8 | 9 | # testing each executable using input/p9 10 | 11 | ./ad_pfm.x ../../input/p9 2 1 1 123456 | grep Final | awk -v p="ad_pfm p9 2 1 1" -v t=75 -f utest.awk 12 | ./ad_pfm.x ../../input/p9 3 1 1 123456 | grep Final | awk -v p="ad_pfm p9 3 1 1" -v t=69 -f utest.awk 13 | ./ad_pfm.x ../../input/p9 2 2 1 123456 | grep Final | awk -v p="ad_pfm p9 2 2 1" -v t=53 -f utest.awk 14 | ./ad_pfm.x ../../input/p9 3 2 1 123456 | grep Final | awk -v p="ad_pfm p9 3 2 1" -v t=75 -f utest.awk 15 | ./ad_pfm.x ../../input/p9 2 3 2 123456 | grep Final | awk -v p="ad_pfm p9 2 3 2" -v t=32 -f utest.awk 16 | ./ad_pfm.x ../../input/p9 3 3 2 123456 | grep Final | awk -v p="ad_pfm p9 3 3 2" -v t=58 -f utest.awk 17 | 18 | # EOF 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/plm/utest.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # testing each executable using input/p1 4 | 5 | ./ad_plm.x ../../input/p1 2 1 1 123456 | grep Final | awk -v p="ad_plm p1 2 1 1" -v t=1 -f utest.awk 6 | ./ad_plm.x ../../input/p1 2 2 1 123456 | grep Final | awk -v p="ad_plm p1 2 2 1" -v t=1 -f utest.awk 7 | ./ad_plm.x ../../input/p1 2 1 2 123456 | grep Final | awk -v p="ad_plm p1 2 1 2" -v t=1 -f utest.awk 8 | 9 | # testing each executable using input/p9 10 | 11 | ./ad_plm.x ../../input/p9 2 1 1 123456 | grep Final | awk -v p="ad_plm p9 2 1 1" -v t=26 -f utest.awk 12 | ./ad_plm.x ../../input/p9 3 1 1 123456 | grep Final | awk -v p="ad_plm p9 3 1 1" -v t=157 -f utest.awk 13 | ./ad_plm.x ../../input/p9 2 2 1 123456 | grep Final | awk -v p="ad_plm p9 2 2 1" -v t=35 -f utest.awk 14 | ./ad_plm.x ../../input/p9 3 2 1 123456 | grep Final | awk -v p="ad_plm p9 3 2 1" -v t=163 -f utest.awk 15 | ./ad_plm.x ../../input/p9 2 1 2 123456 | grep Final | awk -v p="ad_plm p9 2 1 2" -v t=27 -f utest.awk 16 | ./ad_plm.x ../../input/p9 3 1 2 123456 | grep Final | awk -v p="ad_plm p9 3 1 2" -v t=175 -f utest.awk 17 | 18 | # EOF 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/share/ad_readinput.h: -------------------------------------------------------------------------------- 1 | #ifndef AD_READINPUT_INCLUDED 2 | #define AD_READINPUT_INCLUDED 3 | 4 | /* COPYRIGHT C 1991- Ali Dasdan */ 5 | 6 | /* initialize cells array */ 7 | void init_cells(int nocells, cells_t cells[]); 8 | 9 | /* initialize netlist pointers */ 10 | void init_netlist(int nonets, 11 | cells_t cells[], 12 | nets_t nets[], 13 | corn_t cnets[]); 14 | 15 | /* read input graph size to allocate memory */ 16 | void read_graph_size(char fname[], 17 | int *nocells, 18 | int *nonets); 19 | 20 | /* read input graph and construct cell, net arrays */ 21 | void read_graph(char fname[], 22 | int nocells, 23 | int nonets, 24 | int noparts, 25 | int *totsize, 26 | int *totcellsize, 27 | int *max_density, 28 | int *max_cweight, 29 | int *max_nweight, 30 | cells_t cells[], 31 | nets_t nets[], 32 | corn_t cnets[]); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/share/ad_random.c: -------------------------------------------------------------------------------- 1 | 2 | /* COPYRIGHT C 1991- Ali Dasdan */ 3 | 4 | #include 5 | #include 6 | #include "ad_random.h" 7 | 8 | /* initializes random number generator with seed or */ 9 | /* with any value if seed = -1 */ 10 | long randomize(long seed) 11 | { 12 | long in_seed; 13 | 14 | if (seed == -1) { 15 | time(&in_seed); /* init with current time */ 16 | } else { 17 | in_seed = seed; /* init with seed */ 18 | } 19 | srand48(in_seed); 20 | 21 | return in_seed; 22 | } /* randomize */ 23 | 24 | /* generates a float random number in [0, 1) */ 25 | float rand01() 26 | { 27 | return (float) drand48(); 28 | } /* rand01 */ 29 | 30 | /* generates a int random number in [min, max] */ 31 | /* if int output is needed, prms are true min & max */ 32 | int irandom(int min, int max) 33 | { 34 | if (min >= max) { 35 | return min; 36 | } else { 37 | int retval = (int) (rand01() * (float) (max + 1 - min) + (float) min); 38 | if (retval > max) { 39 | retval = max; 40 | } 41 | return retval; 42 | } /* else */ 43 | } /* irandom */ 44 | 45 | /* EOF */ 46 | -------------------------------------------------------------------------------- /src/share/Makefile: -------------------------------------------------------------------------------- 1 | CC0 = gcc 2 | CC = $(CC0) 3 | LD = $(CC0) 4 | FLAGS1 = -O3 5 | FLAGS2 = -lm 6 | FLAGS3 = -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow 7 | FLAGS = $(FLAGS1) $(FLAGS3) 8 | 9 | DEPS_COMMON = ad_bucketio.h ad_fileio.h ad_lib.h ad_partition.h ad_print.h ad_random.h ad_readinput.h 10 | OBJS = $(patsubst %.h,%.o,$(DEPS_COMMON)) 11 | 12 | all: $(OBJS) 13 | 14 | ad_bucketio.o: ad_bucketio.c ad_bucketio.h ad_defs.h 15 | $(CC) $(FLAGS) -c -o $@ $< 16 | 17 | ad_fileio.o: ad_fileio.c ad_fileio.h 18 | $(CC) $(FLAGS) -c -o $@ $< 19 | 20 | ad_lib.o: ad_lib.c ad_lib.h ad_defs.h 21 | $(CC) $(FLAGS) -c -o $@ $< 22 | 23 | ad_partition.o: ad_partition.c ad_partition.h ad_defs.h ad_fileio.h ad_random.h 24 | $(CC) $(FLAGS) -c -o $@ $< 25 | 26 | ad_print.o: ad_print.c ad_print.h ad_defs.h 27 | $(CC) $(FLAGS) -c -o $@ $< 28 | 29 | ad_random.o: ad_random.c 30 | $(CC) $(FLAGS) -c -o $@ $< 31 | 32 | ad_readinput.o: ad_readinput.c ad_readinput.h ad_fileio.h ad_defs.h 33 | $(CC) $(FLAGS) -c -o $@ $< 34 | 35 | # Testing: 36 | test: 37 | ./utest.sh 38 | 39 | # Cleaning: 40 | clean c cl cle clea: 41 | rm -f *.o *~ core *.x 42 | cleano: 43 | rm -f *.o *~ core 44 | 45 | # End of file 46 | -------------------------------------------------------------------------------- /doc/make_test.out: -------------------------------------------------------------------------------- 1 | make -C fms test 2 | ./utest.sh 3 | Passed: program=ad_fms p1 2: cutsize=1 target=1 4 | Passed: program=ad_fms p9 2: cutsize=85 target=85 5 | Passed: program=ad_fms p9 3: cutsize=201 target=201 6 | make -C plm test 7 | ./utest.sh 8 | Passed: program=ad_plm p1 2 1 1: cutsize=1 target=1 9 | Passed: program=ad_plm p1 2 2 1: cutsize=1 target=1 10 | Passed: program=ad_plm p1 2 1 2: cutsize=1 target=1 11 | Passed: program=ad_plm p9 2 1 1: cutsize=26 target=26 12 | Passed: program=ad_plm p9 3 1 1: cutsize=157 target=157 13 | Passed: program=ad_plm p9 2 2 1: cutsize=35 target=35 14 | Passed: program=ad_plm p9 3 2 1: cutsize=163 target=163 15 | Passed: program=ad_plm p9 2 1 2: cutsize=27 target=27 16 | Passed: program=ad_plm p9 3 1 2: cutsize=175 target=175 17 | make -C pfm test 18 | ./utest.sh 19 | Passed: program=ad_pfm p1 2 1 1: cutsize=1 target=1 20 | Passed: program=ad_pfm p1 2 2 1: cutsize=1 target=1 21 | Passed: program=ad_pfm p1 2 3 1: cutsize=1 target=1 22 | Passed: program=ad_pfm p9 2 1 1: cutsize=75 target=75 23 | Passed: program=ad_pfm p9 3 1 1: cutsize=69 target=69 24 | Passed: program=ad_pfm p9 2 2 1: cutsize=53 target=53 25 | Passed: program=ad_pfm p9 3 2 1: cutsize=75 target=75 26 | Passed: program=ad_pfm p9 2 3 2: cutsize=32 target=32 27 | Passed: program=ad_pfm p9 3 3 2: cutsize=58 target=58 28 | -------------------------------------------------------------------------------- /src/share/ad_bucketio.h: -------------------------------------------------------------------------------- 1 | #ifndef AD_BUCKETIO_INCLUDED 2 | #define AD_BUCKETIO_INCLUDED 3 | 4 | /* COPYRIGHT C 1991- Ali Dasdan */ 5 | 6 | /* create a partb node */ 7 | void create_partb_node(int noparts, 8 | int mov_cell_no, 9 | int home_part, 10 | int mapped_dest_part, 11 | int mov_gain_inx, 12 | partb_t partb[][noparts - 1], 13 | cells_info_t cells_info[]); 14 | 15 | /* insert a node into partb */ 16 | void insert_partb_node(bnode_ptr_t tnode_ptr, 17 | int mapped_dest_part, 18 | int mov_gain_inx, 19 | partb_t *partb_ptr, 20 | cells_info_t *cells_info_ptr); 21 | 22 | /* delete all nodes of a cell from partb */ 23 | void delete_partb_nodes_of_cell(int noparts, 24 | int mov_cell_no, 25 | int home_part, 26 | partb_t partb[][noparts - 1], 27 | cells_info_t cells_info[]); 28 | 29 | /* delete a partb node */ 30 | bnode_ptr_t delete_partb_node(int deletion_ok, 31 | int mapped_dest_part, 32 | partb_t *partb_ptr, 33 | cells_info_t *cells_info_ptr); 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /src/share/ad_print.h: -------------------------------------------------------------------------------- 1 | #ifndef AD_PRINT_INCLUDED 2 | #define AD_PRINT_INCLUDED 3 | 4 | /* COPYRIGHT C 1991- Ali Dasdan */ 5 | 6 | void print_graph(int nocells, 7 | int nonets, 8 | int noparts, 9 | cells_t cells[], 10 | nets_t nets[]); 11 | 12 | void print_vars(int nocells, 13 | int noparts, 14 | int nonets, 15 | int totsize, 16 | int cutsize, 17 | int bucketsize); 18 | 19 | void print_parts(int nocells, 20 | int noparts, 21 | ind_t *ind, 22 | allele tchrom[]); 23 | 24 | void print_parts_info(int nocells, 25 | int noparts, 26 | allele chrom[], 27 | parts_info_t parts_info[]); 28 | 29 | void print_cells(int nocells, 30 | cells_t cells[], 31 | corn_t cnets[]); 32 | 33 | void print_nets(int nonets, nets_t nets[]); 34 | 35 | void print_cnets(int nonets, corn_t cnets[]); 36 | 37 | void print_chrom(int nocells, allele chrom[]); 38 | 39 | void print_cells_info(int nocells, 40 | int noparts, 41 | cells_info_t cells_info[]); 42 | 43 | void print_inx(int noparts, partb_t partb[][noparts - 1]); 44 | 45 | void print_buckets(int noparts, 46 | int bucketsize, 47 | partb_t partb[][noparts - 1]); 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/fms/ad_lib_fms.h: -------------------------------------------------------------------------------- 1 | #ifndef AD_LIB_FMS_INCLUDED 2 | #define AD_LIB_FMS_INCLUDED 3 | 4 | /* COPYRIGHT C 1991- Ali Dasdan */ 5 | 6 | #include "ad_defs.h" 7 | 8 | /* map a given mov_gain into index to a bucket array */ 9 | int map_gain(int mov_gain, int max_gain); 10 | 11 | /* fill all bucket arrays */ 12 | void create_buckets(int nocells, 13 | int noparts, 14 | int max_gain, 15 | allele chrom[], 16 | partb_t partb[][noparts - 1], 17 | cells_info_t cells_info[]); 18 | 19 | /* select a cell to move */ 20 | int select_cell(int noparts, 21 | selected_cell_t scell[], 22 | parts_info_t parts_info[], 23 | cells_t cells[], 24 | partb_t partb[][noparts - 1], 25 | cells_info_t cells_info[]); 26 | 27 | /* move selected cell, and save the move in a file */ 28 | void move_cell(mcells_t mcells[], 29 | int msize, 30 | selected_cell_t scell[]); 31 | 32 | /* update gains after a move */ 33 | void update_gains(int noparts, 34 | int max_gain, 35 | selected_cell_t scell[], 36 | allele tchrom[], 37 | cells_t cells[], 38 | nets_t nets[], 39 | corn_t cnets[], 40 | partb_t partb[][noparts - 1], 41 | cells_info_t cells_info[]); 42 | 43 | void create_partb_nodes_of_cell(int noparts, 44 | int max_gain, 45 | int cell_no, 46 | int part_no, 47 | partb_t partb[][noparts - 1], 48 | cells_info_t cells_info[]); 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /src/plm/ad_lib_plm.h: -------------------------------------------------------------------------------- 1 | #ifndef AD_LIB_PLM_INCLUDED 2 | #define AD_LIB_PLM_INCLUDED 3 | 4 | /* COPYRIGHT C 1991- Ali Dasdan */ 5 | 6 | /* map a given mov_gain into index to a bucket array */ 7 | int map_gain(int mov_gain, int max_gain); 8 | 9 | /* fill all bucket arrays */ 10 | void create_buckets(int nocells, 11 | int noparts, 12 | int max_gain, 13 | allele chrom[], 14 | partb_t partb[][noparts - 1], 15 | cells_info_t cells_info[]); 16 | 17 | /* select a cell to move */ 18 | int select_cell(int noparts, 19 | selected_cell_t scell[], 20 | parts_info_t parts_info[], 21 | cells_t cells[], 22 | partb_t partb[][noparts - 1], 23 | cells_info_t cells_info[]); 24 | 25 | /* move selected cell, and save the move in a file */ 26 | void move_cell(mcells_t mcells[], 27 | int msize, 28 | selected_cell_t scell[], 29 | allele tchrom[]); 30 | 31 | /* update gains after a move */ 32 | void update_gains(int noparts, 33 | int max_gain, 34 | selected_cell_t scell[], 35 | allele tchrom[], 36 | cells_t cells[], 37 | nets_t nets[], 38 | corn_t cnets[], 39 | partb_t partb[][noparts - 1], 40 | cells_info_t cells_info[]); 41 | 42 | void create_partb_nodes_of_cell(int noparts, 43 | int max_gain, 44 | int cell_no, 45 | int part_no, 46 | partb_t partb[][noparts - 1], 47 | cells_info_t cells_info[]); 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /doc/make_build.out: -------------------------------------------------------------------------------- 1 | make -C share all 2 | gcc -O3 -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow -c -o ad_bucketio.o ad_bucketio.c 3 | gcc -O3 -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow -c -o ad_fileio.o ad_fileio.c 4 | gcc -O3 -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow -c -o ad_lib.o ad_lib.c 5 | gcc -O3 -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow -c -o ad_partition.o ad_partition.c 6 | gcc -O3 -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow -c -o ad_print.o ad_print.c 7 | gcc -O3 -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow -c -o ad_random.o ad_random.c 8 | gcc -O3 -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow -c -o ad_readinput.o ad_readinput.c 9 | make -C fms all 10 | gcc -O3 -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow -I../share -c -o ad_lib_fms.o ad_lib_fms.c 11 | gcc -O3 -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow -I../share -o ad_fms.x ad_fms.c ../share/ad_bucketio.o ../share/ad_fileio.o ../share/ad_lib.o ../share/ad_partition.o ../share/ad_print.o ../share/ad_random.o ../share/ad_readinput.o ad_lib_fms.o 12 | make -C plm all 13 | gcc -O3 -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow -I../share -c -o ad_lib_plm.o ad_lib_plm.c 14 | gcc -O3 -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow -I../share -o ad_plm.x ad_plm.c ../share/ad_bucketio.o ../share/ad_fileio.o ../share/ad_lib.o ../share/ad_partition.o ../share/ad_print.o ../share/ad_random.o ../share/ad_readinput.o ad_lib_plm.o 15 | make -C pfm all 16 | gcc -O3 -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow -I../share -c -o ad_lib_pfm.o ad_lib_pfm.c -lm 17 | gcc -O3 -std=c99 -Dlint -D__lint -Wall -Winline -Wno-deprecated -Wno-strict-overflow -I../share -o ad_pfm.x ad_pfm.c ../share/ad_bucketio.o ../share/ad_fileio.o ../share/ad_lib.o ../share/ad_partition.o ../share/ad_print.o ../share/ad_random.o ../share/ad_readinput.o ad_lib_pfm.o -lm 18 | -------------------------------------------------------------------------------- /src/share/ad_lib.h: -------------------------------------------------------------------------------- 1 | #ifndef AD_LIB_INCLUDED 2 | #define AD_LIB_INCLUDED 3 | 4 | /* COPYRIGHT C 1991- Ali Dasdan */ 5 | 6 | /* find the neighbor cell of cell_no, on the net net_no */ 7 | void find_other_cell(int net_no, 8 | int cell_no, 9 | int *other_cell, 10 | int *other_part_no, 11 | int *net_weight, 12 | allele chrom[], 13 | nets_t nets[]); 14 | 15 | /* initialize all bucket indices and pointers */ 16 | void init_buckets(int noparts, 17 | int bucketsize, 18 | partb_t partb[][noparts - 1]); 19 | 20 | /* map part no such that home_part is excluded */ 21 | int map_part_no(int dest_part, int home_part); 22 | 23 | /* compute move gain from home_part to dest_part */ 24 | int calculate_gain(int cell_no, 25 | int home_part, 26 | int dest_part, 27 | cells_info_t cells_info[]); 28 | 29 | /* compute gains of all cells and place them into cells_info */ 30 | void compute_gains(int nocells, 31 | int noparts, 32 | allele tchrom[], 33 | cells_t cells[], 34 | nets_t nets[], 35 | corn_t cnets[], 36 | cells_info_t cells_info[]); 37 | 38 | /* free all allocated nodes */ 39 | void free_nodes(int noparts, 40 | int bucketsize, 41 | partb_t partb[][noparts - 1]); 42 | 43 | /* count number of bucket nodes */ 44 | void number_nodes(int noparts, 45 | int bucketsize, 46 | int *npartb, 47 | partb_t partb[][noparts - 1]); 48 | 49 | /* find set of cells to be actually moved */ 50 | int find_move_set(mcells_t mcells[], 51 | int msize, 52 | int *max_mcells_inx); 53 | 54 | /* move cells actually */ 55 | int move_cells(int wflag, 56 | mcells_t mcells[], 57 | int max_mcells_inx, 58 | int cutsize, 59 | int *glob_inx, 60 | ind_t *ind, 61 | cells_t cells[]); 62 | 63 | /* finds cut size of a given partition - used for control */ 64 | int find_cut_size(int nonets, 65 | int totsize, 66 | nets_t nets[], 67 | ind_t *ind); 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /src/pfm/ad_lib_pfm.h: -------------------------------------------------------------------------------- 1 | #ifndef AD_LIB_PFM_INCLUDED 2 | #define AD_LIB_PFM_INCLUDED 3 | 4 | /* COPYRIGHT C 1991- Ali Dasdan */ 5 | 6 | /* map a given mov_gain into index to a bucket array */ 7 | int map_gain(int bucketsize, 8 | int mov_gain, 9 | int mov_count, 10 | int max_gain, 11 | eval_t eval[]); 12 | 13 | /* fill all bucket arrays */ 14 | void create_buckets(int bucketsize, 15 | int nocells, 16 | int noparts, 17 | int max_gain, 18 | eval_t eval[], 19 | allele chrom[], 20 | partb_t partb[][noparts - 1], 21 | cells_info_t cells_info[]); 22 | 23 | /* select a cell to move */ 24 | void select_cell(int noparts, 25 | selected_cell_t scell[], 26 | parts_info_t parts_info[], 27 | cells_t cells[], 28 | partb_t partb[][noparts - 1], 29 | cells_info_t cells_info[]); 30 | 31 | /* move selected cell, and save the move in a file */ 32 | void move_cell(mcells_t mcells[], 33 | int msize, 34 | selected_cell_t scell[], 35 | allele tchrom[], 36 | cells_info_t cells_info[]); 37 | 38 | /* update gains after a move */ 39 | void update_gains(int bucketsize, 40 | int noparts, 41 | int max_gain, 42 | eval_t eval[], 43 | selected_cell_t scell[], 44 | allele tchrom[], 45 | cells_t cells[], 46 | nets_t nets[], 47 | corn_t cnets[], 48 | partb_t partb[][noparts - 1], 49 | cells_info_t cells_info[]); 50 | 51 | /* fill eval array */ 52 | void fill_eval(int max_gain, 53 | float K, 54 | eval_t eval[]); 55 | 56 | void create_partb_nodes_of_cell(int bucketsize, 57 | int noparts, 58 | int max_gain, 59 | int cell_no, 60 | int part_no, 61 | eval_t eval[], 62 | partb_t partb[][noparts - 1], 63 | cells_info_t cells_info[]); 64 | 65 | /* calculate K and scale factor */ 66 | void calculate_scale(int nocells, 67 | int noparts, 68 | int max_gain, 69 | float *K); 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /src/share/ad_defs.h: -------------------------------------------------------------------------------- 1 | #ifndef AD_DEFS_INCLUDED 2 | #define AD_DEFS_INCLUDED 3 | 4 | /* COPYRIGHT C 1991- Ali Dasdan */ 5 | 6 | /* naming conventions : 7 | cell = node, net = edge, 8 | */ 9 | 10 | #define True 1 /* boolean true */ 11 | #define False 0 /* boolean false */ 12 | 13 | #define MAX_POP 1 /* max numbr of individuals in population */ 14 | #define NIL -1 /* point to nowhere */ 15 | #define STR_SIZE 30 /* string size */ 16 | #define NO_ITERATIONS 200 /* max number of iterations for KL */ 17 | #define EPSILON 0.01 /* min move value of a cell */ 18 | 19 | /* cells type */ 20 | typedef struct cells_st { 21 | int cno_nets; /* total number of nets on the cell */ 22 | int cno_inets; /* number of internal nets */ 23 | int cweight; /* weight of cell */ 24 | int netlist; /* pointer to nets on the cell */ 25 | } cells_t; 26 | 27 | /* nets type */ 28 | typedef struct nets_st { 29 | int nweight; /* weight of node */ 30 | int ncells[2]; /* For GP, nno_cells = 2 and */ 31 | /* ncells[0] & ncells[1] are the cells on the net */ 32 | } nets_t; 33 | 34 | /* cell cornlist type - CorN = Cell or Net */ 35 | typedef struct corn_st { 36 | int corn_no; /* cell or net number */ 37 | } corn_t; 38 | 39 | /* allele definition - for compatibility purposes */ 40 | typedef int allele; 41 | 42 | /* partition type */ 43 | typedef struct parts_st { 44 | int pmax_cells; /* maximum number of cells in partition */ 45 | int pmax_size; /* maximum size of part */ 46 | int pmin_size; /* minimum size of part */ 47 | int pcurr_size; /* current size of part */ 48 | float pratio; /* pmax_size / totsize */ 49 | } parts_t; 50 | 51 | /* individual type */ 52 | typedef struct pop_st { 53 | allele *chrom; /* string holding partitions */ 54 | parts_t *parts; /* partition array */ 55 | int incost; /* sum of net weights - cut cost */ 56 | } ind_t; 57 | 58 | /* temporary partition type */ 59 | typedef struct tparts_st { /* used while creating partition celllists */ 60 | char filled; /* set if partition is filled with cells */ 61 | int pcells_inx; /* an index to pcells */ 62 | } tparts_t; 63 | 64 | /* bucket nodes (= bnode) */ 65 | typedef struct bnode_st *bnode_ptr_t; 66 | 67 | typedef struct bnode_st { 68 | int cell_no; /* cell in the node */ 69 | bnode_ptr_t lptr; /* pointer to left node */ 70 | bnode_ptr_t rptr; /* pointer to right node */ 71 | } bnode_t; 72 | 73 | /* partition bucket (partb) type */ 74 | typedef struct partb_st { 75 | bnode_ptr_t *bnode_ptr; 76 | int max_inx; /* max index of filled bucket cell */ 77 | int min_inx; /* min index of filled bucket cell */ 78 | int nobuckets; /* number of filled buckets */ 79 | } partb_t; 80 | 81 | /* additional information for cells */ 82 | typedef struct cells_info_st { 83 | int mcount; /* count of moves that cell performs */ 84 | int locked; /* set if cell is locked */ 85 | int *mgain; /* external costs of moving cell_no to all parts */ 86 | /* only mgain[part_no of cell_no] is internal cost */ 87 | bnode_ptr_t *partb_ptr; /* pointer to partb node */ 88 | int *partb_gain_inx; /* index to partb bucket */ 89 | /* pointers to part_bucket */ 90 | } cells_info_t; 91 | 92 | /* selected cell structure */ 93 | typedef struct selected_cell_st { 94 | int mov_cell_no; /* current properties */ 95 | int from_part; 96 | int to_part; 97 | int mov_gain; 98 | } selected_cell_t; 99 | 100 | /* moved cells array */ 101 | typedef struct mcells_st { 102 | int cell_no; /* the cell moved */ 103 | int from; /* cell's home partition */ 104 | int to; /* cell's destination partition */ 105 | int mgain; /* move gain */ 106 | } mcells_t; 107 | 108 | /* partition information type */ 109 | typedef struct parts_info_st { 110 | int pmax_cells; /* maximum number of cells in partition */ 111 | int pmax_size; /* maximum size of part */ 112 | int pmin_size; /* minimum size of part */ 113 | int pcurr_size; /* current size of part */ 114 | } parts_info_t; 115 | 116 | /* precomputed exponential values */ 117 | typedef struct eval_st { 118 | float val; 119 | } eval_t; 120 | 121 | #endif 122 | -------------------------------------------------------------------------------- /src/share/ad_readinput.c: -------------------------------------------------------------------------------- 1 | 2 | /* COPYRIGHT C 1991- Ali Dasdan */ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "ad_defs.h" 9 | #include "ad_fileio.h" 10 | #include "ad_readinput.h" 11 | 12 | /* initialize cells array */ 13 | void init_cells(int nocells, cells_t cells[]) 14 | { 15 | for (int i = 0; i < nocells; i++) { 16 | cells[i].cno_nets = 0; 17 | cells[i].cno_inets = 0; 18 | cells[i].netlist = NIL; 19 | } /* for */ 20 | } /* init_cells */ 21 | 22 | /* initialize netlist pointers */ 23 | void init_netlist(int nonets, 24 | cells_t cells[], 25 | nets_t nets[], 26 | corn_t cnets[]) 27 | { 28 | for (int i = 0; i < nonets; i++) { 29 | /* for cell1 and cell2 */ 30 | for (int j = 0; j < 2; j++) { 31 | int tcell_no = nets[i].ncells[0]; 32 | if (j != 0) { 33 | tcell_no = nets[i].ncells[1]; 34 | } 35 | int net_index = cells[tcell_no].netlist + cells[tcell_no].cno_inets; 36 | cnets[net_index].corn_no = i; 37 | cells[tcell_no].cno_inets++; 38 | if (cells[tcell_no].cno_inets > cells[tcell_no].cno_nets) { 39 | printf("Error: Inconsistency in cell_%d degrees.\n", j); 40 | exit(1); 41 | } /* if */ 42 | } /* for j */ 43 | } /* for i */ 44 | } /* init_netlist */ 45 | 46 | /* read input graph size to allocate memory */ 47 | void read_graph_size(char fname[], 48 | int *nocells, 49 | int *nonets) 50 | { 51 | FILE *fp; 52 | 53 | open_file(&fp, fname, "r"); 54 | 55 | if (fscanf(fp, "%d%d", nocells, nonets) == EOF) { 56 | printf("Error: Cannot read from %s: errno= %d error= %s\n", fname, errno, strerror(errno)); 57 | close_file(&fp); 58 | exit(1); 59 | } 60 | 61 | if ((*nocells < 0) || (*nonets < 0)) { 62 | printf("Error: Invalid attributes of graph.\n"); 63 | close_file(&fp); 64 | exit(1); 65 | } /* if */ 66 | 67 | close_file(&fp); 68 | } /* read_graph_size */ 69 | 70 | /* read input graph and construct cell, net arrays */ 71 | void read_graph(char fname[], 72 | int nocells, 73 | int nonets, 74 | int noparts, 75 | int *totsize, 76 | int *totcellsize, 77 | int *max_density, 78 | int *max_cweight, 79 | int *max_nweight, 80 | cells_t cells[], 81 | nets_t nets[], 82 | corn_t cnets[]) 83 | { 84 | FILE *fp; 85 | open_file(&fp, fname, "r"); 86 | 87 | /* graph size is already read so re-read and discard. */ 88 | int ignore1, ignore2; 89 | if (fscanf(fp, "%d%d", &ignore1, &ignore2) == EOF) { 90 | printf("Error: Cannot read from %s: errno= %d error= %s\n", fname, errno, strerror(errno)); 91 | close_file(&fp); 92 | exit(1); 93 | } 94 | 95 | /* initialize cells array */ 96 | init_cells(nocells, cells); 97 | 98 | /* read nets */ 99 | *max_nweight = -1; 100 | *totsize = 0; 101 | for (int i = 0; i < nonets; i++) { 102 | int ignore; /* this is the number of pins on this net; it 103 | makes sense for hypergraphs; for graphs, it is 104 | always 2. */ 105 | if (fscanf(fp, "%d%d%d%d", &nets[i].nweight, &ignore, &nets[i].ncells[0], &nets[i].ncells[1]) == EOF) { 106 | printf("Error: Cannot read from %s: errno= %d error= %s\n", fname, errno, strerror(errno)); 107 | close_file(&fp); 108 | exit(1); 109 | } 110 | /* temp for reading 2, the net degree */ 111 | cells[nets[i].ncells[0]].cno_nets++; 112 | cells[nets[i].ncells[1]].cno_nets++; 113 | *totsize += nets[i].nweight; 114 | if (nets[i].nweight > (*max_nweight)) { 115 | *max_nweight = nets[i].nweight; 116 | } 117 | } /* for */ 118 | 119 | /* set netlist pointers */ 120 | *max_density = -1; 121 | *max_cweight = -1; 122 | *totcellsize = 0; 123 | int part_sum = 0; 124 | for (int i = 0; i < nocells; i++) { 125 | if (fscanf(fp, "%d", &cells[i].cweight) == EOF) { 126 | printf("Error: Cannot read from %s: errno= %d error= %s\n", fname, errno, strerror(errno)); 127 | close_file(&fp); 128 | exit(1); 129 | } 130 | (*totcellsize) += cells[i].cweight; 131 | if (cells[i].cweight > (*max_cweight)) { 132 | *max_cweight = cells[i].cweight; 133 | } 134 | if (cells[i].cno_nets > (*max_density)) { 135 | *max_density = cells[i].cno_nets; 136 | } 137 | cells[i].netlist = part_sum; 138 | part_sum += cells[i].cno_nets; 139 | } /* for */ 140 | 141 | close_file(&fp); 142 | 143 | /* create netlists */ 144 | init_netlist(nonets, cells, nets, cnets); 145 | } /* read_graph */ 146 | 147 | /* EOF */ 148 | 149 | -------------------------------------------------------------------------------- /src/share/ad_bucketio.c: -------------------------------------------------------------------------------- 1 | 2 | /* COPYRIGHT C 1991- Ali Dasdan */ 3 | 4 | #include 5 | #include 6 | #include 7 | #include "ad_defs.h" 8 | #include "ad_bucketio.h" 9 | 10 | /* create a partb node */ 11 | void create_partb_node(int noparts, 12 | int mov_cell_no, 13 | int home_part, 14 | int mapped_dest_part, 15 | int mov_gain_inx, 16 | partb_t partb[][noparts - 1], 17 | cells_info_t cells_info[]) 18 | { 19 | bnode_ptr_t tnode_ptr = (bnode_ptr_t) malloc(sizeof(bnode_t)); 20 | if (tnode_ptr == NULL) { 21 | printf("Error: Cannot allocate memory for tnode_ptr.\n"); 22 | exit(1); 23 | } /* if */ 24 | tnode_ptr->cell_no = mov_cell_no; 25 | insert_partb_node(tnode_ptr, 26 | mapped_dest_part, mov_gain_inx, 27 | &partb[home_part][mapped_dest_part], 28 | &cells_info[mov_cell_no]); 29 | } /* create_partb_node */ 30 | 31 | /* insert a node into partb */ 32 | void insert_partb_node(bnode_ptr_t tnode_ptr, 33 | int mapped_dest_part, 34 | int mov_gain_inx, 35 | partb_t *partb_ptr, 36 | cells_info_t *cells_info_ptr) 37 | { 38 | /* 39 | partb_ptr = partb[home_part][mapped_dest_part] 40 | cells_info_ptr = cells_info[mov_cell_no] 41 | */ 42 | int bucket_empty = False; 43 | if (partb_ptr->bnode_ptr[mov_gain_inx] == NULL) { 44 | bucket_empty = True; 45 | } 46 | tnode_ptr->lptr = NULL; 47 | tnode_ptr->rptr = partb_ptr->bnode_ptr[mov_gain_inx]; 48 | if (! bucket_empty) { 49 | (tnode_ptr->rptr)->lptr = tnode_ptr; 50 | } 51 | partb_ptr->bnode_ptr[mov_gain_inx] = tnode_ptr; 52 | 53 | /* insert into cells_info */ 54 | cells_info_ptr->partb_ptr[mapped_dest_part] = tnode_ptr; 55 | cells_info_ptr->partb_gain_inx[mapped_dest_part] = mov_gain_inx; 56 | 57 | /* update indices */ 58 | if (partb_ptr->nobuckets == 0) { 59 | partb_ptr->max_inx = mov_gain_inx; 60 | partb_ptr->min_inx = mov_gain_inx; 61 | } else if (mov_gain_inx > partb_ptr->max_inx) { 62 | partb_ptr->max_inx = mov_gain_inx; 63 | } else if (mov_gain_inx < partb_ptr->min_inx) { 64 | partb_ptr->min_inx = mov_gain_inx; 65 | } 66 | if (bucket_empty) { 67 | partb_ptr->nobuckets++; 68 | } 69 | } /* insert_partb_node */ 70 | 71 | /* delete all nodes of a cell from partb */ 72 | void delete_partb_nodes_of_cell(int noparts, 73 | int mov_cell_no, 74 | int home_part, 75 | partb_t partb[][noparts - 1], 76 | cells_info_t cells_info[]) 77 | { 78 | for (int mapped_dest_part = 0; mapped_dest_part < (noparts - 1); mapped_dest_part++) { 79 | delete_partb_node(True, mapped_dest_part, 80 | &partb[home_part][mapped_dest_part], 81 | &cells_info[mov_cell_no]); 82 | } 83 | } /* delete_partb_nodes_of_cell */ 84 | 85 | /* delete a partb node */ 86 | bnode_ptr_t delete_partb_node(int deletion_ok, 87 | int mapped_dest_part, 88 | partb_t *partb_ptr, 89 | cells_info_t *cells_info_ptr) 90 | { 91 | /* 92 | cells_info_ptr = cells_info[mov_cell_no] 93 | partb_ptr = partb[home_part][mapped_dest_part] 94 | */ 95 | bnode_ptr_t tnode_ptr = cells_info_ptr->partb_ptr[mapped_dest_part]; 96 | int mov_gain_inx = cells_info_ptr->partb_gain_inx[mapped_dest_part]; 97 | if (tnode_ptr != NULL) { 98 | if (tnode_ptr->lptr == NULL) { /* if 1st node */ 99 | if (tnode_ptr->rptr != NULL) { /* make next node the 1st node */ 100 | (tnode_ptr->rptr)->lptr = NULL; 101 | } 102 | partb_ptr->bnode_ptr[mov_gain_inx] = tnode_ptr->rptr; 103 | if (partb_ptr->bnode_ptr[mov_gain_inx] == NULL) { 104 | partb_ptr->nobuckets--; 105 | if (partb_ptr->nobuckets == 0) { /* if no more full buckets */ 106 | partb_ptr->max_inx = -1; 107 | partb_ptr->min_inx = -1; 108 | } else { /* set max_inx to the next full bucket index */ 109 | while ((partb_ptr->max_inx > partb_ptr->min_inx) && 110 | (partb_ptr->bnode_ptr[partb_ptr->max_inx] == NULL)) { 111 | partb_ptr->max_inx--; 112 | } /* while */ 113 | } /* else */ 114 | } /* if bucket is empty */ 115 | } else { 116 | (tnode_ptr->lptr)->rptr = tnode_ptr->rptr; 117 | if (tnode_ptr->rptr != NULL) { 118 | (tnode_ptr->rptr)->lptr = tnode_ptr->lptr; 119 | } 120 | } /* else */ 121 | 122 | if (deletion_ok) { 123 | free(tnode_ptr); 124 | cells_info_ptr->partb_ptr[mapped_dest_part] = NULL; 125 | } /* if */ 126 | } /* if tnode_ptr is not nil */ 127 | 128 | return (tnode_ptr); 129 | } /* delete_partb_node */ 130 | 131 | /* EOF */ 132 | -------------------------------------------------------------------------------- /src/share/ad_partition.c: -------------------------------------------------------------------------------- 1 | 2 | /* COPYRIGHT C 1991- Ali Dasdan */ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "ad_random.h" 9 | #include "ad_fileio.h" 10 | #include "ad_defs.h" 11 | #include "ad_partition.h" 12 | 13 | /* create initial partition */ 14 | int create_partition(int nocells, 15 | int noparts, 16 | int totsize, 17 | cells_t cells[], 18 | ind_t *ind) 19 | { 20 | /* init current size */ 21 | for (int i = 0; i < noparts; i++) { 22 | ind->parts[i].pratio = 1.0 / noparts; 23 | ind->parts[i].pcurr_size = 0; 24 | ind->parts[i].pmax_cells = 0; 25 | } /* for i */ 26 | 27 | /* allocate temporary memory */ 28 | int *tparts = (int *) calloc(noparts, sizeof(int)); 29 | if (tparts == NULL) { 30 | printf("Error: Unable to allocate memory for tparts.\n"); 31 | exit(1); 32 | } /* if */ 33 | 34 | /* insert cells */ 35 | for (int i = 0; i < nocells; i++) { 36 | 37 | /* find minimum */ 38 | int min_inx = 0; 39 | int min_size = ind->parts[0].pcurr_size; 40 | for (int j = 1; j < noparts; j++) { 41 | if (min_size > ind->parts[j].pcurr_size) { 42 | min_inx = j; 43 | min_size = ind->parts[j].pcurr_size; 44 | } /* if */ 45 | } /* for j */ 46 | 47 | /* find a new minimum among the same minimums */ 48 | int tcount = -1; /* tparts is used to randomize partitioning */ 49 | for (int j = 0; j < noparts; j++) { 50 | if (ind->parts[j].pcurr_size == min_size) { 51 | tcount++; 52 | tparts[tcount] = j; 53 | } /* if */ 54 | } /* for j */ 55 | min_inx = tparts[irandom(0, tcount)]; 56 | 57 | /* assign cell i to part[min_inx] */ 58 | ind->chrom[i] = min_inx; 59 | ind->parts[min_inx].pcurr_size += cells[i].cweight; 60 | ind->parts[min_inx].pmax_cells++; 61 | } /* for i */ 62 | 63 | float off_ratio = 0.1; 64 | int max_size = -1; 65 | for (int i = 0; i < noparts; i++) { 66 | float part_size = ((float) totsize) * ind->parts[i].pratio; 67 | ind->parts[i].pmax_size = (int) (part_size * (1.0 + off_ratio) + 1.0); 68 | if (ind->parts[i].pmax_size > max_size) { 69 | max_size = ind->parts[i].pmax_size; 70 | } 71 | ind->parts[i].pmin_size = (int) (part_size * (1.0 - off_ratio) - 1.0); 72 | } /* for i */ 73 | 74 | free(tparts); 75 | 76 | return max_size; 77 | } /* create_partition */ 78 | 79 | /* copy partition properties to parts_info for temporary use */ 80 | void copy_partition(int noparts, 81 | parts_info_t parts_info[], 82 | ind_t *ind) 83 | { 84 | for (int i = 0; i < noparts; i++) { 85 | parts_info[i].pmax_cells = ind->parts[i].pmax_cells; 86 | parts_info[i].pmin_size = ind->parts[i].pmin_size; 87 | parts_info[i].pcurr_size = ind->parts[i].pcurr_size; 88 | parts_info[i].pmax_size = ind->parts[i].pmax_size; 89 | } /* for i */ 90 | } /* copy_partition */ 91 | 92 | /* read a partition prepared beforehand */ 93 | int read_partition(FILE *fp, 94 | char *filename, 95 | int noparts, 96 | ind_t *ind) 97 | { 98 | int max_size = -1; 99 | open_file(&fp, filename, "r"); 100 | 101 | for (int i = 0; i < noparts; i++) { 102 | 103 | int part_no; 104 | if (fscanf(fp, "%d", &part_no) == EOF) { 105 | printf("Error: Cannot read from %s: errno= %d error= %s\n", filename, errno, strerror(errno)); 106 | } 107 | 108 | if (fscanf(fp, "%d%d%d%d", 109 | &(ind->parts[part_no].pmax_cells), 110 | &(ind->parts[part_no].pmin_size), 111 | &(ind->parts[part_no].pcurr_size), 112 | &(ind->parts[part_no].pmax_size)) == EOF) { 113 | printf("Error: Cannot read from %s: errno= %d error= %s\n", filename, errno, strerror(errno)); 114 | } 115 | 116 | if (ind->parts[part_no].pmax_size > max_size) 117 | max_size = ind->parts[part_no].pmax_size; 118 | 119 | for (int j = 0; j < ind->parts[part_no].pmax_cells; j++) { 120 | 121 | int cell_no; 122 | if (fscanf(fp, "%d", &cell_no) == EOF) { 123 | printf("Error: Cannot read from %s: errno= %d error= %s\n", filename, errno, strerror(errno)); 124 | } 125 | ind->chrom[cell_no] = part_no; 126 | 127 | } /* for j */ 128 | 129 | } /* for i */ 130 | 131 | close_file(&fp); 132 | 133 | return max_size; 134 | } /* read_partition */ 135 | 136 | /* write a partition */ 137 | void write_partition(FILE *fp, 138 | char *filename, 139 | int nocells, 140 | int noparts, 141 | ind_t *ind) 142 | { 143 | open_file(&fp, filename, "w"); 144 | 145 | for (int i = 0; i < noparts; i++) { 146 | fprintf(fp, "%d %d %d %d %d\n", i, 147 | ind->parts[i].pmax_cells, 148 | ind->parts[i].pmin_size, 149 | ind->parts[i].pcurr_size, 150 | ind->parts[i].pmax_size); 151 | for (int j = 0; j < nocells; j++) 152 | if (ind->chrom[j] == i) 153 | fprintf(fp, "%d ", j); 154 | fprintf(fp, "\n"); 155 | } /* for i */ 156 | 157 | close_file(&fp); 158 | } /* read_partition */ 159 | 160 | /* EOF */ 161 | -------------------------------------------------------------------------------- /src/share/ad_print.c: -------------------------------------------------------------------------------- 1 | 2 | /* COPYRIGHT C 1991- Ali Dasdan */ 3 | 4 | #include 5 | #include "ad_defs.h" 6 | #include "ad_print.h" 7 | 8 | void print_graph(int nocells, 9 | int nonets, 10 | int noparts, 11 | cells_t cells[], 12 | nets_t nets[]) 13 | { 14 | printf("\nGRAPH\n"); 15 | printf("%d\n%d\n%d\n", nocells, noparts, nonets); 16 | for (int i = 0; i < nonets; i++) { 17 | printf("%d %d -1 %d\n", nets[i].ncells[0], nets[i].ncells[1], nets[i].nweight); 18 | } 19 | for (int i = 0; i < nocells; i++) { 20 | printf("%d\n", cells[i].cweight); 21 | } 22 | } /* print_graph */ 23 | 24 | void print_vars(int nocells, 25 | int noparts, 26 | int nonets, 27 | int totsize, 28 | int cutsize, 29 | int bucketsize) 30 | { 31 | printf("\nGRAPH VARIABLES\n"); 32 | printf("nocells = %d\n", nocells); 33 | printf("noparts = %d\n", noparts); 34 | printf("nonets = %d\n", nonets); 35 | printf("totsize = %d\n", totsize); 36 | printf("cutsize = %d\n", cutsize); 37 | printf("bucketsize = %d\n", bucketsize); 38 | } /* print_vars */ 39 | 40 | void print_parts(int nocells, 41 | int noparts, 42 | ind_t *ind, 43 | allele tchrom[]) 44 | { 45 | printf("\nPARTS\n"); 46 | 47 | for (int i = 0; i < noparts; i++) { 48 | 49 | printf("part_no=%d: %d <= %d <= %d * #cells=%d\n", i, 50 | ind->parts[i].pmin_size, 51 | ind->parts[i].pcurr_size, 52 | ind->parts[i].pmax_size, 53 | ind->parts[i].pmax_cells); 54 | 55 | int k = 0; 56 | for (int j = 0; j < nocells; j++) { 57 | if (tchrom[j] == i) { 58 | printf("%d ", j); 59 | k++; 60 | if (k % 20 == 0) { 61 | printf("\n"); 62 | } 63 | } /* if */ 64 | } /* for j */ 65 | 66 | printf("\n"); 67 | 68 | } /* for i */ 69 | } /* print_parts */ 70 | 71 | void print_parts_info(int nocells, 72 | int noparts, 73 | allele chrom[], 74 | parts_info_t parts_info[]) 75 | { 76 | printf("\nPARTS_INFO\n"); 77 | 78 | for (int i = 0; i < noparts; i++) { 79 | 80 | printf("part_no=%d: %d <= %d <= %d * #cells=%d\n", i, 81 | parts_info[i].pmin_size, 82 | parts_info[i].pcurr_size, 83 | parts_info[i].pmax_size, 84 | parts_info[i].pmax_cells); 85 | 86 | for (int j = 0; j < nocells; j++) { 87 | if (chrom[j] == i) { 88 | printf("%d ", j); 89 | } 90 | } /* for j */ 91 | 92 | printf("\n"); 93 | 94 | } /* for i */ 95 | } /* print_parts_info */ 96 | 97 | void print_cells(int nocells, 98 | cells_t cells[], 99 | corn_t cnets[]) 100 | { 101 | printf("\nCELLS\n"); 102 | 103 | int totsize = 0; 104 | for (int i = 0; i < nocells; i++) { 105 | 106 | printf("c=%d #n=%d cw=%d nl=%d ns= ", 107 | i, cells[i].cno_nets, cells[i].cweight, cells[i].netlist); 108 | 109 | totsize += cells[i].cweight; 110 | 111 | for (int j = 0; j < cells[i].cno_nets; j++) 112 | printf("%d ", cnets[cells[i].netlist + j].corn_no); 113 | 114 | printf("\n"); 115 | 116 | } /* for */ 117 | 118 | printf("Totsize = %d\n", totsize); 119 | } /* print_cells */ 120 | 121 | void print_nets(int nonets, nets_t nets[]) 122 | { 123 | printf("\nNETS\n"); 124 | 125 | for (int i = 0; i < nonets; i++) { 126 | printf("n=%d nw=%d nc1=%d nc2=%d\n", 127 | i, nets[i].nweight, nets[i].ncells[0], nets[i].ncells[1]); 128 | } /* for i */ 129 | 130 | } /* print_nets */ 131 | 132 | void print_cnets(int nonets, corn_t cnets[]) 133 | { 134 | printf("\nCNETS\n"); 135 | 136 | for (int i = 0; i < (2 * nonets); i++) { 137 | printf("%d ", cnets[i].corn_no); 138 | if (i % 14 == 0) { 139 | printf("\n"); 140 | } 141 | } /* for i */ 142 | 143 | printf("\n"); 144 | } /* print_cnets */ 145 | 146 | void print_chrom(int nocells, allele chrom[]) 147 | { 148 | printf("\nCHROM:\n"); 149 | for (int i = 0; i < nocells; i++) { 150 | printf("%d ", chrom[i]); 151 | } 152 | printf("\n"); 153 | } /* print_chrom */ 154 | 155 | void print_cells_info(int nocells, 156 | int noparts, 157 | cells_info_t cells_info[]) 158 | { 159 | printf("\nCELLS_INFO\n"); 160 | for (int i = 0; i < nocells; i++) { 161 | printf("c=%d mc=%d l=%d mg= ", i, cells_info[i].mcount, cells_info[i].locked); 162 | for (int j = 0; j < noparts; j++) 163 | printf("%d ", cells_info[i].mgain[j]); 164 | printf("\n"); 165 | } /* for i */ 166 | } /* print_cells_info */ 167 | 168 | void print_inx(int noparts, partb_t partb[][noparts - 1]) 169 | { 170 | printf("\nINDICES:\n"); 171 | for (int i = 0; i < noparts; i++) { 172 | for (int j = 0; j < (noparts - 1); j++) { 173 | printf("(%d,%d) max=%d min=%d nobucs=%d\n", 174 | i, j, partb[i][j].max_inx, partb[i][j].min_inx, partb[i][j].nobuckets); 175 | } /* for j */ 176 | } /* for i */ 177 | } /* print_inx */ 178 | 179 | void print_buckets(int noparts, 180 | int bucketsize, 181 | partb_t partb[][noparts - 1]) 182 | { 183 | printf("\nPARTB:\n"); 184 | 185 | for (int i = 0; i < noparts; i++) { 186 | for (int j = 0; j < (noparts - 1); j++) { 187 | for (int k = 0; k < bucketsize; k++) { 188 | 189 | bnode_ptr_t next = partb[i][j].bnode_ptr[k]; 190 | if (next != NULL) { 191 | printf("Partb[%d][%d].bnode_ptr[%d]=", i, j, k); 192 | while (next != NULL) { 193 | if (next->lptr != NULL) { 194 | printf("%d<", (next->lptr)->cell_no); 195 | } 196 | printf("%d>", next->cell_no); 197 | if (next->rptr != NULL) { 198 | printf("%d ", (next->rptr)->cell_no); 199 | } 200 | next = next->rptr; 201 | } /* while */ 202 | 203 | printf("\n"); 204 | 205 | } /* if */ 206 | } /* for k */ 207 | } /* for j */ 208 | } /* for i */ 209 | } /* print_buckets */ 210 | 211 | /* EOF */ 212 | -------------------------------------------------------------------------------- /src/share/ad_lib.c: -------------------------------------------------------------------------------- 1 | 2 | /* COPYRIGHT C 1991- Ali Dasdan */ 3 | 4 | #include 5 | #include 6 | #include "ad_defs.h" 7 | #include "ad_lib.h" 8 | 9 | /* find the neighbor cell of cell_no, on the net net_no */ 10 | void find_other_cell(int net_no, 11 | int cell_no, 12 | int *other_cell, 13 | int *other_part_no, 14 | int *net_weight, 15 | allele chrom[], 16 | nets_t nets[]) 17 | { 18 | /* first find the index of other_cell */ 19 | int cell_inx = 0; 20 | if (nets[net_no].ncells[0] == cell_no) { 21 | cell_inx = 1; 22 | } 23 | *other_cell = nets[net_no].ncells[cell_inx]; 24 | *other_part_no = chrom[*other_cell]; 25 | *net_weight = nets[net_no].nweight; 26 | } /* find_other_cell */ 27 | 28 | /* initialize all bucket indices and pointers */ 29 | void init_buckets(int noparts, 30 | int bucketsize, 31 | partb_t partb[][noparts - 1]) 32 | { 33 | /* init partition bucket indices */ 34 | for (int i = 0; i < noparts; i++) { 35 | for (int j = 0; j < (noparts - 1); j++) { 36 | 37 | partb[i][j].max_inx = partb[i][j].min_inx = -1; 38 | partb[i][j].nobuckets = 0; 39 | 40 | /* init partb bucket pointers */ 41 | for (int k = 0; k < bucketsize; k++) { 42 | partb[i][j].bnode_ptr[k] = NULL; 43 | } 44 | 45 | } /* for j */ 46 | } /* for i */ 47 | } /* init_buckets */ 48 | 49 | /* map part no such that home_part is excluded */ 50 | int map_part_no(int dest_part, int home_part) 51 | { 52 | if (dest_part < home_part) { 53 | return (dest_part); 54 | } else if (dest_part > home_part) { 55 | return (dest_part - 1); 56 | } else { 57 | printf("Error: Unexpected inputs\n"); 58 | exit(1); 59 | } 60 | } /* map_part_no */ 61 | 62 | /* compute move gain from home_part to dest_part */ 63 | int calculate_gain(int cell_no, 64 | int home_part, 65 | int dest_part, 66 | cells_info_t cells_info[]) 67 | { 68 | int mov_gain = cells_info[cell_no].mgain[dest_part] - 69 | cells_info[cell_no].mgain[home_part]; 70 | return mov_gain; 71 | } /* calculate_gain */ 72 | 73 | /* compute gains of all cells and place them into cells_info */ 74 | void compute_gains(int nocells, 75 | int noparts, 76 | allele tchrom[], 77 | cells_t cells[], 78 | nets_t nets[], 79 | corn_t cnets[], 80 | cells_info_t cells_info[]) 81 | { 82 | for (int cell_no = 0; cell_no < nocells; cell_no++) { 83 | 84 | /* initialize cells_info */ 85 | cells_info[cell_no].locked = False; 86 | cells_info[cell_no].mcount = 0; 87 | 88 | /* find info about cell_no */ 89 | int net_ptr = cells[cell_no].netlist; /* ptr to nets of cell_no */ 90 | cells[cell_no].cno_inets = 0; /* # of internal nets of cell_no */ 91 | 92 | /* init external & internal costs of moving cell_no to each partition */ 93 | for (int j = 0; j < noparts; j++) { 94 | cells_info[cell_no].mgain[j] = 0; 95 | } 96 | 97 | /* for each cell connected to cell_no do */ 98 | for (int j = 0; j < cells[cell_no].cno_nets; j++) { 99 | 100 | /* find the neighbor cell */ 101 | int net_no = cnets[net_ptr].corn_no; 102 | 103 | int other_cell, other_part_no, net_weight; 104 | find_other_cell(net_no, cell_no, 105 | &other_cell, &other_part_no, &net_weight, 106 | tchrom, nets); 107 | cells_info[cell_no].mgain[other_part_no] += net_weight; 108 | net_ptr++; 109 | 110 | } /* for j */ 111 | 112 | } /* for cell_no */ 113 | } /* compute_gains */ 114 | 115 | /* free all allocated nodes */ 116 | void free_nodes(int noparts, 117 | int bucketsize, 118 | partb_t partb[][noparts - 1]) 119 | { 120 | /* delete nodes connected to partb */ 121 | for (int i = 0; i < noparts; i++) { 122 | for (int j = 0; j < (noparts - 1); j++) { 123 | 124 | for (int k = 0; k < bucketsize; k++) { 125 | bnode_ptr_t next = partb[i][j].bnode_ptr[k]; 126 | partb[i][j].bnode_ptr[k] = NULL; 127 | while (next != NULL) { 128 | bnode_ptr_t prev = next; 129 | next = next->rptr; 130 | free(prev); 131 | } /* while */ 132 | } /* for k */ 133 | 134 | partb[i][j].max_inx = -1; 135 | partb[i][j].min_inx = -1; 136 | partb[i][j].nobuckets = 0; 137 | } /* for j */ 138 | } /* for i */ 139 | } /* free_nodes */ 140 | 141 | /* count number of bucket nodes */ 142 | void number_nodes(int noparts, 143 | int bucketsize, 144 | int *npartb, 145 | partb_t partb[][noparts - 1]) 146 | { 147 | *npartb = 0; 148 | 149 | /* count nodes connected to partb */ 150 | for (int i = 0; i < noparts; i++) { 151 | for (int j = 0; j < (noparts - 1); j++) { 152 | for (int k = 0; k < bucketsize; k++) { 153 | bnode_ptr_t next = partb[i][j].bnode_ptr[k]; 154 | while (next != NULL) { 155 | next = next->rptr; 156 | (*npartb)++; 157 | } /* while */ 158 | } /* for k */ 159 | } /* for j */ 160 | } /* for i */ 161 | } /* number_nodes */ 162 | 163 | /* find set of cells to be actually moved */ 164 | int find_move_set(mcells_t mcells[], 165 | int msize, 166 | int *max_mcells_inx) 167 | { 168 | int max_gain_sum = 0; 169 | *max_mcells_inx = -1; 170 | int gain_sum = 0; 171 | for (int i = 0; i < msize; i++) { 172 | gain_sum += mcells[i].mgain; 173 | if (gain_sum > max_gain_sum) { 174 | *max_mcells_inx = i; 175 | max_gain_sum = gain_sum; 176 | } /* if */ 177 | } /* for i */ 178 | 179 | return max_gain_sum; 180 | } /* find_move_set */ 181 | 182 | /* move cells actually */ 183 | int move_cells(int wflag, 184 | mcells_t mcells[], 185 | int max_mcells_inx, 186 | int cutsize, 187 | int *glob_inx, 188 | ind_t *ind, 189 | cells_t cells[]) 190 | { 191 | /* used only under wflag == True */ 192 | int tcutsize, fcutsize; 193 | tcutsize = fcutsize = cutsize; 194 | 195 | int cut_gain = 0; 196 | 197 | for (int i = 0; i <= max_mcells_inx; i++) { 198 | 199 | if (wflag == True) { 200 | tcutsize -= mcells[i].mgain; 201 | if (tcutsize < fcutsize) fcutsize = tcutsize; 202 | printf ("%d %d %d\n", *glob_inx, tcutsize, fcutsize); 203 | (*glob_inx)++; 204 | } /* if wflag */ 205 | 206 | ind->chrom[mcells[i].cell_no] = mcells[i].to; 207 | cut_gain += mcells[i].mgain; 208 | 209 | /* update partition size limits */ 210 | ind->parts[mcells[i].from].pmax_cells--; 211 | ind->parts[mcells[i].from].pcurr_size -= cells[mcells[i].cell_no].cweight; 212 | ind->parts[mcells[i].to].pmax_cells++; 213 | ind->parts[mcells[i].to].pcurr_size += cells[mcells[i].cell_no].cweight; 214 | 215 | } /* for i */ 216 | 217 | return cut_gain; 218 | } /* find_move_set */ 219 | 220 | /* finds cut size of a given partition - used for control */ 221 | int find_cut_size(int nonets, 222 | int totsize, 223 | nets_t nets[], 224 | ind_t *ind) 225 | { 226 | ind->incost = 0; 227 | for (int i = 0; i < nonets; i++) { 228 | if (ind->chrom[nets[i].ncells[0]] == 229 | ind->chrom[nets[i].ncells[1]]) 230 | ind->incost += nets[i].nweight; 231 | } /* for i */ 232 | 233 | return (totsize - ind->incost); 234 | } /* find_cut_size */ 235 | 236 | /* EOF */ 237 | -------------------------------------------------------------------------------- /src/fms/ad_fms.c: -------------------------------------------------------------------------------- 1 | 2 | /* COPYRIGHT C 1991- Ali Dasdan */ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "ad_defs.h" 9 | #include "ad_random.h" 10 | #include "ad_fileio.h" 11 | #include "ad_readinput.h" 12 | #include "ad_partition.h" 13 | #include "ad_print.h" 14 | #include "ad_bucketio.h" 15 | #include "ad_lib.h" 16 | #include "ad_lib_fms.h" 17 | 18 | /* FOR SANCHIS' VERSION OF MULTI-WAY PARTITIONING */ 19 | /* Also mentioned as the SN algorithm */ 20 | /* Direct multi-way partitioning. 21 | Locking is used. 22 | Cells are moved wrt their gains. 23 | */ 24 | 25 | int main(int argc, char *argv[]) 26 | { 27 | /* definitions */ 28 | int nocells; /* number of cells */ 29 | int nonets; /* number of nets */ 30 | int nopins; /* number of pins */ 31 | int noparts; /* number of partitions */ 32 | int totsize; /* total net weight of the partition */ 33 | int totcellsize; /* total cell weight of the partition */ 34 | int cutsize; /* cutsize of the partition */ 35 | int max_gain; /* max gain of a cell */ 36 | int max_density; /* max density of a cell */ 37 | int max_cweight; /* max cell weight */ 38 | int max_nweight; /* max net weight */ 39 | int bucketsize; /* max size of a bucket array */ 40 | int msize; /* index to mcells */ 41 | 42 | if (argc < 3) { 43 | printf("\nUsage: %s InputFileName NoParts [Seed]\n", argv[0]); 44 | exit(1); 45 | } /* if */ 46 | 47 | char fname[STR_SIZE]; 48 | sprintf(fname, "%s", argv[1]); 49 | 50 | noparts = atoi(argv[2]); 51 | 52 | long seed; 53 | if (argc > 3) { 54 | seed = (long) atoi(argv[3]); 55 | } else { 56 | seed = (long) -1; 57 | } 58 | seed = randomize((long) seed); 59 | printf("SEED = %ld fname = %s\n", seed, fname); 60 | 61 | read_graph_size(fname, &nocells, &nonets); 62 | nopins = 2 * nonets; 63 | 64 | /* alloc memory for all data structures */ 65 | cells_t *cells = (cells_t *) calloc(nocells, sizeof(cells_t)); 66 | assert(cells != NULL); 67 | cells_info_t *cells_info = (cells_info_t *) calloc(nocells, sizeof(cells_info_t)); 68 | assert(cells_info != NULL); 69 | for (int i = 0; i < nocells; i++) { 70 | cells_info[i].mgain = (int *) calloc(noparts, sizeof(int)); 71 | assert(cells_info[i].mgain != NULL); 72 | cells_info[i].partb_ptr = (bnode_ptr_t *) calloc(noparts - 1, sizeof(bnode_ptr_t)); 73 | assert(cells_info[i].partb_ptr != NULL); 74 | cells_info[i].partb_gain_inx = (int *) calloc(noparts - 1, sizeof(int)); 75 | assert(cells_info[i].partb_gain_inx != NULL); 76 | } 77 | 78 | nets_t *nets = (nets_t *) calloc(nonets, sizeof(nets_t)); 79 | assert(nets != NULL); 80 | 81 | /* cells of nets */ 82 | corn_t *cnets = (corn_t *) calloc(nopins, sizeof(corn_t)); 83 | assert(cnets != NULL); 84 | 85 | /* partition buckets */ 86 | partb_t partb[noparts][noparts - 1]; 87 | parts_info_t parts_info[noparts]; 88 | 89 | /* population (w/ one individual!) */ 90 | ind_t pop[MAX_POP]; 91 | for (int i = 0; i < MAX_POP; i++) { 92 | pop[i].chrom = (allele *) calloc(nocells, sizeof(allele)); 93 | pop[i].parts = (parts_t *) calloc(noparts, sizeof(parts_t)); 94 | } 95 | 96 | /* selected cell */ 97 | selected_cell_t scell[1]; 98 | 99 | /* moved cells */ 100 | mcells_t *mcells = (mcells_t *) calloc(nocells, sizeof(mcells_t)); 101 | assert(mcells != NULL); 102 | 103 | read_graph(fname, nocells, nonets, noparts, &totsize, &totcellsize, 104 | &max_density, &max_cweight, &max_nweight, 105 | cells, nets, cnets); 106 | 107 | max_gain = max_density * max_nweight; 108 | bucketsize = 2 * max_gain + 1; 109 | 110 | /* alloc memory (statically if possible) */ 111 | for (int i = 0; i < noparts; i++) { 112 | for (int j = 0; j < noparts - 1; ++j) { 113 | partb[i][j].bnode_ptr = (bnode_ptr_t *) calloc(bucketsize, sizeof(bnode_ptr_t)); 114 | } 115 | } 116 | 117 | create_partition(nocells, noparts, totcellsize, 118 | cells, &pop[0]); 119 | 120 | #ifdef DEBUG 121 | printf("Initial : Part_no min_size curr_size max_size\n"); 122 | for (int i = 0; i < noparts; i++) { 123 | printf("II %d %d %d %d\n", i, pop[0].parts[i].pmin_size, 124 | pop[0].parts[i].pcurr_size, pop[0].parts[i].pmax_size); 125 | } 126 | #endif 127 | 128 | init_buckets(noparts, bucketsize, partb); 129 | cutsize = find_cut_size(nonets, totsize, nets, &pop[0]); 130 | 131 | #ifdef DEBUG 132 | printf("Totalsize = %d Initial cutsize = %d\n", totsize, cutsize); 133 | #endif 134 | 135 | int gain_sum; 136 | int no_iter = 0; 137 | int glob_inx = 0; 138 | do { 139 | 140 | copy_partition(noparts, parts_info, &pop[0]); 141 | 142 | compute_gains(nocells, noparts, pop[0].chrom, 143 | cells, nets, cnets, cells_info); 144 | 145 | create_buckets(nocells, noparts, max_gain, pop[0].chrom, 146 | partb, cells_info); 147 | 148 | msize = 0; 149 | 150 | int nlocked = 0; 151 | do { 152 | 153 | int move_possible = select_cell(noparts, scell, parts_info, cells, 154 | partb, cells_info); 155 | 156 | delete_partb_nodes_of_cell(noparts, scell[0].mov_cell_no, 157 | scell[0].from_part, partb, cells_info); 158 | 159 | /* lock cell */ 160 | cells_info[scell[0].mov_cell_no].locked = True; 161 | if (move_possible == True) { 162 | move_cell(mcells, msize, scell); 163 | msize++; 164 | update_gains(noparts, max_gain, scell, pop[0].chrom, 165 | cells, nets, cnets, 166 | partb, cells_info); 167 | } /* if */ 168 | nlocked++; 169 | 170 | } while (nlocked < nocells); 171 | 172 | int max_mcells_inx; 173 | gain_sum = find_move_set(mcells, msize, &max_mcells_inx); 174 | 175 | #ifdef DEBUG 176 | printf("gain_sum=%d max_mcells_inx=%d msize = %d\n", 177 | gain_sum, max_mcells_inx, msize); 178 | #endif 179 | 180 | if (gain_sum > 0) { 181 | int cut_gain = move_cells(False, mcells, max_mcells_inx, cutsize, 182 | &glob_inx, &pop[0], cells); 183 | cutsize -= cut_gain; 184 | } /* if */ 185 | no_iter++; 186 | 187 | #ifdef DEBUG 188 | printf("pass_no = %d Final cutsize = %d Check cutsize = %d\n", no_iter, 189 | cutsize, find_cut_size(nonets, totsize, nets, &pop[0])); 190 | #endif 191 | 192 | } while ((gain_sum > 0) && (cutsize > 0) && (no_iter < NO_ITERATIONS)); 193 | 194 | printf("pass_no = %d Final cutsize = %d Check cutsize = %d\n", no_iter, 195 | cutsize, find_cut_size(nonets, totsize, nets, &pop[0])); 196 | 197 | free_nodes(noparts, bucketsize, partb); 198 | 199 | #ifdef DEBUG 200 | printf("Final : Part_no min_size curr_size max_size\n"); 201 | for (int i = 0; i < noparts; i++) { 202 | printf("FF %d %d %d %d\n", i, pop[0].parts[i].pmin_size, 203 | pop[0].parts[i].pcurr_size, pop[0].parts[i].pmax_size); 204 | } 205 | #endif 206 | 207 | /* free memory for all data structures */ 208 | free(cells); 209 | for (int i = 0; i < nocells; i++) { 210 | free(cells_info[i].mgain); 211 | free(cells_info[i].partb_ptr); 212 | free(cells_info[i].partb_gain_inx); 213 | } 214 | free(cells_info); 215 | 216 | free(nets); 217 | 218 | free(cnets); 219 | 220 | for (int i = 0; i < noparts; i++) { 221 | for (int j = 0; j < noparts - 1; ++j) { 222 | free(partb[i][j].bnode_ptr); 223 | } 224 | } 225 | 226 | for (int i = 0; i < MAX_POP; i++) { 227 | free(pop[i].chrom); 228 | free(pop[i].parts); 229 | } 230 | 231 | free(mcells); 232 | 233 | return (0); 234 | } /* main-fms */ 235 | 236 | /* EOF */ 237 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # graph-partitioning-algorithms 2 | ============================= 3 | 4 | This package contains multi-way partitioning algorithms: FMS 5 | (Fiduccia-Mattheyses-Sanchis), PLM (Partitioning by Locked Moves), PFM 6 | (Partitioning by Free Moves) as detailed in [DaAy97]. 7 | 8 | ## THE GRAPH PARTITIONING PROBLEM 9 | 10 | The graph partitioning problem is defined as follows: Given an input 11 | graph, partition it into a given number of almost equal-sized parts in 12 | such a way that the cutsize, i.e., the sum of the edge weights whose 13 | end vertices are in different parts, is minimized . This problem has 14 | many variations as well as important applications in many 15 | areas. Unfortunately, the problem is NP-hard so the algorithms in this 16 | package are heuristics (but they work very very well). 17 | 18 | A related problem is the hypergraph partitioning problem. If you do 19 | not know what a hypergraph is, remember this: In a graph, you have 20 | vertices and edges, where every edge connects two vertices; in a 21 | hypergraph, you have vertices and hyperedges, where every hyperedge 22 | connects two or more vertices. Since hypergraphs can model electronic 23 | circuits well, a hypergraph is often said to have cells and nets 24 | instead of vertices and hyperedges. In a circuit cell where a net is 25 | connected is called a pin. You may see the cell, net, and pin 26 | terminology in my code. 27 | 28 | ## A SHORT HISTORY ON THESE ALGORITHMS 29 | 30 | The basis for these algorithms go back to the Kernighan-Lin (KL) 31 | algorithm for graph partitioning. The KL algorithm produces very good 32 | partitions but it is slow. The Fiduccia-Mattheyses (FM) algorithm is 33 | not only a faster version of the KL algorithm but it also generalizes 34 | the KL algorithm to run on hypergraphs. Sanchis generalized the FM 35 | algorithm from 2-way partitioning to multi-way partitioning. 36 | 37 | All these KL-based algorithms work in multiple passes over the number 38 | of vertices; in each pass, these algorithms find the best destination 39 | part for a vertex and lock this vertex from moving again in the rest 40 | of the current pass. Realizing the limitations of this "locking" 41 | mechanism, I devised ways to relax this mechanism, resulting in the 42 | Partitioning by Locked Moves (PLM) algorithm and the Partitioning by 43 | Free Moves (PFM) algorithm. The PLM algorithm still uses locking but 44 | it goes through multiple phases of locking and unlocking within a pass 45 | over the input graph. The PFM algorithm does not use locking at all; 46 | it uses a way to penalize the moves to march towards a local 47 | minimum. For more details, please refer to [DaAy97]. 48 | 49 | ## MORE INTRODUCTION 50 | 51 | I originally developed this package in C during my MSc study (around 52 | 1991-1993). Before putting this package on github, I converted my code 53 | to ANSI C (c99) and cleaned it quite a bit. 54 | 55 | In my code, you may notice some biologically inspired variable names 56 | such as 'population', 'chromosome', 'allele', etc. These names 57 | actually come from genetic algorithms. During my MSc years, my 58 | eventual goal was to implement graph and hypergraph partitioning using 59 | genetic algorithms on a hypercube connected parallel computer (from 60 | Intel). Once I discovered the limitations of the locking mechanism, I 61 | changed my research direction towards what would become PLM and 62 | PFM. By the way, I did still work on genetic algorithms but in a 63 | different setting (applying genetic algorithms to synthesize 64 | unsupervised learning algorithms). 65 | 66 | This package is available on an "as is" basis. I do not say or imply 67 | that it will be useful for whatever you want to do with it. It may 68 | also contain bugs, and I assume no responsibility for any potential 69 | problems associated with its use. You can use this package free of 70 | charge in academic research and teaching. For any commercial use, 71 | contact Ali Dasdan at ali_dasdan@yahoo.com. See the COPYRIGHT section 72 | below. 73 | 74 | ## DIRECTORY STRUCTURE 75 | 76 | At the top level, you see two directories: 'src' and 'input'. 'src' 77 | contains all the source files and 'input' contains the input graphs 78 | used for testing the executables. Under 'src', there is one directory, 79 | called 'share', for the shared source files as well as one directory 80 | for each algorithm: 'fms', 'plm', and 'pfm'. 81 | 82 | ## HOW TO BUILD 83 | 84 | Under 'src', type 'make' (or 'gmake') to build each executable under 85 | its own directory. The executables are all have .x extension: 86 | ad_fms.x, ad_plm.x, and ad_pfm.x. 87 | 88 | The output you expect to see with 'make' is shown in 89 | 'doc/make_build.out'. 90 | 91 | ## HOW TO RUN 92 | 93 | Go to the respective directory for an algorithm and type the name of 94 | one of the executables in your command line to get the usage 95 | information. At minimum, each executable requires the input graph and 96 | the number of parts to partition the hypergraph. PLM and PFM require 97 | additional parameters to create different versions of them, which 98 | trade off runtime for partition quality. 99 | 100 | For example, a run of FMS (in 'ad_fms.x') to partition the input graph 101 | 'p9' into two parts will produce this output: 102 | 103 | ``` 104 | > ad_fms.x input/p9 2 123456 105 | SEED = 123456 fname = input/p9 106 | pass_no = 7 Final cutsize = 85 Check cutsize = 85 107 | ``` 108 | 109 | This output shows that FMS took 7 passes over the cells of the input 110 | hypergraph 'hp9' when started with a seed of 123456. Note that 111 | specifying a seed will make the results repeatable. FMS found a 112 | cutsize of 85, which is correct as FMS and the other programs will 113 | check every cutsize they report for correctness. That is, each of the 114 | executables are self validating. 115 | 116 | __NOTE__: When you run this program for a large number of parts (i.e., 117 | the 2nd argument on the command line), you may get a seg fault. The 118 | reason seems to be the allocation of the 2D array 'partb' on the 119 | stack. When I find time (hopefully soon), I will remove this weakness 120 | by allocating partb dynamically on the heap. 121 | 122 | ## HOW TO TEST 123 | 124 | Under 'src', type 'make test' to test each executable on the input 125 | graphs under the 'input' directory. The result will be a 'pass' or a 126 | 'fail'. 127 | 128 | The output you expect to see with 'make test' is shown in 129 | 'doc/make_test.out'. 130 | 131 | ## HOW TO CLEAN 132 | 133 | Under 'src', type 'make clean' to clean all temporary files including 134 | the object files and the executables. 135 | 136 | The output you expect to see with 'make clean' is shown in 137 | 'doc/make_clean.out'. 138 | 139 | ## INPUT FILE FORMAT 140 | 141 | The input file format is explained below using a very simple graph. 142 | 143 | ``` 144 | > cat input/p1 145 | 6 146 | 7 147 | 14 148 | 1 2 0 1 149 | 1 2 1 2 150 | 1 2 2 0 151 | 1 2 3 4 152 | 1 2 4 5 153 | 1 2 5 3 154 | 1 2 0 3 155 | 1 156 | 1 157 | 1 158 | 1 159 | 1 160 | 1 161 | ``` 162 | 163 | The first three lines give the number of vertices (or cells), the 164 | number of edges (or nets), and the number of pins (or endpoints), 165 | respectively. Thus, 'p1' has 6 vertices, 7 edges, and 14 pins. 166 | 167 | The following 7 lines describe the edges, one edge per line. The first 168 | number is the edge weight; the second number is the number of vertices 169 | on an edge (always equal to 2 for graphs)); the third number is the 170 | source vertex; and the fourth number is the target vertex. For 171 | example, the first edge from vertex 0 to vertex 1 has a weight of 1. 172 | 173 | The last 6 lines describe the vertex weights. 174 | 175 | ## REFERENCE 176 | 177 | Please cite this reference if you use my programs in your research 178 | work. 179 | 180 | ``` 181 | @article{DaAy97, 182 | author = {Ali Dasdan and C. Aykanat}, 183 | title = {Two Novel Circuit Partitioning Algorithms Using Relaxed Locking}, 184 | journal = {IEEE Transactions on Computer-Aided Design of Integrated Circuits and Systems (TCAD)}, 185 | volume = {16}, 186 | number = {2}, 187 | year = {1997}, 188 | pages = {169-178}, 189 | url = {http://yoksis.bilkent.edu.tr/doi_getpdf/articles/10.1109-43.573831.pdf}, 190 | } 191 | ``` 192 | 193 | ## COPYRIGHT 194 | 195 | COPYRIGHT C 1991 - Ali Dasdan 196 | 197 | Permission to use for non-commercial purposes is granted provided that 198 | proper acknowledgments are given. For a commercial licence, contact 199 | Ali Dasdan at ali_dasdan@yahoo.com. 200 | 201 | This software is provided on an "as is" basis, without warranties or 202 | conditions of any kind, either express or implied including, without 203 | limitation, any warranties or conditions of title, non-infringement, 204 | merchantability or fitness for a particular purpose. 205 | 206 | ## END OF FILE 207 | 208 | -------------------------------------------------------------------------------- /src/pfm/ad_pfm.c: -------------------------------------------------------------------------------- 1 | 2 | /* COPYRIGHT C 1991- Ali Dasdan */ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "ad_defs.h" 11 | #include "ad_random.h" 12 | #include "ad_fileio.h" 13 | #include "ad_readinput.h" 14 | #include "ad_partition.h" 15 | #include "ad_print.h" 16 | #include "ad_bucketio.h" 17 | #include "ad_lib.h" 18 | #include "ad_lib_pfm.h" 19 | 20 | /* PARTITIONING BY FREE MOVES */ 21 | 22 | int main(int argc, char *argv[]) 23 | { 24 | /* definitions */ 25 | int nocells; /* number of cells */ 26 | int nonets; /* number of nets */ 27 | int nopins; /* number of pins */ 28 | int noparts; /* number of partitions */ 29 | int totsize; /* total net weight of the partition */ 30 | int totcellsize; /* total cell weight of the partition */ 31 | int cutsize; /* cutsize of the partition */ 32 | int max_gain; /* max gain of a cell */ 33 | int max_density; /* max density of a cell */ 34 | int max_cweight; /* max cell weight */ 35 | int max_nweight; /* max net weight */ 36 | 37 | if (argc < 5) { 38 | printf("\nUsage: %s InputFileName NoParts Version BucketSizeFactor [Seed]\n", argv[0]); 39 | exit(1); 40 | } /* if */ 41 | 42 | char fname[STR_SIZE]; 43 | sprintf(fname, "%s", argv[1]); 44 | 45 | noparts = atoi(argv[2]); 46 | int version = atoi(argv[3]); 47 | 48 | int bucketsize_factor = atoi(argv[4]); 49 | 50 | long seed; 51 | if (argc > 5) { 52 | seed = (long) atoi(argv[5]); 53 | } else { 54 | seed = (long) -1; 55 | } 56 | seed = randomize((long) seed); 57 | printf("SEED = %ld fname = %s\n", seed, fname); 58 | 59 | read_graph_size(fname, &nocells, &nonets); 60 | nopins = 2 * nonets; 61 | 62 | /* determine max_noiter based on pfm version */ 63 | /* pfm1: size=max_cells; 64 | pfm2: size=max_cells * max_parts; 65 | pfm3: size=max_cells * max_parts^2 */ 66 | int max_noiter = nocells; 67 | switch (version) { 68 | case 1 : break; 69 | case 2 : max_noiter *= noparts; break; 70 | case 3 : max_noiter *= noparts * noparts; break; 71 | default : break; 72 | } 73 | cells_t *cells = (cells_t *) calloc(nocells, sizeof(cells_t)); 74 | assert(cells != NULL); 75 | cells_info_t *cells_info = (cells_info_t *) calloc(nocells, sizeof(cells_info_t)); 76 | assert(cells_info != NULL); 77 | for (int i = 0; i < nocells; i++) { 78 | cells_info[i].mgain = (int *) calloc(noparts, sizeof(int)); 79 | cells_info[i].partb_ptr = (bnode_ptr_t *) calloc(noparts - 1, sizeof(bnode_ptr_t)); 80 | cells_info[i].partb_gain_inx = (int *) calloc(noparts - 1, sizeof(int)); 81 | } 82 | 83 | nets_t *nets = (nets_t *) calloc(nonets, sizeof(nets_t)); 84 | assert(nets != NULL); 85 | 86 | /* cells of nets */ 87 | corn_t *cnets = (corn_t *) calloc(nopins, sizeof(corn_t)); 88 | assert(cnets != NULL); 89 | 90 | /* partition buckets */ 91 | partb_t partb[noparts][noparts - 1]; 92 | parts_info_t parts_info[noparts]; 93 | 94 | /* population (w/ one individual!) */ 95 | ind_t pop[MAX_POP]; 96 | for (int i = 0; i < MAX_POP; i++) { 97 | pop[i].chrom = (allele *) calloc(nocells, sizeof(allele)); 98 | pop[i].parts = (parts_t *) calloc(noparts, sizeof(parts_t)); 99 | } 100 | 101 | /* selected cell */ 102 | selected_cell_t scell[1]; 103 | selected_cell_t prev_scell[1]; 104 | 105 | /* moved cells */ 106 | mcells_t *mcells = (mcells_t *) calloc(2 * max_noiter, sizeof(mcells_t)); 107 | assert(mcells != NULL); 108 | 109 | /* temp chrom */ 110 | allele *tchrom = (allele *) calloc(nocells, sizeof(allele)); 111 | assert(tchrom != NULL); 112 | 113 | read_graph(fname, nocells, nonets, noparts, &totsize, &totcellsize, 114 | &max_density, &max_cweight, &max_nweight, 115 | cells, nets, cnets); 116 | 117 | /* bucketsize has impact on cutsize and runtime */ 118 | max_gain = max_density * max_nweight; 119 | int bucketsize = 2 * max_gain + 1; 120 | if (bucketsize_factor > 0) { 121 | bucketsize *= bucketsize_factor; 122 | } 123 | 124 | /* cache to speed up math heavy function evals */ 125 | eval_t *eval = (eval_t *) calloc(2 * max_gain + 1, sizeof(eval_t)); 126 | float K; 127 | calculate_scale(nocells, noparts, max_gain, &K); 128 | fill_eval(max_gain, K, eval); 129 | 130 | create_partition(nocells, noparts, totcellsize, cells, &pop[0]); 131 | 132 | #ifdef DEBUG 133 | printf("Initial : Part_no min_size curr_size max_size\n"); 134 | for (int i = 0; i < noparts; i++) { 135 | printf("II %d %d %d %d\n", i, pop[0].parts[i].pmin_size, 136 | pop[0].parts[i].pcurr_size, pop[0].parts[i].pmax_size); 137 | } 138 | #endif 139 | 140 | /* alloc memory (statically if possible) */ 141 | for (int i = 0; i < noparts; i++) { 142 | for (int j = 0; j < noparts - 1; ++j) { 143 | partb[i][j].bnode_ptr = (bnode_ptr_t *) calloc(bucketsize, sizeof(bnode_ptr_t)); 144 | } 145 | } 146 | 147 | init_buckets(noparts, bucketsize, partb); 148 | cutsize = find_cut_size(nonets, totsize, nets, &pop[0]); 149 | 150 | #ifdef DEBUG 151 | printf("BB bucketsize=%d\n", bucketsize); 152 | printf("Totalsize = %d Initial cutsize = %d\n", totsize, cutsize); 153 | #endif 154 | 155 | int gain_sum; 156 | int glob_inx = 0; 157 | int pass_no = 0; 158 | do { 159 | 160 | copy_partition(noparts, parts_info, &pop[0]); 161 | 162 | for (int i = 0; i < nocells; i++) { 163 | tchrom[i] = pop[0].chrom[i]; 164 | } 165 | 166 | compute_gains(nocells, noparts, tchrom, 167 | cells, nets, cnets, cells_info); 168 | 169 | create_buckets(bucketsize, nocells, noparts, max_gain, eval, pop[0].chrom, 170 | partb, cells_info); 171 | 172 | prev_scell[0].mov_cell_no = -1; 173 | 174 | int msize = 0; /* index to mcells */ 175 | int mov_count = 0; /* count of total moves */ 176 | while (mov_count < max_noiter) { 177 | 178 | select_cell(noparts, scell, parts_info, cells, partb, cells_info); 179 | 180 | move_cell(mcells, msize, scell, tchrom, cells_info); 181 | 182 | msize++; 183 | 184 | /* insert previous cell */ 185 | create_partb_nodes_of_cell(bucketsize, noparts, max_gain, 186 | prev_scell[0].mov_cell_no, 187 | prev_scell[0].to_part, 188 | eval, partb, cells_info); 189 | 190 | update_gains(bucketsize, noparts, max_gain, eval, scell, tchrom, cells, 191 | nets, cnets, partb, cells_info); 192 | 193 | /* currently moved cell becomes previous cell */ 194 | bcopy((void *) scell, (void *) prev_scell, sizeof(scell[0])); 195 | 196 | /* delete current cell */ 197 | delete_partb_nodes_of_cell(noparts, scell[0].mov_cell_no, 198 | scell[0].from_part, partb, cells_info); 199 | 200 | mov_count++; 201 | } /* while */ 202 | 203 | int max_mcells_inx; 204 | gain_sum = find_move_set(mcells, msize, &max_mcells_inx); 205 | 206 | #ifdef DEBUG 207 | printf("gain_sum=%d max_mcells_inx=%d msize = %d\n", 208 | gain_sum, max_mcells_inx, msize); 209 | #endif 210 | 211 | if (gain_sum > 0) { 212 | int cut_gain = move_cells(False, mcells, max_mcells_inx, 213 | cutsize, &glob_inx, &pop[0], cells); 214 | cutsize -= cut_gain; 215 | } /* if */ 216 | 217 | pass_no++; 218 | 219 | #ifdef DEBUG 220 | printf("pass_no = %d Final cutsize = %d Check cutsize = %d\n", pass_no, 221 | cutsize, find_cut_size(nonets, totsize, nets, &pop[0])); 222 | #endif 223 | 224 | free_nodes(noparts, bucketsize, partb); 225 | 226 | } while ((gain_sum > 0) && (cutsize > 0)); /* while pass_no */ 227 | /* or (pass_no < noparts) */ 228 | 229 | printf("pass_no = %d Final cutsize = %d Check cutsize = %d\n", pass_no, 230 | cutsize, find_cut_size(nonets, totsize, nets, &pop[0])); 231 | 232 | #ifdef DEBUG 233 | printf("Final : Part_no min_size curr_size max_size\n"); 234 | for (int i = 0; i < noparts; i++) { 235 | printf("FF %d %d %d %d\n", i, pop[0].parts[i].pmin_size, 236 | pop[0].parts[i].pcurr_size, pop[0].parts[i].pmax_size); 237 | } 238 | #endif 239 | 240 | /* free memory for all data structures */ 241 | free(cells); 242 | for (int i = 0; i < nocells; i++) { 243 | free(cells_info[i].mgain); 244 | free(cells_info[i].partb_ptr); 245 | free(cells_info[i].partb_gain_inx); 246 | } 247 | free(cells_info); 248 | 249 | free(nets); 250 | 251 | free(cnets); 252 | 253 | for (int i = 0; i < noparts; i++) { 254 | for (int j = 0; j < noparts - 1; ++j) { 255 | free(partb[i][j].bnode_ptr); 256 | } 257 | } 258 | 259 | for (int i = 0; i < MAX_POP; i++) { 260 | free(pop[i].chrom); 261 | free(pop[i].parts); 262 | } 263 | 264 | free(mcells); 265 | 266 | free(tchrom); 267 | 268 | free(eval); 269 | 270 | return (0); 271 | } /* main-pfm */ 272 | 273 | /* EOF */ 274 | -------------------------------------------------------------------------------- /src/plm/ad_plm.c: -------------------------------------------------------------------------------- 1 | 2 | /* COPYRIGHT C 1991- Ali Dasdan */ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "ad_defs.h" 10 | #include "ad_random.h" 11 | #include "ad_fileio.h" 12 | #include "ad_readinput.h" 13 | #include "ad_partition.h" 14 | #include "ad_print.h" 15 | #include "ad_bucketio.h" 16 | #include "ad_lib.h" 17 | #include "ad_lib_plm.h" 18 | 19 | /* PARTITIONING BY LOCKED MOVES */ 20 | /* Direct multi-way partitioning. 21 | Locking is used. 22 | Cells are moved wrt their gains. 23 | Prefix sum is computed at the end of the outher loop as in 1st heuristic. 24 | Run until a local optimum is found. 25 | */ 26 | 27 | int main(int argc, char *argv[]) 28 | { 29 | /* definitions */ 30 | int nocells; /* number of cells */ 31 | int nonets; /* number of nets */ 32 | int nopins; /* number of pins */ 33 | int noparts; /* number of partitions */ 34 | int totsize; /* total net weight of the partition */ 35 | int totcellsize; /* total cell weight of the partition */ 36 | int cutsize; /* cutsize of the partition */ 37 | int max_gain; /* max gain of a cell */ 38 | int max_density; /* max density of a cell */ 39 | int max_cweight; /* max cell weight */ 40 | int max_nweight; /* max net weight */ 41 | int bucketsize; /* max size of a bucket array */ 42 | int msize; /* index to mcells */ 43 | 44 | if (argc < 5) { 45 | printf("\nUsage: %s InputFileName NoParts InCount OutCount [Seed]\n", argv[0]); 46 | printf("\t#cells moved per phase = incount * nocells / 4\n"); 47 | printf("\t\tUse 1, 2, 3, or 4 for incount.\n"); 48 | printf("\t#cells moved per pass = nocells if outcount = 1,\n"); 49 | printf("\t#cells moved per pass = nocells * noparts if outcount = 2, and\n"); 50 | printf("\t#cells moved per pass = nocells * noparts * noparts if outcount = 3.\n"); 51 | exit(1); 52 | } /* if */ 53 | 54 | char fname[STR_SIZE]; 55 | sprintf(fname, "%s", argv[1]); 56 | 57 | noparts = atoi(argv[2]); 58 | 59 | int incount = atoi(argv[3]); 60 | int outcount = atoi(argv[4]); 61 | 62 | long seed; 63 | if (argc > 5) { 64 | seed = (long) atoi(argv[5]); 65 | } else { 66 | seed = (long) -1; 67 | } 68 | seed = randomize((long) seed); 69 | printf("SEED = %ld fname = %s\n", seed, fname); 70 | 71 | read_graph_size(fname, &nocells, &nonets); 72 | nopins = 2 * nonets; 73 | 74 | /* determine what in- & out-count imply */ 75 | int max_moved_cells = incount * nocells / 4; 76 | switch (outcount) { 77 | case 1 : outcount = nocells; break; 78 | case 2 : outcount = nocells * noparts; break; 79 | case 3 : outcount = nocells * noparts * noparts; break; 80 | default : break; 81 | } 82 | /* max_noiter = outcount / max_moved_cells;*/ /* do that many iterations */ 83 | int max_noiter = outcount; 84 | 85 | /* alloc memory for all data structures */ 86 | cells_t *cells = (cells_t *) calloc(nocells, sizeof(cells_t)); 87 | assert(cells != NULL); 88 | cells_info_t *cells_info = (cells_info_t *) calloc(nocells, sizeof(cells_info_t)); 89 | assert(cells_info != NULL); 90 | for (int i = 0; i < nocells; i++) { 91 | cells_info[i].mgain = (int *) calloc(noparts, sizeof(int)); 92 | cells_info[i].partb_ptr = (bnode_ptr_t *) calloc(noparts - 1, sizeof(bnode_ptr_t)); 93 | cells_info[i].partb_gain_inx = (int *) calloc(noparts - 1, sizeof(int)); 94 | } 95 | 96 | nets_t *nets = (nets_t *) calloc(nonets, sizeof(nets_t)); 97 | assert(nets != NULL); 98 | 99 | /* cells of nets */ 100 | corn_t *cnets = (corn_t *) calloc(nopins, sizeof(corn_t)); 101 | assert(cnets != NULL); 102 | 103 | /* partition buckets */ 104 | partb_t partb[noparts][noparts - 1]; 105 | parts_info_t parts_info[noparts]; 106 | 107 | /* population (w/ one individual!) */ 108 | ind_t pop[MAX_POP]; 109 | for (int i = 0; i < MAX_POP; i++) { 110 | pop[i].chrom = (allele *) calloc(nocells, sizeof(allele)); 111 | pop[i].parts = (parts_t *) calloc(noparts, sizeof(parts_t)); 112 | } 113 | 114 | /* selected cell */ 115 | selected_cell_t scell[1]; 116 | 117 | /* moved cells */ 118 | mcells_t *mcells = (mcells_t *) calloc(2 * max_noiter, sizeof(mcells_t)); 119 | assert(mcells != NULL); 120 | 121 | /* temp chrom */ 122 | allele *tchrom = (allele *) calloc(nocells, sizeof(allele)); 123 | assert(tchrom != NULL); 124 | 125 | read_graph(fname, nocells, nonets, noparts, &totsize, &totcellsize, 126 | &max_density, &max_cweight, &max_nweight, 127 | cells, nets, cnets); 128 | 129 | max_gain = max_density * max_nweight; 130 | bucketsize = 2 * max_gain + 1; 131 | 132 | /* alloc memory (statically if possible) */ 133 | for (int i = 0; i < noparts; i++) { 134 | for (int j = 0; j < noparts - 1; ++j) { 135 | partb[i][j].bnode_ptr = (bnode_ptr_t *) calloc(bucketsize, sizeof(bnode_ptr_t)); 136 | } 137 | } 138 | 139 | create_partition(nocells, noparts, totcellsize, 140 | cells, &pop[0]); 141 | 142 | #ifdef DEBUG 143 | printf("Initial : Part_no min_size curr_size max_size\n"); 144 | for (int i = 0; i < noparts; i++) { 145 | printf("II %d %d %d %d\n", i, pop[0].parts[i].pmin_size, 146 | pop[0].parts[i].pcurr_size, pop[0].parts[i].pmax_size); 147 | } 148 | #endif 149 | 150 | init_buckets(noparts, bucketsize, partb); 151 | cutsize = find_cut_size(nonets, totsize, nets, &pop[0]); 152 | 153 | #ifdef DEBUG 154 | printf("Totalsize = %d Initial cutsize = %d\n", totsize, cutsize); 155 | #endif 156 | 157 | int gain_sum; 158 | int glob_inx = 0; 159 | int pass_no = 0; 160 | do { 161 | 162 | copy_partition(noparts, parts_info, &pop[0]); 163 | 164 | for (int i = 0; i < nocells; i++) { 165 | tchrom[i] = pop[0].chrom[i]; 166 | } 167 | 168 | msize = 0; 169 | 170 | int noiter = 0; 171 | while (noiter < max_noiter) { 172 | 173 | compute_gains(nocells, noparts, tchrom, 174 | cells, nets, cnets, cells_info); 175 | 176 | create_buckets(nocells, noparts, max_gain, tchrom, partb, cells_info); 177 | 178 | /* max_moved_cells = nocells / 2; */ 179 | int nlocked = 0; 180 | do { 181 | 182 | int move_possible = select_cell(noparts, scell, parts_info, cells, 183 | partb, cells_info); 184 | 185 | delete_partb_nodes_of_cell(noparts, scell[0].mov_cell_no, 186 | scell[0].from_part, partb, cells_info); 187 | 188 | /* lock cell */ 189 | cells_info[scell[0].mov_cell_no].locked = True; 190 | if (move_possible == True) { 191 | move_cell(mcells, msize, scell, tchrom); 192 | msize++; 193 | update_gains(noparts, max_gain, scell, tchrom, 194 | cells, nets, cnets, 195 | partb, cells_info); 196 | } /* if */ 197 | nlocked++; 198 | 199 | noiter++; 200 | } while ((nlocked < max_moved_cells) && (noiter < max_noiter)); 201 | 202 | free_nodes(noparts, bucketsize, partb); 203 | 204 | } /* while */ 205 | 206 | int max_mcells_inx; 207 | gain_sum = find_move_set(mcells, msize, &max_mcells_inx); 208 | 209 | #ifdef DEBUG 210 | printf("gain_sum=%d max_mcells_inx=%d msize = %d\n", 211 | gain_sum, max_mcells_inx, msize); 212 | #endif 213 | if (gain_sum > 0) { 214 | int cut_gain = move_cells(False, mcells, max_mcells_inx, cutsize, &glob_inx, 215 | &pop[0], cells); 216 | cutsize -= cut_gain; 217 | } /* if */ 218 | pass_no++; 219 | 220 | #ifdef DEBUG 221 | printf("pass_no = %d Final cutsize = %d Check cutsize = %d\n", pass_no, 222 | cutsize, find_cut_size(nonets, totsize, nets, &pop[0])); 223 | #endif 224 | 225 | } while ((gain_sum > 0) && (cutsize > 0)); 226 | 227 | printf("pass_no = %d Final cutsize = %d Check cutsize = %d\n", pass_no, 228 | cutsize, find_cut_size(nonets, totsize, nets, &pop[0])); 229 | 230 | free_nodes(noparts, bucketsize, partb); 231 | 232 | #ifdef DEBUG 233 | printf("Final : Part_no min_size curr_size max_size\n"); 234 | for (int i = 0; i < noparts; i++) { 235 | printf("FF %d %d %d %d\n", i, pop[0].parts[i].pmin_size, 236 | pop[0].parts[i].pcurr_size, pop[0].parts[i].pmax_size); 237 | } 238 | #endif 239 | 240 | /* free memory for all data structures */ 241 | free(cells); 242 | for (int i = 0; i < nocells; i++) { 243 | free(cells_info[i].mgain); 244 | free(cells_info[i].partb_ptr); 245 | free(cells_info[i].partb_gain_inx); 246 | } 247 | free(cells_info); 248 | 249 | free(nets); 250 | 251 | free(cnets); 252 | 253 | for (int i = 0; i < noparts; i++) { 254 | for (int j = 0; j < noparts - 1; ++j) { 255 | free(partb[i][j].bnode_ptr); 256 | } 257 | } 258 | 259 | for (int i = 0; i < MAX_POP; i++) { 260 | free(pop[i].chrom); 261 | free(pop[i].parts); 262 | } 263 | 264 | free(mcells); 265 | 266 | free(tchrom); 267 | 268 | return (0); 269 | } /* main-plm */ 270 | 271 | /* EOF */ 272 | -------------------------------------------------------------------------------- /src/fms/ad_lib_fms.c: -------------------------------------------------------------------------------- 1 | 2 | /* COPYRIGHT C 1991- Ali Dasdan */ 3 | 4 | #include "../share/ad_defs.h" 5 | #include "../share/ad_bucketio.h" 6 | #include "../share/ad_lib.h" 7 | #include "ad_lib_fms.h" 8 | 9 | /* map a given mov_gain into index to a bucket array */ 10 | int map_gain(int mov_gain, int max_gain) 11 | { 12 | return (mov_gain + max_gain); 13 | } /* map_gain */ 14 | 15 | /* fill all bucket arrays */ 16 | void create_buckets(int nocells, 17 | int noparts, 18 | int max_gain, 19 | allele chrom[], 20 | partb_t partb[][noparts - 1], 21 | cells_info_t cells_info[]) 22 | { 23 | /* read cell gains from cells_info and insert them into buckets */ 24 | for (int cell_no = 0; cell_no < nocells; cell_no++) { 25 | 26 | int part_no = chrom[cell_no]; 27 | 28 | /* for each possible move direction */ 29 | for (int mov_part_no = 0; mov_part_no < noparts; mov_part_no++) { 30 | if (mov_part_no != part_no) { 31 | 32 | int mov_gain = calculate_gain(cell_no, part_no, mov_part_no, cells_info); 33 | 34 | /* find mapped_after calculating gain & max */ 35 | int mapped_part_no = map_part_no(mov_part_no, part_no); 36 | int gain_inx = map_gain(mov_gain, max_gain); 37 | 38 | /* create a partb node */ 39 | create_partb_node(noparts, cell_no, part_no, mapped_part_no, 40 | gain_inx, partb, cells_info); 41 | 42 | } /* if mapped_part_no not equal part_no */ 43 | } /* for mapped_part_no */ 44 | } /* for part_no */ 45 | } /* create_buckets */ 46 | 47 | /* select a cell to move */ 48 | int select_cell(int noparts, 49 | selected_cell_t scell[], 50 | parts_info_t parts_info[], 51 | cells_t cells[], 52 | partb_t partb[][noparts - 1], 53 | cells_info_t cells_info[]) 54 | { 55 | /* 56 | add to the 1st "if" && (parts_info[from].pmax_cells > 0) 57 | */ 58 | int move_possible = True; 59 | int max_mov_value = -1; 60 | for (int from = 0; from < noparts; from++) { 61 | int fpcurr_size = parts_info[from].pcurr_size; 62 | int fpmin_size = parts_info[from].pmin_size; 63 | if (fpcurr_size > fpmin_size) { 64 | for (int to = 0; to < noparts; to++) { 65 | int tpmax_size = parts_info[to].pmax_size; 66 | int tpcurr_size = parts_info[to].pcurr_size; 67 | if ((from != to) && (tpcurr_size < tpmax_size)) { 68 | int dest_part = map_part_no(to, from); 69 | int max_inx = partb[from][dest_part].max_inx; 70 | if (max_inx > 0) { 71 | int cell_no = partb[from][dest_part].bnode_ptr[max_inx]->cell_no; 72 | if ((max_mov_value < max_inx) && 73 | (fpcurr_size >= (fpmin_size + cells[cell_no].cweight)) && 74 | ((tpcurr_size + cells[cell_no].cweight) <= tpmax_size)) { 75 | max_mov_value = max_inx; 76 | scell[0].mov_cell_no = cell_no; 77 | scell[0].from_part = from; 78 | scell[0].to_part = to; 79 | } /* if many conditions */ 80 | } /* if */ 81 | } /* if */ 82 | } /* for to */ 83 | } /* if curr > min */ 84 | } /* for from */ 85 | 86 | if (max_mov_value != -1) { 87 | 88 | scell[0].mov_gain = calculate_gain(scell[0].mov_cell_no, 89 | scell[0].from_part, 90 | scell[0].to_part, 91 | cells_info); 92 | parts_info[scell[0].from_part].pmax_cells--; 93 | parts_info[scell[0].to_part].pmax_cells++; 94 | parts_info[scell[0].from_part].pcurr_size -= 95 | cells[scell[0].mov_cell_no].cweight; 96 | parts_info[scell[0].to_part].pcurr_size += 97 | cells[scell[0].mov_cell_no].cweight; 98 | 99 | } else { 100 | 101 | move_possible = False; 102 | max_mov_value = -1; 103 | for (int from = 0; from < noparts; from++) { 104 | // int fpcurr_size = parts_info[from].pcurr_size; 105 | // int fpmin_size = parts_info[from].pmin_size; 106 | for (int to = 0; to < noparts; to++) { 107 | // int tpmax_size = parts_info[to].pmax_size; 108 | // int tpcurr_size = parts_info[to].pcurr_size; 109 | if (from != to) { 110 | int dest_part = map_part_no(to, from); 111 | int max_inx = partb[from][dest_part].max_inx; 112 | if (max_inx > 0) { 113 | int cell_no = partb[from][dest_part].bnode_ptr[max_inx]->cell_no; 114 | if (max_mov_value < max_inx) { 115 | max_mov_value = max_inx; 116 | scell[0].mov_cell_no = cell_no; 117 | scell[0].from_part = from; 118 | } /* if many conditions */ 119 | } /* if */ 120 | } /* if */ 121 | } /* for to */ 122 | } /* for from */ 123 | 124 | } /* else */ 125 | 126 | return move_possible; 127 | } /* select_cell */ 128 | 129 | /* move selected cell, and save the move in a file */ 130 | void move_cell(mcells_t mcells[], 131 | int msize, 132 | selected_cell_t scell[]) 133 | { 134 | mcells[msize].cell_no = scell[0].mov_cell_no; 135 | mcells[msize].from = scell[0].from_part; 136 | mcells[msize].to = scell[0].to_part; 137 | mcells[msize].mgain = scell[0].mov_gain; 138 | } /* move_cell */ 139 | 140 | /* update gains after a move */ 141 | void update_gains(int noparts, 142 | int max_gain, 143 | selected_cell_t scell[], 144 | allele tchrom[], 145 | cells_t cells[], 146 | nets_t nets[], 147 | corn_t cnets[], 148 | partb_t partb[][noparts - 1], 149 | cells_info_t cells_info[]) 150 | { 151 | /* for each neighbor do */ 152 | int net_ptr = cells[scell[0].mov_cell_no].netlist; 153 | for (int i = 0; i < cells[scell[0].mov_cell_no].cno_nets; i++) { 154 | 155 | int net_no = cnets[net_ptr].corn_no; 156 | 157 | /* find neighbor cell */ 158 | int other_cell, other_part_no, net_weight; 159 | find_other_cell(net_no, scell[0].mov_cell_no, 160 | &other_cell, &other_part_no, &net_weight, 161 | tchrom, nets); 162 | 163 | if (cells_info[other_cell].locked == False) { 164 | 165 | /* update costs */ 166 | cells_info[other_cell].mgain[scell[0].from_part] -= net_weight; 167 | cells_info[other_cell].mgain[scell[0].to_part] += net_weight; 168 | 169 | /* update gains */ 170 | if ((scell[0].from_part != other_part_no) && 171 | (scell[0].to_part != other_part_no)) { 172 | 173 | for (int j = 0; j < 2; j++) { 174 | int dest_part = scell[0].from_part; 175 | if (j == 1) { 176 | dest_part = scell[0].to_part; 177 | } 178 | int mov_gain = calculate_gain(other_cell, other_part_no, 179 | dest_part, cells_info); 180 | int gain_inx = map_gain(mov_gain, max_gain); 181 | int mapped_part_no = map_part_no(dest_part, other_part_no); 182 | bnode_ptr_t tnode_ptr = delete_partb_node(False, mapped_part_no, 183 | &partb[other_part_no][mapped_part_no], 184 | &cells_info[other_cell]); 185 | insert_partb_node(tnode_ptr, mapped_part_no, gain_inx, 186 | &partb[other_part_no][mapped_part_no], 187 | &cells_info[other_cell]); 188 | } /* for j */ 189 | 190 | } else { /* internal cost changed, update all gains */ 191 | 192 | delete_partb_nodes_of_cell(noparts, other_cell, other_part_no, 193 | partb, cells_info); 194 | create_partb_nodes_of_cell(noparts, max_gain, 195 | other_cell, other_part_no, 196 | partb, cells_info); 197 | 198 | } /* else */ 199 | } /* if cell is free */ 200 | 201 | net_ptr++; 202 | 203 | } /* for i */ 204 | } /* update_gains */ 205 | 206 | void create_partb_nodes_of_cell(int noparts, 207 | int max_gain, 208 | int cell_no, 209 | int part_no, 210 | partb_t partb[][noparts - 1], 211 | cells_info_t cells_info[]) 212 | { 213 | if (cell_no == -1) { 214 | return; 215 | } 216 | 217 | /* for each possible move direction */ 218 | for (int mov_part_no = 0; mov_part_no < noparts; mov_part_no++) { 219 | 220 | if (mov_part_no != part_no) { /* part-no is home_part of cell_no */ 221 | 222 | int mov_gain = calculate_gain(cell_no, part_no, mov_part_no, cells_info); 223 | 224 | /* find mapped_after calculating gain & max */ 225 | int mapped_part_no = map_part_no(mov_part_no, part_no); 226 | int gain_inx = map_gain(mov_gain, max_gain); 227 | 228 | /* create a partb node */ 229 | create_partb_node(noparts, cell_no, part_no, mapped_part_no, 230 | gain_inx, partb, cells_info); 231 | 232 | } /* if mapped_part_no not equal part_no */ 233 | 234 | } /* for mapped_part_no */ 235 | } /* create_partb_nodes_of_cell */ 236 | 237 | /* EOF */ 238 | -------------------------------------------------------------------------------- /src/plm/ad_lib_plm.c: -------------------------------------------------------------------------------- 1 | 2 | /* COPYRIGHT C 1991- Ali Dasdan */ 3 | 4 | #include 5 | #include 6 | #include "ad_defs.h" 7 | #include "ad_bucketio.h" 8 | #include "ad_lib.h" 9 | #include "ad_lib_plm.h" 10 | 11 | /* map a given mov_gain into index to a bucket array */ 12 | int map_gain(int mov_gain, int max_gain) 13 | { 14 | return (mov_gain + max_gain); 15 | } /* map_gain */ 16 | 17 | /* fill all bucket arrays */ 18 | void create_buckets(int nocells, 19 | int noparts, 20 | int max_gain, 21 | allele chrom[], 22 | partb_t partb[][noparts - 1], 23 | cells_info_t cells_info[]) 24 | { 25 | /* read cell gains from cells_info and insert them into buckets */ 26 | for (int cell_no = 0; cell_no < nocells; cell_no++) { 27 | 28 | int part_no = chrom[cell_no]; 29 | 30 | /* for each possible move direction */ 31 | for (int mov_part_no = 0; mov_part_no < noparts; mov_part_no++) { 32 | if (mov_part_no != part_no) { 33 | int mov_gain = calculate_gain(cell_no, part_no, mov_part_no, cells_info); 34 | 35 | /* find mapped_after calculating gain & max */ 36 | int mapped_part_no = map_part_no(mov_part_no, part_no); 37 | int gain_inx = map_gain(mov_gain, max_gain); 38 | 39 | /* create a partb node */ 40 | create_partb_node(noparts, cell_no, part_no, mapped_part_no, 41 | gain_inx, partb, cells_info); 42 | 43 | } /* if mapped_part_no not equal part_no */ 44 | } /* for mapped_part_no */ 45 | 46 | } /* for part_no */ 47 | } /* create_buckets */ 48 | 49 | /* select a cell to move */ 50 | int select_cell(int noparts, 51 | selected_cell_t scell[], 52 | parts_info_t parts_info[], 53 | cells_t cells[], 54 | partb_t partb[][noparts - 1], 55 | cells_info_t cells_info[]) 56 | { 57 | /* 58 | add to the 1st "if" && (parts_info[from].pmax_cells > 0) 59 | */ 60 | int move_possible = True; 61 | int max_mov_value = -1; 62 | for (int from = 0; from < noparts; from++) { 63 | int fpcurr_size = parts_info[from].pcurr_size; 64 | int fpmin_size = parts_info[from].pmin_size; 65 | if (fpcurr_size > fpmin_size) { 66 | for (int to = 0; to < noparts; to++) { 67 | int tpmax_size = parts_info[to].pmax_size; 68 | int tpcurr_size = parts_info[to].pcurr_size; 69 | if ((from != to) && (tpcurr_size < tpmax_size)) { 70 | int dest_part = map_part_no (to, from); 71 | int max_inx = partb[from][dest_part].max_inx; 72 | if (max_inx < 0) { 73 | printf("Error: max_inx cannot be negative.\n"); 74 | exit(1); 75 | } /* if */ 76 | int cell_no = partb[from][dest_part].bnode_ptr[max_inx]->cell_no; 77 | if ((max_mov_value < max_inx) && 78 | (fpcurr_size >= (fpmin_size + cells[cell_no].cweight)) && 79 | ((tpcurr_size + cells[cell_no].cweight) <= tpmax_size)) { 80 | max_mov_value = max_inx; 81 | scell[0].mov_cell_no = cell_no; 82 | scell[0].from_part = from; 83 | scell[0].to_part = to; 84 | } /* if many conditions */ 85 | } /* if */ 86 | } /* for to */ 87 | } /* if curr > min */ 88 | } /* for from */ 89 | 90 | if (max_mov_value != -1) { 91 | 92 | scell[0].mov_gain = calculate_gain(scell[0].mov_cell_no, 93 | scell[0].from_part, 94 | scell[0].to_part, 95 | cells_info); 96 | parts_info[scell[0].from_part].pmax_cells--; 97 | parts_info[scell[0].to_part].pmax_cells++; 98 | parts_info[scell[0].from_part].pcurr_size -= 99 | cells[scell[0].mov_cell_no].cweight; 100 | parts_info[scell[0].to_part].pcurr_size += 101 | cells[scell[0].mov_cell_no].cweight; 102 | 103 | } else { 104 | 105 | move_possible = False; 106 | max_mov_value = -1; 107 | for (int from = 0; from < noparts; from++) { 108 | // int fpcurr_size = parts_info[from].pcurr_size; 109 | // int fpmin_size = parts_info[from].pmin_size; 110 | for (int to = 0; to < noparts; to++) { 111 | // int tpmax_size = parts_info[to].pmax_size; 112 | // int tpcurr_size = parts_info[to].pcurr_size; 113 | if (from != to) { 114 | int dest_part = map_part_no(to, from); 115 | int max_inx = partb[from][dest_part].max_inx; 116 | if (max_inx > 0) { 117 | int cell_no = partb[from][dest_part].bnode_ptr[max_inx]->cell_no; 118 | if (max_mov_value < max_inx) { 119 | max_mov_value = max_inx; 120 | scell[0].mov_cell_no = cell_no; 121 | scell[0].from_part = from; 122 | } /* if many conditions */ 123 | } /* if */ 124 | } /* if */ 125 | } /* for to */ 126 | } /* for from */ 127 | 128 | } /* else */ 129 | 130 | return move_possible; 131 | } /* select_cell */ 132 | 133 | /* move selected cell, and save the move in a file */ 134 | void move_cell(mcells_t mcells[], 135 | int msize, 136 | selected_cell_t scell[], 137 | allele tchrom[]) 138 | { 139 | tchrom[scell[0].mov_cell_no] = scell[0].to_part; 140 | mcells[msize].cell_no = scell[0].mov_cell_no; 141 | mcells[msize].from = scell[0].from_part; 142 | mcells[msize].to = scell[0].to_part; 143 | mcells[msize].mgain = scell[0].mov_gain; 144 | } /* move_cell */ 145 | 146 | /* update gains after a move */ 147 | void update_gains(int noparts, 148 | int max_gain, 149 | selected_cell_t scell[], 150 | allele tchrom[], 151 | cells_t cells[], 152 | nets_t nets[], 153 | corn_t cnets[], 154 | partb_t partb[][noparts - 1], 155 | cells_info_t cells_info[]) 156 | { 157 | /* for each neighbor do */ 158 | int net_ptr = cells[scell[0].mov_cell_no].netlist; 159 | for (int i = 0; i < cells[scell[0].mov_cell_no].cno_nets; i++) { 160 | 161 | int net_no = cnets[net_ptr].corn_no; 162 | 163 | /* find neighbor cell */ 164 | int other_cell, other_part_no, net_weight; 165 | find_other_cell(net_no, scell[0].mov_cell_no, 166 | &other_cell, &other_part_no, &net_weight, 167 | tchrom, nets); 168 | 169 | if (cells_info[other_cell].locked == False) { 170 | 171 | /* update costs */ 172 | cells_info[other_cell].mgain[scell[0].from_part] -= net_weight; 173 | cells_info[other_cell].mgain[scell[0].to_part] += net_weight; 174 | 175 | /* update gains */ 176 | if ((scell[0].from_part != other_part_no) && 177 | (scell[0].to_part != other_part_no)) { 178 | 179 | for (int j = 0; j < 2; j++) { 180 | int dest_part = scell[0].from_part; 181 | if (j == 1) { 182 | dest_part = scell[0].to_part; 183 | } 184 | int mov_gain = calculate_gain(other_cell, other_part_no, 185 | dest_part, cells_info); 186 | int gain_inx = map_gain(mov_gain, max_gain); 187 | int mapped_part_no = map_part_no(dest_part, other_part_no); 188 | bnode_ptr_t tnode_ptr = delete_partb_node(False, mapped_part_no, 189 | &partb[other_part_no][mapped_part_no], 190 | &cells_info[other_cell]); 191 | insert_partb_node(tnode_ptr, mapped_part_no, gain_inx, 192 | &partb[other_part_no][mapped_part_no], 193 | &cells_info[other_cell]); 194 | } /* for j */ 195 | 196 | } else { /* internal cost changed, update all gains */ 197 | 198 | delete_partb_nodes_of_cell(noparts, other_cell, other_part_no, 199 | partb, cells_info); 200 | create_partb_nodes_of_cell(noparts, max_gain, 201 | other_cell, other_part_no, 202 | partb, cells_info); 203 | 204 | } /* else */ 205 | } /* if cell is free */ 206 | 207 | net_ptr++; 208 | 209 | } /* for i */ 210 | } /* update_gains */ 211 | 212 | void create_partb_nodes_of_cell(int noparts, 213 | int max_gain, 214 | int cell_no, 215 | int part_no, 216 | partb_t partb[][noparts - 1], 217 | cells_info_t cells_info[]) 218 | { 219 | if (cell_no == -1) { 220 | return; 221 | } 222 | 223 | /* for each possible move direction */ 224 | for (int mov_part_no = 0; mov_part_no < noparts; mov_part_no++) { 225 | 226 | if (mov_part_no != part_no) { /* part-no is home_part of cell_no */ 227 | 228 | int mov_gain = calculate_gain(cell_no, part_no, mov_part_no, cells_info); 229 | 230 | /* find mapped_after calculating gain & max */ 231 | int mapped_part_no = map_part_no(mov_part_no, part_no); 232 | int gain_inx = map_gain(mov_gain, max_gain); 233 | 234 | /* create a partb node */ 235 | create_partb_node(noparts, cell_no, part_no, mapped_part_no, 236 | gain_inx, partb, cells_info); 237 | 238 | } /* if mapped_part_no not equal part_no */ 239 | 240 | } /* for mapped_part_no */ 241 | } /* create_partb_nodes_of_cell */ 242 | 243 | /* EOF */ 244 | -------------------------------------------------------------------------------- /src/pfm/ad_lib_pfm.c: -------------------------------------------------------------------------------- 1 | 2 | /* COPYRIGHT C 1991- Ali Dasdan */ 3 | 4 | #include 5 | #include 6 | #include 7 | #include "ad_defs.h" 8 | #include "ad_bucketio.h" 9 | #include "ad_lib.h" 10 | #include "ad_lib_pfm.h" 11 | 12 | /* 13 | ALSO TRY THESE: 14 | mov_value = ((float) (mov_gain + max_gain)) / 15 | ((float) mcount * 2.0 * max_gain); 16 | 17 | mov_value = ((float) (mov_gain + max_gain)) / 18 | ((float) log((double) (mcount + 3.0)) * 2.0 * max_gain); 19 | */ 20 | 21 | /* map a given mov_gain into index to a bucket array */ 22 | int map_gain(int bucketsize, 23 | int mov_gain, 24 | int mov_count, 25 | int max_gain, 26 | eval_t eval[]) 27 | { 28 | int mcount = mov_count; 29 | if (mcount == 0) { 30 | mcount = 1; 31 | } 32 | float mov_value = ((float) (bucketsize) / 33 | (1.0 + (float) sqrt((double) (mcount)) * 34 | (float) eval[max_gain - mov_gain].val)); 35 | return ((int) mov_value); 36 | } /* map_gain */ 37 | 38 | /* fill all bucket arrays */ 39 | void create_buckets(int bucketsize, 40 | int nocells, 41 | int noparts, 42 | int max_gain, 43 | eval_t eval[], 44 | allele chrom[], 45 | partb_t partb[][noparts - 1], 46 | cells_info_t cells_info[]) 47 | { 48 | /* read cell gains from cells_info and insert them into buckets */ 49 | for (int cell_no = 0; cell_no < nocells; cell_no++) { 50 | 51 | int part_no = chrom[cell_no]; 52 | 53 | /* for each possible move direction */ 54 | for (int mov_part_no = 0; mov_part_no < noparts; mov_part_no++) { 55 | if (mov_part_no != part_no) { 56 | 57 | int mov_gain = calculate_gain(cell_no, part_no, mov_part_no, cells_info); 58 | 59 | /* find mapped_after calculating gain & max */ 60 | int mapped_part_no = map_part_no(mov_part_no, part_no); 61 | int gain_inx = map_gain(bucketsize, mov_gain, cells_info[cell_no].mcount, 62 | max_gain, eval); 63 | 64 | /* create a partb node */ 65 | create_partb_node(noparts, cell_no, part_no, mapped_part_no, 66 | gain_inx, partb, cells_info); 67 | 68 | } /* if mapped_part_no not equal part_no */ 69 | } /* for mapped_part_no */ 70 | } /* for part_no */ 71 | } /* create_buckets */ 72 | 73 | /* select a cell to move */ 74 | void select_cell(int noparts, 75 | selected_cell_t scell[], 76 | parts_info_t parts_info[], 77 | cells_t cells[], 78 | partb_t partb[][noparts - 1], 79 | cells_info_t cells_info[]) 80 | { 81 | int max_mov_value = -1; 82 | scell[0].mov_cell_no = -1; 83 | for (int from = 0; from < noparts; from++) { 84 | int fpcurr_size = parts_info[from].pcurr_size; 85 | int fpmin_size = parts_info[from].pmin_size; 86 | if (fpcurr_size > fpmin_size) { 87 | for (int to = 0; to < noparts; to++) { 88 | int tpmax_size = parts_info[to].pmax_size; 89 | int tpcurr_size = parts_info[to].pcurr_size; 90 | if ((from != to) && (tpcurr_size < tpmax_size)) { 91 | int dest_part = map_part_no(to, from); 92 | int max_inx = partb[from][dest_part].max_inx; 93 | if (max_inx < 0) { 94 | printf("Error: max_inx cannot be negative.\n"); 95 | exit(1); 96 | } /* if */ 97 | int cell_no = partb[from][dest_part].bnode_ptr[max_inx]->cell_no; 98 | if ((max_mov_value < max_inx) && 99 | (fpcurr_size >= (fpmin_size + cells[cell_no].cweight)) && 100 | ((tpcurr_size + cells[cell_no].cweight) <= tpmax_size)) { 101 | max_mov_value = max_inx; 102 | scell[0].mov_cell_no = cell_no; 103 | scell[0].from_part = from; 104 | scell[0].to_part = to; 105 | } /* if many conditions */ 106 | } /* if */ 107 | } /* for to */ 108 | } /* if curr > min */ 109 | } /* for from */ 110 | 111 | if (scell[0].mov_cell_no == -1) { 112 | printf("Error: Cannot find a node to move.\n"); 113 | exit(1); 114 | } /* if */ 115 | 116 | scell[0].mov_gain = calculate_gain(scell[0].mov_cell_no, 117 | scell[0].from_part, 118 | scell[0].to_part, 119 | cells_info); 120 | parts_info[scell[0].from_part].pmax_cells--; 121 | parts_info[scell[0].to_part].pmax_cells++; 122 | parts_info[scell[0].from_part].pcurr_size -= 123 | cells[scell[0].mov_cell_no].cweight; 124 | parts_info[scell[0].to_part].pcurr_size += 125 | cells[scell[0].mov_cell_no].cweight; 126 | } /* select_cell */ 127 | 128 | /* move selected cell, and save the move in a file */ 129 | void move_cell(mcells_t mcells[], 130 | int msize, 131 | selected_cell_t scell[], 132 | allele tchrom[], 133 | cells_info_t cells_info[]) 134 | { 135 | tchrom[scell[0].mov_cell_no] = scell[0].to_part; 136 | cells_info[scell[0].mov_cell_no].mcount++; 137 | mcells[msize].cell_no = scell[0].mov_cell_no; 138 | mcells[msize].from = scell[0].from_part; 139 | mcells[msize].to = scell[0].to_part; 140 | mcells[msize].mgain = scell[0].mov_gain; 141 | } /* move_cell */ 142 | 143 | /* update gains after a move */ 144 | void update_gains(int bucketsize, 145 | int noparts, 146 | int max_gain, 147 | eval_t eval[], 148 | selected_cell_t scell[], 149 | allele tchrom[], 150 | cells_t cells[], 151 | nets_t nets[], 152 | corn_t cnets[], 153 | partb_t partb[][noparts - 1], 154 | cells_info_t cells_info[]) 155 | { 156 | /* for each neighbor do */ 157 | int net_ptr = cells[scell[0].mov_cell_no].netlist; 158 | for (int i = 0; i < cells[scell[0].mov_cell_no].cno_nets; i++) { 159 | 160 | int net_no = cnets[net_ptr].corn_no; 161 | 162 | /* find neighbor cell */ 163 | int other_cell, other_part_no, net_weight; 164 | find_other_cell(net_no, scell[0].mov_cell_no, 165 | &other_cell, &other_part_no, &net_weight, 166 | tchrom, nets); 167 | 168 | /* update costs */ 169 | cells_info[other_cell].mgain[scell[0].from_part] -= net_weight; 170 | cells_info[other_cell].mgain[scell[0].to_part] += net_weight; 171 | 172 | /* update gains */ 173 | if ((scell[0].from_part != other_part_no) && 174 | (scell[0].to_part != other_part_no)) { 175 | 176 | for (int j = 0; j < 2; j++) { 177 | int dest_part = scell[0].from_part; 178 | if (j == 1) { 179 | dest_part = scell[0].to_part; 180 | } 181 | int mov_gain = calculate_gain(other_cell, other_part_no, 182 | dest_part, cells_info); 183 | int gain_inx = map_gain(bucketsize, mov_gain, cells_info[other_cell].mcount, 184 | max_gain, eval); 185 | int mapped_part_no = map_part_no(dest_part, other_part_no); 186 | bnode_ptr_t tnode_ptr = delete_partb_node(False, mapped_part_no, 187 | &partb[other_part_no][mapped_part_no], 188 | &cells_info[other_cell]); 189 | insert_partb_node(tnode_ptr, mapped_part_no, gain_inx, 190 | &partb[other_part_no][mapped_part_no], 191 | &cells_info[other_cell]); 192 | } /* for j */ 193 | } else { /* internal cost changed, update all gains */ 194 | 195 | delete_partb_nodes_of_cell(noparts, other_cell, other_part_no, 196 | partb, cells_info); 197 | 198 | create_partb_nodes_of_cell(bucketsize, noparts, max_gain, 199 | other_cell, other_part_no, 200 | eval, partb, cells_info); 201 | 202 | } /* else */ 203 | 204 | net_ptr++; 205 | 206 | } /* for i */ 207 | } /* update_gains */ 208 | 209 | /* fill eval array */ 210 | void fill_eval(int max_gain, 211 | float K, 212 | eval_t eval[]) 213 | { 214 | for (int i = 0; i <= (2 * max_gain); i++) 215 | eval[i].val = (float) exp((double) (-K * (max_gain - i))); 216 | } /* fill_eval */ 217 | 218 | void create_partb_nodes_of_cell(int bucketsize, 219 | int noparts, 220 | int max_gain, 221 | int cell_no, 222 | int part_no, 223 | eval_t eval[], 224 | partb_t partb[][noparts - 1], 225 | cells_info_t cells_info[]) 226 | { 227 | if (cell_no == -1) { 228 | return; 229 | } 230 | 231 | /* for each possible move direction */ 232 | for (int mov_part_no = 0; mov_part_no < noparts; mov_part_no++) { 233 | 234 | if (mov_part_no != part_no) { /* part_no is home_part of cell_no */ 235 | 236 | int mov_gain = calculate_gain(cell_no, part_no, mov_part_no, cells_info); 237 | 238 | /* find mapped_after calculating gain & max */ 239 | int mapped_part_no = map_part_no(mov_part_no, part_no); 240 | int gain_inx = map_gain(bucketsize, mov_gain, cells_info[cell_no].mcount, 241 | max_gain, eval); 242 | 243 | /* create a partb node */ 244 | create_partb_node(noparts, cell_no, part_no, mapped_part_no, 245 | gain_inx, partb, cells_info); 246 | 247 | } /* if mapped_part_no not equal part_no */ 248 | 249 | } /* for mapped_part_no */ 250 | } /* create_partb_nodes_of_cell */ 251 | 252 | /* calculate K and scale factor */ 253 | void calculate_scale(int nocells, 254 | int noparts, 255 | int max_gain, 256 | float *K) 257 | { 258 | double ratio = log((double) ((1.0 - EPSILON) / EPSILON)); 259 | *K = (1.0 / max_gain) * (float) ratio; 260 | double scale = (double) pow(ratio, (double) 1.0 / max_gain); 261 | scale = (scale + 1.0 + ratio * noparts * sqrt((double) nocells)) / (scale - 1.0); 262 | scale = (double) pow(ratio, (double) 1.0 / max_gain); 263 | scale = (scale + 1.0 + ratio * noparts) / (scale - 1.0); 264 | } /* calculate_scale */ 265 | 266 | /* EOF */ 267 | -------------------------------------------------------------------------------- /input/p9: -------------------------------------------------------------------------------- 1 | 1723 2 | 2394 3 | 1 2 1416 0 4 | 1 2 1174 1 5 | 1 2 1106 2 6 | 1 2 1083 3 7 | 1 2 598 4 8 | 1 2 1504 5 9 | 1 2 528 6 10 | 1 2 8 7 11 | 1 2 90 8 12 | 1 2 10 9 13 | 1 2 484 10 14 | 1 2 13 11 15 | 1 2 13 12 16 | 1 2 284 13 17 | 1 2 597 14 18 | 1 2 1641 15 19 | 1 2 1641 16 20 | 1 2 1648 17 21 | 1 2 20 18 22 | 1 2 20 19 23 | 1 2 596 20 24 | 1 2 1581 21 25 | 1 2 1581 22 26 | 1 2 1568 23 27 | 1 2 595 24 28 | 1 2 26 25 29 | 1 2 27 26 30 | 1 2 594 27 31 | 1 2 593 28 32 | 1 2 31 29 33 | 1 2 31 30 34 | 1 2 592 31 35 | 1 2 33 32 36 | 1 2 591 33 37 | 1 2 590 34 38 | 1 2 1173 35 39 | 1 2 1153 36 40 | 1 2 488 37 41 | 1 2 1410 38 42 | 1 2 521 39 43 | 1 2 1172 40 44 | 1 2 42 41 45 | 1 2 589 42 46 | 1 2 588 43 47 | 1 2 588 44 48 | 1 2 46 45 49 | 1 2 1121 46 50 | 1 2 587 47 51 | 1 2 1681 48 52 | 1 2 586 49 53 | 1 2 1650 50 54 | 1 2 1624 51 55 | 1 2 1521 52 56 | 1 2 585 53 57 | 1 2 584 54 58 | 1 2 58 55 59 | 1 2 1658 56 60 | 1 2 58 57 61 | 1 2 967 58 62 | 1 2 1722 59 63 | 1 2 1605 60 64 | 1 2 1605 61 65 | 1 2 1605 62 66 | 1 2 1605 63 67 | 1 2 507 64 68 | 1 2 1171 65 69 | 1 2 1491 66 70 | 1 2 1591 67 71 | 1 2 69 68 72 | 1 2 70 69 73 | 1 2 1508 70 74 | 1 2 72 71 75 | 1 2 486 72 76 | 1 2 1168 73 77 | 1 2 1097 74 78 | 1 2 1167 75 79 | 1 2 1459 76 80 | 1 2 583 77 81 | 1 2 1627 78 82 | 1 2 1627 79 83 | 1 2 1627 80 84 | 1 2 1166 81 85 | 1 2 1091 82 86 | 1 2 1091 83 87 | 1 2 85 84 88 | 1 2 1091 85 89 | 1 2 1143 86 90 | 1 2 88 87 91 | 1 2 89 88 92 | 1 2 90 89 93 | 1 2 706 90 94 | 1 2 1540 91 95 | 1 2 582 92 96 | 1 2 1642 93 97 | 1 2 1161 94 98 | 1 2 96 95 99 | 1 2 481 96 100 | 1 2 1642 97 101 | 1 2 1565 98 102 | 1 2 579 99 103 | 1 2 581 100 104 | 1 2 1455 101 105 | 1 2 1539 102 106 | 1 2 1165 103 107 | 1 2 578 104 108 | 1 2 1163 105 109 | 1 2 577 106 110 | 1 2 577 107 111 | 1 2 111 108 112 | 1 2 111 109 113 | 1 2 111 110 114 | 1 2 112 111 115 | 1 2 1376 112 116 | 1 2 188 113 117 | 1 2 1540 114 118 | 1 2 1128 115 119 | 1 2 1448 116 120 | 1 2 1448 117 121 | 1 2 1448 118 122 | 1 2 1448 119 123 | 1 2 1448 120 124 | 1 2 122 121 125 | 1 2 1448 122 126 | 1 2 1162 123 127 | 1 2 125 124 128 | 1 2 1584 125 129 | 1 2 576 126 130 | 1 2 575 127 131 | 1 2 572 128 132 | 1 2 571 129 133 | 1 2 748 130 134 | 1 2 748 131 135 | 1 2 237 132 136 | 1 2 570 133 137 | 1 2 569 134 138 | 1 2 569 135 139 | 1 2 569 136 140 | 1 2 1161 137 141 | 1 2 1533 138 142 | 1 2 1637 139 143 | 1 2 1637 140 144 | 1 2 1637 141 145 | 1 2 1637 142 146 | 1 2 1665 143 147 | 1 2 1665 144 148 | 1 2 1665 145 149 | 1 2 566 146 150 | 1 2 565 147 151 | 1 2 149 148 152 | 1 2 1397 149 153 | 1 2 151 150 154 | 1 2 548 151 155 | 1 2 1160 152 156 | 1 2 564 153 157 | 1 2 1652 154 158 | 1 2 1480 155 159 | 1 2 1480 156 160 | 1 2 1480 157 161 | 1 2 1480 158 162 | 1 2 1480 159 163 | 1 2 563 160 164 | 1 2 1159 161 165 | 1 2 1159 162 166 | 1 2 1159 163 167 | 1 2 1689 164 168 | 1 2 1689 165 169 | 1 2 1689 166 170 | 1 2 168 167 171 | 1 2 561 168 172 | 1 2 170 169 173 | 1 2 1158 170 174 | 1 2 172 171 175 | 1 2 173 172 176 | 1 2 1679 173 177 | 1 2 1620 173 178 | 1 2 1464 173 179 | 1 2 1308 173 180 | 1 2 1277 173 181 | 1 2 559 174 182 | 1 2 550 175 183 | 1 2 1439 176 184 | 1 2 1092 177 185 | 1 2 557 178 186 | 1 2 1540 179 187 | 1 2 553 180 188 | 1 2 553 181 189 | 1 2 769 182 190 | 1 2 556 183 191 | 1 2 556 184 192 | 1 2 1682 185 193 | 1 2 187 186 194 | 1 2 188 187 195 | 1 2 1574 188 196 | 1 2 190 189 197 | 1 2 1489 190 198 | 1 2 554 191 199 | 1 2 553 192 200 | 1 2 552 193 201 | 1 2 1697 194 202 | 1 2 551 195 203 | 1 2 1157 196 204 | 1 2 1157 197 205 | 1 2 549 198 206 | 1 2 200 199 207 | 1 2 547 200 208 | 1 2 203 201 209 | 1 2 203 202 210 | 1 2 546 203 211 | 1 2 463 204 212 | 1 2 1599 205 213 | 1 2 545 206 214 | 1 2 544 207 215 | 1 2 1638 208 216 | 1 2 543 209 217 | 1 2 542 210 218 | 1 2 1155 211 219 | 1 2 539 212 220 | 1 2 214 213 221 | 1 2 1619 214 222 | 1 2 538 215 223 | 1 2 463 216 224 | 1 2 218 217 225 | 1 2 219 218 226 | 1 2 352 219 227 | 1 2 1153 220 228 | 1 2 1154 221 229 | 1 2 1067 222 230 | 1 2 224 223 231 | 1 2 225 224 232 | 1 2 226 225 233 | 1 2 227 226 234 | 1 2 535 227 235 | 1 2 1085 228 236 | 1 2 230 229 237 | 1 2 534 230 238 | 1 2 533 231 239 | 1 2 233 232 240 | 1 2 530 233 241 | 1 2 1655 234 242 | 1 2 1655 235 243 | 1 2 237 236 244 | 1 2 748 237 245 | 1 2 526 238 246 | 1 2 525 239 247 | 1 2 1153 240 248 | 1 2 1095 241 249 | 1 2 1095 242 250 | 1 2 524 243 251 | 1 2 524 244 252 | 1 2 523 245 253 | 1 2 248 246 254 | 1 2 248 247 255 | 1 2 491 248 256 | 1 2 522 249 257 | 1 2 522 250 258 | 1 2 253 251 259 | 1 2 253 252 260 | 1 2 1453 253 261 | 1 2 520 254 262 | 1 2 257 255 263 | 1 2 257 256 264 | 1 2 1152 257 265 | 1 2 1447 258 266 | 1 2 1447 259 267 | 1 2 1105 260 268 | 1 2 560 261 269 | 1 2 560 262 270 | 1 2 264 263 271 | 1 2 519 264 272 | 1 2 266 265 273 | 1 2 518 266 274 | 1 2 268 267 275 | 1 2 1151 268 276 | 1 2 270 269 277 | 1 2 1151 270 278 | 1 2 516 271 279 | 1 2 515 272 280 | 1 2 514 273 281 | 1 2 1150 274 282 | 1 2 276 275 283 | 1 2 277 276 284 | 1 2 1495 277 285 | 1 2 512 278 286 | 1 2 1646 279 287 | 1 2 1646 280 288 | 1 2 511 281 289 | 1 2 284 282 290 | 1 2 284 283 291 | 1 2 285 284 292 | 1 2 1376 285 293 | 1 2 510 286 294 | 1 2 508 287 295 | 1 2 506 288 296 | 1 2 506 289 297 | 1 2 505 290 298 | 1 2 503 291 299 | 1 2 502 292 300 | 1 2 1510 293 301 | 1 2 501 294 302 | 1 2 1012 295 303 | 1 2 297 296 304 | 1 2 1012 297 305 | 1 2 499 298 306 | 1 2 300 299 307 | 1 2 301 300 308 | 1 2 302 301 309 | 1 2 498 302 310 | 1 2 1355 303 311 | 1 2 1355 304 312 | 1 2 496 305 313 | 1 2 495 306 314 | 1 2 494 307 315 | 1 2 493 308 316 | 1 2 1149 309 317 | 1 2 492 310 318 | 1 2 1700 311 319 | 1 2 1149 312 320 | 1 2 1107 313 321 | 1 2 1148 314 322 | 1 2 1147 315 323 | 1 2 1147 316 324 | 1 2 491 317 325 | 1 2 491 318 326 | 1 2 321 319 327 | 1 2 321 320 328 | 1 2 489 321 329 | 1 2 487 322 330 | 1 2 1146 323 331 | 1 2 486 324 332 | 1 2 485 325 333 | 1 2 484 326 334 | 1 2 1145 327 335 | 1 2 483 328 336 | 1 2 483 329 337 | 1 2 483 330 338 | 1 2 482 331 339 | 1 2 482 332 340 | 1 2 481 333 341 | 1 2 1099 334 342 | 1 2 1099 335 343 | 1 2 1099 336 344 | 1 2 1099 337 345 | 1 2 1099 338 346 | 1 2 1686 339 347 | 1 2 1144 340 348 | 1 2 342 341 349 | 1 2 1697 342 350 | 1 2 1659 343 351 | 1 2 1659 344 352 | 1 2 1659 345 353 | 1 2 347 346 354 | 1 2 1659 347 355 | 1 2 1702 348 356 | 1 2 480 349 357 | 1 2 1565 350 358 | 1 2 352 351 359 | 1 2 353 352 360 | 1 2 1143 353 361 | 1 2 1612 354 362 | 1 2 1612 355 363 | 1 2 1415 356 364 | 1 2 1415 357 365 | 1 2 1658 358 366 | 1 2 1458 359 367 | 1 2 479 360 368 | 1 2 1457 361 369 | 1 2 1142 362 370 | 1 2 1142 363 371 | 1 2 478 364 372 | 1 2 1384 365 373 | 1 2 368 366 374 | 1 2 368 367 375 | 1 2 369 368 376 | 1 2 477 369 377 | 1 2 1709 370 378 | 1 2 1709 371 379 | 1 2 476 372 380 | 1 2 476 373 381 | 1 2 497 374 382 | 1 2 475 375 383 | 1 2 1540 376 384 | 1 2 1425 377 385 | 1 2 1421 378 386 | 1 2 474 379 387 | 1 2 1141 380 388 | 1 2 1141 381 389 | 1 2 1141 382 390 | 1 2 1141 383 391 | 1 2 473 384 392 | 1 2 1595 385 393 | 1 2 1140 386 394 | 1 2 1140 387 395 | 1 2 1139 388 396 | 1 2 1567 389 397 | 1 2 1567 390 398 | 1 2 1138 391 399 | 1 2 393 392 400 | 1 2 472 393 401 | 1 2 395 394 402 | 1 2 1438 395 403 | 1 2 1170 396 404 | 1 2 398 397 405 | 1 2 1659 398 406 | 1 2 400 399 407 | 1 2 1659 400 408 | 1 2 1450 401 409 | 1 2 1137 402 410 | 1 2 471 403 411 | 1 2 406 404 412 | 1 2 406 405 413 | 1 2 433 406 414 | 1 2 470 407 415 | 1 2 470 408 416 | 1 2 469 409 417 | 1 2 527 410 418 | 1 2 412 411 419 | 1 2 1136 412 420 | 1 2 1135 413 421 | 1 2 468 414 422 | 1 2 1450 415 423 | 1 2 1090 416 424 | 1 2 467 417 425 | 1 2 513 418 426 | 1 2 1134 419 427 | 1 2 1688 420 428 | 1 2 1688 421 429 | 1 2 466 422 430 | 1 2 1093 423 431 | 1 2 465 424 432 | 1 2 465 425 433 | 1 2 1357 426 434 | 1 2 428 427 435 | 1 2 464 428 436 | 1 2 463 429 437 | 1 2 1133 430 438 | 1 2 728 431 439 | 1 2 433 432 440 | 1 2 1252 433 441 | 1 2 1540 434 442 | 1 2 462 435 443 | 1 2 437 436 444 | 1 2 1531 437 445 | 1 2 1495 438 446 | 1 2 1132 439 447 | 1 2 1132 440 448 | 1 2 1131 441 449 | 1 2 1534 442 450 | 1 2 1534 443 451 | 1 2 1130 444 452 | 1 2 1130 445 453 | 1 2 1129 446 454 | 1 2 448 447 455 | 1 2 1703 448 456 | 1 2 1593 449 457 | 1 2 1593 450 458 | 1 2 1128 451 459 | 1 2 1500 452 460 | 1 2 461 453 461 | 1 2 461 454 462 | 1 2 457 455 463 | 1 2 457 456 464 | 1 2 460 457 465 | 1 2 459 458 466 | 1 2 1534 459 467 | 1 2 1124 459 468 | 1 2 1633 460 469 | 1 2 618 460 470 | 1 2 1598 461 471 | 1 2 1596 461 472 | 1 2 1581 462 473 | 1 2 612 462 474 | 1 2 1563 463 475 | 1 2 1129 463 476 | 1 2 1654 464 477 | 1 2 1132 464 478 | 1 2 1529 465 479 | 1 2 692 465 480 | 1 2 1372 466 481 | 1 2 478 466 482 | 1 2 1362 467 483 | 1 2 1332 467 484 | 1 2 1652 468 485 | 1 2 1536 468 486 | 1 2 1540 469 487 | 1 2 1512 469 488 | 1 2 1117 470 489 | 1 2 637 470 490 | 1 2 1524 471 491 | 1 2 1259 471 492 | 1 2 1642 472 493 | 1 2 581 472 494 | 1 2 1663 473 495 | 1 2 831 473 496 | 1 2 1452 474 497 | 1 2 552 474 498 | 1 2 1565 475 499 | 1 2 1251 475 500 | 1 2 1709 476 501 | 1 2 1569 476 502 | 1 2 1585 477 503 | 1 2 1411 477 504 | 1 2 1282 478 505 | 1 2 1674 479 506 | 1 2 1339 479 507 | 1 2 562 480 508 | 1 2 561 480 509 | 1 2 509 481 510 | 1 2 508 481 511 | 1 2 1580 482 512 | 1 2 1127 482 513 | 1 2 641 483 514 | 1 2 524 483 515 | 1 2 1642 484 516 | 1 2 1211 484 517 | 1 2 525 485 518 | 1 2 523 485 519 | 1 2 1114 486 520 | 1 2 667 486 521 | 1 2 1452 487 522 | 1 2 488 487 523 | 1 2 1452 488 524 | 1 2 879 489 525 | 1 2 490 489 526 | 1 2 879 490 527 | 1 2 1693 491 528 | 1 2 1447 491 529 | 1 2 1700 492 530 | 1 2 1466 492 531 | 1 2 1687 493 532 | 1 2 934 493 533 | 1 2 1139 494 534 | 1 2 495 494 535 | 1 2 1531 495 536 | 1 2 1682 496 537 | 1 2 497 496 538 | 1 2 1682 497 539 | 1 2 1126 497 540 | 1 2 897 498 541 | 1 2 887 498 542 | 1 2 640 499 543 | 1 2 500 499 544 | 1 2 1448 500 545 | 1 2 640 500 546 | 1 2 1696 501 547 | 1 2 1564 501 548 | 1 2 1445 502 549 | 1 2 851 502 550 | 1 2 871 503 551 | 1 2 504 503 552 | 1 2 871 504 553 | 1 2 591 504 554 | 1 2 1472 505 555 | 1 2 920 505 556 | 1 2 537 506 557 | 1 2 507 506 558 | 1 2 537 507 559 | 1 2 1492 508 560 | 1 2 1492 509 561 | 1 2 1461 509 562 | 1 2 1408 510 563 | 1 2 901 510 564 | 1 2 1489 511 565 | 1 2 1487 511 566 | 1 2 1706 512 567 | 1 2 513 512 568 | 1 2 1707 513 569 | 1 2 1564 513 570 | 1 2 1253 513 571 | 1 2 1245 513 572 | 1 2 1244 513 573 | 1 2 565 513 574 | 1 2 1666 514 575 | 1 2 515 514 576 | 1 2 1183 515 577 | 1 2 1421 516 578 | 1 2 517 516 579 | 1 2 1421 517 580 | 1 2 1125 517 581 | 1 2 1341 518 582 | 1 2 594 518 583 | 1 2 1498 519 584 | 1 2 805 519 585 | 1 2 1252 520 586 | 1 2 521 520 587 | 1 2 1252 521 588 | 1 2 1322 522 589 | 1 2 1320 522 590 | 1 2 1667 523 591 | 1 2 1095 524 592 | 1 2 1473 525 593 | 1 2 528 526 594 | 1 2 527 526 595 | 1 2 1578 527 596 | 1 2 528 527 597 | 1 2 1578 528 598 | 1 2 529 528 599 | 1 2 1578 529 600 | 1 2 1455 529 601 | 1 2 871 530 602 | 1 2 531 530 603 | 1 2 871 531 604 | 1 2 532 531 605 | 1 2 871 532 606 | 1 2 870 532 607 | 1 2 1491 533 608 | 1 2 856 533 609 | 1 2 1534 534 610 | 1 2 1124 534 611 | 1 2 537 535 612 | 1 2 536 535 613 | 1 2 537 536 614 | 1 2 1487 537 615 | 1 2 598 537 616 | 1 2 1577 538 617 | 1 2 1451 538 618 | 1 2 541 539 619 | 1 2 540 539 620 | 1 2 1485 540 621 | 1 2 541 540 622 | 1 2 1481 541 623 | 1 2 1379 542 624 | 1 2 1048 542 625 | 1 2 1652 543 626 | 1 2 643 543 627 | 1 2 1599 544 628 | 1 2 545 544 629 | 1 2 1436 545 630 | 1 2 1647 546 631 | 1 2 1629 546 632 | 1 2 1348 547 633 | 1 2 548 547 634 | 1 2 1348 548 635 | 1 2 1123 549 636 | 1 2 550 549 637 | 1 2 1123 550 638 | 1 2 1697 551 639 | 1 2 1342 551 640 | 1 2 1033 552 641 | 1 2 1451 553 642 | 1 2 1067 553 643 | 1 2 1122 554 644 | 1 2 555 554 645 | 1 2 1122 555 646 | 1 2 1585 556 647 | 1 2 1552 556 648 | 1 2 1092 557 649 | 1 2 558 557 650 | 1 2 1092 558 651 | 1 2 1121 559 652 | 1 2 560 559 653 | 1 2 1121 560 654 | 1 2 582 560 655 | 1 2 1491 561 656 | 1 2 1491 562 657 | 1 2 1093 562 658 | 1 2 1693 563 659 | 1 2 1446 563 660 | 1 2 1047 564 661 | 1 2 624 564 662 | 1 2 1120 565 663 | 1 2 568 566 664 | 1 2 567 566 665 | 1 2 568 567 666 | 1 2 1699 568 667 | 1 2 1588 569 668 | 1 2 1227 569 669 | 1 2 1109 570 670 | 1 2 755 570 671 | 1 2 573 571 672 | 1 2 572 571 673 | 1 2 573 572 674 | 1 2 574 573 675 | 1 2 1397 574 676 | 1 2 1137 574 677 | 1 2 1588 575 678 | 1 2 1119 575 679 | 1 2 1641 576 680 | 1 2 1584 576 681 | 1 2 1101 577 682 | 1 2 879 577 683 | 1 2 1489 578 684 | 1 2 1118 578 685 | 1 2 581 579 686 | 1 2 580 579 687 | 1 2 1378 580 688 | 1 2 581 580 689 | 1 2 785 582 690 | 1 2 1238 583 691 | 1 2 1221 583 692 | 1 2 1239 584 693 | 1 2 967 584 694 | 1 2 1239 585 695 | 1 2 967 585 696 | 1 2 1112 586 697 | 1 2 1111 586 698 | 1 2 1356 587 699 | 1 2 1129 587 700 | 1 2 1200 588 701 | 1 2 795 588 702 | 1 2 1624 589 703 | 1 2 829 589 704 | 1 2 687 590 705 | 1 2 641 590 706 | 1 2 872 591 707 | 1 2 872 592 708 | 1 2 753 592 709 | 1 2 1535 593 710 | 1 2 1237 593 711 | 1 2 664 594 712 | 1 2 1535 595 713 | 1 2 1237 595 714 | 1 2 1507 596 715 | 1 2 1397 596 716 | 1 2 1490 597 717 | 1 2 1402 597 718 | 1 2 1054 598 719 | 1 2 922 599 720 | 1 2 602 599 721 | 1 2 1538 600 722 | 1 2 1370 600 723 | 1 2 1324 601 724 | 1 2 602 601 725 | 1 2 1691 603 726 | 1 2 1496 603 727 | 1 2 1692 604 728 | 1 2 1511 604 729 | 1 2 1692 605 730 | 1 2 1176 605 731 | 1 2 1686 606 732 | 1 2 722 606 733 | 1 2 1524 607 734 | 1 2 1173 607 735 | 1 2 1613 608 736 | 1 2 1275 608 737 | 1 2 1610 609 738 | 1 2 1059 609 739 | 1 2 1664 610 740 | 1 2 1239 610 741 | 1 2 1403 611 742 | 1 2 815 611 743 | 1 2 1258 612 744 | 1 2 1158 613 745 | 1 2 614 613 746 | 1 2 908 614 747 | 1 2 1495 615 748 | 1 2 1452 615 749 | 1 2 1500 616 750 | 1 2 1412 616 751 | 1 2 1504 617 752 | 1 2 1457 617 753 | 1 2 1256 618 754 | 1 2 1283 619 755 | 1 2 906 619 756 | 1 2 1485 620 757 | 1 2 1483 620 758 | 1 2 1037 621 759 | 1 2 900 621 760 | 1 2 1236 622 761 | 1 2 1235 622 762 | 1 2 1576 623 763 | 1 2 821 623 764 | 1 2 1490 624 765 | 1 2 1453 625 766 | 1 2 626 625 767 | 1 2 1616 626 768 | 1 2 1074 627 769 | 1 2 1028 627 770 | 1 2 1063 628 771 | 1 2 1004 628 772 | 1 2 1544 629 773 | 1 2 917 629 774 | 1 2 1648 630 775 | 1 2 677 630 776 | 1 2 1435 631 777 | 1 2 990 631 778 | 1 2 1183 632 779 | 1 2 799 632 780 | 1 2 1266 633 781 | 1 2 1087 633 782 | 1 2 1367 634 783 | 1 2 1156 634 784 | 1 2 1206 635 785 | 1 2 1187 635 786 | 1 2 912 636 787 | 1 2 759 636 788 | 1 2 1062 637 789 | 1 2 1284 638 790 | 1 2 972 638 791 | 1 2 1496 639 792 | 1 2 640 639 793 | 1 2 1496 640 794 | 1 2 1509 642 795 | 1 2 1190 642 796 | 1 2 1501 643 797 | 1 2 1210 644 798 | 1 2 773 644 799 | 1 2 1391 645 800 | 1 2 646 645 801 | 1 2 1632 646 802 | 1 2 709 647 803 | 1 2 694 647 804 | 1 2 1532 648 805 | 1 2 1040 648 806 | 1 2 1443 649 807 | 1 2 1089 649 808 | 1 2 1515 650 809 | 1 2 1222 650 810 | 1 2 1704 651 811 | 1 2 1196 651 812 | 1 2 1445 652 813 | 1 2 1117 652 814 | 1 2 1627 653 815 | 1 2 654 653 816 | 1 2 689 654 817 | 1 2 1656 655 818 | 1 2 994 655 819 | 1 2 1252 656 820 | 1 2 1086 656 821 | 1 2 1638 657 822 | 1 2 1633 657 823 | 1 2 1096 658 824 | 1 2 965 658 825 | 1 2 1701 659 826 | 1 2 1096 659 827 | 1 2 1701 660 828 | 1 2 1548 660 829 | 1 2 1699 661 830 | 1 2 662 661 831 | 1 2 1699 662 832 | 1 2 1116 663 833 | 1 2 1115 663 834 | 1 2 1646 664 835 | 1 2 1576 665 836 | 1 2 1455 665 837 | 1 2 1114 666 838 | 1 2 667 666 839 | 1 2 1508 667 840 | 1 2 1397 668 841 | 1 2 1114 668 842 | 1 2 1508 669 843 | 1 2 674 669 844 | 1 2 1508 670 845 | 1 2 674 670 846 | 1 2 1507 671 847 | 1 2 674 671 848 | 1 2 1648 672 849 | 1 2 1507 672 850 | 1 2 1507 673 851 | 1 2 674 673 852 | 1 2 1112 675 853 | 1 2 1111 675 854 | 1 2 1648 676 855 | 1 2 1203 676 856 | 1 2 1297 677 857 | 1 2 729 678 858 | 1 2 728 678 859 | 1 2 1521 679 860 | 1 2 1142 679 861 | 1 2 1717 680 862 | 1 2 1104 680 863 | 1 2 1106 681 864 | 1 2 732 681 865 | 1 2 1677 682 866 | 1 2 1620 682 867 | 1 2 1412 683 868 | 1 2 1146 683 869 | 1 2 1721 684 870 | 1 2 1461 684 871 | 1 2 1558 685 872 | 1 2 944 685 873 | 1 2 1095 686 874 | 1 2 687 686 875 | 1 2 1236 687 876 | 1 2 1621 688 877 | 1 2 1162 688 878 | 1 2 1226 689 879 | 1 2 1722 690 880 | 1 2 1463 690 881 | 1 2 1693 691 882 | 1 2 759 691 883 | 1 2 1624 692 884 | 1 2 1432 693 885 | 1 2 910 693 886 | 1 2 1024 694 887 | 1 2 1388 695 888 | 1 2 1091 695 889 | 1 2 1368 696 890 | 1 2 1216 696 891 | 1 2 1488 697 892 | 1 2 1085 697 893 | 1 2 1557 698 894 | 1 2 1168 698 895 | 1 2 1440 699 896 | 1 2 700 699 897 | 1 2 1440 700 898 | 1 2 1654 701 899 | 1 2 1457 701 900 | 1 2 1627 702 901 | 1 2 1152 702 902 | 1 2 1619 703 903 | 1 2 1428 703 904 | 1 2 1661 704 905 | 1 2 1605 704 906 | 1 2 1087 705 907 | 1 2 706 705 908 | 1 2 1379 706 909 | 1 2 1087 706 910 | 1 2 1615 707 911 | 1 2 1093 707 912 | 1 2 1237 708 913 | 1 2 715 708 914 | 1 2 887 709 915 | 1 2 1435 710 916 | 1 2 881 710 917 | 1 2 1697 711 918 | 1 2 841 711 919 | 1 2 1561 712 920 | 1 2 1161 712 921 | 1 2 1565 713 922 | 1 2 1260 713 923 | 1 2 1237 714 924 | 1 2 715 714 925 | 1 2 1237 715 926 | 1 2 777 715 927 | 1 2 1509 716 928 | 1 2 1397 716 929 | 1 2 1241 717 930 | 1 2 788 717 931 | 1 2 1444 718 932 | 1 2 1089 718 933 | 1 2 1048 719 934 | 1 2 720 719 935 | 1 2 1047 720 936 | 1 2 1545 721 937 | 1 2 1398 721 938 | 1 2 1106 722 939 | 1 2 1694 723 940 | 1 2 891 723 941 | 1 2 1632 724 942 | 1 2 1130 724 943 | 1 2 1534 725 944 | 1 2 968 725 945 | 1 2 728 726 946 | 1 2 727 726 947 | 1 2 729 727 948 | 1 2 728 727 949 | 1 2 729 728 950 | 1 2 1347 729 951 | 1 2 1056 729 952 | 1 2 1210 730 953 | 1 2 782 730 954 | 1 2 1449 731 955 | 1 2 1082 731 956 | 1 2 765 732 957 | 1 2 1687 733 958 | 1 2 1385 733 959 | 1 2 1186 734 960 | 1 2 735 734 961 | 1 2 1559 735 962 | 1 2 1653 736 963 | 1 2 1031 736 964 | 1 2 975 737 965 | 1 2 816 737 966 | 1 2 1680 738 967 | 1 2 928 738 968 | 1 2 1663 739 969 | 1 2 1635 739 970 | 1 2 1674 740 971 | 1 2 1584 740 972 | 1 2 1590 741 973 | 1 2 1110 741 974 | 1 2 1582 742 975 | 1 2 1248 742 976 | 1 2 1663 743 977 | 1 2 1635 743 978 | 1 2 1324 744 979 | 1 2 877 744 980 | 1 2 996 745 981 | 1 2 791 745 982 | 1 2 1701 746 983 | 1 2 1139 746 984 | 1 2 1691 747 985 | 1 2 748 747 986 | 1 2 1691 748 987 | 1 2 1228 748 988 | 1 2 1208 749 989 | 1 2 798 749 990 | 1 2 1700 750 991 | 1 2 1447 750 992 | 1 2 1639 751 993 | 1 2 935 751 994 | 1 2 1694 752 995 | 1 2 995 752 996 | 1 2 870 753 997 | 1 2 1109 754 998 | 1 2 755 754 999 | 1 2 1555 755 1000 | 1 2 1070 756 1001 | 1 2 1038 756 1002 | 1 2 1478 757 1003 | 1 2 1216 757 1004 | 1 2 1382 758 1005 | 1 2 1086 758 1006 | 1 2 1619 760 1007 | 1 2 1108 760 1008 | 1 2 1628 761 1009 | 1 2 1107 761 1010 | 1 2 1584 762 1011 | 1 2 1255 762 1012 | 1 2 1456 763 1013 | 1 2 1148 763 1014 | 1 2 1106 764 1015 | 1 2 765 764 1016 | 1 2 1681 765 1017 | 1 2 924 766 1018 | 1 2 905 766 1019 | 1 2 1199 767 1020 | 1 2 800 767 1021 | 1 2 1528 768 1022 | 1 2 769 768 1023 | 1 2 1528 769 1024 | 1 2 909 769 1025 | 1 2 1382 770 1026 | 1 2 1086 770 1027 | 1 2 1715 771 1028 | 1 2 1636 771 1029 | 1 2 1460 772 1030 | 1 2 1316 772 1031 | 1 2 1207 773 1032 | 1 2 1695 774 1033 | 1 2 985 774 1034 | 1 2 1417 775 1035 | 1 2 986 775 1036 | 1 2 1266 776 1037 | 1 2 882 776 1038 | 1 2 1235 777 1039 | 1 2 1578 778 1040 | 1 2 1576 778 1041 | 1 2 1492 779 1042 | 1 2 1463 779 1043 | 1 2 1443 780 1044 | 1 2 1089 780 1045 | 1 2 1456 781 1046 | 1 2 1388 781 1047 | 1 2 1632 782 1048 | 1 2 903 783 1049 | 1 2 895 783 1050 | 1 2 1635 784 1051 | 1 2 1199 784 1052 | 1 2 1209 785 1053 | 1 2 1575 786 1054 | 1 2 1188 786 1055 | 1 2 1640 787 1056 | 1 2 1591 787 1057 | 1 2 907 788 1058 | 1 2 1091 789 1059 | 1 2 833 789 1060 | 1 2 1644 790 1061 | 1 2 1593 790 1062 | 1 2 1686 791 1063 | 1 2 1644 792 1064 | 1 2 1105 792 1065 | 1 2 1078 793 1066 | 1 2 1077 793 1067 | 1 2 1309 794 1068 | 1 2 1018 794 1069 | 1 2 1493 795 1070 | 1 2 1329 796 1071 | 1 2 854 796 1072 | 1 2 1696 797 1073 | 1 2 1001 797 1074 | 1 2 1209 798 1075 | 1 2 1422 799 1076 | 1 2 1366 800 1077 | 1 2 1717 801 1078 | 1 2 834 801 1079 | 1 2 1666 802 1080 | 1 2 828 802 1081 | 1 2 1609 803 1082 | 1 2 1591 803 1083 | 1 2 1643 804 1084 | 1 2 1642 804 1085 | 1 2 1424 805 1086 | 1 2 1666 806 1087 | 1 2 1498 806 1088 | 1 2 1694 807 1089 | 1 2 1659 807 1090 | 1 2 1601 808 1091 | 1 2 1315 808 1092 | 1 2 1082 809 1093 | 1 2 1078 809 1094 | 1 2 1611 810 1095 | 1 2 1372 810 1096 | 1 2 1593 811 1097 | 1 2 1102 811 1098 | 1 2 1485 812 1099 | 1 2 1465 812 1100 | 1 2 1343 813 1101 | 1 2 912 813 1102 | 1 2 1550 814 1103 | 1 2 1090 814 1104 | 1 2 1176 815 1105 | 1 2 1283 816 1106 | 1 2 819 817 1107 | 1 2 818 817 1108 | 1 2 1292 818 1109 | 1 2 819 818 1110 | 1 2 1587 819 1111 | 1 2 1669 820 1112 | 1 2 1120 820 1113 | 1 2 1455 821 1114 | 1 2 1555 822 1115 | 1 2 1304 822 1116 | 1 2 1571 823 1117 | 1 2 933 823 1118 | 1 2 1529 824 1119 | 1 2 825 824 1120 | 1 2 1529 825 1121 | 1 2 1007 825 1122 | 1 2 1365 826 1123 | 1 2 1278 826 1124 | 1 2 1638 827 1125 | 1 2 828 827 1126 | 1 2 1427 829 1127 | 1 2 1598 830 1128 | 1 2 1182 830 1129 | 1 2 990 831 1130 | 1 2 1621 832 1131 | 1 2 890 832 1132 | 1 2 998 833 1133 | 1 2 1104 834 1134 | 1 2 1504 835 1135 | 1 2 1289 835 1136 | 1 2 1072 836 1137 | 1 2 837 836 1138 | 1 2 1071 837 1139 | 1 2 1454 838 1140 | 1 2 839 838 1141 | 1 2 845 839 1142 | 1 2 1360 840 1143 | 1 2 980 840 1144 | 1 2 842 841 1145 | 1 2 843 842 1146 | 1 2 1244 843 1147 | 1 2 1238 844 1148 | 1 2 1235 844 1149 | 1 2 846 845 1150 | 1 2 1454 846 1151 | 1 2 1383 846 1152 | 1 2 1665 847 1153 | 1 2 1619 847 1154 | 1 2 1096 848 1155 | 1 2 862 848 1156 | 1 2 1685 849 1157 | 1 2 1505 849 1158 | 1 2 1566 850 1159 | 1 2 1154 850 1160 | 1 2 1444 851 1161 | 1 2 1495 852 1162 | 1 2 884 852 1163 | 1 2 1661 853 1164 | 1 2 919 853 1165 | 1 2 1432 854 1166 | 1 2 1154 855 1167 | 1 2 989 855 1168 | 1 2 1143 856 1169 | 1 2 1628 857 1170 | 1 2 1219 857 1171 | 1 2 1307 858 1172 | 1 2 859 858 1173 | 1 2 1034 859 1174 | 1 2 1636 860 1175 | 1 2 1103 860 1176 | 1 2 1485 861 1177 | 1 2 1060 861 1178 | 1 2 1549 862 1179 | 1 2 1581 863 1180 | 1 2 1433 863 1181 | 1 2 1501 864 1182 | 1 2 866 864 1183 | 1 2 989 865 1184 | 1 2 866 865 1185 | 1 2 1085 867 1186 | 1 2 868 867 1187 | 1 2 1085 868 1188 | 1 2 1054 868 1189 | 1 2 1683 869 1190 | 1 2 1608 869 1191 | 1 2 1065 871 1192 | 1 2 963 872 1193 | 1 2 1697 873 1194 | 1 2 889 873 1195 | 1 2 1102 874 1196 | 1 2 875 874 1197 | 1 2 1102 875 1198 | 1 2 1042 875 1199 | 1 2 1323 876 1200 | 1 2 877 876 1201 | 1 2 1323 877 1202 | 1 2 1101 878 1203 | 1 2 879 878 1204 | 1 2 1471 879 1205 | 1 2 1359 880 1206 | 1 2 891 880 1207 | 1 2 1099 881 1208 | 1 2 1488 882 1209 | 1 2 1495 883 1210 | 1 2 1451 883 1211 | 1 2 1577 884 1212 | 1 2 1671 885 1213 | 1 2 1335 885 1214 | 1 2 1637 886 1215 | 1 2 1100 886 1216 | 1 2 1554 888 1217 | 1 2 1099 888 1218 | 1 2 1659 889 1219 | 1 2 1416 890 1220 | 1 2 1638 892 1221 | 1 2 1554 892 1222 | 1 2 1394 893 1223 | 1 2 1197 893 1224 | 1 2 1195 894 1225 | 1 2 1113 894 1226 | 1 2 968 895 1227 | 1 2 1676 896 1228 | 1 2 1360 896 1229 | 1 2 1540 897 1230 | 1 2 1540 898 1231 | 1 2 1025 898 1232 | 1 2 1451 899 1233 | 1 2 1067 899 1234 | 1 2 1525 900 1235 | 1 2 1158 901 1236 | 1 2 1662 902 1237 | 1 2 903 902 1238 | 1 2 1680 904 1239 | 1 2 1302 904 1240 | 1 2 1194 905 1241 | 1 2 1198 906 1242 | 1 2 1695 907 1243 | 1 2 940 908 1244 | 1 2 1699 909 1245 | 1 2 1692 910 1246 | 1 2 1471 911 1247 | 1 2 1298 911 1248 | 1 2 1691 913 1249 | 1 2 1496 913 1250 | 1 2 1542 914 1251 | 1 2 1144 914 1252 | 1 2 1394 915 1253 | 1 2 1198 915 1254 | 1 2 1304 916 1255 | 1 2 946 916 1256 | 1 2 1503 917 1257 | 1 2 1507 918 1258 | 1 2 1231 918 1259 | 1 2 920 919 1260 | 1 2 1327 921 1261 | 1 2 1300 921 1262 | 1 2 1327 922 1263 | 1 2 1667 923 1264 | 1 2 1554 923 1265 | 1 2 930 924 1266 | 1 2 1530 925 1267 | 1 2 1178 925 1268 | 1 2 1506 926 1269 | 1 2 927 926 1270 | 1 2 937 927 1271 | 1 2 1608 928 1272 | 1 2 1640 929 1273 | 1 2 1016 929 1274 | 1 2 1692 930 1275 | 1 2 1697 931 1276 | 1 2 1453 931 1277 | 1 2 1697 932 1278 | 1 2 1453 932 1279 | 1 2 1501 933 1280 | 1 2 1525 934 1281 | 1 2 1472 935 1282 | 1 2 1212 936 1283 | 1 2 962 936 1284 | 1 2 1212 937 1285 | 1 2 1394 938 1286 | 1 2 979 938 1287 | 1 2 1675 939 1288 | 1 2 940 939 1289 | 1 2 1515 941 1290 | 1 2 1300 941 1291 | 1 2 1638 942 1292 | 1 2 1300 942 1293 | 1 2 1327 943 1294 | 1 2 1032 943 1295 | 1 2 1167 944 1296 | 1 2 1634 945 1297 | 1 2 1558 945 1298 | 1 2 1366 946 1299 | 1 2 1459 947 1300 | 1 2 1006 947 1301 | 1 2 1357 948 1302 | 1 2 1160 948 1303 | 1 2 1420 949 1304 | 1 2 1418 949 1305 | 1 2 1330 950 1306 | 1 2 1222 950 1307 | 1 2 1459 951 1308 | 1 2 952 951 1309 | 1 2 1634 952 1310 | 1 2 1601 953 1311 | 1 2 1315 953 1312 | 1 2 1484 954 1313 | 1 2 963 954 1314 | 1 2 1637 955 1315 | 1 2 1021 955 1316 | 1 2 1550 956 1317 | 1 2 1449 956 1318 | 1 2 1382 957 1319 | 1 2 1035 957 1320 | 1 2 1078 958 1321 | 1 2 1077 958 1322 | 1 2 1669 959 1323 | 1 2 961 959 1324 | 1 2 1098 960 1325 | 1 2 961 960 1326 | 1 2 1098 961 1327 | 1 2 1390 962 1328 | 1 2 1577 964 1329 | 1 2 1097 964 1330 | 1 2 1701 965 1331 | 1 2 1095 966 1332 | 1 2 967 966 1333 | 1 2 1095 967 1334 | 1 2 1394 969 1335 | 1 2 975 969 1336 | 1 2 1504 970 1337 | 1 2 1016 970 1338 | 1 2 1315 971 1339 | 1 2 1314 971 1340 | 1 2 1633 972 1341 | 1 2 1425 973 1342 | 1 2 1422 973 1343 | 1 2 1616 974 1344 | 1 2 1120 974 1345 | 1 2 1438 976 1346 | 1 2 1094 976 1347 | 1 2 1311 977 1348 | 1 2 1043 977 1349 | 1 2 1615 978 1350 | 1 2 1093 978 1351 | 1 2 1504 979 1352 | 1 2 1352 980 1353 | 1 2 1656 981 1354 | 1 2 1516 981 1355 | 1 2 1656 982 1356 | 1 2 1516 982 1357 | 1 2 1443 983 1358 | 1 2 1088 983 1359 | 1 2 1691 984 1360 | 1 2 1496 984 1361 | 1 2 1390 985 1362 | 1 2 991 986 1363 | 1 2 1318 987 1364 | 1 2 1317 987 1365 | 1 2 1384 988 1366 | 1 2 1246 988 1367 | 1 2 1130 991 1368 | 1 2 1577 992 1369 | 1 2 1092 992 1370 | 1 2 1516 993 1371 | 1 2 994 993 1372 | 1 2 1516 994 1373 | 1 2 1372 995 1374 | 1 2 1247 996 1375 | 1 2 1659 997 1376 | 1 2 1640 997 1377 | 1 2 1388 998 1378 | 1 2 1366 999 1379 | 1 2 1103 999 1380 | 1 2 1496 1000 1381 | 1 2 1090 1000 1382 | 1 2 1611 1001 1383 | 1 2 1449 1002 1384 | 1 2 1084 1002 1385 | 1 2 1653 1003 1386 | 1 2 1144 1003 1387 | 1 2 1330 1004 1388 | 1 2 1642 1005 1389 | 1 2 1460 1005 1390 | 1 2 1631 1006 1391 | 1 2 1591 1007 1392 | 1 2 1549 1008 1393 | 1 2 1009 1008 1394 | 1 2 1549 1009 1395 | 1 2 1545 1009 1396 | 1 2 1573 1010 1397 | 1 2 1523 1010 1398 | 1 2 1088 1011 1399 | 1 2 1012 1011 1400 | 1 2 1444 1012 1401 | 1 2 1088 1012 1402 | 1 2 1676 1013 1403 | 1 2 1246 1013 1404 | 1 2 1430 1014 1405 | 1 2 1115 1014 1406 | 1 2 1356 1015 1407 | 1 2 1331 1015 1408 | 1 2 1636 1017 1409 | 1 2 1635 1017 1410 | 1 2 1135 1018 1411 | 1 2 1651 1019 1412 | 1 2 1410 1019 1413 | 1 2 1284 1020 1414 | 1 2 1051 1020 1415 | 1 2 1109 1021 1416 | 1 2 1549 1022 1417 | 1 2 1333 1022 1418 | 1 2 1025 1023 1419 | 1 2 1024 1023 1420 | 1 2 1025 1024 1421 | 1 2 1488 1026 1422 | 1 2 1087 1026 1423 | 1 2 1618 1027 1424 | 1 2 1294 1027 1425 | 1 2 1336 1028 1426 | 1 2 1688 1029 1427 | 1 2 1247 1029 1428 | 1 2 1505 1030 1429 | 1 2 1301 1030 1430 | 1 2 1403 1031 1431 | 1 2 1637 1032 1432 | 1 2 1495 1033 1433 | 1 2 1699 1034 1434 | 1 2 1086 1035 1435 | 1 2 1699 1036 1436 | 1 2 1249 1036 1437 | 1 2 1689 1037 1438 | 1 2 1506 1038 1439 | 1 2 1535 1039 1440 | 1 2 1124 1039 1441 | 1 2 1124 1040 1442 | 1 2 1516 1041 1443 | 1 2 1316 1041 1444 | 1 2 1614 1042 1445 | 1 2 1463 1043 1446 | 1 2 1615 1044 1447 | 1 2 1262 1044 1448 | 1 2 1047 1045 1449 | 1 2 1046 1045 1450 | 1 2 1048 1046 1451 | 1 2 1379 1048 1452 | 1 2 1684 1049 1453 | 1 2 1157 1049 1454 | 1 2 1225 1050 1455 | 1 2 1223 1050 1456 | 1 2 1635 1051 1457 | 1 2 1483 1052 1458 | 1 2 1481 1052 1459 | 1 2 1482 1053 1460 | 1 2 1430 1053 1461 | 1 2 1348 1055 1462 | 1 2 1056 1055 1463 | 1 2 1348 1056 1464 | 1 2 1496 1057 1465 | 1 2 1084 1057 1466 | 1 2 1476 1058 1467 | 1 2 1406 1058 1468 | 1 2 1525 1059 1469 | 1 2 1337 1060 1470 | 1 2 1379 1061 1471 | 1 2 1118 1061 1472 | 1 2 1687 1062 1473 | 1 2 1631 1063 1474 | 1 2 1687 1064 1475 | 1 2 1600 1064 1476 | 1 2 1116 1065 1477 | 1 2 1451 1066 1478 | 1 2 1067 1066 1479 | 1 2 1580 1067 1480 | 1 2 1699 1068 1481 | 1 2 1346 1068 1482 | 1 2 1619 1069 1483 | 1 2 1256 1069 1484 | 1 2 1613 1070 1485 | 1 2 1083 1071 1486 | 1 2 1364 1072 1487 | 1 2 1083 1072 1488 | 1 2 1654 1073 1489 | 1 2 1504 1073 1490 | 1 2 1382 1074 1491 | 1 2 1586 1075 1492 | 1 2 1480 1075 1493 | 1 2 1078 1076 1494 | 1 2 1077 1076 1495 | 1 2 1082 1077 1496 | 1 2 1560 1079 1497 | 1 2 1177 1079 1498 | 1 2 1584 1080 1499 | 1 2 1081 1080 1500 | 1 2 1584 1081 1501 | 1 2 1177 1081 1502 | 1 2 1550 1082 1503 | 1 2 1450 1082 1504 | 1 2 1362 1083 1505 | 1 2 1175 1083 1506 | 1 2 1496 1084 1507 | 1 2 1448 1084 1508 | 1 2 1487 1085 1509 | 1 2 1486 1085 1510 | 1 2 1251 1086 1511 | 1 2 1488 1087 1512 | 1 2 1089 1088 1513 | 1 2 1444 1089 1514 | 1 2 1441 1089 1515 | 1 2 1550 1090 1516 | 1 2 1496 1090 1517 | 1 2 1450 1090 1518 | 1 2 1716 1091 1519 | 1 2 1493 1091 1520 | 1 2 1577 1092 1521 | 1 2 1440 1092 1522 | 1 2 1439 1092 1523 | 1 2 1402 1093 1524 | 1 2 1482 1094 1525 | 1 2 1481 1094 1526 | 1 2 1438 1094 1527 | 1 2 1237 1095 1528 | 1 2 1236 1095 1529 | 1 2 1548 1096 1530 | 1 2 1579 1097 1531 | 1 2 1577 1097 1532 | 1 2 1437 1097 1533 | 1 2 1671 1098 1534 | 1 2 1436 1098 1535 | 1 2 1666 1099 1536 | 1 2 1554 1099 1537 | 1 2 1637 1100 1538 | 1 2 1326 1100 1539 | 1 2 1325 1100 1540 | 1 2 1596 1101 1541 | 1 2 1551 1101 1542 | 1 2 1528 1102 1543 | 1 2 1636 1103 1544 | 1 2 1555 1103 1545 | 1 2 1685 1104 1546 | 1 2 1434 1104 1547 | 1 2 1644 1105 1548 | 1 2 1563 1105 1549 | 1 2 1433 1105 1550 | 1 2 1432 1106 1551 | 1 2 1628 1107 1552 | 1 2 1219 1107 1553 | 1 2 1218 1107 1554 | 1 2 1636 1108 1555 | 1 2 1619 1108 1556 | 1 2 1607 1108 1557 | 1 2 1431 1109 1558 | 1 2 1651 1110 1559 | 1 2 1590 1110 1560 | 1 2 1536 1110 1561 | 1 2 1297 1111 1562 | 1 2 1113 1111 1563 | 1 2 1297 1112 1564 | 1 2 1195 1112 1565 | 1 2 1295 1113 1566 | 1 2 1397 1114 1567 | 1 2 1137 1114 1568 | 1 2 1485 1115 1569 | 1 2 1116 1115 1570 | 1 2 1485 1116 1571 | 1 2 1445 1117 1572 | 1 2 1429 1117 1573 | 1 2 1489 1118 1574 | 1 2 1214 1118 1575 | 1 2 1604 1119 1576 | 1 2 1588 1119 1577 | 1 2 1164 1119 1578 | 1 2 1672 1120 1579 | 1 2 1556 1121 1580 | 1 2 1210 1121 1581 | 1 2 1639 1122 1582 | 1 2 1428 1122 1583 | 1 2 1319 1122 1584 | 1 2 1658 1123 1585 | 1 2 1557 1123 1586 | 1 2 1427 1123 1587 | 1 2 1421 1125 1588 | 1 2 1419 1125 1589 | 1 2 1418 1125 1590 | 1 2 1682 1126 1591 | 1 2 1621 1126 1592 | 1 2 1620 1126 1593 | 1 2 1580 1127 1594 | 1 2 1579 1127 1595 | 1 2 1451 1127 1596 | 1 2 1700 1128 1597 | 1 2 1613 1128 1598 | 1 2 1526 1128 1599 | 1 2 1357 1129 1600 | 1 2 1534 1130 1601 | 1 2 1620 1131 1602 | 1 2 1533 1131 1603 | 1 2 1416 1131 1604 | 1 2 1657 1132 1605 | 1 2 1599 1132 1606 | 1 2 1710 1133 1607 | 1 2 1569 1133 1608 | 1 2 1511 1133 1609 | 1 2 1490 1134 1610 | 1 2 1401 1134 1611 | 1 2 1143 1134 1612 | 1 2 1677 1135 1613 | 1 2 1308 1135 1614 | 1 2 1702 1136 1615 | 1 2 1645 1136 1616 | 1 2 1415 1136 1617 | 1 2 1172 1137 1618 | 1 2 1621 1138 1619 | 1 2 1567 1138 1620 | 1 2 1414 1138 1621 | 1 2 1574 1139 1622 | 1 2 1674 1140 1623 | 1 2 1595 1140 1624 | 1 2 1492 1140 1625 | 1 2 1663 1141 1626 | 1 2 1660 1141 1627 | 1 2 1142 1141 1628 | 1 2 1660 1142 1629 | 1 2 1401 1143 1630 | 1 2 1686 1144 1631 | 1 2 1593 1145 1632 | 1 2 1413 1145 1633 | 1 2 1249 1145 1634 | 1 2 1587 1146 1635 | 1 2 1586 1146 1636 | 1 2 1226 1147 1637 | 1 2 1224 1147 1638 | 1 2 1223 1147 1639 | 1 2 1627 1148 1640 | 1 2 1559 1148 1641 | 1 2 1700 1149 1642 | 1 2 1661 1149 1643 | 1 2 1506 1149 1644 | 1 2 1570 1150 1645 | 1 2 1540 1150 1646 | 1 2 1513 1150 1647 | 1 2 1667 1151 1648 | 1 2 1666 1151 1649 | 1 2 1411 1151 1650 | 1 2 1598 1152 1651 | 1 2 1551 1152 1652 | 1 2 1691 1153 1653 | 1 2 1531 1153 1654 | 1 2 1171 1153 1655 | 1 2 1410 1154 1656 | 1 2 1604 1155 1657 | 1 2 1603 1155 1658 | 1 2 1156 1155 1659 | 1 2 1604 1156 1660 | 1 2 1603 1156 1661 | 1 2 1502 1157 1662 | 1 2 1409 1157 1663 | 1 2 1600 1158 1664 | 1 2 1664 1159 1665 | 1 2 1498 1159 1666 | 1 2 1466 1159 1667 | 1 2 1359 1160 1668 | 1 2 1358 1160 1669 | 1 2 1694 1161 1670 | 1 2 1640 1161 1671 | 1 2 1553 1162 1672 | 1 2 1407 1162 1673 | 1 2 1604 1163 1674 | 1 2 1588 1163 1675 | 1 2 1164 1163 1676 | 1 2 1227 1164 1677 | 1 2 1539 1165 1678 | 1 2 1478 1165 1679 | 1 2 1406 1165 1680 | 1 2 1580 1166 1681 | 1 2 1579 1166 1682 | 1 2 1509 1166 1683 | 1 2 1630 1167 1684 | 1 2 1532 1167 1685 | 1 2 1170 1168 1686 | 1 2 1169 1168 1687 | 1 2 1557 1169 1688 | 1 2 1170 1169 1689 | 1 2 1656 1170 1690 | 1 2 1622 1170 1691 | 1 2 1691 1171 1692 | 1 2 1405 1171 1693 | 1 2 1649 1172 1694 | 1 2 1397 1172 1695 | 1 2 1623 1173 1696 | 1 2 1404 1173 1697 | 1 2 1690 1174 1698 | 1 2 1575 1174 1699 | 1 2 1523 1174 1700 | 1 2 1608 1175 1701 | 1 2 1364 1175 1702 | 1 2 1720 1176 1703 | 1 2 1562 1177 1704 | 1 2 1674 1178 1705 | 1 2 1615 1178 1706 | 1 2 1680 1179 1707 | 1 2 1678 1179 1708 | 1 2 1650 1179 1709 | 1 2 1719 1180 1710 | 1 2 1402 1180 1711 | 1 2 1401 1180 1712 | 1 2 1625 1181 1713 | 1 2 1596 1181 1714 | 1 2 1400 1181 1715 | 1 2 1626 1182 1716 | 1 2 1625 1182 1717 | 1 2 1340 1183 1718 | 1 2 1657 1184 1719 | 1 2 1641 1184 1720 | 1 2 1527 1184 1721 | 1 2 1677 1185 1722 | 1 2 1650 1185 1723 | 1 2 1568 1185 1724 | 1 2 1606 1186 1725 | 1 2 1399 1186 1726 | 1 2 1503 1187 1727 | 1 2 1398 1187 1728 | 1 2 1690 1188 1729 | 1 2 1496 1188 1730 | 1 2 1584 1189 1731 | 1 2 1582 1189 1732 | 1 2 1248 1189 1733 | 1 2 1507 1190 1734 | 1 2 1397 1190 1735 | 1 2 1622 1191 1736 | 1 2 1609 1191 1737 | 1 2 1529 1191 1738 | 1 2 1617 1192 1739 | 1 2 1513 1192 1740 | 1 2 1396 1192 1741 | 1 2 1689 1193 1742 | 1 2 1594 1193 1743 | 1 2 1528 1193 1744 | 1 2 1610 1194 1745 | 1 2 1403 1194 1746 | 1 2 1296 1195 1747 | 1 2 1517 1196 1748 | 1 2 1367 1196 1749 | 1 2 1371 1197 1750 | 1 2 1198 1197 1751 | 1 2 1371 1198 1752 | 1 2 1284 1199 1753 | 1 2 1665 1200 1754 | 1 2 1606 1200 1755 | 1 2 1684 1201 1756 | 1 2 1393 1201 1757 | 1 2 1392 1201 1758 | 1 2 1545 1202 1759 | 1 2 1544 1202 1760 | 1 2 1355 1202 1761 | 1 2 1386 1203 1762 | 1 2 1297 1203 1763 | 1 2 1232 1204 1764 | 1 2 1231 1204 1765 | 1 2 1230 1204 1766 | 1 2 1425 1205 1767 | 1 2 1420 1205 1768 | 1 2 1419 1205 1769 | 1 2 1543 1206 1770 | 1 2 1503 1206 1771 | 1 2 1391 1207 1772 | 1 2 1209 1207 1773 | 1 2 1391 1208 1774 | 1 2 1210 1208 1775 | 1 2 1595 1211 1776 | 1 2 1527 1211 1777 | 1 2 1661 1212 1778 | 1 2 1420 1213 1779 | 1 2 1377 1213 1780 | 1 2 1375 1213 1781 | 1 2 1491 1214 1782 | 1 2 1489 1214 1783 | 1 2 1492 1215 1784 | 1 2 1463 1215 1785 | 1 2 1462 1215 1786 | 1 2 1290 1216 1787 | 1 2 1583 1217 1788 | 1 2 1560 1217 1789 | 1 2 1389 1217 1790 | 1 2 1473 1218 1791 | 1 2 1219 1218 1792 | 1 2 1628 1219 1793 | 1 2 1625 1219 1794 | 1 2 1473 1219 1795 | 1 2 1601 1220 1796 | 1 2 1462 1220 1797 | 1 2 1461 1220 1798 | 1 2 1630 1221 1799 | 1 2 1239 1221 1800 | 1 2 1630 1222 1801 | 1 2 1226 1223 1802 | 1 2 1388 1224 1803 | 1 2 1225 1224 1804 | 1 2 1388 1225 1805 | 1 2 1526 1227 1806 | 1 2 1690 1228 1807 | 1 2 1387 1228 1808 | 1 2 1624 1229 1809 | 1 2 1518 1229 1810 | 1 2 1404 1229 1811 | 1 2 1386 1230 1812 | 1 2 1232 1230 1813 | 1 2 1507 1231 1814 | 1 2 1386 1231 1815 | 1 2 1232 1231 1816 | 1 2 1698 1232 1817 | 1 2 1386 1232 1818 | 1 2 1596 1233 1819 | 1 2 1471 1233 1820 | 1 2 1354 1233 1821 | 1 2 1539 1234 1822 | 1 2 1538 1234 1823 | 1 2 1470 1234 1824 | 1 2 1238 1236 1825 | 1 2 1535 1239 1826 | 1 2 1679 1240 1827 | 1 2 1645 1240 1828 | 1 2 1612 1240 1829 | 1 2 1645 1241 1830 | 1 2 1385 1241 1831 | 1 2 1568 1242 1832 | 1 2 1567 1242 1833 | 1 2 1414 1242 1834 | 1 2 1703 1243 1835 | 1 2 1571 1243 1836 | 1 2 1566 1243 1837 | 1 2 1245 1244 1838 | 1 2 1359 1245 1839 | 1 2 1383 1246 1840 | 1 2 1525 1247 1841 | 1 2 1641 1248 1842 | 1 2 1593 1249 1843 | 1 2 1652 1250 1844 | 1 2 1651 1250 1845 | 1 2 1589 1250 1846 | 1 2 1252 1251 1847 | 1 2 1690 1252 1848 | 1 2 1565 1252 1849 | 1 2 1564 1253 1850 | 1 2 1358 1253 1851 | 1 2 1703 1254 1852 | 1 2 1571 1254 1853 | 1 2 1381 1254 1854 | 1 2 1582 1255 1855 | 1 2 1380 1255 1856 | 1 2 1638 1256 1857 | 1 2 1581 1257 1858 | 1 2 1543 1257 1859 | 1 2 1258 1257 1860 | 1 2 1546 1258 1861 | 1 2 1591 1259 1862 | 1 2 1537 1259 1863 | 1 2 1574 1260 1864 | 1 2 1523 1260 1865 | 1 2 1517 1261 1866 | 1 2 1367 1261 1867 | 1 2 1293 1261 1868 | 1 2 1671 1262 1869 | 1 2 1652 1262 1870 | 1 2 1603 1263 1871 | 1 2 1522 1263 1872 | 1 2 1517 1263 1873 | 1 2 1446 1264 1874 | 1 2 1443 1264 1875 | 1 2 1442 1264 1876 | 1 2 1326 1265 1877 | 1 2 1323 1265 1878 | 1 2 1321 1265 1879 | 1 2 1489 1266 1880 | 1 2 1583 1267 1881 | 1 2 1582 1267 1882 | 1 2 1378 1267 1883 | 1 2 1672 1268 1884 | 1 2 1589 1268 1885 | 1 2 1519 1268 1886 | 1 2 1702 1269 1887 | 1 2 1695 1269 1888 | 1 2 1645 1269 1889 | 1 2 1576 1270 1890 | 1 2 1494 1270 1891 | 1 2 1437 1270 1892 | 1 2 1570 1271 1893 | 1 2 1566 1271 1894 | 1 2 1410 1271 1895 | 1 2 1420 1272 1896 | 1 2 1376 1272 1897 | 1 2 1374 1272 1898 | 1 2 1611 1273 1899 | 1 2 1395 1273 1900 | 1 2 1371 1273 1901 | 1 2 1697 1274 1902 | 1 2 1655 1274 1903 | 1 2 1599 1274 1904 | 1 2 1605 1275 1905 | 1 2 1521 1275 1906 | 1 2 1721 1276 1907 | 1 2 1656 1276 1908 | 1 2 1601 1276 1909 | 1 2 1676 1277 1910 | 1 2 1408 1277 1911 | 1 2 1608 1278 1912 | 1 2 1363 1278 1913 | 1 2 1592 1279 1914 | 1 2 1520 1279 1915 | 1 2 1373 1279 1916 | 1 2 1702 1280 1917 | 1 2 1661 1280 1918 | 1 2 1390 1280 1919 | 1 2 1683 1281 1920 | 1 2 1675 1281 1921 | 1 2 1520 1281 1922 | 1 2 1371 1282 1923 | 1 2 1283 1282 1924 | 1 2 1665 1285 1925 | 1 2 1664 1285 1926 | 1 2 1638 1285 1927 | 1 2 1559 1286 1928 | 1 2 1493 1286 1929 | 1 2 1456 1286 1930 | 1 2 1651 1287 1931 | 1 2 1590 1287 1932 | 1 2 1519 1287 1933 | 1 2 1586 1288 1934 | 1 2 1539 1288 1935 | 1 2 1514 1288 1936 | 1 2 1654 1289 1937 | 1 2 1395 1289 1938 | 1 2 1478 1290 1939 | 1 2 1369 1290 1940 | 1 2 1622 1291 1941 | 1 2 1537 1291 1942 | 1 2 1518 1291 1943 | 1 2 1662 1292 1944 | 1 2 1470 1292 1945 | 1 2 1603 1293 1946 | 1 2 1367 1293 1947 | 1 2 1540 1294 1948 | 1 2 1513 1294 1949 | 1 2 1508 1295 1950 | 1 2 1297 1295 1951 | 1 2 1508 1296 1952 | 1 2 1297 1296 1953 | 1 2 1649 1298 1954 | 1 2 1354 1298 1955 | 1 2 1699 1299 1956 | 1 2 1688 1299 1957 | 1 2 1499 1299 1958 | 1 2 1685 1301 1959 | 1 2 1542 1301 1960 | 1 2 1568 1302 1961 | 1 2 1567 1302 1962 | 1 2 1423 1303 1963 | 1 2 1421 1303 1964 | 1 2 1419 1303 1965 | 1 2 1633 1304 1966 | 1 2 1365 1305 1967 | 1 2 1361 1305 1968 | 1 2 1332 1305 1969 | 1 2 1649 1306 1970 | 1 2 1596 1306 1971 | 1 2 1348 1306 1972 | 1 2 1617 1307 1973 | 1 2 1572 1307 1974 | 1 2 1309 1308 1975 | 1 2 1408 1309 1976 | 1 2 1666 1310 1977 | 1 2 1424 1310 1978 | 1 2 1423 1310 1979 | 1 2 1722 1311 1980 | 1 2 1670 1311 1981 | 1 2 1702 1312 1982 | 1 2 1695 1312 1983 | 1 2 1360 1312 1984 | 1 2 1516 1313 1985 | 1 2 1315 1313 1986 | 1 2 1314 1313 1987 | 1 2 1601 1314 1988 | 1 2 1516 1314 1989 | 1 2 1316 1315 1990 | 1 2 1601 1316 1991 | 1 2 1634 1317 1992 | 1 2 1319 1317 1993 | 1 2 1634 1318 1994 | 1 2 1319 1318 1995 | 1 2 1634 1319 1996 | 1 2 1326 1320 1997 | 1 2 1321 1320 1998 | 1 2 1323 1321 1999 | 1 2 1326 1322 2000 | 1 2 1324 1322 2001 | 1 2 1323 1322 2002 | 1 2 1325 1324 2003 | 1 2 1327 1325 2004 | 1 2 1703 1328 2005 | 1 2 1617 1328 2006 | 1 2 1541 1328 2007 | 1 2 1686 1329 2008 | 1 2 1610 1329 2009 | 1 2 1515 1330 2010 | 1 2 1564 1331 2011 | 1 2 1358 1331 2012 | 1 2 1365 1332 2013 | 1 2 1547 1333 2014 | 1 2 1334 1333 2015 | 1 2 1549 1334 2016 | 1 2 1355 1334 2017 | 1 2 1709 1335 2018 | 1 2 1618 1335 2019 | 1 2 1578 1336 2020 | 1 2 1565 1336 2021 | 1 2 1673 1337 2022 | 1 2 1486 1337 2023 | 1 2 1659 1338 2024 | 1 2 1655 1338 2025 | 1 2 1609 1338 2026 | 1 2 1615 1339 2027 | 1 2 1590 1339 2028 | 1 2 1666 1340 2029 | 1 2 1424 1340 2030 | 1 2 1679 1341 2031 | 1 2 1612 1341 2032 | 1 2 1562 1342 2033 | 1 2 1453 1342 2034 | 1 2 1581 1343 2035 | 1 2 1547 1343 2036 | 1 2 1425 1344 2037 | 1 2 1376 1344 2038 | 1 2 1375 1344 2039 | 1 2 1602 1345 2040 | 1 2 1538 1345 2041 | 1 2 1514 1345 2042 | 1 2 1703 1346 2043 | 1 2 1594 1346 2044 | 1 2 1596 1347 2045 | 1 2 1354 1347 2046 | 1 2 1649 1348 2047 | 1 2 1354 1348 2048 | 1 2 1572 1349 2049 | 1 2 1570 1349 2050 | 1 2 1512 1349 2051 | 1 2 1668 1350 2052 | 1 2 1598 1350 2053 | 1 2 1597 1350 2054 | 1 2 1617 1351 2055 | 1 2 1541 1351 2056 | 1 2 1511 1351 2057 | 1 2 1704 1352 2058 | 1 2 1676 1352 2059 | 1 2 1696 1353 2060 | 1 2 1644 1353 2061 | 1 2 1510 1353 2062 | 1 2 1647 1354 2063 | 1 2 1549 1355 2064 | 1 2 1547 1355 2065 | 1 2 1357 1356 2066 | 1 2 1564 1357 2067 | 1 2 1364 1361 2068 | 1 2 1363 1361 2069 | 1 2 1363 1362 2070 | 1 2 1684 1364 2071 | 1 2 1682 1365 2072 | 1 2 1480 1368 2073 | 1 2 1370 1368 2074 | 1 2 1369 1368 2075 | 1 2 1480 1369 2076 | 1 2 1477 1369 2077 | 1 2 1370 1369 2078 | 1 2 1477 1370 2079 | 1 2 1680 1373 2080 | 1 2 1675 1373 2081 | 1 2 1377 1374 2082 | 1 2 1375 1374 2083 | 1 2 1422 1376 2084 | 1 2 1420 1376 2085 | 1 2 1423 1377 2086 | 1 2 1422 1377 2087 | 1 2 1643 1378 2088 | 1 2 1583 1380 2089 | 1 2 1562 1380 2090 | 1 2 1618 1381 2091 | 1 2 1540 1381 2092 | 1 2 1701 1382 2093 | 1 2 1565 1382 2094 | 1 2 1682 1383 2095 | 1 2 1704 1384 2096 | 1 2 1682 1384 2097 | 1 2 1454 1384 2098 | 1 2 1600 1385 2099 | 1 2 1611 1387 2100 | 1 2 1561 1387 2101 | 1 2 1456 1388 2102 | 1 2 1641 1389 2103 | 1 2 1616 1389 2104 | 1 2 1660 1391 2105 | 1 2 1619 1391 2106 | 1 2 1556 1391 2107 | 1 2 1608 1392 2108 | 1 2 1505 1392 2109 | 1 2 1681 1393 2110 | 1 2 1505 1393 2111 | 1 2 1504 1394 2112 | 1 2 1395 1394 2113 | 1 2 1572 1396 2114 | 1 2 1512 1396 2115 | 1 2 1548 1398 2116 | 1 2 1629 1399 2117 | 1 2 1626 1399 2118 | 1 2 1628 1400 2119 | 1 2 1597 1400 2120 | 1 2 1518 1404 2121 | 1 2 1691 1405 2122 | 1 2 1576 1405 2123 | 1 2 1573 1405 2124 | 1 2 1531 1405 2125 | 1 2 1480 1406 2126 | 1 2 1679 1407 2127 | 1 2 1620 1407 2128 | 1 2 1686 1409 2129 | 1 2 1681 1409 2130 | 1 2 1552 1411 2131 | 1 2 1588 1412 2132 | 1 2 1594 1413 2133 | 1 2 1499 1413 2134 | 1 2 1677 1414 2135 | 1 2 1646 1415 2136 | 1 2 1612 1415 2137 | 1 2 1677 1416 2138 | 1 2 1558 1417 2139 | 1 2 1532 1417 2140 | 1 2 1423 1418 2141 | 1 2 1424 1421 2142 | 1 2 1425 1424 2143 | 1 2 1426 1425 2144 | 1 2 1623 1427 2145 | 1 2 1556 1428 2146 | 1 2 1447 1429 2147 | 1 2 1446 1429 2148 | 1 2 1483 1430 2149 | 1 2 1634 1431 2150 | 1 2 1631 1431 2151 | 1 2 1497 1433 2152 | 1 2 1675 1434 2153 | 1 2 1592 1434 2154 | 1 2 1639 1435 2155 | 1 2 1672 1436 2156 | 1 2 1494 1437 2157 | 1 2 1486 1438 2158 | 1 2 1484 1438 2159 | 1 2 1579 1439 2160 | 1 2 1468 1439 2161 | 1 2 1550 1440 2162 | 1 2 1468 1440 2163 | 1 2 1446 1441 2164 | 1 2 1442 1441 2165 | 1 2 1614 1442 2166 | 1 2 1446 1442 2167 | 1 2 1444 1442 2168 | 1 2 1445 1443 2169 | 1 2 1693 1446 2170 | 1 2 1614 1446 2171 | 1 2 1447 1446 2172 | 1 2 1576 1448 2173 | 1 2 1550 1448 2174 | 1 2 1449 1448 2175 | 1 2 1576 1449 2176 | 1 2 1450 1449 2177 | 1 2 1576 1450 2178 | 1 2 1577 1451 2179 | 1 2 1495 1451 2180 | 1 2 1576 1452 2181 | 1 2 1494 1452 2182 | 1 2 1455 1452 2183 | 1 2 1560 1453 2184 | 1 2 1682 1454 2185 | 1 2 1553 1454 2186 | 1 2 1578 1455 2187 | 1 2 1494 1455 2188 | 1 2 1627 1456 2189 | 1 2 1697 1457 2190 | 1 2 1640 1457 2191 | 1 2 1504 1457 2192 | 1 2 1674 1458 2193 | 1 2 1657 1458 2194 | 1 2 1656 1458 2195 | 1 2 1595 1458 2196 | 1 2 1630 1459 2197 | 1 2 1558 1459 2198 | 1 2 1658 1460 2199 | 1 2 1516 1460 2200 | 1 2 1601 1461 2201 | 1 2 1721 1462 2202 | 1 2 1702 1464 2203 | 1 2 1682 1464 2204 | 1 2 1676 1464 2205 | 1 2 1483 1465 2206 | 1 2 1482 1465 2207 | 1 2 1481 1465 2208 | 1 2 1664 1466 2209 | 1 2 1552 1466 2210 | 1 2 1581 1467 2211 | 1 2 1547 1467 2212 | 1 2 1544 1467 2213 | 1 2 1543 1467 2214 | 1 2 1579 1468 2215 | 1 2 1575 1468 2216 | 1 2 1670 1469 2217 | 1 2 1489 1469 2218 | 1 2 1484 1469 2219 | 1 2 1483 1469 2220 | 1 2 1587 1470 2221 | 1 2 1538 1470 2222 | 1 2 1551 1471 2223 | 1 2 1705 1472 2224 | 1 2 1693 1472 2225 | 1 2 1606 1473 2226 | 1 2 1628 1474 2227 | 1 2 1627 1474 2228 | 1 2 1626 1474 2229 | 1 2 1625 1474 2230 | 1 2 1615 1475 2231 | 1 2 1590 1475 2232 | 1 2 1536 1475 2233 | 1 2 1530 1475 2234 | 1 2 1539 1476 2235 | 1 2 1480 1476 2236 | 1 2 1477 1476 2237 | 1 2 1539 1477 2238 | 1 2 1478 1477 2239 | 1 2 1685 1479 2240 | 1 2 1681 1479 2241 | 1 2 1678 1479 2242 | 1 2 1646 1479 2243 | 1 2 1714 1480 2244 | 1 2 1539 1480 2245 | 1 2 1538 1480 2246 | 1 2 1514 1480 2247 | 1 2 1485 1481 2248 | 1 2 1483 1481 2249 | 1 2 1483 1482 2250 | 1 2 1487 1484 2251 | 1 2 1670 1485 2252 | 1 2 1670 1487 2253 | 1 2 1670 1489 2254 | 1 2 1495 1494 2255 | 1 2 1691 1496 2256 | 1 2 1696 1497 2257 | 1 2 1564 1497 2258 | 1 2 1563 1497 2259 | 1 2 1648 1498 2260 | 1 2 1552 1498 2261 | 1 2 1696 1499 2262 | 1 2 1688 1499 2263 | 1 2 1604 1500 2264 | 1 2 1603 1500 2265 | 1 2 1588 1500 2266 | 1 2 1678 1502 2267 | 1 2 1612 1502 2268 | 1 2 1546 1503 2269 | 1 2 1648 1509 2270 | 1 2 1688 1510 2271 | 1 2 1614 1510 2272 | 1 2 1594 1510 2273 | 1 2 1513 1512 2274 | 1 2 1636 1515 2275 | 1 2 1631 1515 2276 | 1 2 1658 1516 2277 | 1 2 1643 1516 2278 | 1 2 1601 1516 2279 | 1 2 1605 1517 2280 | 1 2 1524 1518 2281 | 1 2 1669 1519 2282 | 1 2 1650 1520 2283 | 1 2 1662 1521 2284 | 1 2 1605 1522 2285 | 1 2 1604 1522 2286 | 1 2 1602 1522 2287 | 1 2 1602 1526 2288 | 1 2 1656 1527 2289 | 1 2 1659 1529 2290 | 1 2 1589 1530 2291 | 1 2 1536 1530 2292 | 1 2 1691 1531 2293 | 1 2 1573 1531 2294 | 1 2 1684 1533 2295 | 1 2 1650 1533 2296 | 1 2 1621 1533 2297 | 1 2 1662 1535 2298 | 1 2 1654 1537 2299 | 1 2 1609 1537 2300 | 1 2 1618 1541 2301 | 1 2 1569 1541 2302 | 1 2 1681 1542 2303 | 1 2 1546 1543 2304 | 1 2 1546 1544 2305 | 1 2 1548 1545 2306 | 1 2 1718 1546 2307 | 1 2 1549 1546 2308 | 1 2 1576 1550 2309 | 1 2 1597 1551 2310 | 1 2 1585 1552 2311 | 1 2 1682 1553 2312 | 1 2 1637 1554 2313 | 1 2 1607 1556 2314 | 1 2 1674 1557 2315 | 1 2 1658 1557 2316 | 1 2 1583 1560 2317 | 1 2 1655 1561 2318 | 1 2 1578 1565 2319 | 1 2 1573 1565 2320 | 1 2 1572 1566 2321 | 1 2 1708 1567 2322 | 1 2 1683 1567 2323 | 1 2 1568 1567 2324 | 1 2 1683 1568 2325 | 1 2 1692 1569 2326 | 1 2 1618 1569 2327 | 1 2 1671 1571 2328 | 1 2 1652 1571 2329 | 1 2 1703 1572 2330 | 1 2 1578 1573 2331 | 1 2 1578 1574 2332 | 1 2 1690 1575 2333 | 1 2 1579 1575 2334 | 1 2 1576 1575 2335 | 1 2 1647 1580 2336 | 1 2 1584 1583 2337 | 1 2 1674 1584 2338 | 1 2 1659 1584 2339 | 1 2 1641 1584 2340 | 1 2 1648 1585 2341 | 1 2 1647 1585 2342 | 1 2 1629 1585 2343 | 1 2 1587 1586 2344 | 1 2 1613 1588 2345 | 1 2 1602 1588 2346 | 1 2 1659 1591 2347 | 1 2 1678 1592 2348 | 1 2 1644 1593 2349 | 1 2 1594 1593 2350 | 1 2 1721 1595 2351 | 1 2 1597 1596 2352 | 1 2 1657 1599 2353 | 1 2 1646 1600 2354 | 1 2 1642 1601 2355 | 1 2 1700 1602 2356 | 1 2 1700 1605 2357 | 1 2 1639 1607 2358 | 1 2 1635 1607 2359 | 1 2 1633 1607 2360 | 1 2 1684 1608 2361 | 1 2 1657 1609 2362 | 1 2 1689 1614 2363 | 1 2 1674 1615 2364 | 1 2 1652 1615 2365 | 1 2 1706 1616 2366 | 1 2 1697 1616 2367 | 1 2 1641 1616 2368 | 1 2 1636 1619 2369 | 1 2 1677 1620 2370 | 1 2 1650 1621 2371 | 1 2 1623 1622 2372 | 1 2 1697 1624 2373 | 1 2 1629 1625 2374 | 1 2 1627 1626 2375 | 1 2 1629 1628 2376 | 1 2 1665 1630 2377 | 1 2 1660 1630 2378 | 1 2 1634 1632 2379 | 1 2 1664 1633 2380 | 1 2 1639 1633 2381 | 1 2 1638 1633 2382 | 1 2 1639 1635 2383 | 1 2 1636 1635 2384 | 1 2 1643 1641 2385 | 1 2 1643 1642 2386 | 1 2 1674 1643 2387 | 1 2 1717 1653 2388 | 1 2 1655 1654 2389 | 1 2 1657 1655 2390 | 1 2 1700 1663 2391 | 1 2 1665 1664 2392 | 1 2 1711 1674 2393 | 1 2 1686 1681 2394 | 1 2 1712 1686 2395 | 1 2 1713 1689 2396 | 1 2 1722 1721 2397 | 1 2398 | 1 2399 | 1 2400 | 1 2401 | 1 2402 | 1 2403 | 1 2404 | 1 2405 | 1 2406 | 1 2407 | 1 2408 | 1 2409 | 1 2410 | 1 2411 | 1 2412 | 1 2413 | 1 2414 | 1 2415 | 1 2416 | 1 2417 | 1 2418 | 1 2419 | 1 2420 | 1 2421 | 1 2422 | 1 2423 | 1 2424 | 1 2425 | 1 2426 | 1 2427 | 1 2428 | 1 2429 | 1 2430 | 1 2431 | 1 2432 | 1 2433 | 1 2434 | 1 2435 | 1 2436 | 1 2437 | 1 2438 | 1 2439 | 1 2440 | 1 2441 | 1 2442 | 1 2443 | 1 2444 | 1 2445 | 1 2446 | 1 2447 | 1 2448 | 1 2449 | 1 2450 | 1 2451 | 1 2452 | 1 2453 | 1 2454 | 1 2455 | 1 2456 | 1 2457 | 1 2458 | 1 2459 | 1 2460 | 1 2461 | 1 2462 | 1 2463 | 1 2464 | 1 2465 | 1 2466 | 1 2467 | 1 2468 | 1 2469 | 1 2470 | 1 2471 | 1 2472 | 1 2473 | 1 2474 | 1 2475 | 1 2476 | 1 2477 | 1 2478 | 1 2479 | 1 2480 | 1 2481 | 1 2482 | 1 2483 | 1 2484 | 1 2485 | 1 2486 | 1 2487 | 1 2488 | 1 2489 | 1 2490 | 1 2491 | 1 2492 | 1 2493 | 1 2494 | 1 2495 | 1 2496 | 1 2497 | 1 2498 | 1 2499 | 1 2500 | 1 2501 | 1 2502 | 1 2503 | 1 2504 | 1 2505 | 1 2506 | 1 2507 | 1 2508 | 1 2509 | 1 2510 | 1 2511 | 1 2512 | 1 2513 | 1 2514 | 1 2515 | 1 2516 | 1 2517 | 1 2518 | 1 2519 | 1 2520 | 1 2521 | 1 2522 | 1 2523 | 1 2524 | 1 2525 | 1 2526 | 1 2527 | 1 2528 | 1 2529 | 1 2530 | 1 2531 | 1 2532 | 1 2533 | 1 2534 | 1 2535 | 1 2536 | 1 2537 | 1 2538 | 1 2539 | 1 2540 | 1 2541 | 1 2542 | 1 2543 | 1 2544 | 1 2545 | 1 2546 | 1 2547 | 1 2548 | 1 2549 | 1 2550 | 1 2551 | 1 2552 | 1 2553 | 1 2554 | 1 2555 | 1 2556 | 1 2557 | 1 2558 | 1 2559 | 1 2560 | 1 2561 | 1 2562 | 1 2563 | 1 2564 | 1 2565 | 1 2566 | 1 2567 | 1 2568 | 1 2569 | 1 2570 | 1 2571 | 1 2572 | 1 2573 | 1 2574 | 1 2575 | 1 2576 | 1 2577 | 1 2578 | 1 2579 | 1 2580 | 1 2581 | 1 2582 | 1 2583 | 1 2584 | 1 2585 | 1 2586 | 1 2587 | 1 2588 | 1 2589 | 1 2590 | 1 2591 | 1 2592 | 1 2593 | 1 2594 | 1 2595 | 1 2596 | 1 2597 | 1 2598 | 1 2599 | 1 2600 | 1 2601 | 1 2602 | 1 2603 | 1 2604 | 1 2605 | 1 2606 | 1 2607 | 1 2608 | 1 2609 | 1 2610 | 1 2611 | 1 2612 | 1 2613 | 1 2614 | 1 2615 | 1 2616 | 1 2617 | 1 2618 | 1 2619 | 1 2620 | 1 2621 | 1 2622 | 1 2623 | 1 2624 | 1 2625 | 1 2626 | 1 2627 | 1 2628 | 1 2629 | 1 2630 | 1 2631 | 1 2632 | 1 2633 | 1 2634 | 1 2635 | 1 2636 | 1 2637 | 1 2638 | 1 2639 | 1 2640 | 1 2641 | 1 2642 | 1 2643 | 1 2644 | 1 2645 | 1 2646 | 1 2647 | 1 2648 | 1 2649 | 1 2650 | 1 2651 | 1 2652 | 1 2653 | 1 2654 | 1 2655 | 1 2656 | 1 2657 | 1 2658 | 1 2659 | 1 2660 | 1 2661 | 1 2662 | 1 2663 | 1 2664 | 1 2665 | 1 2666 | 1 2667 | 1 2668 | 1 2669 | 1 2670 | 1 2671 | 1 2672 | 1 2673 | 1 2674 | 1 2675 | 1 2676 | 1 2677 | 1 2678 | 1 2679 | 1 2680 | 1 2681 | 1 2682 | 1 2683 | 1 2684 | 1 2685 | 1 2686 | 1 2687 | 1 2688 | 1 2689 | 1 2690 | 1 2691 | 1 2692 | 1 2693 | 1 2694 | 1 2695 | 1 2696 | 1 2697 | 1 2698 | 1 2699 | 1 2700 | 1 2701 | 1 2702 | 1 2703 | 1 2704 | 1 2705 | 1 2706 | 1 2707 | 1 2708 | 1 2709 | 1 2710 | 1 2711 | 1 2712 | 1 2713 | 1 2714 | 1 2715 | 1 2716 | 1 2717 | 1 2718 | 1 2719 | 1 2720 | 1 2721 | 1 2722 | 1 2723 | 1 2724 | 1 2725 | 1 2726 | 1 2727 | 1 2728 | 1 2729 | 1 2730 | 1 2731 | 1 2732 | 1 2733 | 1 2734 | 1 2735 | 1 2736 | 1 2737 | 1 2738 | 1 2739 | 1 2740 | 1 2741 | 1 2742 | 1 2743 | 1 2744 | 1 2745 | 1 2746 | 1 2747 | 1 2748 | 1 2749 | 1 2750 | 1 2751 | 1 2752 | 1 2753 | 1 2754 | 1 2755 | 1 2756 | 1 2757 | 1 2758 | 1 2759 | 1 2760 | 1 2761 | 1 2762 | 1 2763 | 1 2764 | 1 2765 | 1 2766 | 1 2767 | 1 2768 | 1 2769 | 1 2770 | 1 2771 | 1 2772 | 1 2773 | 1 2774 | 1 2775 | 1 2776 | 1 2777 | 1 2778 | 1 2779 | 1 2780 | 1 2781 | 1 2782 | 1 2783 | 1 2784 | 1 2785 | 1 2786 | 1 2787 | 1 2788 | 1 2789 | 1 2790 | 1 2791 | 1 2792 | 1 2793 | 1 2794 | 1 2795 | 1 2796 | 1 2797 | 1 2798 | 1 2799 | 1 2800 | 1 2801 | 1 2802 | 1 2803 | 1 2804 | 1 2805 | 1 2806 | 1 2807 | 1 2808 | 1 2809 | 1 2810 | 1 2811 | 1 2812 | 1 2813 | 1 2814 | 1 2815 | 1 2816 | 1 2817 | 1 2818 | 1 2819 | 1 2820 | 1 2821 | 1 2822 | 1 2823 | 1 2824 | 1 2825 | 1 2826 | 1 2827 | 1 2828 | 1 2829 | 1 2830 | 1 2831 | 1 2832 | 1 2833 | 1 2834 | 1 2835 | 1 2836 | 1 2837 | 1 2838 | 1 2839 | 1 2840 | 1 2841 | 1 2842 | 1 2843 | 1 2844 | 1 2845 | 1 2846 | 1 2847 | 1 2848 | 1 2849 | 1 2850 | 1 2851 | 1 2852 | 1 2853 | 1 2854 | 1 2855 | 1 2856 | 1 2857 | 1 2858 | 1 2859 | 1 2860 | 1 2861 | 1 2862 | 1 2863 | 1 2864 | 1 2865 | 1 2866 | 1 2867 | 1 2868 | 1 2869 | 1 2870 | 1 2871 | 1 2872 | 1 2873 | 1 2874 | 1 2875 | 1 2876 | 1 2877 | 1 2878 | 1 2879 | 1 2880 | 1 2881 | 1 2882 | 1 2883 | 1 2884 | 1 2885 | 1 2886 | 1 2887 | 1 2888 | 1 2889 | 1 2890 | 1 2891 | 1 2892 | 1 2893 | 1 2894 | 1 2895 | 1 2896 | 1 2897 | 1 2898 | 1 2899 | 1 2900 | 1 2901 | 1 2902 | 1 2903 | 1 2904 | 1 2905 | 1 2906 | 1 2907 | 1 2908 | 1 2909 | 1 2910 | 1 2911 | 1 2912 | 1 2913 | 1 2914 | 1 2915 | 1 2916 | 1 2917 | 1 2918 | 1 2919 | 1 2920 | 1 2921 | 1 2922 | 1 2923 | 1 2924 | 1 2925 | 1 2926 | 1 2927 | 1 2928 | 1 2929 | 1 2930 | 1 2931 | 1 2932 | 1 2933 | 1 2934 | 1 2935 | 1 2936 | 1 2937 | 1 2938 | 1 2939 | 1 2940 | 1 2941 | 1 2942 | 1 2943 | 1 2944 | 1 2945 | 1 2946 | 1 2947 | 1 2948 | 1 2949 | 1 2950 | 1 2951 | 1 2952 | 1 2953 | 1 2954 | 1 2955 | 1 2956 | 1 2957 | 1 2958 | 1 2959 | 1 2960 | 1 2961 | 1 2962 | 1 2963 | 1 2964 | 1 2965 | 1 2966 | 1 2967 | 1 2968 | 1 2969 | 1 2970 | 1 2971 | 1 2972 | 1 2973 | 1 2974 | 1 2975 | 1 2976 | 1 2977 | 1 2978 | 1 2979 | 1 2980 | 1 2981 | 1 2982 | 1 2983 | 1 2984 | 1 2985 | 1 2986 | 1 2987 | 1 2988 | 1 2989 | 1 2990 | 1 2991 | 1 2992 | 1 2993 | 1 2994 | 1 2995 | 1 2996 | 1 2997 | 1 2998 | 1 2999 | 1 3000 | 1 3001 | 1 3002 | 1 3003 | 1 3004 | 1 3005 | 1 3006 | 1 3007 | 1 3008 | 1 3009 | 1 3010 | 1 3011 | 1 3012 | 1 3013 | 1 3014 | 1 3015 | 1 3016 | 1 3017 | 1 3018 | 1 3019 | 1 3020 | 1 3021 | 1 3022 | 1 3023 | 1 3024 | 1 3025 | 1 3026 | 1 3027 | 1 3028 | 1 3029 | 1 3030 | 1 3031 | 1 3032 | 1 3033 | 1 3034 | 1 3035 | 1 3036 | 1 3037 | 1 3038 | 1 3039 | 1 3040 | 1 3041 | 1 3042 | 1 3043 | 1 3044 | 1 3045 | 1 3046 | 1 3047 | 1 3048 | 1 3049 | 1 3050 | 1 3051 | 1 3052 | 1 3053 | 1 3054 | 1 3055 | 1 3056 | 1 3057 | 1 3058 | 1 3059 | 1 3060 | 1 3061 | 1 3062 | 1 3063 | 1 3064 | 1 3065 | 1 3066 | 1 3067 | 1 3068 | 1 3069 | 1 3070 | 1 3071 | 1 3072 | 1 3073 | 1 3074 | 1 3075 | 1 3076 | 1 3077 | 1 3078 | 1 3079 | 1 3080 | 1 3081 | 1 3082 | 1 3083 | 1 3084 | 1 3085 | 1 3086 | 1 3087 | 1 3088 | 1 3089 | 1 3090 | 1 3091 | 1 3092 | 1 3093 | 1 3094 | 1 3095 | 1 3096 | 1 3097 | 1 3098 | 1 3099 | 1 3100 | 1 3101 | 1 3102 | 1 3103 | 1 3104 | 1 3105 | 1 3106 | 1 3107 | 1 3108 | 1 3109 | 1 3110 | 1 3111 | 1 3112 | 1 3113 | 1 3114 | 1 3115 | 1 3116 | 1 3117 | 1 3118 | 1 3119 | 1 3120 | 1 3121 | 1 3122 | 1 3123 | 1 3124 | 1 3125 | 1 3126 | 1 3127 | 1 3128 | 1 3129 | 1 3130 | 1 3131 | 1 3132 | 1 3133 | 1 3134 | 1 3135 | 1 3136 | 1 3137 | 1 3138 | 1 3139 | 1 3140 | 1 3141 | 1 3142 | 1 3143 | 1 3144 | 1 3145 | 1 3146 | 1 3147 | 1 3148 | 1 3149 | 1 3150 | 1 3151 | 1 3152 | 1 3153 | 1 3154 | 1 3155 | 1 3156 | 1 3157 | 1 3158 | 1 3159 | 1 3160 | 1 3161 | 1 3162 | 1 3163 | 1 3164 | 1 3165 | 1 3166 | 1 3167 | 1 3168 | 1 3169 | 1 3170 | 1 3171 | 1 3172 | 1 3173 | 1 3174 | 1 3175 | 1 3176 | 1 3177 | 1 3178 | 1 3179 | 1 3180 | 1 3181 | 1 3182 | 1 3183 | 1 3184 | 1 3185 | 1 3186 | 1 3187 | 1 3188 | 1 3189 | 1 3190 | 1 3191 | 1 3192 | 1 3193 | 1 3194 | 1 3195 | 1 3196 | 1 3197 | 1 3198 | 1 3199 | 1 3200 | 1 3201 | 1 3202 | 1 3203 | 1 3204 | 1 3205 | 1 3206 | 1 3207 | 1 3208 | 1 3209 | 1 3210 | 1 3211 | 1 3212 | 1 3213 | 1 3214 | 1 3215 | 1 3216 | 1 3217 | 1 3218 | 1 3219 | 1 3220 | 1 3221 | 1 3222 | 1 3223 | 1 3224 | 1 3225 | 1 3226 | 1 3227 | 1 3228 | 1 3229 | 1 3230 | 1 3231 | 1 3232 | 1 3233 | 1 3234 | 1 3235 | 1 3236 | 1 3237 | 1 3238 | 1 3239 | 1 3240 | 1 3241 | 1 3242 | 1 3243 | 1 3244 | 1 3245 | 1 3246 | 1 3247 | 1 3248 | 1 3249 | 1 3250 | 1 3251 | 1 3252 | 1 3253 | 1 3254 | 1 3255 | 1 3256 | 1 3257 | 1 3258 | 1 3259 | 1 3260 | 1 3261 | 1 3262 | 1 3263 | 1 3264 | 1 3265 | 1 3266 | 1 3267 | 1 3268 | 1 3269 | 1 3270 | 1 3271 | 1 3272 | 1 3273 | 1 3274 | 1 3275 | 1 3276 | 1 3277 | 1 3278 | 1 3279 | 1 3280 | 1 3281 | 1 3282 | 1 3283 | 1 3284 | 1 3285 | 1 3286 | 1 3287 | 1 3288 | 1 3289 | 1 3290 | 1 3291 | 1 3292 | 1 3293 | 1 3294 | 1 3295 | 1 3296 | 1 3297 | 1 3298 | 1 3299 | 1 3300 | 1 3301 | 1 3302 | 1 3303 | 1 3304 | 1 3305 | 1 3306 | 1 3307 | 1 3308 | 1 3309 | 1 3310 | 1 3311 | 1 3312 | 1 3313 | 1 3314 | 1 3315 | 1 3316 | 1 3317 | 1 3318 | 1 3319 | 1 3320 | 1 3321 | 1 3322 | 1 3323 | 1 3324 | 1 3325 | 1 3326 | 1 3327 | 1 3328 | 1 3329 | 1 3330 | 1 3331 | 1 3332 | 1 3333 | 1 3334 | 1 3335 | 1 3336 | 1 3337 | 1 3338 | 1 3339 | 1 3340 | 1 3341 | 1 3342 | 1 3343 | 1 3344 | 1 3345 | 1 3346 | 1 3347 | 1 3348 | 1 3349 | 1 3350 | 1 3351 | 1 3352 | 1 3353 | 1 3354 | 1 3355 | 1 3356 | 1 3357 | 1 3358 | 1 3359 | 1 3360 | 1 3361 | 1 3362 | 1 3363 | 1 3364 | 1 3365 | 1 3366 | 1 3367 | 1 3368 | 1 3369 | 1 3370 | 1 3371 | 1 3372 | 1 3373 | 1 3374 | 1 3375 | 1 3376 | 1 3377 | 1 3378 | 1 3379 | 1 3380 | 1 3381 | 1 3382 | 1 3383 | 1 3384 | 1 3385 | 1 3386 | 1 3387 | 1 3388 | 1 3389 | 1 3390 | 1 3391 | 1 3392 | 1 3393 | 1 3394 | 1 3395 | 1 3396 | 1 3397 | 1 3398 | 1 3399 | 1 3400 | 1 3401 | 1 3402 | 1 3403 | 1 3404 | 1 3405 | 1 3406 | 1 3407 | 1 3408 | 1 3409 | 1 3410 | 1 3411 | 1 3412 | 1 3413 | 1 3414 | 1 3415 | 1 3416 | 1 3417 | 1 3418 | 1 3419 | 1 3420 | 1 3421 | 1 3422 | 1 3423 | 1 3424 | 1 3425 | 1 3426 | 1 3427 | 1 3428 | 1 3429 | 1 3430 | 1 3431 | 1 3432 | 1 3433 | 1 3434 | 1 3435 | 1 3436 | 1 3437 | 1 3438 | 1 3439 | 1 3440 | 1 3441 | 1 3442 | 1 3443 | 1 3444 | 1 3445 | 1 3446 | 1 3447 | 1 3448 | 1 3449 | 1 3450 | 1 3451 | 1 3452 | 1 3453 | 1 3454 | 1 3455 | 1 3456 | 1 3457 | 1 3458 | 1 3459 | 1 3460 | 1 3461 | 1 3462 | 1 3463 | 1 3464 | 1 3465 | 1 3466 | 1 3467 | 1 3468 | 1 3469 | 1 3470 | 1 3471 | 1 3472 | 1 3473 | 1 3474 | 1 3475 | 1 3476 | 1 3477 | 1 3478 | 1 3479 | 1 3480 | 1 3481 | 1 3482 | 1 3483 | 1 3484 | 1 3485 | 1 3486 | 1 3487 | 1 3488 | 1 3489 | 1 3490 | 1 3491 | 1 3492 | 1 3493 | 1 3494 | 1 3495 | 1 3496 | 1 3497 | 1 3498 | 1 3499 | 1 3500 | 1 3501 | 1 3502 | 1 3503 | 1 3504 | 1 3505 | 1 3506 | 1 3507 | 1 3508 | 1 3509 | 1 3510 | 1 3511 | 1 3512 | 1 3513 | 1 3514 | 1 3515 | 1 3516 | 1 3517 | 1 3518 | 1 3519 | 1 3520 | 1 3521 | 1 3522 | 1 3523 | 1 3524 | 1 3525 | 1 3526 | 1 3527 | 1 3528 | 1 3529 | 1 3530 | 1 3531 | 1 3532 | 1 3533 | 1 3534 | 1 3535 | 1 3536 | 1 3537 | 1 3538 | 1 3539 | 1 3540 | 1 3541 | 1 3542 | 1 3543 | 1 3544 | 1 3545 | 1 3546 | 1 3547 | 1 3548 | 1 3549 | 1 3550 | 1 3551 | 1 3552 | 1 3553 | 1 3554 | 1 3555 | 1 3556 | 1 3557 | 1 3558 | 1 3559 | 1 3560 | 1 3561 | 1 3562 | 1 3563 | 1 3564 | 1 3565 | 1 3566 | 1 3567 | 1 3568 | 1 3569 | 1 3570 | 1 3571 | 1 3572 | 1 3573 | 1 3574 | 1 3575 | 1 3576 | 1 3577 | 1 3578 | 1 3579 | 1 3580 | 1 3581 | 1 3582 | 1 3583 | 1 3584 | 1 3585 | 1 3586 | 1 3587 | 1 3588 | 1 3589 | 1 3590 | 1 3591 | 1 3592 | 1 3593 | 1 3594 | 1 3595 | 1 3596 | 1 3597 | 1 3598 | 1 3599 | 1 3600 | 1 3601 | 1 3602 | 1 3603 | 1 3604 | 1 3605 | 1 3606 | 1 3607 | 1 3608 | 1 3609 | 1 3610 | 1 3611 | 1 3612 | 1 3613 | 1 3614 | 1 3615 | 1 3616 | 1 3617 | 1 3618 | 1 3619 | 1 3620 | 1 3621 | 1 3622 | 1 3623 | 1 3624 | 1 3625 | 1 3626 | 1 3627 | 1 3628 | 1 3629 | 1 3630 | 1 3631 | 1 3632 | 1 3633 | 1 3634 | 1 3635 | 1 3636 | 1 3637 | 1 3638 | 1 3639 | 1 3640 | 1 3641 | 1 3642 | 1 3643 | 1 3644 | 1 3645 | 1 3646 | 1 3647 | 1 3648 | 1 3649 | 1 3650 | 1 3651 | 1 3652 | 1 3653 | 1 3654 | 1 3655 | 1 3656 | 1 3657 | 1 3658 | 1 3659 | 1 3660 | 1 3661 | 1 3662 | 1 3663 | 1 3664 | 1 3665 | 1 3666 | 1 3667 | 1 3668 | 1 3669 | 1 3670 | 1 3671 | 1 3672 | 1 3673 | 1 3674 | 1 3675 | 1 3676 | 1 3677 | 1 3678 | 1 3679 | 1 3680 | 1 3681 | 1 3682 | 1 3683 | 1 3684 | 1 3685 | 1 3686 | 1 3687 | 1 3688 | 1 3689 | 1 3690 | 1 3691 | 1 3692 | 1 3693 | 1 3694 | 1 3695 | 1 3696 | 1 3697 | 1 3698 | 1 3699 | 1 3700 | 1 3701 | 1 3702 | 1 3703 | 1 3704 | 1 3705 | 1 3706 | 1 3707 | 1 3708 | 1 3709 | 1 3710 | 1 3711 | 1 3712 | 1 3713 | 1 3714 | 1 3715 | 1 3716 | 1 3717 | 1 3718 | 1 3719 | 1 3720 | 1 3721 | 1 3722 | 1 3723 | 1 3724 | 1 3725 | 1 3726 | 1 3727 | 1 3728 | 1 3729 | 1 3730 | 1 3731 | 1 3732 | 1 3733 | 1 3734 | 1 3735 | 1 3736 | 1 3737 | 1 3738 | 1 3739 | 1 3740 | 1 3741 | 1 3742 | 1 3743 | 1 3744 | 1 3745 | 1 3746 | 1 3747 | 1 3748 | 1 3749 | 1 3750 | 1 3751 | 1 3752 | 1 3753 | 1 3754 | 1 3755 | 1 3756 | 1 3757 | 1 3758 | 1 3759 | 1 3760 | 1 3761 | 1 3762 | 1 3763 | 1 3764 | 1 3765 | 1 3766 | 1 3767 | 1 3768 | 1 3769 | 1 3770 | 1 3771 | 1 3772 | 1 3773 | 1 3774 | 1 3775 | 1 3776 | 1 3777 | 1 3778 | 1 3779 | 1 3780 | 1 3781 | 1 3782 | 1 3783 | 1 3784 | 1 3785 | 1 3786 | 1 3787 | 1 3788 | 1 3789 | 1 3790 | 1 3791 | 1 3792 | 1 3793 | 1 3794 | 1 3795 | 1 3796 | 1 3797 | 1 3798 | 1 3799 | 1 3800 | 1 3801 | 1 3802 | 1 3803 | 1 3804 | 1 3805 | 1 3806 | 1 3807 | 1 3808 | 1 3809 | 1 3810 | 1 3811 | 1 3812 | 1 3813 | 1 3814 | 1 3815 | 1 3816 | 1 3817 | 1 3818 | 1 3819 | 1 3820 | 1 3821 | 1 3822 | 1 3823 | 1 3824 | 1 3825 | 1 3826 | 1 3827 | 1 3828 | 1 3829 | 1 3830 | 1 3831 | 1 3832 | 1 3833 | 1 3834 | 1 3835 | 1 3836 | 1 3837 | 1 3838 | 1 3839 | 1 3840 | 1 3841 | 1 3842 | 1 3843 | 1 3844 | 1 3845 | 1 3846 | 1 3847 | 1 3848 | 1 3849 | 1 3850 | 1 3851 | 1 3852 | 1 3853 | 1 3854 | 1 3855 | 1 3856 | 1 3857 | 1 3858 | 1 3859 | 1 3860 | 1 3861 | 1 3862 | 1 3863 | 1 3864 | 1 3865 | 1 3866 | 1 3867 | 1 3868 | 1 3869 | 1 3870 | 1 3871 | 1 3872 | 1 3873 | 1 3874 | 1 3875 | 1 3876 | 1 3877 | 1 3878 | 1 3879 | 1 3880 | 1 3881 | 1 3882 | 1 3883 | 1 3884 | 1 3885 | 1 3886 | 1 3887 | 1 3888 | 1 3889 | 1 3890 | 1 3891 | 1 3892 | 1 3893 | 1 3894 | 1 3895 | 1 3896 | 1 3897 | 1 3898 | 1 3899 | 1 3900 | 1 3901 | 1 3902 | 1 3903 | 1 3904 | 1 3905 | 1 3906 | 1 3907 | 1 3908 | 1 3909 | 1 3910 | 1 3911 | 1 3912 | 1 3913 | 1 3914 | 1 3915 | 1 3916 | 1 3917 | 1 3918 | 1 3919 | 1 3920 | 1 3921 | 1 3922 | 1 3923 | 1 3924 | 1 3925 | 1 3926 | 1 3927 | 1 3928 | 1 3929 | 1 3930 | 1 3931 | 1 3932 | 1 3933 | 1 3934 | 1 3935 | 1 3936 | 1 3937 | 1 3938 | 1 3939 | 1 3940 | 1 3941 | 1 3942 | 1 3943 | 1 3944 | 1 3945 | 1 3946 | 1 3947 | 1 3948 | 1 3949 | 1 3950 | 1 3951 | 1 3952 | 1 3953 | 1 3954 | 1 3955 | 1 3956 | 1 3957 | 1 3958 | 1 3959 | 1 3960 | 1 3961 | 1 3962 | 1 3963 | 1 3964 | 1 3965 | 1 3966 | 1 3967 | 1 3968 | 1 3969 | 1 3970 | 1 3971 | 1 3972 | 1 3973 | 1 3974 | 1 3975 | 1 3976 | 1 3977 | 1 3978 | 1 3979 | 1 3980 | 1 3981 | 1 3982 | 1 3983 | 1 3984 | 1 3985 | 1 3986 | 1 3987 | 1 3988 | 1 3989 | 1 3990 | 1 3991 | 1 3992 | 1 3993 | 1 3994 | 1 3995 | 1 3996 | 1 3997 | 1 3998 | 1 3999 | 1 4000 | 1 4001 | 1 4002 | 1 4003 | 1 4004 | 1 4005 | 1 4006 | 1 4007 | 1 4008 | 1 4009 | 1 4010 | 1 4011 | 1 4012 | 1 4013 | 1 4014 | 1 4015 | 1 4016 | 1 4017 | 1 4018 | 1 4019 | 1 4020 | 1 4021 | 1 4022 | 1 4023 | 1 4024 | 1 4025 | 1 4026 | 1 4027 | 1 4028 | 1 4029 | 1 4030 | 1 4031 | 1 4032 | 1 4033 | 1 4034 | 1 4035 | 1 4036 | 1 4037 | 1 4038 | 1 4039 | 1 4040 | 1 4041 | 1 4042 | 1 4043 | 1 4044 | 1 4045 | 1 4046 | 1 4047 | 1 4048 | 1 4049 | 1 4050 | 1 4051 | 1 4052 | 1 4053 | 1 4054 | 1 4055 | 1 4056 | 1 4057 | 1 4058 | 1 4059 | 1 4060 | 1 4061 | 1 4062 | 1 4063 | 1 4064 | 1 4065 | 1 4066 | 1 4067 | 1 4068 | 1 4069 | 1 4070 | 1 4071 | 1 4072 | 1 4073 | 1 4074 | 1 4075 | 1 4076 | 1 4077 | 1 4078 | 1 4079 | 1 4080 | 1 4081 | 1 4082 | 1 4083 | 1 4084 | 1 4085 | 1 4086 | 1 4087 | 1 4088 | 1 4089 | 1 4090 | 1 4091 | 1 4092 | 1 4093 | 1 4094 | 1 4095 | 1 4096 | 1 4097 | 1 4098 | 1 4099 | 1 4100 | 1 4101 | 1 4102 | 1 4103 | 1 4104 | 1 4105 | 1 4106 | 1 4107 | 1 4108 | 1 4109 | 1 4110 | 1 4111 | 1 4112 | 1 4113 | 1 4114 | 1 4115 | 1 4116 | 1 4117 | 1 4118 | 1 4119 | 1 4120 | --------------------------------------------------------------------------------