go back

I will convert this photo to an ascii picture using R base.

This requires several step. 1. Import the photo on R 2. Reduce the size of the picture 3. Reduce the number of colors to 10 shades of gray 4. Replace every gray pixel by an ascii character with an equivalent grayness 5. Export the output on a text file I used GIMP to export my photo into PPM ascii format. I could have used a regular format and parsed the bits of my photos but it's a lot easier with the minimalist and ascii based PPM format. A PPM image file starts with "P3", a code to indicate a RGB ascii PPM format; then 2 integers to indicate the width and the height of the image in pixels; then the number of possible colors. For instance, if you enter 255, it's mean that every pixel is defined by a red, a green and a blue value that goes from 0 to 255. So there are 256*256*256 possible colors. And finally a list of set of 3 integers that contains the RGB values of the pixels of your image. In regexp like code, the structure of your image file is the following: P3[\n\s][0-9]+\s[0-9]+[\n\s][0-9]+[\n\s]([0-9]+\s[0-9]+\s[0-9]+)+ I open my image of Petronas tower kl.jpg in GIMP and resized it to only 2 pixels. Then I export it to the PPM ascii format and I obtain a file kl_pixel.ppm containing the following text: P3 # Created by GIMP version 2.10.6 PNM plug-in 2 1 255 119 124 124 143 148 149 First of all I create a function that will read this ppm file and stock it into a list that contains a string with the format of the image, here "P3", a vector that contains the width and the height of the image, an integer with the precision of colors, and a matrix with 3 columns, one for the red coordonates of the pixel, one for the green and one for the blue. fn_import_ppm_p3=function(p_source){ v_img_raw=readLines(p_source) v_img_raw=strsplit(paste(v_img_raw[substr(v_img_raw,1,1)!="#"],collapse=" ")," ")[[1]] list(fmt=v_img_raw[1], siz=as.numeric(v_img_raw[2:3]), col=as.numeric(v_img_raw[4]), img=matrix(as.numeric(v_img_raw[-(1:4)]),nc=3,b=T))} Let's try our function: > fn_import_ppm_p3("kl_pixel.ppm") $fmt [1] "P3" $siz [1] 2 1 $col [1] 255 $img [,1] [,2] [,3] [1,] 119 124 124 [2,] 143 148 149 I also create an export function to use my list to write a text file in the ppm format. I can then open the file with a graphic application like gimp and convert it into a more regular format. pr_export_ppm=function(p_img,p_out){ s_img_raw=paste(p_img$fmt,paste(c(p_img$siz,p_img$col,c(t(p_img$img))),collapse=" ")) #add the right extention according to the format type (PPM, PGM, PBM) s_out_ext=c("ppm","pgm","pbm")[c("P3","P2","P1")==p_img$fmt] s_out_filename=paste(p_out,".",s_out_ext,sep="") writeLines(s_img_raw,s_out_filename)} Let's try it: l_img=list(fmt="P3", siz=c(2,3), col=2, img=rbind(c(0,0,0),c(1,0,0),c(1,1,1),c(0,1,0),c(2,2,2),c(0,0,1))) pr_export_ppm(l_img,"test_export_ppm") And I obtained this marvellous image: Now, let's take kl.jpg (700Ko) and I use GIMP to export it in PPM ascii format. This gives me kl.ppm with 38Mo! PPM ascii format is maybe the simplest image format but definitively not the lightest! I first need to drastically reduce the size of my image. Its size is actually 2560*1536 pixels. I want to reduce the width to 225 pixels. And as a pixel is a square but not a rectangular letter... So I need to reduce the height a bit more, up to (1536*224/2560)/2.0149 = 67. To do this, I will use the smooth.spline function. Let's suppose on the width, I have 10 pixels with the various values of red. I want to reduce the size to 6. I first draw a smooth curve based on the 10 values. Then I take 6 equidistant points on this curve and I get my 6 values of red! # function to force value to be between 0 and 255 fn_limit=function(p_vec,p_min=0,p_max=255)c(apply(matrix(p_vec),1,function(x)min(max(x,p_min),p_max))) set.seed(1) v_old_red_pixels=ceiling(runif(10,0,256)) plot(v_old_red_pixels,col="blue",ylim=c(0,260),ylab=NA,xlab=NA) l_smooth=smooth.spline(v_old_red_pixels,df=10) lines(seq(1,10,0.01),fn_limit(predict(l_smooth,seq(1,10,0.01))$y)) v_new_red_pixels=list(x=seq(1,10,l=6),y=fn_limit(predict(l_smooth,seq(1,10,l=6))$y)) points(v_new_red_pixels,col="green") legend(x="bottom",legend=c("old pixels' red values","new pixels' red values","smooth spline curve"), pch=c(1,1,NA), lty=c(NA,NA,1),col=c("blue","green","black")) I use the same method to build a function that will be able to resize my image. fn_resize=function(p_img, p_size=50000, p_ratio_width_height=1){ fn_limit=function(p_vec,p_min=0,p_max=255)c(apply(matrix(p_vec),1,function(x)min(max(x,p_min),p_max))) fn_reduce_vector=function(p_vec,p_new_size){ l_resized_vect=predict(smooth.spline(p_vec,df=length(p_vec)),seq(1,length(p_vec),l=p_new_size))$y round(fn_limit(l_resized_vect))} l_ratio=(p_size/(p_img$siz[1]*p_img$siz[1]))^0.5 l_new_width=ceiling(p_img$siz[1]*l_ratio) l_new_height=ceiling(p_img$siz[2]*l_ratio/p_ratio_width_height) list( fmt=p_img$fmt, siz=c(l_new_width,l_new_height), col=p_img$col, img=apply(p_img$img,2, function(x)c(t(apply(t(apply(matrix(x,nc=p_img$siz[1],byr=T),1, function(x)fn_reduce_vector(x,l_new_width))),2, function(x)fn_reduce_vector(x,l_new_height))))))} pr_export_ppm(fn_resize(fn_import_ppm_p3("kl.ppm")),"kl_small_spline") Let's see what we get: It isn't so bad! Now, we have to reduce the number of colors. We have actually in our picture up to 256*256*256 colors. We want to reduce it to a few number of colors. To do that, we implement the Floyd–Steinberg dithering algorithm. The idea is the following, you have a pallet of colors, for instance, only black and white. You take the first pixel of your image, you replace it by the closest color in the pallet. Then you propagate the "error" you made replacing the pixel by a color of the pallet to the neighbouring pixels. Then you repeat the same steps for the second pixels and so on. In practice it gives that. fn_dithering=function(p_img, p_color){ m_fsd_wht=matrix(c(0,0,7/16,3/16,5/16,1/16),nc=3,nr=2,b=T) l_rgb=list(r=matrix(p_img$img[,1],nc=p_img$siz[1],b=T), g=matrix(p_img$img[,2],nc=p_img$siz[1],b=T), b=matrix(p_img$img[,3],nc=p_img$siz[1],b=T)) m_rgb_dit=p_img$img for (i in 1:(p_img$siz[2])){for(j in 1:(p_img$siz[1])){ v_pix=c(l_rgb$r[i,j],l_rgb$g[i,j],l_rgb$b[i,j]) v_dist_pix_color=unlist(lapply(p_color, function(col)(v_pix[1]-col[1])^2+(v_pix[2]-col[2])^2+(v_pix[3]-col[3])^2)) v_closest_color=p_color[v_dist_pix_color==min(v_dist_pix_color)][[1]] if(i!=1&&i!=p_img$siz[2]&&j!=1&&j!=p_img$siz[1]){ l_rgb$r[0:1+i,-1:1+j]=l_rgb$r[0:1+i,-1:1+j]+m_fsd_wht*(v_pix-v_closest_color)[1] l_rgb$g[0:1+i,-1:1+j]=l_rgb$g[0:1+i,-1:1+j]+m_fsd_wht*(v_pix-v_closest_color)[2] l_rgb$b[0:1+i,-1:1+j]=l_rgb$b[0:1+i,-1:1+j]+m_fsd_wht*(v_pix-v_closest_color)[3]} m_rgb_dit[(i-1)*p_img$siz[1]+j,]=v_closest_color}} list(fmt="P3",siz=p_img$siz,col=p_img$col,img=m_rgb_dit)} I test it with a 10 shades of gray pallet: l_pallet=list(rep(0,3),rep(28,3),rep(57,3),rep(85,3),rep(113,3),rep(142,3), rep(170,3),rep(198,3),rep(227,3),rep(255,3)) pr_export_ppm(fn_dithering(fn_import_ppm_p3("kl_small.ppm"),l_pallet),"kl_dit") And now, all I have to do is to replace these 10 shades of gray by an ascii equivalent and export it into a text / html file: pr_export_to_ascii=function(p_img,p_out){ l_pallet=list(rep(0,3),rep(28,3),rep(57,3),rep(85,3),rep(113,3),rep(142,3), rep(170,3),rep(198,3),rep(227,3),rep(255,3)) t_grayscale=data.frame(gray=c(0,28,57,85,113,142,170,198,227,255), ascii=c("@","%","#","*","+","=","-",":","."," ")) l_img=fn_dithering(fn_resize(p_img,100000,2.0149),l_pallet) v_img_ascii=c(l_img$img[,1]) for(i in 1:10)v_img_ascii[v_img_ascii==t_grayscale[i,"gray"]]=as.character(t_grayscale[i,"ascii"]) v_img_ascii=apply(matrix(v_img_ascii,nc=l_img$siz[1],b=T),1,function(x)paste(x,collapse="")) writeLines(c('<pre style="font-family:monospace;font-size:3;">',v_img_ascii,"</pre>"), paste(p_out,".html",sep=""))} pr_export_to_ascii(fn_import_ppm_p3("kl.ppm"),"kl_ascii") And this gives us our ascii art verion of Petronas tower! --------------------------------:::::::::::::::::::::::::::::::::::::::::::..::::::..=#*===*#*: .:::..:.....................................::...........:::::::::::::::::::::::::::::..............::::::::::::::::::.............................................................................:::::::::::............... -----:--:--:--:--:-:-:-:-:-:-:-:-:-::-::-:::::::::::::::::::::::-::::.:::--=++*#####*#*#**#****++--:::..:..:..:..:..:..:....................:..:.:.:.:.:.:.:.::.::.:::.::.:.:.:.:.:.:.:..:..:..:.:.:.:.:.::::::::::.::.:.:....:.:..:................:................:.:..........................:.:.:.:.:.:.:........:...:. ---:--:--:--:--:-:--:--:-:-:-:-:-::-::-:::-::::-::-:-:::::::::---==+*#######*#*****#**#*###*#****##*==-:.:..:..:..:..:..:.:..................:.:..:.:.:.:.:::.::.::.:.::.::.::.::.:.:.:.:..:..:.:.::::.::.:.:.:.:.::.:.:..:.:...:.:..:.:...:.:.:.:.:..:...:.:.:::::-:::.::.:.......... . . .....:.:.:..:.:.:.:.:.:..:...:.:.. --:--:--:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:::::-:-::::::::-=++*##%###*#*#**###*##*####*##*#*#**##***#***#**=-::..:...:.:..:........... ........:....:..:...:.:..::.:.:.:::.::.:.:.:.:.:.:.:..:..:.:.:.:.:.::::::::::::.::.:.:....:.:.:.::.:..:....:..:..:.:-=-==+******++++**++++==-:.. . ....................:.:.:..:.:.:..:.: ----:-:-:--:-:-:--:-:-:-:-::::-:---:-::::::--=++*#*########*#*##*####*########*#*##*#*#*#*#**#*#******##*=-:...:.........:...... .............:..:...:...:.:.:.::.:.:.:.:.:.:..:.:.:..:.:.:..:.:.::.:::.:.:.::.::::.:..:..:.:.:.::.:.:.:...:.:.::.::-=+**####*##******#***##****#*****++==-::... . .....:.:.......:..::.::::: --:---:-:-:-:-:-:-:-:-:-:-:--::::---=++*##%####**#*#*#######*##*###*####*#***##*#****#******#****#*******#+=::..:...:..:...................:...:...:...:.:.:..:.::::.:::.:.:.:...:.:.:.:.:.:.:.:.:.::.::::::::::.:.:.:...:...:.:.::.:.:.:.:.::.::-=+*######****+*+****+***++*****#*#******#*####***==--:...........:.:.:::::: ---:-:-:-:-:-:----:-::::--=++###########*#*###%##**##%#***###***%#*+###+*#%++#*+*#******#******#***#******#*=::...:.....................:.:..:..:.:.......:.:.::.:.::.:.::.:..:.:..:.:.:.:..:.:.:::.:::.::::.::.:::.:.:....:.:.:.:.:.:.::.::..--=+#%##%**#+**#++**=+**==+*+-***=+*#+++*#*++*##****###****##*#*++==--:.....::: -:------:::::----++**##%##%##*#*#*##%####**#%###**####*+**##*++##*+*##++***+*#*+***+***+*******************#*=-.:...:.......................:.:..:....:.:..:.:.:.::.::::.:..:....:.:.::.:.::.::.:.::::::::.:::::.:.:.:.:.:.:..:.:.:.:::.:::.:-=+#%####*#*+**++*+++*+=**==*+=++*+=+**==+#*=+++**+=+****++**###***######****+++ --:-:-==+**####%#################%##****#%##**+*#%#+++*##*+=*##+=+##==*#*=+#*=+#++**++**+*+*+***+******#***#**=:..:...:.................:.:....:..:.:..:.:.:..:.:::::.:.:.:...:...:.:.::::.::.:::::.::.::::::.:::.:.:..:.:.::.:..:.::.:::.::-+*%######*+***+*+**++++*==#*-*#+=+**+-+*#+-=**+===*#+++++*#+=++++***++***##****# ##%#%##***###%#%%%%##**+*#*#%%%%*+=+**#%%*===*###+=-+#%*+==##*==*%*-=*#+-*%==**-+*++**=+**+**+**************##+-:................ ...........:..:..:.:.:.:.:.:::.:.:::.::.:.:...:.:.:.:..::.:::.:.:::::::.::.:.:.:.:.:.:.:.:.:.::.:.:::::::=+*#%####**+***++**++**=+*+=+**=+**-=*#+==#*+==*##+-=*#*===+*%*=-=+*###+-=++*###+= #*#*#####%%%%###******##%###+++++*###*+=++*##*+-=*##*+-=*#*+=+*#+-=##+-+#+-**=+**=*+++**++*+*++++*+******#**#**-:..:...:..........................:.:.:..:.:.:.:.:::.::.:....:.:.:.:.::::.::.:::::::.::.:::.:::..:...:..:.:.:::.::::::::::-+*%%####**+**++**++**=+#+=**+++**=+#*=+*#*-=*#*==+*#+==***#+==*#*+++==*#*+=++=+**% #%%%%%%##*++**++##%%#**+++==*#%#*+*+==*%#*+=++*##*==+*##+==*#+==*#*=-+#+-+#==**=+*++*+++*+++++**+*+******#**##*=-....:....:.........................:..:....:..:.:.::.:.:.::.:.:.:.:.:..::.:::.:::.::::::.:::.::.:.:..::.:::.:::::::.::.:-=*#%####****++**+*+*=+*++***++**=+#*=+#*==+##+=+##+=+*##+==+##*==+*###+--*###**+-== #++++*+++**#%%#*++++=++#%%**+++==*#%*+++==*##+==++##+=-=#**==+**=-+*#==*#=-*#=+*+=**++*+++++*++++*******###*##**=::--...:........................:.:......:..:.:.::.:.:.:..:..:.:.:.::::.:::.:::.::::.:.::.:.:.:.::.:.:::.:::.:::.:::::::-+#%%#%#****+*+***++*++**+*+++*++*#+=#*+=*##+=*#*==*##*+=+##*+=*####=-+*##**+=+*##** *##%%##*++*+==+*##%#***+===*#%**+++=+*##+++=+*##++-=*#*+==+#*=-+#*+-+**==##==#+=+#==*+=++++++++******#*#*######*+++**+-....................................:...:.:.:.::.:.:.:.:.::.::.:.::.::::::::.::::.:::::..:-:.::.:-:.:::.::::::.:::=*#%####********++*++**=+#+=##=*#*=*#*++##+=*#*++*##*=+*##*++*##*+=+###**+=+###*+=*+ *+*+==+#%%##***#*=-=*#%#*+**+-=*%#++++=+##**+=-+#*#+==+**+=-+#*===*#==**+==*+=+#+-+*=+++++++***+****#*#####*##*+#*++**+=+++-:............................:..:.:.:.:.:.:.:.:.:.::.:::.::::::::.:::.::::.::::.:-===*#*--=+***:.:::::::::::-=*%%%###***+****++**+++#++*#++**++*#*=*#*=+##*++##*=+###*++*##*=+*%###+=+###**++*##* %##**+***+==+#%#**++**=-+%##*++++=*##**==-=#%*++=-+%*+=++*#+==+#*==+#+-+**=+*+==++++=+++++*+++*****###########**+*****#***++=-...:........................:..:.:.:.:.:.:.:.:.:.::.:.:::.:::.:::::::::::::-=+*+++**++++**#*++*++++**#*=:::=+%%#%#********+*+***++#*+**++#*=##+=##*+*##++*##++*#%*=+*##*+**#%*+==*%###*++#%#*#= *++##%#****++++++#%#***+==+*###**+=-+*%#***--*##++==*#*+=-+*#+==*#+-=*#=-*#--*+-+*==+*=++++******############*+***++****+****==-::........ ...........:.:..:.:.:.:.::.:.:.:::.:.:::::::::::::::::.:-::-+**#*++******+##*+=++=++****++**+-=+#%%##****+***+**++***+**++*#++#*++*%*=*#*++##*++#%*++*%%#++*#%**+*#%%#*+=*#%#***+* +**=-=#%#####*+*+--*###%#**=-=+####*++-=##**+-=*##*+--*#*++=+**=-+**==+*=-=*+=+*=-+*++++***+***#*##########*++*+++**#********+****=: .. ...........:.:..:.:.:.:.:.:.::::::.:.:::.:.:.:.::.::::::::=====+*#*+*#**++***+=+++++++++++*++**##**##%%##*****+*********++#*+#*+*#*+##+=*##++##*++#%*+*#%#+++#%#**+*%%**++#%####=+*#% ###*#*+=-=*%#####***=-+#####+*+=+*##**+=-+#%**+-=+#**+==*#*=-=*#+-=**=:+#=-**-=*+=*+++**+****#*#############*+**#***+==+*#*+****+++-:. .. ..........:.:.:..:.:.:.:.:.:.:.::::::::::::::::::::::.:-+##*#**==*#*+++++++*#++++++++++++*##*+++*##%%##*****++*+*+*************#+*##+*%#=*##*+*%#*++#%#++#%%**++%%#**+*%%##*++#%%%* ##*#%##**++=+*##*%#***=-+#*###**=-=*###**+-=###*===##*+=-+*#+==***--*#==+++-+**=+*+++**+*****######%###%#**++*##*****#*=+**+***++#*-.. .... ........:.:.::.:.:.::.::.::.::.::.::::.:::::::::.::::=+*++***##***#*++++++++++++*++++*##**++++++*#%%####***+++*+++****#%#**#*+*#**+##++#%*+*#%*+*%%*++##%**+#%%#*++#%###*+#%%##** -=#%*###%%***=:+#######*+=-+%#*##*+=+*###*+=-*##**--=##*===*#*--+#*==+*=:*#==*+=+*++******#*#####%######*+*#%#***++****#+=+**+******=. .. ... ....:..:.:.:.:.::.:.:.:.:::::::::.:::::.:.::.::::-=++****+*+*##+++#*+++*+*###*#*##**#*+++++++++###%%%####*+++*+****+**#*#%#*#%++##**###++#%*+*#%*+*#%%*+*#%##+**%%%#*+*#%####+# ***==*#*###*#**++=+##*#%**+=-*%**##*=-=*###*+--*##*+-=*#*+--+#*=-+**:=#*==*+=+*+*+******#*#####%####%##++###****+*++**##*+++****#*+*+:.. ..........:.:.:.::.:.:.::.:.:.:.:.:.::::::::::::::::.:+*#*+*##****+*#*+++*#++##**+++++*#*+=+++++++*++**+*%%##%###*++*++++*#*++##*#%*#%#*#%#**#%*+*#%#+*#%#*+*#%%#+*#%%##+*#%%%#*++#% %#**+-=+#####%%#*+=-+##*#%#**=-+##*##++=+*##**=-=###+=-=##+==+#*=-+#+==**=-*#=+#*+******##########%##*+#####**++++*+*#*+****++===+*++=: ... ........:.:.:.:.:.:.:.::.::.::::::::::.:::.::.::::-*#+++#####***++***+++*###++++++++++##*+=+++++*+++*++*%%#%%##%#***++++*+*#*+*%*#%#*#%#*#%##*#%#*+*%%***#%#***#%%#***#%%##***%%% %##%#**#=-*%+*####*++=*#**#%**+-=*####*+--*###*+==+##+=-+##+=-+#*==*#+:+#++*#++#*+*#***###*##%##%%**+*%####*+++++++##*++**++****#*++**=:..........:..:.:.:.:.:.:.:.::.::.:.:.::.::::.:::::::.-=*+=*#***###+=+++++**#**###++++++++++++##*=+++*++++++++*#%#%%%#%*###*+++***+*#++####%#*%%#*#%%**#%%**+#%%#**#%###+*%%%##*+#@%%# *####%#**+--*#####%##*--*#*####*+-=*#*##*=-+##*#=--+##*=-=##+==*#+--*#++#*+**+*#******#####%###%#*++#%###%**+++++*##*=+**++*+++***++**+:........:..:.:.:.:..:..:.:.:.:.::.::::::::::::::.::.::=+*#*+**++##+##*###***##+++##*+++++++++++*#**=+*+++++*+***#*#@%#%%#####*+*+*#*++##=#%#*%%##%%###%%##*#%%#*+#%%%**##%%%***%%%### *##*##%#%#**=++*#*##%#**-=*######+=-+#####=--*##**+=+##*=-=##+-=*#*+##++**##*****+**#*###%###%#*++#%#######+++++*##+=+*+++*+++*#*+++**+..:.::.:..:..:....:.:.:.:.::.:::.:::::.:::.:.::.:::.:-+**#**+++**++*###*++*+***#*+=+##*++++++++++++*%#***+*+++**+*#*+*%%%%%%###%#*=+*+*#*+*%++#%*##%###%%###%%%**#%%##**#@%##**#%%%##+ +:+####%##%#*+===##**%##*+--***#%#*+==*#*##+-=+#%#+=-+###==+##+-+###*########*****#*###%###%##++*%#######%*++++*##++++++++++**#**++**+-..::.::.::.:.:.::.:..:.:.:.::.:::.::.:::.::::.::.:.:.:=*+*#*+++++#++*####+++*+***##+=+##**+++*+++++=+*##*#**++*****++**+*%%%%%#%%##%%++**+#%++#%++##%##%%##%%%###%%%#**#%%%#**#@%%##+% **+=+##*####%#*+==*##*####*=-+##*#%*+-=+####*=-+##**==*##+==+#%#*###**%#*##++*#+**####%#%%#*++*#%###%#%##*++++*#*+==*+++++++**#**++++*+-:.:.:.::.:.:....:.:.:.:.::.::.::::::::::.:.:..:..:.:.:-+***#++++*+*######**+++++***#+=+##**++++++++**######*********+*#*+*###%%%%%%###%#=****##+*#%*+*%%##%%%##%%%%##%@%#%*+#@%#%#**% %%**+:+#**#%##%#*+-=*##*#%#*+=-*#*###+-=+####+=-+#%#+==+%#*+#####*#%*#%*+*#++**+#%##%##%##*+*##%##%###%#*+=++###==+*=+++++++*#*++##*++*+=:::::.:.:...:.:..:..:.:.:.:::.:.:.:.:.:.:..:.:..:..:-+**##***++++**#######**+++++***#+=+###*+*++*++*%%#########****+*+**+***###%%%%%%###%%+=*****##**@#*#%%%##%%%##%%%%%##%%%%%#*+%% #%@#**=-+##*###%%#+=-+*####%*+=-+####%*=-=####*=+*##*+-=*%##*###*#%#**%+-**++###*#%##%%*++*########%%#*+==++##*=+++++++++++*##==+++****+=::.::::.:.:....:..:..:.:.:.:.::.:.:.:.:..:.:..:...:=+*#*+++*++*##*#*+*%##*#**++++++**#*+=+*##*+**+=+**##%######*#*****++*+#***%#*#%#%%%%#%#####==##++%%*#%%#*#%%%##%%%%###%%%%###%%% %##%%##*==+#*######*+-+**###%#*=-+#####+=-=*#%#+-=+%######%#*##%#*%#==#*+*#***##%%##%#++**####%#%#%##*++=++##*==+++++++++=*#*+==+++***+=-.:::.:::.:.:.:..:..:.:.::.::.:.:.:.:...:.....:..:...=++++++++##*+++**++*%####*++++++++*##+=+*##*++#++****%%%#%####*******+**+*#*+#%##%%%%%%%#%%##%#=+##++#%%*#%%%##%%%%%#%@%%%###@%% ##%###%#*+-=*#*##%#%#+--+#**#%##+-=*####*+=*###*+-+#%###*##%#*#%*=##=+#*=*#**%%###%##*+*####%####%##*++++*##+==*+++++=+=++##+=++++**#*+-:::::::.::.:.:.:.:.:.:.:.:.:.:.:.:...:.:..:...........:+++=+*###+++++#*++*######*++++++++*##++=*#%*+*#==##+*%%%%######*#****#++**+*#+*%%##%%%%%%##%%###%*+*%%++#%%**%%%%##%%@%%#%%@%@ *#*#%##%%**=-=#####%##*=-=####%#*=-=*##%#+==+##%##*##%##*#%##*#%=:*%==##+#%###%#%%%*++####%##%##@%+=*++*###+=+++=++=+++=+##*+=++=+****=::.::.:::.:::.:.:.:..:.:.:.:..:.:..:.:...:...:...:......:+++++*#**++++=*#*=+####*#*+++=+++++*#**==*#%*=##++##+*#%%%########************#*+#@%%%%%%%%%%###%+*%#**#%%**#@%###%%%%##%%%%% *#**##%#%%##*=-*##*#%%##+==*##*%#*+=+###%#+-=*%%#%#*#%%#####*=*%*-*%++##*#%%#%%%#*==#%##%##%##%%*+++=+*###+-+++++++=+=++##*+==+++***+=-:::::::.:::.:::.:.:.:.:.:..:.:.:.:..:..:.......:........:=**=++*##*++++++*#+=*#####**+==+++++**##*==+#%**#***#***#%@%%##%#####***#**+#****%#++%@%%%%%%%%%%##%%*=+%%*+*%%%##%%%%##%@%@% =-##**#%##%%*+==+*####%#*+-=*#*#%%*+==####%%####%%#*##%###%*+-+#+-*#++%%#%###@*==+########%#%%%*++++++*%*==++++++++++++*##+==++=+*##**=-:.::.:::.:::.:::.::.:.:.:.:.:....:.......:............. -**++**###*++++++*##=+#%###****===+==+**##*+=*###*#**##%*=+%%%%#%#######*#**##+*#*+*#%*+*%%%%%%%%%%%%%%#%%##%%%#*+#%@%##%%@%# ++-+#####%#%%#*=-+####%##*=--*%###%*=-+##%%####%%#####%*-+##+=*%*+*%**#%##%%#+*##########%#%%%+=++==*##*+=***+++++++*+*##*==++=+******#+=-:.::.:::.:::.::.::.:.:.:.:.:.:....:.............. ... .-+***##+*#**+*++++*#*=+%####**++==++++*#*##*+=+#%####*+*%#=+#%@%%%#%######*##*###*###**#%%**#@%#%%%%%%%%%%%%%%%###%%%##%@%%% @*#=-*#*##%#%%##*-=##*#%%%#*=+*##%#%***#%#%%%**#%%####%*-=#*+=+#++#%%#%%%%%%*++#####%#%%##%%*=+*==*###*==+*******++++*##*==++=++*#*++***=:::::::.:::.::::::.::.:.:........:.............. ......-+**##*+++*#**++*++**#*+=#%####**+++++++=***##*+=+#%#*#%#++#%*+*#@%%%%%#%%#*%%+*##+###**#%*+%%%%%%%%%%%%%%%%%%%%%%%%%%##%@%%% #%#*+-=##*#%#%%%*+==*###%%#*+==#%##%%%*##%#%####%%*+=*%#=*##**###*##%##%%*=-+######%#%##%%*=+#=-***#%+=+*+====+++*****##+==++++****++++-:.::.:.::::::::.:.:::.::.::.:.:.:................... .. .-+#+++++++*#***++*+++%#+=+#%####*#*++++++**%%#%%*-+%%*####*++%%*+*%%%%#%%##%%+#@*+*##+*#%++#%#++#%@%#%%%%%%#%%%%#%%@%#%%%%%% @%%#*+==*%##%##%%#+-+#%##%%#*==+##%%%%#*#%#%%###%#*-=*#*-=%####%%%%%%%%*+###*#####%#%##%#**#+-+**###++++++==+=+******%#+=++=+++*#*+=++=-::.:::::::.::.::::::::.::..:..:........:.......... ........-++++++++*##++**+++*##*++*#####***++++***#%%%##%*-+###%##%%++*%%**#%%%%%#%%##@#*#%***%#++@%++#%%#**#@@%%%%%%%%%#%%%##%%@%% *#%%%#*++**###%%#%#*=+*%##%%%####%#%%%###%%%%#*+#%#++##*=*%###%##%#%%%#+=*###########%#%#*+==***###+==*#*+***++++=+*##*==+++==***+++++=:.::::::.::::::::::.:.::.:.:.:....:..:........... .... ......=+++++++++*#*+***++++##++*####%#*#**+++++###%###%+=+########%+=*#%##%%##%%#%%#*%%#*#%#*#%%**%%#**%%%%%%%%%%%%%%%%@%%#%%%% %%#%%%#*==*#*#%%#%%*+=+###%%%%%#*%##%%%###%%*==+#%#**#%%##%%#%%%#%@#=-#####%##%#%%%%%%@+==++*+*#%#+-=*#**###*#*+=++#%*+===++=+*#*+++++-::::.:::::::.:::.::::::::.:.:.:.:.............. ........ .. .:=+*++*+*+**##++##==**##*=+*%###%#*****++*#########*++#%##%%*#%%*++*#%%@%%#%%%#%%#*###+*%%++%%#+*%%%*+*#%@%%%%%%%%%%%%%%% #%%##%%#*+=+#%##%%%#*+=*#%#%%%%#*#%%%%%%###%#+=+##%*##%###%##%%#%%%#**###########%#%%+-+#+=+*###*+-+###******++++*#%#+=+=+==++**+++++=-:.:::::.:::::::::::::.:.::.:..:..:.:........ ...... . ...... .-**++*++*++##***##+=*#**#+=+####%#**+**#*#####%#%###*++#%#%#%%#*#%%*++#%%%%%%#%%##%%#**%%+*%%#**%%#**%%%%%##%@%@%@%%%@%% ##%#%%%%%#**%##%%%%%%%##%%##%%%%###%%%%*=+%%####%%%###%##%%%%#%@*-=#**####%#%#%%#%##*#%+-+#%#*##=-#####*=+===+++*#%#+==**+==+*#**++*+=:::::::::::::::::::.:::::.::.::.:.:..:......... .. ....... ....:*#+++++*+*+*##++*##+=+##%#+=#%#####*+=*%%#%%%#%%%%###*==##%##%#%#+*%%%**#%@%#%@#%%%%#%@###%%#*#%@#*#%@%***%%%%%%%%%%%%% @*#%%#%%%@%#**%##%%%%@%##%#%%%%#%###%%*+=+#%%%##%%#*%%##%###%%%%#*####%#%#%#%%%%%%%#+=+*###*##*=+*#%##++===+***##%#*==+**+++****+++++-:::::::::::::::.:::::::.:::::.:.:..:...:..... ....... . ... .. .:+#*++*+++*+*#**+*##*==##%#*=+#%##%##*+**#%%%%%%%%%%%#%#==#%*#%##%%%*+*%%%%%%@%%%%%%%%%%*%%%###@%##%@%%#%%%%%%#*#%@%@@@ *###%%%%%%@#**%##%%%%%%%###%#%%%%##%%#%#**#%%#*##%###%##%%%%#=-*##%%#%#####%###%#*-+##=+*####*==*##*##****#*#***#%#==+**++++##**++*+=::::::::::::::::::::::.::::.:.::.::.:............. .. ... ... ... .=+**++**++**#*****##*+*#%%#*=*%###%##+*######%#%%%%%#%%#++*%%##%%*##%%#++*#%%%@%%%%%%%%%@%%%%%%%%%%%%%%@%%%#*#%%%%@%% *###%%%#%%@%##*%%##%%%%%##%%%%%%%*##%#@%**%%+-=#%#*%%#%%#%%%%*##%#####%##%%%%%#####*-=#%####+-=####%#%###*++==*#%#++**+-=+**##*+*+*+=::::::::::::::::::::::::::.:::.:.:.:..:................ .. . .. .. .=**+**++*++*###+***###++####++####%###+**%%##%##%##%###%*++##%%%#%@#***%%%#**#@%%#%@%#%%%#%%@%%%%@%%%%%@%%%@@%%%%##* ##%###%%%%%@%%#%%#%%%%%%###%#%%%%###%%*==*%#++*%%*#%%%%%#==*%**%##%%##%%#%%#%%%*==*#*#%**##==*#%%%%####++===+*#%#*=**--++**##******=::.::.:::::.:.:.:.::.::.:.::::::::......:.::.:.:................ .. .=+*++***+**#*###*%#**##*+*##++*%##%%##*#*#%%%%%%%%#%%####*+=*#%#%%##%@%*+*%%%%%@%%%%%%@%%%%@%%%%@%%%%@%%%%%@%%%**#% %*%###%%%%%%@%#%%#%%%%%@%##%#%%%%#*#%##++*%%##%%%%%%##%%%*+*%%#%#%#%###%##%%*++#%*-=#%####+=+####*#*#*##*###*#%%*+====+****#**+***++=========-=====-==-==-=-=--=-----:--=+=-::::::::::::.:............ .. .=#*+**+*#=--+###*#%#++*%#*##*=+####%%%%%#%#%#%%#%%%%%%%%%##*=*%%#%%%%##%%%%#++*%%%%%%@%%%%@%#%@%%%%%@%%%%%%@%%%%@% %%*%%##%%%%%%@%#*%%#%%%%%#*#%%#@#++*%#+=+*%##%%###%#####%####*##%##%##%#%%%%#*+=+##%%#*##--*%##%#%%%%##**+=+#%%#==+*#*+*++*##*##%#######*#***#******+*++++++++++=+++===========+=+==========================+*#**##+=---=##***#%#*=+*#%%#*+*###%#%#%#%#%##%##%#%%%%#%###*=*%#%%%#%%%#++%%%%%%%%%@%%%%%%%%%@%%%%@%%%%%@%%%#%@% %%###%%%%%%%%%%#%#%#%%%%%#*#%%##*++####**#%%*#%%%%%%*==*#%##%%#%#%#%%##%%*+=*%#+=+#%**#*++*#%#%###****++++*##%*+=*##+=+***###*#%#**+*+*+*++*+++++++++++++=++=+=++=+++=++++++=+*******#*#*#*###########%#%%%%#%#%%%%%#*=--+#%#**#**%#+=+#%%*+*####%%%%%%%%%%%%%%%#%%%#%%*##+=*%##%%%%#%%%%%*+**%%%%%%@@%%%@%%%%%@%%#%%@@%#*#%% @%%%%%%##%%%%@%%#%%#%%%%%#**%%#%#+*#%#*#%%%%%%%#%%%%%%##%#*%%*#%###%#%%%%%#*==*%#######=-+#########%#%####*#%%*+*+=-=****#########################*###*#*##*##*#*#*#***********************+*+*++*++*++++++*#%##%##%%#+==-+*%%##%%++#%#*+*%#+=*%##%%%%%%#%#%#%#%%%#%%%%@%%%%*++#%%%%%%@%#**%%%%####%@%%%%%@%%%%@%%###@%%##%@% @@@%#%%#%%%@%%%%##%#%%%%%#+*#%#*+-+%%%#%%###%@%*++*%%###%###%##%%%%%%##*=+#%#=+*%####+=+#%%%%#######+++=+*#%#*+-=++*#**+**####%%###%##################################*++##*++*######*#*#*#*##*##*###################%%#+==*#%%%##%%*++*%%####+=#%*#%##%%%%%%#%%#%%#%%##%%#*##+++#%##@%#%%@%%##*+#%%#%@%%@%%%%%@%%%%%%@%**#%% %%%%###%%#%%%@%%#**%%%%#+=-+%%*+=+#%##*#%%%%%%%%*+*%%#*#%##%%##%###%%%%##==*##%#####+==*###**#######%#%###%%*++*##++=**+*#######%###%%%%##*#*#*#**#***#**#**#**#*#*#++*########++***#*#**#*##*#####*#########%#%%%%%%%%#**#%####%#####%*+=+#%%##++#%#%%#%%%#%%%%%%%%%%%%%%%%%%%%#+=#%%%%%%%%##*#@%#%%#*#@@%%%%@%%%%%@%%%##%@% %@%%%#%%%#%@%%%#*=+#%###+--+#%#####%##@%%#%%%#%%%#######%###%%%%%%%#++*###*=+%%*##*==+#%#%%%%######*+==*###%*=+*===*##*%#%###%#%######*##*##**#*****#***********#*++*#########*##****#*########*############%#%%%%%%%%%##%%#*#%%%%#%%#**#%%*+###**+*%##%%#%%**#%#%#%#%%#%%#%%%###%*=+%%#%@%#%%%%%%#***%%%%%@%%@@%%%%%@@%#%@%@ %%%@%%#%%%%%%%#+==+#%#%%#**#%####%%##%%%@#+=+*%%#####%#%###%%##%%%%%#+=+*##%%%#*%#==+*###**#########%#%##%#+==++*#****#*########***#*#####################%###%*+**#############**#**+##*#*#*#*#*#*##*########%###%%%#%%%###%#**#%%##%#%*++*%%#%##*++#%###%%**#*+*@%%%%%%%%%%%%%@#%@#==#%%%%%%@%%**#%%%#%%#%%%@%@%%@@%%%%%@@@ %%@%@%%%#%#%%%%%*+*#%%#*+=+#%#*##%%%%%%%%%%*+##%###%%%##%##%%%%%#*#%##%=-+#%#*##+=+*%%#%%%#%###%##*+=+###%#=*##*===*%#######%##*+-.:::::::::::::::::::::::::.-++=:::::-*##%+--:------=**+=====++++++*+*****########%#%%##%%####%###%%#%##%%%*=+*%%%#+**#%%%%%%%#+*%%##%#%%%#%%%%%%%#%%*=+#%#%@%%%%%@%%%##***%%#%@%%@%@%%%%@%@ %%@%%%#*#%%#%%#*=--#%###**###%%#%%%#%%%%#%%%###%#*#%#*#%%%%%%##%#+==###%%#%##*##=-*###############%%%###%#+==+=+**#****###%####=:.:::::.:::.:::::::::::::::-**-..::.:-+*##*##=-....... -+*=:.. .+##%%###%%#*##%###%%#%*++%%%##*##*=*####%%#####+*%@%%%%%@%%%@%%%%#%%#++*%%%%%%@%%%#+*%%@#%%@%%%@@%@%%%@%@ @%@%%%*-*%##@%#+=-=*%####*#%%%%@%#%%*=*###%%#*#%%##%%#%%%##%%%%%#%#*==*%#%####+++####%%%#%%#%##**==+*#%%#++*###*=+############*=:.::.:::::::::::::::::::-=*+-..:..:+**-. ....-*#+:... ....=**-...... . . . .=####%%#*#%%#**%###%##%%#*+=*%%%%#*+##%#%%%%%##*#%%#%%#%%%#%#%%%%##%%*++*%##%@%%%%@%%%%%##++*%#%@%%%%@@@ @%%%%#==+##%%%##*+*###%%%#@%#*#%%#%@#*+*#%#####%#*#%###%%%%%%+=*##%%#*#%%**%#+-=*########%#%%%#%####%##%*==++==**###***#%##%#**=::::::.::::::::::::::::=*+:.:..:+*+:....:.:.....:=**=:. ... :+#+- .. . . . . . . .+######%%#*#%%#####*%%#**%%###*###*=*####%%#####*+#%@%%%%%%%%%%%@%%%%%#*=*%%%@%%%@@%%#***%@%%%%%@@%@@%@ @%%%#*++*###%%#*==*%%%###%%%%@%%%@%#%@####%%##%%#%%%%#%%#%%%%%#+=+*#%%#%%#*#*=+#%%%%%%#%###*****+*###%%*++##%#*+**##%#########-:..:.:.:::.::::::::::-+*=:.:::+*+-..::.:.:..:...:...:=+*+-. .. .-+*=.. .. . . . . .=####%#*#%%####%######%%#**+*#%%%%%*+*%%%%%%#%%#**%%#%%%%%%%%%%%%%%##%##++#%#%%%@%%%%#%@%%%%%%#*#%@%@% %%%@%#+=+#%%%#*=++*%%%#%@%##%##%###%%%#*#%%%#%%%##%%##%%%#####%%*+=*%%#**%*=-+###%#%#%#######%%#%#%##%#+=++==++*#%%*+*%##%###*-::.::.:::::::.:::::-++=:::-+*+-..::.:..:.:.:.:......... :+**-.. ...=#+- . . . .+*####%%###%%#*##%*+*%%*#%%######*##++#%##%%%##*#%**%@%%@@%@%%%@%%%@%%%##++#%%%@%%%%@@%%%##***%@%%%@% %%%%#*===*#%#%%#*##%##%%%%%%%%+=+*##%%###%%###%###%%%%%%%*=+*##%%%%%%%*##*+=+#%%%%####*#****#**###*%%#*+*#%#****############*+-:.::.:::.::.:::::=+*-::-+**-::::::.:.::.:.:.:.:.......... ..=+*+-. .-+*+. . . . . . .+###%###%%#*#%%%######%%%**+*##%%%%##+*#%#%%%#%%#**#%%%%%%%%%%%%%%%%%%##%#==##%%%%%@%%@%#*#%@%#%%%%% #@%%%*===*#%#%%##%%%#*#%%%%%%%%#*#%%%%###%%%#%%%%%%%%%%%%%%#+++#%%%%####*+=*%###%#%%%%%%%@%%#*++*##%%+=++==+**####*+*#%%####*-:.::.::.::::::::=**-:-+*+=:.:::.::.:::.:::.:.:...:....... .. .-+*+-. :=**=. . . .=####%%#*#%%%#**#%#+*#%###%%####*###*+*#%##%%%%%*+#%##%%#%%%%%%%%@%@%@@%%@#=+#%#%%@@%%%%%@%#%%%##** #%%%%#***#%%#####%%%%@%%%@%%#%#%#**%%###%%%%#%%%#%%%###%##%%%*+*#%#*#%%*-+**#######%#%%%%#########%##++*####+=*%##*#%####%#**+:.:::::::::::-=*+-:+**-:::::::::::::.:::.::.:.:.:...... ... .. .. ..+**=. .-**+: . . :+#*####%%%#*%%%%%#*###%%%%#*++%%%%%%#*+##%%%%%%##%%++#%%%%%%%%%%%%%@%%%%%%@#+=+%%%%@%%%@%@%%#***%% #%%%#+==*#%%%%###%%##@#*####%%%%###%%%%#%%%##%%%%%%%%*=+*#%#%%%%%%%###*+=*%%%%%%%%%####****+++###%%#=++==+**%%###*+*%%######-::::::.:::::-+*+-=*#=-:::::::::::::.:::.::.::.:.:......... .. .. . . :-**+:..=**-. . . :=####%###%%%%#####%#+*%%#*#%%%####*##*++#%###%#%%%+*#%%%%%%%%%%%%%%%%%%%%#%%#*=*%%##%@@%@%%##%%@% #%%#*++=#%%#%%%%@%%#%%#*=+*##%%%%##%@%##%%%%%%%%#%%%%%%#++*#%%%%####*+-+%##%%%%%#%#%%%%%%%%%#%#%#%%*++%%%#+-+###*######%###*=-:.:::::::-+*+=+*+-:::::-::::::::::::::::.::.::.:.:.:....... .. . .. .. .=*#+-.:**+: . . :+###%#%%%##*%%%%#####%#%%@%##*++#%@%%%*+*%%%%%%%%#%%%*##%@%%@%@%@%@%@@%%@%%%%#*+*%%%%@@%%%%@@%#% #%%%%#**%%##%%%%%%%%%@%%#*#%#%%#*##%%##%%%%##%%%#%#%%#%%%#+*#%%#*#%#==+#######*######%#%%#%###*#%%*+++*#**#%####++#%#%####*+-::::::::=***+**=:-::-:-::-:-:::::::::.::.::.::.::.:...... . .... .. .. . . -+#*-:=**= :=#*#%%####%%######%%+*#%%#**#%%##%%%###+=#%%#%%%#%%%##%%%%%%%%@%%%@%%@%%%%%%#%%+=*%%#@%%@@%%@@% #%%%#%%%%%%%*#%%#%%@#*#%@%*#%%%%%#%%%%##%%%%%%%%#++*##%%%%%%%%%####*=+#%%%%%%%%%%%#%##***+++#%%%%#=+*#*++==*#%#**#####%###*=-::::::=+**#*=-::-:-::-:-:::::-:::::.:::::::::.::.:.:.:....... ......... . . .. :+**+=*#+- .. :+#####%%%%##%%%%%####%%#%%%%%%#++*#%%%%#=*%%#%%%%%%*#%%%#%%%%%%%%%%%%%%@%@%@%%%%*=*#%%#%@@%@%% #%%%%#%%%%%%@%%%%%%##@%%%###%%%%%#%%%%#%%%%#%%@%%%*+**##%%%%#%###*-=#%#%%%%%%%%%#%#%#%#%%%%%%#%##+++#####%####***#%%####%#+-:::::=+***+-:::-:::-:-:::-:-:-::::::::::.::.::::.:.:.:........... ...... . . . . .. :=##**#*-. :=**#%%###%%%%######%#*+#@%#*+*%@%#%%%##%*+*%%%#%%%%#%@#+*%%@%@%@%@%@%@%%@%%@%%#%%***%%%%@@%%% %%%%#*#@%#*#@%#+=*#*#%%%%###%%%###%%%%%%%%@%%@%###%%#++*%%%###%%*=+**####*#*#####%%%%%%##%##*%%%+=++==+*#*#%*+****##%%####+-::--+**+-:::-:-:-:-::-:-:-:-:::-:::::::::::::.:.:::.:.:.:............ .... . . . . . .=##***=: :+#%###%%%%###%%%%#####%%#%%%%%%%##**####*++%%##@%#%%%%*#%%%%%%%%%@%@%@%%%%%%@%#%%#*=*#@#%@@% @%#%%%@%%%%%@%%#*+*#%#%%%%##%%%%%%%%%%%%%@%#*#%#%%%%%%%%%%%%###*==*%%%%%%%%%%%%#%##***+++*#%%#%#=+##%%#+=+#%*++#%#**#####+-:-=+*+=:::::-::-::-:-:-:-:-::-:-::-::::::::::::::..:.:..:.:.:..:........... . . . . . .. . .-+*#*+-. :+#*#%%%##%%%%%#*+#%####*#@%%##+**#%%%%%%***#%%%%%%%@#*#%%%#%%%%%%%%%%@%@%@%@%@%@%%%#++#@%## %%@%%@%%%@%%#%@@%%###%%%%###%@%%#%%%@%%%%%%#*=+*#%%%%%%%#%%#*#+=+%##%%%%%%%%%#%%#%%%%%%%%%##%%*=+**##*##%%###*+*#%****###*+++*=::::::-:::-:-:-:-:-:-:-:-:-::-::-::::::::.:.::.:.:.:..:..:..:........ ... . . . . . . -+*#*-.:+#%###%%%%%#***+**#%#**#%%#**%%%#%%%%%#%%*++#%%#%%%%##%%#*+%@%@@%@@%@%@%%@%%@%@%%%#%#+*%%% #%#*%@#+%@%#%#*%@#*#%%%%%%#%%%%%%%%%%%#%%%#%@%#**##%%%@##*%%#==+*#######%%%%%%%%%#%###%####%%#+=+#*==++*#%#==+#%#%##**++**=--::::::-:::-:::-:-:-:-:-:-:-:-:-:-:::::::::::::.::.:.:.:..:..:...:........ .. . . . . . . .=*#++*#*%%%#%#******####%#*#%%%%@%%%%**++#%%%%#++%###%%%%%%@###%%@%%%@%%%@%@%%@%@%%@%%%%%%*=+% %%%@%#%%#*#%%%%@%###%%%%%###%@%#%%%@%%%%%%%##%%%#**%%%%#*#%*==+%%%%%@%@%#%####********###%%%#*++###%%*+**###*+####%%##*+++=-:-:::-:::-::-:-:-:-:-:-:-:-:-:-:::-:-:::::::.:::.:.:.:.:.:.:............ .. . . . . . . . . ... .-++**#%###*#**####%%%##%%***%%%#***#%%%%%%%#%*+#%%%%%%%%%#*#%%#%%%%%%%%%%%@%%%@%@@%%%@%%@#= *%%@%*++*#**%%%%@##%%%%%%%%%%@%%#%%%%%######%%%@%%%%%%%%#%#*+*##%%%%%%#%%%%%%%%@%@%%####%##%*=+##*#####%%*##++*%###%####%##+-.:::::-::-::::-::-::-:-:-:-:-:-:-::::-:::::::.::.:.:.:.:....:.............. ... .. . . . . . .. .. .+++*###**####%%%%%%%######%%%##%%%#%%#%#%##%#++#%%%#%@%%%%%%%**#%@@@@@@@@@@@%@%%@%@%@%#%@ %%@%@%%#++####%@%%#%%%%%@%%%%%@%%@%@%##*++#%#%%%%@%#%%#%#+-+#%%%%%%%#%%%#%##%#%#%%##%###%%%#+=*#*++=++###*==*%##%%###%#***=-::-:::::-:::-:-::-:-:-:-:--:-:-:-::-:::::::::::.::.:.:..:.:.:..:.............. .. . .. . . .. . ... . .=*+*###*##%%%%%%##%%##%%%%##%%@%#%#*++*#%@%%%*++%%##@%%#%%@%##%%%%%%%@%%%%%%@%@%@%@%@%%% %@#%%@%%%##%%%%%%##%%%%@###%@@%##%@%%%@%%%####%%%@%#*#%%+=+*########%#####%###%#%#%####%#%#*+**###%#**##%#*+*#%##%%####+::::-:::-:-:::-::::-::-:-:-:-:-:-:-::-:-:-::-::::.:::.::.:.:..:...:..:.......... .. . . . . ... ...... ... .+#%%#%%#%%%%%##%%%%%%##%***#%%%#**#%@%%%%%%%##**#%%%%%%%%%%**#%%%%%%%%%@%%%%%%%%@%%%@%# %@%##%%@%%#%#%%%@%##%%%%##%%%%%@@%%%%###%@%%##%%%%####%+-+%##%@%%@%@%@%@%%%%%***+++*%%##%#+=+####%##*%%#*#*+*#%####%%#*+::::::-::::-:-::-:::::::-:-:-:-:-:-:-:::::-::::::::.:::.:::.:..:.:..:.:.:........ .. . . .. .. ...... .. . ....=#%#%%%%%##%@%%%%###%####%%%%#%@%#%%%###%##%#*+*#@%%%%@%%#%%@%%#%%%@%@%@@@@@@@@@@@%@% @##%%%%@%##%%%%@%##%%%@%%#%%@%%##%#*#%%%%%%%%%%%%@%#%#+**##%%%%%%%%%%%%#%%%%%%%%%%%#%%#@%*++**++=+**#%%*==*#%##%%######=-:::-::-:-::::-:::-::-:::::-:-:-:-:-:--:-::::::::::::.:::.::.::...:..:.:.:........ ... .. ... .............. .. .:+##%#%#%%%%%%%#%%@#####%%##%@%%%##**+*#%@%@%#+*#%%##%@%#%%%%%**#%@%%@%%@%@%%%@%@%@@ -#%%%%@%%#%%%%%%@%%%%%%@%%%%%@@%*++**#%%%%%@@%%%%%%#*==+%%##%%%%%#%%%%%%%%#%#%##%######%#+=*#%%%%*++###%#++#%###%%#%#+-.::::::-:::-:-:::-:::::::-:-:-:-:-:-:-::-::-:::::::.::::::::.::.::..:.:..:..:............ ................. ...... -*###%%%%%%##%%%%%%%##%#***%%%%#**#%%%%##%%#%#*+#%%%@%%%%%@%%##%%@%@%@%@%%@%@%%%@%% ###%@%%@%##%%%%@%%#%@%@%%%@%@%@%@%###%##%%%%@%###%%#++*%#%%%########*#####%%#%#%###%%%%#++*####%###%%####++#%#%######*+-:::::::-:-:::-:-:::::::::-::-::-:-:::-:::-::-::::::::::.::.:::.:.::.:.:.:..........................................-+###%%%##%%%%%%%##%%####%%%%#%%%%%#%%%%#%%##%%++#%%%%%%@%%%##%%%%%%%%%%%%%%%%%%%% %*#%%%%%%##%%%%@%##%%%@%%#%%@%*##%@%%%%#%%%@%%#*%%*=+###%%%%@%@%@@%%%%%%%##**+++#####%%+=+*+++**###%%#+=+#%##%#%#####+-::::::-::-::-:::::-:-::-:::-::-:-::-:-::-:::::::::::::::::::::.:::.:.:.:.:.:.:..................................... -*%##%#%%@%%%%%#%%@%##%##%%#%%@%%%%%***+*#%%%%%#+*%@%#%%@%%#%%@%%#*#@@@@@@@@@@@@@ +@%%%%@@%%%%%@%@%%%@%@%@%@%%#%%%#%%%@%%%%%%%%%%%##***%#%%%%%%%%%%%%%%%%%%%%%@%@%%%%%%##+=#%##%+==+##%#***##%###%%###*-.:::::::-:::-::-:-::::-::::-:-::-:-::::-:::-::-::-:::::::::::.:::.::.:::.:..:..:.:..........................:..........:+###%%%%%%%#%%@%%%%###%##+*%@%%%#####%@@%%@%%##*+#%%%%@%%%%@%%%#*#%%%%%%@@%@%%@ +%%%%%@%%#%%%%%@%%#%@%@%##%#*+*%%%%%%@%%@%%@%###+-+%%#%%%%%%%%%%%#%%%%%%%%%####*####%%*+*###*#%%%%###%#+=#%#%%###%%*=*+:.::::-::-::-::-:-:-:::::::::-:::::-::::-:::::::::::::::::.:::.::.::.:.:.:......................:........:..:.:...... -*#%#%%##%%%%%%%%%#%%%####%@%%%%#%%@%%##%%@%%####**#%%%@%%%@%@%#*#@%@%@%%%@%@%% *%%%%%@%%#%%%@%@%%%%@%%@%%*++*##%%%%%%@@#%%#%@#+++####%%##%#####%#%%%%#%#%#%#%#%%%%%#*=*####%####%%%**#*##%##%%####*=:.::::-::::::::-::-::-:-:-:-:-::-:-::::-:::::-::-::::::::::::::::.::.::.:.:.:.:.............................:.............-=*###%%%%%%%%#%#%@%###%#%%%#%%%@%%%%%#***####%%#**#%@%#%%@%%%%#%@%%%%%%%%%%%% #%%%%@%@%#%%%%%@%%%%@%@@@%%%%%##%#%%@%%%###%%#+=*%%%@%%@@%@%%%@%%###****#***##%###%%*+***+=+***##%%#+=**#%####%####+-::::::::::-::-::-::-::-:::::::-:::::::::::::::::::::::::::::::.::::::.:.:.:.....:........ . . ............:..:.:.:....... .+*##%%%%%%%#%%%@%%%%%###%%#**%@%@%%###***#@@@@%@%*+*%@%#%@%%%%#%@%%@##%@@%@@@ #@%%%%@%%##%@%@%%##%@@##*%%@%@%%#%%%%@%%%#*%%==#%*%%%%%%%%@%@%%%%@%@%@@%%#####%%%%%*++##%%@%*+=*#%#%%*=#%%%%%###%#+**-.:::::-::::::-::-::-:::-::-:::::-:::::::::::::::::::::::::::::.:.:.:.::.:.:.:...... . . .............:.:..:..:......... .. -#%#%%%##%%%%%%%%%##%%######%%@%%###%@%@%%#%%%%#%%+*%%%%@@%%%%%@%%%#**%%@%@% *%%%@%@@%#%@%@%@@@@@%%%%%#%%@@%@%%%%%%@%#%%*+*###%%%%%%%%%%%%%%%%%%%%####%%##%%##%##+*####*##%%%%#%##++####%%######=.:::::::::-:-:::-::-:-:-::-:::-:-::::::::::::::::::::::::::.::.:::.:.::.:.:..:..... .. . . . .... ......:.:..:..::.:.:........-=*#%##%%%%%%%%%#%@@%##%##%@%%#%%%@@%%%#%%%#%%%##%#+*%%%%@%%%@@%@%##%%@%@%@ #@%%@%%%%%%@%%%@%##%#=*%#%%%%%@@%%%%%%%%%#*+=#@##%#%%%#%%%%%%#%%%%#%%%%%%%%##%#%%%=+*#**###%###%%#++##%#%##%#%#%#*=::::::::-:-:::-:-::-:-:-:-:::-:::::::::::::::::::::::::::.:::.::.:.::.:..:..:........ .... ...........:.:..:.:.::.:.:...........-*#*%%%%%%%%#%%%@%%%@%##%%%%##%@@%%%%%%*++**###%%%%*+#@%%%%%%@%%%##%%@%%%% #%%%@%@@%#%%@%@@%%#+****#%%%@%%%@@%#%@%%%*=+#%#%%%%%##%######%####%#######%#%%##%*++**++++**###%%#+*##*%%%###%%%#*+=-:.::::::::-::-::-:-:-:-:-::::::::::::::::::::::::::::.::..::.::.:..:.:..:....... . .................:..:.:.:.:.:.:.:.:.... .. .-*%#%%%%##%%%%%%%%%########**#%@%@%%####*#%@@%@%%%##+*%@%#%@@%@%%#%@%%%%@ *@%%@%@%%%%@%@%@%@%%#*##%#%%%@@@%%%##%@#+++#%%%%@%%@@%@@@%@%%%%%#####****#%###@%*+*#%%%%%#+++##%%%%++*%%%%%%######+-:.:::::::-:::-:-:-:-:-:-::-:-:-:::-::::::::::::::::.:.:..:..:.:...:....:.............. ...........:.:.:.:.:.:.:.:.:.:.:.:.... ..:-=*#%#%%%%%%@%@%%#%%@@%#%#%%%@%%%%##%%@@%%%#%%%@%%%#**#@@%%@@%%%%%@@%%%# #@%@%%@@%%@%@%%%#%@%@@%%%##%%%%@%@%##%%*-+%%##@%%%%%%%%%%@%%@%%@%%@%%%%%%#%%%%##****#####%%%%%%#%##**#%##%%%##%#*-:.:::::::::::-:::-:--:--:-:::-::::-:::::::.:.:.:.:.:.:.:.:..:.....:....:.............. ...........:..:.:.:.:.::.::.:.:.:.:.........:=*###%%%%@%%%##%%@@%%%##%#*#%%%%#%@%@%@%%%%%%%#%##%%#**#%@%%@%%%@@%@%%# #@%%@%@@%#%@%%@%###%%%@%@%%%%@%@@%%#%%++#%##%%%%%%%%%%%%%%%%%%%%######%#*%%##%%*****##%%#%##%@%#**#%%%#%###%%%###+:::::.:::::-:::--:-:--:-:-:-::-:::::::::::.:.:.:.:.::.:......................... ........ .. .......:.:.:.:::.::.:::.::.:.:::....:...=*#%%%%%%%#%%@%@%%%@%%##%%%%%##%@@%%%%%%#*+**###%#%%#+*#%@%%%%%@@%%%%+ *%@%@@%@%@%@%%##%%%%%%@%@%%%%%%@%%#%*==*%%##%%#%%%%%%%%%%%%%%%%%%%%%%%%##%%#%@*=*#*++****##%%%%*++##*#@%####%%###*+::::::::::::-:-:--:-:-:-:-:-::-:-:::::::.:.:..:.:.:.:.:...:............:.... ...... .. ..........:..:.:.::.::.::.:.:.:::::.:.::.:...-==*%%%#%#%%%%%%%%%%#%%%%##%#**#%@%@%%####**##@%@@@%@%#+*%@%%%%@%@%%%# %@%@%%@@%#%%#+=*@%%%@%%@@@@%%%%%%%%#+=*%%%%#*###%@@%#***#%@@%#*+==+#%@%%#%%%%#++#%##%#*+++*##%@%*++#%%%%%%%####+::-::::::::---::::-:--------::::::::::::::::........................................ ....... .........:..:::::::::::::::::::::::.::..:: :**+*#%%%@%%%%%%%#%%%@%%%%%##%%%%%%%%##%%%%@@%%%%%%%#%%*+#%%%%@@@%%%*