diff --git a/simulations/README.md b/simulations/README.md
index df75e53..88ceabd 100644
--- a/simulations/README.md
+++ b/simulations/README.md
@@ -1,8 +1,8 @@
# Hyperpolarized Simulation Tools
-## Creating Simulated Data
+## Pharmacokinetic (PK) Models
-This directory includes tools for simulating metabolic imaging data based on kinetic models. These include
+The `pk_models` directory includes tools for simulating metabolic imaging data based on kinetic models. These include
`realistic_input_function` - create a gamma-variate function for simulating the bolus input
@@ -10,22 +10,28 @@ This directory includes tools for simulating metabolic imaging data based on kin
See [Kinetic Modeling Notebook](../demo_notebooks/Test_Kinetic_Modeling.ipynb) for examples
-## Metabolic Phantom
+## Anatomical Phantoms
-The file metabolic_phantom.m provides a matlab function for automatically generating standardized 3-dimensional perfusion and metabolism maps for simulated experiments. The script DEMO.m demonstrates the usage of this function. Examples of the resulting parameter maps are shown below.
+This framework generates anatomically realistic hyperpolarized 13C MRI data by combining anatomical and PK models. This was started with brain and heart phantoms, and built modularly to accomodate multiple anatomies and kinetic models. It also includes experimental factors that incorporate the spatial resolution, SNR, and coil sensitivity profiles.
+
+
+
+## Metabolic Shapes Phantom
+
+In `metabolic_shapes_phantom`, the file metabolic_phantom.m provides a matlab function for automatically generating standardized a geometric shape-based 3-dimensional perfusion and metabolism maps for simulated experiments. The script DEMO.m demonstrates the usage of this function. Examples of the resulting parameter maps are shown below.
kTRANS (perfusion) map:
-
+
kPL (metabolism) map:
-
+
## Monte Carlo Simulations of Analysis Metrics
Given the experimental challenges of time, cost, and lack of ground truth for HP studies, simulations are an invaluable tool for evaluating data acquisition and analysis strategies.
-This toolbox includes a Monte Carlo based simulation tool `HP_montecarlo_evaluation()` which uses a 2-site kinetic model (`simulate_Nsite_model()`) with added noise and your choice of experiment parameters (e.g. flip angles, timings) and analysis metric(s) (e.g. kPL, AUCratios).
+This toolbox includes a Monte Carlo based simulation tool `HP_montecarlo_evaluation()` in `montecarlo_simulations` which uses a 2-site kinetic model (`simulate_Nsite_model()`) with added noise and your choice of experiment parameters (e.g. flip angles, timings) and analysis metric(s) (e.g. kPL, AUCratios).
It evalutes the sensitivity of this combination of experiment parameters and analysis metric to changes in kinetic rate, noise level, bolus characteristics, relaxation rates, and B1+ (e.g. flip angle).
Several examples including different acquisition schemes, different kinetic model approaches, and comparison to an AUCratio are in the `test_HP_montecarlo_evaluation.m` script, which has the expected output:
@@ -34,13 +40,15 @@ Several examples including different acquisition schemes, different kinetic mode
### Examples
```
-Larson PEZ, Chen HY, Gordon JW, Korn N, Maidens J, Arcak M, Tang S, Criekinge M, Carvajal L, Mammoli D, Bok R, Aggarwal R, Ferrone M, Slater JB, Nelson SJ, Kurhanewicz J, Vigneron DB. Investigation of analysis methods for hyperpolarized 13C-pyruvate metabolic MRI in prostate cancer patients. NMR Biomed. 2018 Nov;31(11):e3997.
+Larson PEZ, Chen HY, Gordon JW, Korn N, Maidens J, Arcak M, Tang S, Criekinge M, Carvajal L, Mammoli D, Bok R, Aggarwal R, Ferrone M, Slater JB, Nelson SJ, Kurhanewicz J, Vigneron DB.
+Investigation of analysis methods for hyperpolarized 13C-pyruvate metabolic MRI in prostate cancer patients. NMR Biomed. 2018 Nov;31(11):e3997.
https://doi.org/10.1002/nbm.3997. Epub 2018 Sep 19. PMID: 30230646; PMCID: PMC6392436.
```
* See Figures 4-6
```
-James Bankson, Peder E.Z. Larson, Analysis and visualization of hyperpolarized 13C MR data, Editor(s): Peder E.Z. Larson, Advances in Magnetic Resonance Technology and Applications, Academic Press,
+James Bankson, Peder E.Z. Larson, Analysis and visualization of hyperpolarized 13C MR data,
+Editor(s): Peder E.Z. Larson, Advances in Magnetic Resonance Technology and Applications, Academic Press,
Volume 3, 2021, Pages 129-155, ISSN 2666-9099, ISBN 9780128222690, https://doi.org/10.1016/B978-0-12-822269-0.00004-X
```
* Figures 6.8 and 6.9
@@ -50,7 +58,9 @@ Volume 3, 2021, Pages 129-155, ISSN 2666-9099, ISBN 9780128222690, https://doi.o
Simulates the effect of pulse sequence parameters (flip angles, phase encoding, etc) on pH measurements for HP bicarbonate studies. Based on:
```
-Korenchan, DE, Gordon, JW, Subramaniam, S, et al. Using bidirectional chemical exchange for improved hyperpolarized [13C]bicarbonate pH imaging. Magn Reson Med. 2019; 82: 959–972. doi: 10.1002/mrm.27780
+Korenchan, DE, Gordon, JW, Subramaniam, S, et al.
+Using bidirectional chemical exchange for improved hyperpolarized [13C]bicarbonate pH imaging.
+Magn Reson Med. 2019; 82: 959–972. doi: 10.1002/mrm.27780
```
https://doi.org/10.1002/mrm.27780
##
diff --git a/simulations/anatomical_phantoms/brainweb_metabolic_phantom.m b/simulations/anatomical_phantoms/brainweb_metabolic_phantom.m
deleted file mode 100644
index cb1d2b7..0000000
--- a/simulations/anatomical_phantoms/brainweb_metabolic_phantom.m
+++ /dev/null
@@ -1,297 +0,0 @@
-function [kTRANS, kMaps_out, Mz0Maps_out, metImages, w] = brainweb_metabolic_phantom(kineticRates, ktransScales, Mz0, sampSize, outputSize, simParams, inputFunction, isFuzzy, linear_kTRANS_grad, augmentParams, brain_idx, augmentSeed)
-% BRAINWEB_METABOLIC_PHANTOM generates standardized 3-dimensional perfusion
-% and metabolism maps for simulated experiments. Supports 3 chemical pool
-% kinetic rate mapping.
-%
-% Toolboxes required: Image Processing
-%
-% Parameters:
-% kineticRates = the kinetic rates to simulate, [(# of chemical
-% pools) - 1, 3 (tissue types: vasc, gm, wm)]
-% ktransScales = volume transfer constants for different tissue
-% compartments [vasculature, gray matter, white matter]
-% if linear_kTRANS_grad=true, should include low
-% and high kTRANS [[vasc_low, GM_low, WM_low]; [vasc_hi, GM_hi, WM_hi]]
-% Mz0 = Initial magnetization per metabolite per compartment,
-% size [Nmets 3] in order vessels, gm, wm
-% sampSize = 3x3 or 1x3 vector for desired sampling ("acquisition") matrix size of each
-% dimension for all mets
-% [met dim(nx,ny,nz)], default = [16 16 8]
-% outputSize = 1x3 vector for desored output matrix size,
-% default = [64 64 8]
-% simParams = parameters used for the kinetic simulations:
-% Tarrival, Tbolus, TR, Nt, R1, flips; if empty won't
-% generate metImages, default = empty struct
-% inputFunction = [1 Nt] vector as input into each voxel
-%
-% Optional Parameters:
-% isFuzzy = logical flag to indicate if fuzzy tissue boundaries
-% will be used, default = true
-% linear_kTRANS_grad = boolean flag for whether kTRANS should be set to
-% a gradient
-% augmentParams = random augmentation parameters XTranslation,
-% YTranslation etc, if not defined a single
-% unaugmented phantom will be generated,
-% default = empty struct
-% brain_idx = specify if want to use a specific brain (1-20),
-% default = randomly choose a brain
-% augmentSeed = random seed for augmentations, default no seed
-%
-% Outputs:
-% kTRANS = generated perfusion map
-% kMaps = generated rate maps for 1->2 and 1->3
-% Mz0Maps = generated Mz0 maps
-% metImages = simulated metabolite dynamic images
-% w = simulated coil sensitivity maps
-%
-% Author:
-% Jasmine Hu
-% Anna Bennett
-% Sule Sahin
-%
-% Copyright, 2024
-
- % parse input arguments
- arguments
- kineticRates (:,3) double {mustBeNumeric} = [0.1, 0.2, 0.3; 0, 0, 0]
- ktransScales (:,3) double {mustBeNumeric} = [1, 0.3, 0.3]
- Mz0 (:,3) double {mustBeNumeric} = [0, 0, 0]
- sampSize (:,3) double {mustBeInteger} = [16, 16, 8]
- outputSize (1,3) double {mustBeInteger} = [64, 64, 8]
- simParams struct = struct([])
- inputFunction double = []
- isFuzzy double {mustBeNumericOrLogical} = true
- linear_kTRANS_grad double {mustBeNumericOrLogical} = false
- augmentParams struct = struct()
- brain_idx {mustBeInteger} = [] %TODO: should be int between 1-19
- augmentSeed double {mustBeInteger, mustBePositive, mustBeNonzero} = []
- end
-
- if augmentSeed
- rng(augmentSeed)
- else
- rng("shuffle")
- end
-
- if and(linear_kTRANS_grad, size(ktransScales,1)==1)
- ktransScales = repmat(ktransScales, [2 1]);
- warning("kTRANS linear gradient is 'true' but low/high kTRANS values not defined. Using user-defined kTRANS values as both low and high.")
- elseif and(~linear_kTRANS_grad, size(ktransScales,1)>1)
- ktransScales = squeeze(ktransScales(1,:));
- warning("kTRANS linear gradient is 'false' but low/high kTRANS values defined. Using first row of kTRANS values.")
- end
-
- nMets = size(kineticRates,1) + 1;
-
- if size(sampSize) == [1 3]
- maxSampSize = sampSize;
- sampSize = repmat(sampSize, [nMets 1]);
- else
- [~,i] = max(sampSize(:,1));
- maxSampSize = sampSize(i,:);
- end
-
- % add resources dir to path
- fileDir = split(mfilename('fullpath'),'/');
- utilDir = fullfile(string(join(fileDir(1:end-1),'/')),'/util');
- addpath(utilDir)
-
- % define default augmentation parameters and set augmentParams to them
- % if not defined
- defaultAugParams.XReflection = false; defaultAugParams.YReflection = false;
- defaultAugParams.Rotation = [0 0]; defaultAugParams.Scale = [1 1];
- defaultAugParams.XShear = [0 0]; defaultAugParams.YShear = [0 0];
- defaultAugParams.XTranslation = [0 0]; defaultAugParams.YTranslation = [0 0];
- augs = fieldnames(defaultAugParams);
- for f=1:size(augs,1)
- if ~isfield(augmentParams,augs{f})
- augmentParams(1).(augs{f}) = defaultAugParams.(augs{f});
- end
- end
-
- % load base anatomical information
- if isempty(brain_idx)
- brain_idx = randi(19);
- end
- if isFuzzy
- brainwebFile = 'brainweb_fuzzy.mat';
- else
- brainwebFile = 'brainweb.mat';
- end
- baseMaskFile = dir(fullfile(utilDir,num2str(brain_idx),brainwebFile));
- if isempty(baseMaskFile)
- error('Error. \nBrainWeb mask file, %s, not found in resources directory.',brainwebFile)
- end
-
- load(fullfile(baseMaskFile.folder,brainwebFile),'im_mask');
- vasc_mask = squeeze(im_mask(:,:,:,1));
- gm_mask = squeeze(im_mask(:,:,:,2));
- wm_mask = squeeze(im_mask(:,:,:,3));
- brain_mask = vasc_mask + gm_mask + wm_mask;
- maskSize = size(im_mask,1:3);
-
- weights = coil_dist_map(brain_mask, simParams.coil_lim);
-
- nTissues = 3;
- if size(im_mask,4) ~= nTissues
- error('Unexpected number of tissues present in the imported masks, ask for help, idk.');
- end
-
- % parameters for output map generation
- permuted_mask = double(permute(im_mask,[4 1 2 3]));
- sumWeights = sum(im_mask,4);
-
- if linear_kTRANS_grad
- % generate kTRANS gradients per compartment
- grad_vasc = generate_linear_gradient(maskSize, ktransScales(1,1), ktransScales(2,1));
- grad_gm = generate_linear_gradient(maskSize, ktransScales(1,2), ktransScales(2,2));
- grad_wm = generate_linear_gradient(maskSize, ktransScales(1,3), ktransScales(2,3));
-
- % generate the kTRANS masked volume
- kTRANS_vasc = squeeze(permuted_mask(1,:,:,:)) .* grad_vasc;
- kTRANS_gm = squeeze(permuted_mask(2,:,:,:)) .* grad_gm;
- kTRANS_wm = squeeze(permuted_mask(3,:,:,:)) .* grad_wm;
- kTRANS_wSum = kTRANS_vasc + kTRANS_gm + kTRANS_wm;
- kTRANS = squeeze(kTRANS_wSum)./sumWeights;
- kTRANS(isnan(kTRANS)) = 0;
- else
- kTRANS = create_map(permuted_mask, ktransScales, sumWeights);
- end
-
- % generate the kinetic rate maps
- k_1_2_MAP = create_map(permuted_mask, kineticRates(1,:), sumWeights);
- k_1_3_MAP = create_map(permuted_mask, kineticRates(2,:), sumWeights);
-
- % generate Mz0 maps
- Mz0P_MAP = create_map(permuted_mask, Mz0(1,:), sumWeights);
- Mz0L_MAP = create_map(permuted_mask, Mz0(2,:), sumWeights);
- Mz0B_MAP = create_map(permuted_mask, Mz0(3,:), sumWeights);
-
- %adjust FOV in z
- cropidx1 = randi([40 60]); % TODO: make this optional?
- cropidx2 = randi([300 320]);
- kTRANS = kTRANS(:,:,cropidx1:cropidx2);
- k_1_2_MAP = k_1_2_MAP(:,:,cropidx1:cropidx2);
- k_1_3_MAP = k_1_3_MAP(:,:,cropidx1:cropidx2);
- Mz0P_MAP = Mz0P_MAP(:,:,cropidx1:cropidx2);
- Mz0L_MAP = Mz0L_MAP(:,:,cropidx1:cropidx2);
- Mz0B_MAP = Mz0B_MAP(:,:,cropidx1:cropidx2);
- w = weights(:,:,cropidx1:cropidx2);
-
- % resample/downsample maps to desired SAMPLE size
- kTRANS = imresize3(kTRANS, maxSampSize);
- k_1_2_MAP = imresize3(k_1_2_MAP, maxSampSize);
- k_1_3_MAP = imresize3(k_1_3_MAP, maxSampSize);
- Mz0P_MAP = imresize3(Mz0P_MAP, maxSampSize);
- Mz0L_MAP = imresize3(Mz0L_MAP, maxSampSize);
- Mz0B_MAP = imresize3(Mz0B_MAP, maxSampSize);
- w = imresize3(w, maxSampSize);
-
- % Random Augmentations (requires image processing toolbox)
- tform = randomAffine2d('Rotation',augmentParams.Rotation, 'Scale', ...
- augmentParams.Scale, 'XReflection', augmentParams.XReflection, ...
- 'YReflection', augmentParams.YReflection, 'XTranslation', ...
- augmentParams.XTranslation, 'YTranslation', augmentParams.YTranslation, ...
- 'XShear', augmentParams.XShear, 'YShear', augmentParams.YShear);
- outputView = affineOutputView(size(kTRANS),tform);
- kTRANS = imwarp(kTRANS,tform,OutputView=outputView);
- k_1_2_MAP = imwarp(k_1_2_MAP,tform,OutputView=outputView);
- k_1_3_MAP = imwarp(k_1_3_MAP,tform,OutputView=outputView);
- Mz0P_MAP = imwarp(Mz0P_MAP,tform,OutputView=outputView);
- Mz0L_MAP = imwarp(Mz0L_MAP,tform,OutputView=outputView);
- Mz0B_MAP = imwarp(Mz0B_MAP,tform,OutputView=outputView);
- w = imwarp(w,tform,OutputView=outputView);
-
- %flip 3rd dimension to match in vivo convention
- kTRANS = flip(kTRANS,3);
- kMaps = flip(cat(4,k_1_2_MAP,k_1_3_MAP),3);
- Mz0Maps = flip(cat(4,Mz0P_MAP,Mz0L_MAP, Mz0B_MAP),3);
- w = flip(w,3);
- w = w ./ max(w(:)); % normalize coil sens weights to max of 1 after imresize
-
- if ~isempty(simParams) % output simulated metabolite dynamic images
- % simulate signals
- % store simulation parameters a in a struct,
- % eventually this should be a custom class
-
- if isempty(inputFunction)
- inputFunction = zeros([1 simParams.Nt]);
- end
-
- % first generate voxelwise dynamics
- metImages_sp = zeros(cat(2,maxSampSize,[nMets, simParams.Nt]));
- metImages = zeros(cat(2,outputSize,[nMets, simParams.Nt]));
- for Ix = 1:maxSampSize(1)
- for Iy = 1:maxSampSize(2)
- for Iz = 1:maxSampSize(3)
- Mz0_vx = [Mz0Maps(Ix, Iy, Iz, 1) Mz0Maps(Ix, Iy, Iz, 2) Mz0Maps(Ix, Iy, Iz, 3)];
- [metImages_sp(Ix,Iy,Iz,:,:), ~] = simulate_Nsite_model(Mz0_vx, simParams.R1, [kMaps(Ix,Iy,Iz,1) 0; kMaps(Ix,Iy,Iz,2) 0], simParams.flips, simParams.TR, inputFunction*kTRANS(Ix,Iy,Iz) );
- end
- end
- end
-
- % multiply by coil sens weights
- metImages_sp = metImages_sp .* repmat(w, [1 1 1 size(metImages_sp,4) size(metImages_sp,5)]);
-
- % multi res capability
- metImages_mres = cell(nMets,1); % cast metImages into cell to allow different matrix sizes
- for Imet=1:nMets
-
- % add rician noise
- std_noise = max(sum(squeeze(metImages_sp(:,:,:,Imet,:)),4),[],'all') ./ (simParams.SNR(Imet) * sqrt(simParams.Nt));
- noise_R = randn(cat(2,sampSize(Imet,:),[simParams.Nt]))* std_noise;
- noise_I = randn(cat(2,sampSize(Imet,:),[simParams.Nt]))* std_noise;
-
- if maxSampSize == sampSize(Imet,:)
- temp = squeeze(metImages_sp(:,:,:,Imet,:));
- metImages_mres{Imet} = sqrt((temp + noise_R).^2 + noise_I.^2);
- else
- temp=zeros(cat(2,sampSize(Imet,:),simParams.Nt));
- for t=1:simParams.Nt
- temp(:,:,:,t) = imresize3(metImages_sp(:,:,:,Imet,t), sampSize(Imet,:), 'box'); %box downsampling will effectively average across voxels
- end
- metImages_mres{Imet} = sqrt((temp + noise_R).^2 + noise_I.^2);
- clear temp;
- end
- end
-
- % resize to desired OUTPUT size
- for Imet = 1:size(metImages_sp,4)
- temp = metImages_mres{Imet};
- for It = 1:size(metImages_sp,5)
- metImages(:,:,:,Imet,It) = imresize3(squeeze(temp(:,:,:,It)), outputSize, 'lanczos3');
- %metImages(:,:,:,Imet,It) = zeropad(squeeze(temp(:,:,:,It)), outputSize(1:2));
- end
- end
-
- else
- metImages = 0;
- end
-
- % resample maps to desired OUTPUT size
- kTRANS = imresize3(kTRANS, outputSize, 'lanczos3');
- kMaps_out = zeros(cat(2,outputSize,nMets-1));
- Mz0Maps_out = zeros(cat(2,outputSize,nMets));
- for n=1:nMets-1
- kMaps_out(:,:,:,n) = imresize3(kMaps(:,:,:,n), outputSize, 'lanczos3');
- end
- for n=1:nMets
- Mz0Maps_out(:,:,:,n) = imresize3(Mz0Maps(:,:,:,n), outputSize, 'lanczos3');
- end
-
-end
-
-function [grad] = generate_linear_gradient(maskSize, kTRANS_low, kTRANS_high)
-
- x = linspace(-1, 1, maskSize(1));
- y = linspace(-1, 1, maskSize(2));
- z = linspace(-1, 1, maskSize(3));
- [X, Y, Z] = meshgrid(x, y, z);
- grad = 0.5*(kTRANS_high - kTRANS_low)*Y + 0.5*(kTRANS_low + kTRANS_high);
-end
-
-function [map] = create_map(mask, rates, sumWeights)
- map_wSum = pagemtimes(rates,mask);
- map = squeeze(map_wSum)./sumWeights;
- map(isnan(map)) = 0;
-end
\ No newline at end of file
diff --git a/simulations/anatomical_phantoms/brainweb_metabolic_phantom_test.m b/simulations/anatomical_phantoms/brainweb_metabolic_phantom_test.m
deleted file mode 100644
index d211138..0000000
--- a/simulations/anatomical_phantoms/brainweb_metabolic_phantom_test.m
+++ /dev/null
@@ -1,93 +0,0 @@
-% Quick testing script for the brain web basic metabolic phantom
-clear; close all;
-
-kineticRates = [0, 0.05, 0.03;
- 0, 0.02, 0.01]; % in order [vasc, GM, WM]
-ktransScales = [1, 0.2, 0.2;
- 3, 0.4, 0.4];
-isFuzzy = true;
-sampSize = [16 16 8];
-outputSize = [32 32 8];
-linear_kTRANS_grad = true;
-
-% define simulation parameters: Tarrival, Tbolus, TR, Nt, R1, flips,
-% std_noise
-simParams.Tarrival = 0;
-simParams.Tbolus = 8;
-simParams.TR = 4;
-simParams.Nt = 30;
-simParams.R1 = [1/30 1/25 1/25];
-simParams.flips = repmat([20; 30; 30],[1 simParams.Nt])*pi/180;
-simParams.SNR = [150 40 20];
-simParams.coil_lim = [0.4 1.2];
-
-% define augmentation parameters
-augmentParams.XTranslation = [-1 1];
-augmentParams.YTranslation = [-1 1];
-augmentParams.Scale = [0.95 1.1];
-augmentParams.XReflection = true;
-augmentParams.Rotation = [-5 5];
-
-% input funciton and Mz0
-input_function = realistic_input_function(simParams.Nt, simParams.TR, simParams.Tarrival, simParams.Tbolus);
-Mz0 = [input_function(1), input_function(1)*.5, input_function(1)*.5;
- 0, input_function(1)*.01, input_function(1)*.01;
- 0, input_function(1)*.005, input_function(1)*.005];
-
-[k_trans, k_maps, Mz0_maps, metImages, w] = brainweb_metabolic_phantom(kineticRates, ktransScales, Mz0, sampSize, outputSize, simParams, input_function, isFuzzy, linear_kTRANS_grad, augmentParams);
-
-%% visualize kTRANS and k maps
-
-slices = 1:size(k_trans,3);
-tpts = 1:3:simParams.Nt;
-
-% visualize kTRANS
-figure,
-imagescn(k_trans(:,:,slices),[0 max(k_trans(:,:,slices),[],'all')], [1 numel(slices)]); colormap fire;
-
-% visualize kinetic rates
-figure,
-imagescn(k_maps(:,:,slices,1),[0 max(k_maps(:,:,slices,1),[],'all')], [1 numel(slices)]); colormap fire;
-
-figure,
-imagescn(k_maps(:,:,slices,2),[0 max(k_maps(:,:,slices,2),[],'all')], [1 numel(slices)]); colormap fire;
-
-% visualize Mz0 maps
-figure,
-imagescn(Mz0_maps(:,:,slices,1),[0 max(Mz0_maps(:,:,slices,1),[],'all')], [1 numel(slices)]); colormap fire;
-
-figure,
-imagescn(Mz0_maps(:,:,slices,2),[0 max(Mz0_maps(:,:,slices,2),[],'all')], [1 numel(slices)]); colormap fire;
-
-figure,
-imagescn(Mz0_maps(:,:,slices,3),[0 max(Mz0_maps(:,:,slices,3),[],'all')], [1 numel(slices)]); colormap fire;
-
-%% visualize metImages
-
-%pyruvate
-figure,
-imagescn(squeeze(metImages(:,:,slices,1,tpts)),[0 max(squeeze(metImages(:,:,slices,1,tpts)),[],'all')], [numel(slices) numel(tpts)]); colormap fire;
-
-%lactate
-figure,
-imagescn(squeeze(metImages(:,:,slices,2,tpts)),[0 max(squeeze(metImages(:,:,slices,2,tpts)),[],'all')], [numel(slices) numel(tpts)]); colormap fire;
-
-%bicarb
-figure,
-imagescn(squeeze(metImages(:,:,slices,3,tpts)),[0 max(squeeze(metImages(:,:,slices,3,tpts)),[],'all')], [numel(slices) numel(tpts)]); colormap fire;
-
-%% visualize AUCs
-%pyruvate
-pyrAUC = sum(squeeze(metImages(:,:,:,1,:)),length(size(squeeze(metImages(:,:,:,1,:)))));
-figure,
-imagescn(pyrAUC,[0 max(pyrAUC,[],'all')], [1 numel(slices)]); colormap fire;
-
-%lactate
-lacAUC = sum(squeeze(metImages(:,:,:,2,:)),length(size(squeeze(metImages(:,:,:,2,:)))));
-figure,
-imagescn(lacAUC,[0 max(lacAUC,[],'all')], [1 numel(slices)]); colormap fire;
-
-%bicarb
-bicAUC = sum(squeeze(metImages(:,:,:,3,:)),length(size(squeeze(metImages(:,:,:,3,:)))));
-figure,
-imagescn(bicAUC,[0 max(bicAUC,[],'all')], [1 numel(slices)]); colormap fire;
diff --git a/simulations/anatomical_phantoms/cardiac_metabolic_phantom.m b/simulations/anatomical_phantoms/cardiac_metabolic_phantom.m
deleted file mode 100644
index 0f66f99..0000000
--- a/simulations/anatomical_phantoms/cardiac_metabolic_phantom.m
+++ /dev/null
@@ -1,161 +0,0 @@
-function [kTRANS, kMaps, Mz0Maps, metImages] = cardiac_metabolic_phantom(kineticRates, ktransScales, Mz0_constants, matSize, simParams, heart_idx)
-% CARDIAC_METABOLIC_PHANTOM generates standardized 3-dimensional perfusion
-% and metabolism maps for simulated experiments. Supports 3 chemical pool
-% kinetic rate mapping.
-%
-% Toolboxes required: Image Processing
-%
-% Parameters:
-% kineticRates = the kinetic rates to simulate, [(# of chemical
-% pools) - 1, 4 (tissue types: LV, RV, LV Myocardium, RV Myocardium)]
-% ktransScales = volume transfer constants for different tissue
-% compartments [LV, RV, LV Myocardium, Rv Myocardium]
-% Mz0_constants = Initial magnetization constants per metabolite per compartment,
-% size [Nmets 3] in order LV, RV, LV Myocardium, RV Myocardium
-% matSize = 1x3 vector for desired matrix size of each
-% dimension
-% [met dim(nx,ny,nz)], default = [32 32 5]
-% simParams = parameters used for the kinetic simulations:
-% Tarrival, Tbolus, TR, Nt, R1, flips; if empty won't
-% generate metImages, default = empty struct
-% inputFunction = [1 Nt] vector as input into each voxel
-%
-% Optional Parameters:
-% heart_idx = heart mask used for (1-20). default = random mask
-%
-% Outputs:
-% kTRANS = generated perfusion map
-% kMaps = generated rate maps for 1->2 and 1->3
-% Mz0Maps = generated Mz0 maps
-% metImages = simulated metabolite dynamic images
-%
-% Copyright, 2024
-
- % parse input arguments
- arguments % !! some may not be robust enough after changes !!
- kineticRates (:,4) double {mustBeNumeric} = [0.1, 0.2, 0.3; 0, 0, 0]
- ktransScales (:,4) double {mustBeNumeric} = [1, 0.3, 0.3]
- Mz0_constants (:,4) double {mustBeNumeric} = [0, 0, 0]
- matSize (:,3) double {mustBeInteger} = [32, 32, 5]
- simParams struct = struct([])
- heart_idx {mustBeInteger, mustBePositive, mustBeNonzero} = []
- end
-
- nMets = size(kineticRates,1) + 1;
-
- % load masks
- if isempty(heart_idx)
- heart_idx = randi(20);
- end
- current_path = pwd;
- mask_path = fullfile(current_path,'util/_src_cardiac',num2str(heart_idx), 'cardiac_masks.mat');
- load(mask_path,'im_mask');
-
- nTissues = 4;
- if size(im_mask,4) ~= nTissues
- error('Unexpected number of tissues present in the imported masks, ask for help, idk.');
- end
-
- % parameters for output map generation
- permuted_mask = double(permute(im_mask,[4 1 2 3]));
- sumWeights = sum(im_mask,4);
-
- kTRANS = create_map(permuted_mask, ktransScales, sumWeights);
-
- % generate Tarrival maps
- Tarrival_MAP = create_map(permuted_mask, simParams.Tarrival, sumWeights);
- Tarrival_MAP(sumWeights == 0) = (simParams.Tarrival(3)+simParams.Tarrival(4)) / 2;
- Tarrival_MAP = squeeze(Tarrival_MAP);
-
- % generate Mz0
- % this is kinda awkward because you need to regenerate the input
- % functions later
- Mz0 = zeros(nMets, nTissues);
- for tissue = 1:nTissues
- input_function = realistic_input_function(simParams.Nt, simParams.TR, simParams.Tarrival(tissue), simParams.Tbolus);
- Mz0(:,tissue) = input_function(1) .* Mz0_constants(:,tissue);
- end
-
- % generate the kinetic rate maps
- k_1_2_MAP = create_map(permuted_mask, kineticRates(1,:), sumWeights);
- k_1_3_MAP = create_map(permuted_mask, kineticRates(2,:), sumWeights);
-
- % generate Mz0 maps
- Mz0P_MAP = create_map(permuted_mask, Mz0(1,:), sumWeights);
- Mz0L_MAP = create_map(permuted_mask, Mz0(2,:), sumWeights);
- Mz0B_MAP = create_map(permuted_mask, Mz0(3,:), sumWeights);
-
- small_matSize = [matSize(1)/2, matSize(2)/2, matSize(3)];
-
- % resample/downsample maps to desired matrix size
- kTRANS = imresize3(kTRANS, small_matSize);
- k_1_2_MAP = imresize3(k_1_2_MAP, small_matSize);
- k_1_3_MAP = imresize3(k_1_3_MAP, small_matSize);
- Mz0P_MAP = imresize3(Mz0P_MAP, small_matSize);
- Mz0L_MAP = imresize3(Mz0L_MAP, small_matSize);
- Mz0B_MAP = imresize3(Mz0B_MAP, small_matSize);
- Tarrival_MAP = imresize3(Tarrival_MAP, small_matSize, "linear");
-
- % upsample maps for blur
- kTRANS = imresize3(kTRANS, matSize);
- k_1_2_MAP = imresize3(k_1_2_MAP, matSize);
- k_1_3_MAP = imresize3(k_1_3_MAP, matSize);
- Mz0P_MAP = imresize3(Mz0P_MAP, matSize);
- Mz0L_MAP = imresize3(Mz0L_MAP, matSize);
- Mz0B_MAP = imresize3(Mz0B_MAP, matSize);
- Tarrival_MAP = imresize3(Tarrival_MAP, matSize, "linear");
-
- % account for downsampling changing kinetic rates
- % TODO: not a perfect solution, areas that should have lower rates go higher
- k_1_2_resize_error = max(kineticRates(1,:),[],'all') / max(k_1_2_MAP,[],'all');
- k_1_3_resize_error = max(kineticRates(2,:),[],'all') / max(k_1_3_MAP,[],'all');
- kTRANS_resize_error = max(ktransScales,[],'all') / max(kTRANS,[],'all');
- k_1_2_MAP = k_1_2_MAP .* k_1_2_resize_error;
- k_1_3_MAP = k_1_3_MAP .* k_1_3_resize_error;
- kTRANS = kTRANS .* kTRANS_resize_error;
-
-
- kMaps = cat(4,k_1_2_MAP,k_1_3_MAP);
- Mz0Maps = cat(4,Mz0P_MAP,Mz0L_MAP, Mz0B_MAP);
-
- if ~isempty(simParams) % output simulated metabolite dynamic images
- % simulate signals
- % store simulation parameters a in a struct,
-
- % generate voxelwise dynamics
- metImages = zeros(cat(2,matSize,[nMets, simParams.Nt]));
- for Ix = 1:matSize(1)
- for Iy = 1:matSize(2)
- for Iz = 1:matSize(3)
- % generate input_function
- Tarrival_vx = Tarrival_MAP(Ix, Iy, Iz);
- input_function_vx = realistic_input_function(simParams.Nt, simParams.TR, Tarrival_vx, simParams.Tbolus);
- Mz0_vx = [Mz0Maps(Ix, Iy, Iz, 1) Mz0Maps(Ix, Iy, Iz, 2) Mz0Maps(Ix, Iy, Iz, 3)];
- [metImages(Ix,Iy,Iz,:,:), ~] = simulate_Nsite_model(Mz0_vx, simParams.R1, [kMaps(Ix,Iy,Iz,1) 0; kMaps(Ix,Iy,Iz,2) 0], simParams.flips, simParams.TR, input_function_vx*kTRANS(Ix,Iy,Iz) );
- end
- end
- end
- end
-
- % add rician noise
- metImages_w_noise = zeros(size(metImages));
- for Imet=1:nMets
- ImetImage = squeeze(metImages(:,:,:,Imet,:));
- std_noise = max(sum(ImetImage,4),[],'all') ./ (simParams.SNR(Imet) * sqrt(simParams.Nt));
- noise_R = randn(cat(2,matSize,[simParams.Nt]))* std_noise;
- noise_I = randn(cat(2,matSize,[simParams.Nt]))* std_noise;
- metImages_w_noise(:,:,:,Imet,:) = sqrt((ImetImage+ noise_R).^2 + noise_I.^2);
- end
-
- metImages = metImages_w_noise;
-
-end
-
-
-function [map] = create_map(mask, rates, sumWeights)
- % apply rates over masks
- map_wSum = pagemtimes(rates,mask);
- map = squeeze(map_wSum)./sumWeights;
- map(isnan(map)) = 0;
-end
-
diff --git a/simulations/anatomical_phantoms/cardiac_metabolic_phantom_test.m b/simulations/anatomical_phantoms/cardiac_metabolic_phantom_test.m
deleted file mode 100644
index 19ef2bb..0000000
--- a/simulations/anatomical_phantoms/cardiac_metabolic_phantom_test.m
+++ /dev/null
@@ -1,109 +0,0 @@
-% Quick testing script for the cardiac metabolic phantom
-clear; close all;
-%
-% kineticRates = [0.0075, 0.0045, 0.0264, 0.0179;
-% 0.0011, 0.0005, 0.0100, 0.0017]; % in order [lv, rv, lv_mc, rv_mc].
-
-
-kineticRates = [0.0075, 0.0045, 0.06, 0.02;
- 0.0011, 0.0005, 0.0400, 0.01]; % in order [lv, rv, lv_mc, rv_mc].
-%ktransScales = [1.2, 1, 0.2, 0.2];
-ktransScales = [1, 1, -0.5, -0.5];
-
-matSize = [32,32,5];
-
-heart_idx = 1;
-
-% define simulation parameters: Tarrival, Tbolus, TR, Nt, R1, flips,
-% std_noise
-simParams.Tarrival = [7,0,10,14]; % in order lv, rv, lvmy, rvmy
-simParams.Tbolus = 1;
-simParams.TR = 3; % changes over time, but this seems like a pretty good estimate
-% TR = 3 * 60/heart_rates(I_subject);
-% subject_ids = [6 7 8 9 10 11 13 18];
-% heart_rates = [76 80 69 64 50 77 61 57];
-simParams.Nt = 20;
-simParams.R1 = [1/30 1/25 1/25];
-simParams.flips = repmat([20; 30; 30],[1 simParams.Nt])*pi/180;
-simParams.SNR = [150 40 20];
-simParams.coil_lim = [0.4 1.2]; % TODO: account for coil sensitivity
-
-Mz0_constants = [1, 1, 0.5, 0.5;
- 0, 0, 0.01, 0.01;
- 0, 0, 0.005, 0.005];
-
-[k_trans, k_maps, Mz0_maps, metImages] = cardiac_metabolic_phantom(kineticRates, ktransScales, Mz0_constants, matSize, simParams, heart_idx);
-
-slices = 1:size(k_trans,3);
-tpts = 1:simParams.Nt;
-
-%% visualize kTRANS and k maps
-
-% visualize kTRANS
-figure("Name","kTRANS")
-imagescn(k_trans(:,:,slices),[0 max(k_trans(:,:,slices),[],'all')], [1 numel(slices)]); colormap hot;
-
-% visualize kinetic rates
-figure("Name","kPL");
-imagescn(k_maps(:,:,slices,1),[0 max(k_maps(:,:,slices,1),[],'all')], [1 numel(slices)]); colormap hot;
-
-figure("Name","kPB");
-imagescn(k_maps(:,:,slices,2),[0 max(k_maps(:,:,slices,2),[],'all')], [1 numel(slices)]); colormap hot;
-
-
-%% visualize Mz0 maps
-figure("Name","Mz0 maps Pyruvate");
-scale = [0 max(Mz0_maps(:,:,slices,1),[],'all')];
-if scale(2) == 0
- scale(2) = 1;
-end
-imagescn(Mz0_maps(:,:,slices,1), scale, [1 numel(slices)]); colormap hot;
-
-figure("Name","Mz0 maps Lactate");
-scale = [0 max(Mz0_maps(:,:,slices,2),[],'all')];
-if scale(2) == 0
- scale(2) = 1;
-end
-imagescn(Mz0_maps(:,:,slices,3), scale, [1 numel(slices)]); colormap hot;
-
-
-figure("Name","Mz0 maps Bicarb");
-scale = [0 max(Mz0_maps(:,:,slices,3),[],'all')];
-if scale(2) == 0
- scale(2) = 1;
-end
-imagescn(Mz0_maps(:,:,slices,3), scale, [1 numel(slices)]); colormap hot;
-
-
-%% visualize metImages
-%pyruvate
-figure("Name","Pyruvate Met Images");
-imagescn(squeeze(metImages(:,:,slices,1,tpts)),[0 max(squeeze(metImages(:,:,slices,1,tpts)),[],'all')], [numel(slices) numel(tpts)]); colormap hot;
-
-%lactate
-figure("Name","Lactate Met Images");
-imagescn(squeeze(metImages(:,:,slices,2,tpts)),[0 max(squeeze(metImages(:,:,slices,2,tpts)),[],'all')], [numel(slices) numel(tpts)]); colormap hot;
-
-%bicarb
-figure("Name","Bicarb Met Images");
-imagescn(squeeze(metImages(:,:,slices,3,tpts)),[0 max(squeeze(metImages(:,:,slices,3,tpts)),[],'all')], [numel(slices) numel(tpts)]); colormap hot;
-
-
-%% visualize AUCs
-
-%pyruvate
-pyrAUC = sum(squeeze(metImages(:,:,:,1,:)),length(size(squeeze(metImages(:,:,:,1,:)))));
-figure("Name","Pyruvate AUC");
-imagescn(pyrAUC,[0 max(pyrAUC,[],'all')], [1 numel(slices)]); colormap hot;
-
-
-%lactate
-lacAUC = sum(squeeze(metImages(:,:,:,2,:)),length(size(squeeze(metImages(:,:,:,2,:)))));
-figure("Name","Lactate AUC");
-imagescn(lacAUC,[0 max(lacAUC,[],'all')], [1 numel(slices)]); colormap hot;
-
-
-%bicarb
-bicAUC = sum(squeeze(metImages(:,:,:,3,:)),length(size(squeeze(metImages(:,:,:,3,:)))));
-figure("Name","Bicarb AUC");
-imagescn(bicAUC,[0 max(bicAUC,[],'all')], [1 numel(slices)]); colormap hot;
diff --git a/simulations/anatomical_phantoms/metabolite.m b/simulations/anatomical_phantoms/metabolite.m
new file mode 100644
index 0000000..61bee9f
--- /dev/null
+++ b/simulations/anatomical_phantoms/metabolite.m
@@ -0,0 +1,34 @@
+classdef metabolite
+ properties
+ Mz0 (1,1) {mustBeNumeric}
+ R1 (1,1) {mustBeNumeric}
+ K (1,2) {mustBeNumeric}
+ end
+
+ methods
+ function obj = metabolite(args) % name=value arguments
+ % Parameters:
+ % Mz0 = initial magnetization. size = (1,1)
+ % R1 = relaxation rate. size = (1,1)
+ % k = kinetic rate(s). size = (1,1) for only forward rate, or (1,2) for forward and reverse rate
+ arguments
+ args.Mz0 (1,1) {mustBeNumeric} = 0
+ args.R1 (1,1) {mustBeNumeric} = 0
+ args.k (1,:) {mustBeNumeric} = 0
+ end
+
+ obj.Mz0 = args.Mz0;
+ obj.R1 = args.R1;
+
+ % parse k
+ if size(args.k, 2) == 1
+ obj.K = [args.k, 0];
+ elseif size(args.k, 2) == 2
+ obj.K = args.k;
+ else
+ error("size of `k` must have size of either (1,1) (forward rate only) or (1,2) (both forward and reverse rates)");
+ end
+
+ end
+ end
+end
diff --git a/simulations/anatomical_phantoms/mri_system.m b/simulations/anatomical_phantoms/mri_system.m
new file mode 100644
index 0000000..3b28d9c
--- /dev/null
+++ b/simulations/anatomical_phantoms/mri_system.m
@@ -0,0 +1,361 @@
+classdef mri_system
+ methods (Static)
+ function [met_images_mres, coil_sens_weights] = run_mri_system(met_images, sample_size, snr, coil_lim, tissue_struct, output_size, augment_params, opts)
+ % Wrapper for easy use of mri system model
+ % Parameters:
+ % met_images = single-resolution metabolite images. size = (row, col, slice, met, tpt)
+ % sample_size = desired size of multires images. size = (met, dim)
+ % snr = signal-to-noise ratio. size = (1, met)
+ % coil_lim = coil limits. [min, max]
+ % tissue_struct = tissue structure. size = (1,1). type = tissue_structure
+ % output_size = desired output_size. size = (met, dim)
+ % augment_params = augmentation parameters. struct
+ % Options:
+ % include_bg_noise = boolean flag to include background noise
+ % Outputs:
+ % met_images_mres = multiresolution metabolite images.
+ % size = (1, met) cell array. size of each cell = (row, col, slice, time_pt)
+ % coil_sens_weights = coil sensitivity weights
+
+
+ % argument validation
+ arguments
+ met_images (:,:,:,:,:) {mustBeNumeric}
+ sample_size (:,3) {mustBeNumeric}
+ snr (1,:) {mustBeNumeric}
+ coil_lim (1,2) {mustBeNumeric}
+ tissue_struct (1,1) tissue_structure
+ output_size (:,3) {mustBeNumeric} = NaN
+ augment_params struct = struct()
+ opts.include_bg_noise (1,1) logical = true
+ end
+
+ n_mets = size(met_images, 4);
+ if size(sample_size, 1) ~= n_mets && size(sample_size, 1) ~= 1
+ error('Mismatched array sizes: the 1st dimension of `sample_size` must equal n_mets OR 1');
+ end
+ if size(snr, 2) ~= n_mets
+ error('mismatched array sizes: the 2nd dimension of `snr` must equal n_mets');
+ end
+ if (size(output_size, 1) ~= n_mets) && (size(output_size, 1) ~= 1) && (all(~isnan(output_size), 'all'))
+ error('mismatched array sizes: the 1st dimension of `output_size` must equal n_mets OR 1');
+ end
+
+ % run the system
+ if ~isempty(fieldnames(augment_params))
+ cell_augment_params = namedargs2cell(augment_params); % unpack the augmentation parameters
+ [met_images, transform] = mri_system.augment(met_images, cell_augment_params{:});
+ tissue_struct = tissue_struct.apply_transforms(transform.tform2d, transform.z_translation);
+ end
+ [met_images, coil_sens_weights] = mri_system.apply_coil_lim(met_images, coil_lim, tissue_struct.Mask);
+ met_images_mres = mri_system.make_met_images_multires(met_images, sample_size);
+ if opts.include_bg_noise
+ [met_images_mres, ~] = mri_system.add_rician_noise(met_images_mres, snr);
+ else
+ [~, met_images_mres] = mri_system.add_rician_noise(met_images_mres, snr);
+ end
+
+ if all(~isnan(output_size), 'all')
+ met_images_mres = mri_system.upsample_to_output_size(met_images_mres, output_size);
+ end
+ end
+
+ function met_images_multires = make_met_images_multires(met_images, sample_size)
+ % Converts single-resolution dynamic metabolite images to multiresolution dynamic metabolite images
+ % Parameters:
+ % met_images = single-resolution dynamic metabolite images.
+ % size = (row, col, slice, metabolite, time_pt)
+ % sample_size = desired matrix sizes for each metabolite.
+ % size = (metabolite, dim) OR (1, dim)
+ %
+ % Outputs:
+ % met_images_multires = multiresolution dynamic metabolite images.
+ % size = (1, met) cell array, where size of each cell = (row, col, slice, time_pt)
+ arguments
+ met_images (:,:,:,:,:) {mustBeNumeric}
+ sample_size (:,3) {mustBeInteger, mustBePositive}
+ end
+
+ n_mets = size(met_images, 4);
+
+ if size(sample_size, 1) == 1
+ sample_size = repmat(sample_size, [n_mets, 1]);
+ elseif size(sample_size, 1) ~= n_mets
+ error('Mismatched array sizes: the 1st dimension of `sample_size` must equal n_mets OR 1');
+ end
+
+ n_mets = size(met_images, 4);
+ n_time_pts = size(met_images, 5);
+ met_images_multires = cell(1, n_mets);
+
+ for Imet = 1:n_mets
+ met_images_multires{Imet} = zeros( ...
+ cat(2, sample_size(Imet, :), n_time_pts) ...
+ );
+ for time_pt = 1:n_time_pts
+ met_images_multires{Imet}(:, :, :, time_pt) = ...
+ imresize3(squeeze(met_images(:, :, :, Imet, time_pt)), sample_size(Imet, :), 'box'); % box averages surrounding voxels
+ end
+ end
+ end
+
+
+ function [met_images_w_noise, met_images_w_noise_no_bg] = add_rician_noise(met_images, snr)
+ % Adds rician noise to dynamic metabolite images
+ % Parameters:
+ % met_images = dynamic metabolite images. either:
+ % - (1, met) cell array, where size of each cell = (row, col, slice, time_pt); OR
+ % - numerical array. size = (met, row, col, slice, time_pt)
+ % snr = signal-to-noise ratio per metabolite. (1, metabolite)
+ %
+ % Outputs:
+ % met_images_w_noise = metabolite images with rician noise.
+ % size = (1, met) cell array, where size of each
+ % cell = (row, col, slice, time_pt)
+ % met_images_w_noise_no_bg = metabolite images with rician noise, without background noise
+ % size = (1, met) cell array, where size of each
+ % cell = (row, col, slice, time_pt)
+
+ % argument validation/input parsing
+ arguments
+ met_images
+ snr (1,:) {mustBeNumeric}
+ end
+
+ % convert to cell array if not already a cell array
+ if isnumeric(met_images)
+ if numel(size(met_images)) ~= 5
+ error("met_images must either be a numeric array with size = [nmets, row, col, slice, time_pt] OR be a [1, nmets] cell array where each cell = [row, col, slice, time_pt],");
+ end
+
+ n_mets = size(met_images, 1);
+ cell_met_images = cell(1, n_mets);
+ for imet = 1:n_mets
+ single_met_image = met_images(imet,:,:,:,:);
+ single_met_image = reshape(single_met_image, size(single_met_image, 2:numel(size(single_met_image)))); % remove first dimension (without squeeze() lest another dim = 1)
+
+ cell_met_images{imet} = single_met_image;
+ end
+
+ met_images = cell_met_images;
+ % error if not either numeric or cell
+ elseif ~iscell(met_images)
+ error("met_images must either be a numeric array with size = [nmets, row, col, slice, time_pt] OR be a [1, nmets] cell array where each cell = [row, col, slice, time_pt],");
+ end
+
+ % error if number of metabolites don't match in met_images and snr
+ if numel(met_images) ~= size(snr, 2)
+ error("mismatched array sizes. met_images_multires and SNR must both have length = n_mets");
+ end
+
+ met_images_w_noise = met_images;
+ met_images_w_noise_no_bg = met_images;
+ n_mets = numel(met_images);
+ for imet = 1:n_mets
+ [image_w_bg, image_w_out_bg] = mri_system.add_rician_noise_image(met_images{imet}, snr(imet));
+ met_images_w_noise{imet} = image_w_bg;
+ met_images_w_noise_no_bg{imet} = image_w_out_bg;
+ end
+ end
+
+ function output_met_images = upsample_to_output_size(met_images_lowres, output_size)
+ % Upsamples dynamic metabolite images to output size
+ % Parameters:
+ % met_images_lowres = un-resized metabolite images.
+ % size = (1, met) cell array, where each cell = (row, col, slice, time_pt)
+ % output_size = desired output matrix size. size = (met, dim) OR (1, dim)
+ % Outputs:
+ % output_met_images = upsampled met images
+ arguments
+ met_images_lowres
+ output_size (:,3) {mustBeNumeric}
+ end
+
+ n_mets = numel(met_images_lowres);
+ if size(output_size, 1) == 1
+ output_size = repmat(output_size, [n_mets, 1]);
+ elseif size(output_size, 1) ~= n_mets
+ error("mismatched array sizes. 1st dimension of `output_size` should both equal n_mets OR 1");
+ end
+
+ % upsample
+ output_met_images = cell(1, n_mets);
+ for i_met = 1:n_mets
+ n_tpts = size(met_images_lowres{i_met}, 4);
+ met_output_size = output_size(i_met, :);
+ output_met_images{i_met} = zeros(cat(2, met_output_size, n_tpts));
+ for i_tpt = 1:n_tpts
+ output_met_images{i_met}(:,:,:,i_tpt) = imresize3(met_images_lowres{i_met}(:,:,:,i_tpt), met_output_size);
+ end
+ end
+ end
+
+ function [augmented_met_images, transform] = augment(met_images, augs)
+ % Augments image
+ % Positional Parameters:
+ % met_images = metabolite images. size = (row, col, slice, met, tpt)
+ % Name-Value Parameters: see randomAffine2d
+ % Outputs:
+ % augmented_met_images = augmented metabolite images. size = (row, col, slice, met, tpt)
+ % transform = transformation applied to images
+ % transform.tform2d = transform applied to images. type = affinetform2d
+ % transform.z_translation = z translation applied to images. size = (1,1)
+ arguments
+ met_images (:,:,:,:,:) {mustBeNumeric}
+ augs.XTranslation (1,2) {mustBeNumeric} = [0,0]
+ augs.YTranslation (1,2) {mustBeNumeric} = [0,0]
+ augs.ZTranslation (1,2) {mustBeNumeric} = [0,0]
+ augs.Rotation (1,2) {mustBeNumeric} = [0,0]
+ augs.Scale (1,2) {mustBeNumeric} = [1,1]
+ augs.XReflection (1,1) {mustBeNumericOrLogical} = false
+ augs.YReflection (1,1) {mustBeNumericOrLogical} = false
+ augs.XShear (1,2) {mustBeNumeric} = [0,0]
+ augs.YShear (1,2) {mustBeNumeric} = [0,0]
+ augs.Seed (1,1) {mustBeNumeric} = NaN
+ end
+
+ % initialize rng
+ if ~isnan(augs.Seed)
+ rng(augs.Seed);
+ else
+ rng("shuffle");
+ end
+
+ tform = randomAffine2d(...
+ XTranslation=augs.XTranslation, ...
+ YTranslation=augs.YTranslation, ...
+ Rotation=augs.Rotation, ...
+ Scale=augs.Scale, ...
+ XReflection=augs.XReflection, ...
+ YReflection=augs.YReflection, ...
+ XShear=augs.XShear, ...
+ YShear=augs.YShear ...
+ );
+
+ output_view = affineOutputView(size(met_images, [1,2]), tform, BoundsStyle="CenterOutput");
+ augmented_met_images = zeros(size(met_images));
+ for i_met = 1:size(met_images, 4)
+ for i_tpt = 1:size(met_images, 5)
+ augmented_met_images(:,:,:,i_met,i_tpt) = imwarp(met_images(:,:,:,i_met,i_tpt), tform, OutputView=output_view);
+ end
+ end
+
+ % z translation
+ offset = randi(augs.ZTranslation);
+ aug_met_img_ztrans = zeros(size(augmented_met_images));
+ n_slices = size(met_images,3);
+ cutoff = n_slices - abs(offset);
+ if offset > 0
+ aug_met_img_ztrans(:,:, 1:cutoff, :,:) = augmented_met_images(:,:, (offset + 1):n_slices ,:,:);
+ augmented_met_images = aug_met_img_ztrans;
+ elseif offset < 0
+ aug_met_img_ztrans(:,:, (abs(offset) + 1):n_slices, :,:) = augmented_met_images(:,:, 1:cutoff, :,:);
+ augmented_met_images = aug_met_img_ztrans;
+ end
+
+ transform.tform2d = tform;
+ transform.z_translation = offset;
+ end
+
+ function [met_images_w_coil_lim, coil_sens_weights] = apply_coil_lim(met_images, coil_lim, tissue_mask)
+ % Parameters:
+ % met_images = metabolite images. size = (row, col, slice, met, time_pt)
+ % coil_lim = coil sensitivity limits. [min, max]
+ % tissue_mask = tissue mask. size = (row, col, slice, tissue)
+ % Outputs:
+ % met_images_w_coil_lim = metabolite images with coil sensitivity. size = (row, col, slice, met, time_pt)
+ % coil_sens_weights = coil sensitivity weights
+
+ % argument validation
+ arguments
+ met_images (:,:,:,:,:) {mustBeNumeric}
+ coil_lim (1,2) {mustBeNumeric}
+ tissue_mask (:,:,:,:) {mustBeNumeric}
+ end
+
+ if any(size(met_images, 1:3) ~= size(tissue_mask, 1:3))
+ error("mismatched array sizes. `met_images` and `tissue_mask` must have the same number of rows, cols, and slices");
+ end
+
+ mask = sum(tissue_mask, 4);
+ coil_sens_weights = mri_system.coil_dist_map(mask, coil_lim);
+
+ n_mets = size(met_images, 4);
+ n_tpts = size(met_images, 5);
+ expanded_coil_sens_weights = repmat(coil_sens_weights, [1, 1, 1, n_mets, n_tpts]);
+
+ met_images_w_coil_lim = met_images .* expanded_coil_sens_weights;
+ end
+ end
+
+ methods (Static, Access = private)
+ function [met_image_w_noise, met_image_w_noise_no_bg] = add_rician_noise_image(met_image, snr)
+ % Adds rician noise to single dynamic metabolite image
+ % Parameters:
+ % met_image = single met image. size = (row, col, slice, time_pt)
+ % snr = signal-to-noise ratio. size = (1,1)
+ % Outputs:
+ % met_image_w_noise = metabolite image with noise. size = (row, col, slice, time_pt)
+ % met_image_w_noise_no_bg = metabolite images with noise, without background noise. size = (row, col, slice, time_pt)
+
+ arguments
+ met_image (:,:,:,:) {mustBeNumeric}
+ snr (1,1) {mustBeNumeric}
+ end
+
+ nt = size(met_image, 4);
+ sample_size = size(met_image, 1:3);
+
+ std_noise = max(sum(met_image, 4), [], 'all') ./ (snr * sqrt(nt));
+ noise_R = randn(cat(2, sample_size, nt)) * std_noise;
+ noise_I = randn(cat(2, sample_size, nt)) * std_noise;
+
+ met_image_w_noise = sqrt((met_image + noise_R).^2 + noise_I.^2);
+
+ met_image_w_noise_no_bg = met_image_w_noise;
+ met_image_w_noise_no_bg(met_image == 0) = 0;
+ end
+
+ % taken from brainweb
+ function [weights] = coil_dist_map(mask, lim)
+ maskSize = size(mask);
+ weights = zeros(maskSize);
+
+ % create y gradient
+ x = linspace(-1, 1, maskSize(1));
+ y = linspace(-1, 1, maskSize(2));
+ z = linspace(-1, 1, maskSize(3));
+ [~, Y, Z] = meshgrid(x, y, z);
+
+ % y gradient
+ %lim = [0.6, 1.2];
+ grady = 0.5*(lim(2) - lim(1))*Y + 0.5*(lim(1) + lim(2));
+
+ % z gradient
+ gradz = (1 - abs(Z).^2) + 0.6;
+ gradz = gradz ./ max(gradz, [], 'all');
+
+ grad = grady .* gradz;
+
+ for z=1:maskSize(3)
+ mask_sl = squeeze(mask(:,:,z));
+
+ % get outline/perim of mask
+ mask_sl = imfill(bwmorph(bwareaopen(mask_sl,300),"fill"),"holes");
+ %figure, imagesc(mask); axis off square;
+ bw2 = bwperim(mask_sl);
+ %figure, imagesc(bw2)
+
+ %reverse_mask
+ mask_rev = imcomplement(mask_sl);
+
+ % calculate weights based on distance from mask perim
+ w = bwdist(bw2) .^0.5;
+ weights(:,:,z) = ((1 - (w ./max(w(:)))) .* grad(:,:,z) .* mask_sl) + mask_rev;
+ %figure, imagesc(weights)
+ end
+
+ weights(isnan(weights)) = 0;
+ end
+ end
+end
diff --git a/simulations/anatomical_phantoms/pk_model.m b/simulations/anatomical_phantoms/pk_model.m
new file mode 100644
index 0000000..0fa8cad
--- /dev/null
+++ b/simulations/anatomical_phantoms/pk_model.m
@@ -0,0 +1,263 @@
+classdef pk_model
+ methods (Static)
+ function [met_images, dynamics_low_ktrans, dynamics_high_ktrans, images_low_ktrans, images_high_ktrans] = run_pk_model(mz0, r1, k, flips, tr, tissue_struct, opts)
+ % Wrapper for easy use of pk model.
+ % Parameters:
+ % mz0 = initial magnetization of each metabolite in each tissue. size = (met, tissue)
+ % r1 = relaxation rates. size = (1, met)
+ % k = forward kinetic rates of product metabolites. size = (met-1, tissue)
+ % flips = flip angles (rad). size = (met, time_pt)
+ % tr = temporal resolution. size = (1,1)
+ % tissue_struct = tissue_structure. size = (1,1), type = tissue_structure
+ % Additional options:
+ % input_function = additional input for substrate per tissue per time point. size = (tissue, tpt). may not be provided if `t_arrival` and `t_bolus` are provided.
+ % t_arrival = arrival time of substrate. size = (1, tissue). must be provided with `t_bolus`.
+ % t_bolus = time it takes for bolus to enter. size = (1,1). must be provided with `t_arrival`
+ % Outputs:
+ % met_images = dynamic metabolite images. size = (row, col, slice, tissue, met, time_pt)
+ % dynamics_low_ktrans = metabolite dynamices with k_trans = 0. size = (tissue, met, time_pt)
+ % dynamics_high_ktrans = metabolite dynamices with k_trans = 1. size = (tissue, met, time_pt)
+ % images_low_ktrans = metabolite images with k_trans = 0. size = (row, col, slice, tissue, met, time_pt)
+ % images_high_ktrans = metabolite images with k_trans = 1. size = (row, col, slice, tissue, met, time_pt)
+ arguments
+ mz0 (:,:) {mustBeNumeric}
+ r1 (1,:) {mustBeNumeric}
+ k (:,:) {mustBeNumeric}
+ flips (:,:) {mustBeNumeric}
+ tr (1,1) {mustBeNumeric}
+ tissue_struct (1,1) tissue_structure
+ opts.input_function (:,:) {mustBeNumeric} = NaN
+ opts.t_arrival (1,:) {mustBeNumeric} = NaN
+ opts.t_bolus (1,1) {mustBeNumeric} = NaN
+ end
+ n_tissues = size(mz0, 2);
+ dynamics_low_ktrans = pk_model.generate_all_met_dynamics(mz0, r1, k, zeros(1, n_tissues), flips, tr, ...
+ input_function=opts.input_function, t_arrival=opts.t_arrival, t_bolus=opts.t_bolus);
+ dynamics_high_ktrans = pk_model.generate_all_met_dynamics(mz0, r1, k, ones(1, n_tissues), flips, tr, ...
+ input_function=opts.input_function, t_arrival=opts.t_arrival, t_bolus=opts.t_bolus);
+
+ images_low_ktrans = pk_model.generate_met_images(tissue_struct, dynamics_low_ktrans);
+ images_high_ktrans = pk_model.generate_met_images(tissue_struct, dynamics_high_ktrans);
+
+ met_images = pk_model.apply_k_trans(images_low_ktrans, images_high_ktrans, tissue_struct.K_trans_map);
+ end
+
+
+ function met_dynamics = generate_all_met_dynamics(mz0, r1, k, k_trans, flips, tr, opts)
+ % Wrapper for easy use of generate_met_dynamics(). Accepts either input_function OR t_arrival and t_bolus
+ % Parameters:
+ % mz0 = initial magnetization of each metabolite in each tissue. size = (met, tissue)
+ % r1 = relaxation rates. size = (1, met)
+ % k = forward kinetic rates of product metabolites. size = (met-1, tissue)
+ % k_trans = volumetric transfer constants. size = (1, tissue)
+ % flips = flip angles (rad). size = (met, time_pt)
+ % tr = temporal resolution. size = (1,1)
+ % Additional options:
+ % input_function = additional input for substrate per tissue per time point. size = (tissue, tpt). may not be provided if `t_arrival` and `t_bolus` are provided.
+ % t_arrival = arrival time of substrate. size = (1, tissue). must be provided with `t_bolus`.
+ % t_bolus = time it takes for bolus to enter. size = (1,1). must be provided with `t_arrival`
+ % Outputs:
+ % met_dynamics = metabolite dynamics. size = (tissue, met, time_pt)
+
+ % argument validation
+ arguments
+ mz0 (:,:) {mustBeNumeric}
+ r1 (1,:) {mustBeNumeric}
+ k (:,:) {mustBeNumeric}
+ k_trans (1,:) {mustBeNumeric}
+ flips (:,:) {mustBeNumeric}
+ tr (1,1) {mustBeNumeric}
+ opts.input_function (:,:) {mustBeNumeric} = NaN
+ opts.t_arrival (1,:) {mustBeNumeric} = NaN
+ opts.t_bolus (1,1) {mustBeNumeric} = NaN
+ end
+
+ % input function, t_arrival, t_bolus parsing
+ provided_opts = [~any(isnan(opts.input_function), 'all'), ~any(isnan(opts.t_arrival), 'all'), ~isnan(opts.t_bolus)]; % e.g. if only input function is provided, this is [1,0,0]
+
+ if provided_opts == [1,0,0] % case when only input_function is provided
+ input_function = opts.input_function;
+ elseif provided_opts == [0,1,1] % case when t_arrival and t_bolus are provided, but not input_function
+ % verify t_arrival and t_bolus
+ n_tissues = size(mz0, 2);
+ n_tpts = size(flips, 2);
+ if size(opts.t_arrival, 1) ~= 1
+ error("`t_arrival` must have a size = (1, tissue)");
+ end
+ if size(opts.t_arrival, 2) ~= n_tissues
+ error("mismatched number of tissues in `Mz0` and `t_arrival`");
+ end
+ % create input_function
+ input_function = zeros(n_tissues, n_tpts);
+ for i_tissue = 1:n_tissues
+ input_function(i_tissue, :) = realistic_input_function(n_tpts, tr, opts.t_arrival(i_tissue), opts.t_bolus);
+ end
+ elseif provided_opts == [0,0,0] % case when nothing is provided
+ n_tissues = size(mz0, 2);
+ n_tpts = size(flips, 2);
+ input_function = zeros(n_tissues, n_tpts);
+ else
+ error("Provide EITHER `input_function` OR both `t_arrival` and `t_bolus`")
+ end
+
+ % validate the rest of the arguments
+ [n_mets, n_tissues, n_tpts] = pk_model.validate_pk_args(mz0, r1, k, k_trans, flips, input_function);
+
+ % migrate everything over to compartment-specific pk params
+ met_dynamics = zeros(n_tissues, n_mets, n_tpts);
+ for i_tissue = 1:n_tissues
+ % get substrate
+ substrate = metabolite( ...
+ Mz0=mz0(1,i_tissue), ...
+ R1=r1(1), ...
+ k=[0,0]);
+
+ % get products
+ products(1, n_mets-1) = metabolite;
+ for i_met = 2:n_mets
+ products(i_met-1) = metabolite( ...
+ Mz0=mz0(i_met, i_tissue), ...
+ R1=r1(i_met), ...
+ k=[k(i_met - 1, i_tissue), 0]);
+ end
+
+ % put it all into pk_params
+ tissue_pk_params = pk_params(...
+ substrate=substrate, ...
+ products=products, ...
+ TR=tr, ...
+ input_function=input_function(i_tissue, :), ...
+ flips=flips);
+
+ % generate met dynamics
+ met_dynamics(i_tissue,:,:) = pk_model.generate_met_dynamics(tissue_pk_params, k_trans(i_tissue));
+ end
+ end
+
+
+ function met_dynamics = generate_met_dynamics(params, k_trans)
+ % Generates metabolite dynamics from PK parameters
+ % Parameters:
+ % params = pk parameters. size = (1,1), type = pk_params
+ % k_trans = volumetric transfer constant. size = (1,1)
+ % Outputs:
+ % met_dynamics = metabolite dynamics. size = (met, tpt)
+ arguments
+ params (1,1) pk_params
+ k_trans (1,1) {mustBeNumeric} = 1;
+ end
+
+ % prep everything for simulate_Nsite_model()
+ Mz0 = params.get_Mz0();
+ R1 = params.get_R1();
+ k = params.get_kinetic_rates();
+ flips = params.get_flips();
+ TR = params.TR;
+ input_function = params.InputFunction;
+
+ [met_dynamics, ~] = simulate_Nsite_model(Mz0, R1, k, flips, TR, input_function .* k_trans);
+ end
+
+ function met_images = generate_met_images(tissue_struct, met_dynamics)
+ % Parameters:
+ % met_dynamics = metabolite dynamics. size = (tissue, met, time_pt)
+ % tissue_struct = tissue_structure. size = (1,1), type = tissue_structure
+ % Outputs:
+ % met_images = dynamic metabolite images.
+ % size = (row, col, slice, tissue, met, time_pt)
+ arguments
+ tissue_struct (1,1) tissue_structure
+ met_dynamics {mustBeNumeric}
+ end
+
+ % validate args
+ if size(tissue_struct.Mask, 4) ~= size(met_dynamics,1)
+ error("mismatched number of tissues in tissue structure and met dynamics");
+ end
+
+ time_pts = size(met_dynamics, 3);
+ n_mets = size(met_dynamics, 2);
+
+ % reshape + expand met dynamic
+ met_dynamics = reshape(met_dynamics, cat(2,[1,1,1],size(met_dynamics)));
+ met_dynamics = repmat(met_dynamics, cat(2, size(tissue_struct.Mask, 1:3), [1,1,1]));
+
+ % expand mask
+ mask = tissue_struct.Mask; % = (row, col, slice, tissue)
+ mask = repmat(mask, cat(2,[1,1,1,1,n_mets,time_pts]));
+
+ % multiply
+ met_images = met_dynamics .* mask;
+
+ % sum across tissues
+ met_images = squeeze(sum(met_images, 4));
+ end
+
+ function met_images = apply_k_trans(met_images_low_ktrans, met_images_high_ktrans, k_trans_map)
+ % Parameters:
+ % met_images_low_ktrans = met_images where k_trans = 0 (no additional input).
+ % size = (row, col, slice, met, time_pt)
+ % met_images_high_ktrans = met_images where k_trans = 1 (100% additional input).
+ % size = (row, col, slice, met, time_pt)
+ % k_trans_map = map of k_trans values. size = (row, col, slice)
+ % Outputs:
+ % met_images = met images with k_trans applied. size = (row, col, slice, met time_pt)
+
+ % argument validation
+ arguments
+ met_images_low_ktrans (:,:,:,:,:) {mustBeNumeric}
+ met_images_high_ktrans (:,:,:,:,:) {mustBeNumeric}
+ k_trans_map (:,:,:) {mustBeNumeric}
+ end
+
+ if any(size(met_images_low_ktrans) ~= size(met_images_high_ktrans))
+ error("mismatched array sizes. `met_images_low_ktrans` and `met_images_high_ktrans` must have the same size");
+ end
+
+ if any(size(k_trans_map) ~= size(met_images_low_ktrans, 1:3))
+ error("mismatched array sizes. `k_trans_map` mut have the same number of rows, columns, and slices as `met_images_low_ktrans`");
+ end
+
+ % expand k_trans_map
+ n_mets = size(met_images_low_ktrans, 4);
+ n_tpts = size(met_images_low_ktrans, 5);
+ full_ktrans_map = repmat(k_trans_map, 1, 1, 1, n_mets, n_tpts);
+
+ % interpolate
+ met_images = met_images_low_ktrans + (met_images_high_ktrans - met_images_low_ktrans) .* full_ktrans_map;
+ end
+ end
+
+
+ methods (Static, Access = private)
+ function [n_mets, n_tissues, n_tpts] = validate_pk_args(mz0, r1, k, k_trans, flips, input_function, t_arrival)
+ % validates arguments for `run_pk_model`
+ n_mets = size(mz0, 1);
+ if size(r1, 2) ~= n_mets
+ error("mismatched number of metabolites in `Mz0` and `R1`");
+ end
+ if size(flips, 1) ~= n_mets
+ error("mismatched number of metabolites in `Mz0` and `flips`");
+ end
+ if size(k, 1) ~= n_mets - 1
+ error("mismatched number of metabolits in `Mz0` and `k`. `k` should have n_mets-1 rows");
+ end
+
+ n_tissues = size(mz0, 2);
+ if size(k, 2) ~= n_tissues
+ error("mismatched number of tissues in `Mz0` and `k`");
+ end
+ if size(input_function, 1) ~= n_tissues
+ error("mismatched number of tissues in `Mz0` and `input_function`");
+ end
+ if size(k_trans, 2) ~= n_tissues
+ error("mismatched number of tissues in `Mz0` and `k_trans`");
+ end
+
+ n_tpts = size(flips, 2);
+ if size(input_function, 2) ~= n_tpts;
+ error("mismatched number of time points in `flips` and `input_function`");
+ end
+ end
+ end
+end
diff --git a/simulations/anatomical_phantoms/pk_params.m b/simulations/anatomical_phantoms/pk_params.m
new file mode 100644
index 0000000..bcb1ed1
--- /dev/null
+++ b/simulations/anatomical_phantoms/pk_params.m
@@ -0,0 +1,76 @@
+classdef pk_params
+ properties
+ Substrate (1,1) metabolite
+ Products (1,:) metabolite
+ TR (1,1) {mustBeNumeric}
+ InputFunction (1,:) {mustBeNumeric}
+ Flips (:,:) {mustBeNumeric}
+ end
+ methods
+ function obj = pk_params(args)
+ % Parameters:
+ % substrate = substrate metabolite. size = (1,1), type = metabolite
+ % products = product metabolites. size = (1, n_mets - 1), type = metabolite
+ % TR = repetition time. size = (1,1)
+ % input_function = additional input of substrate. size = (1, time_pt)
+ % flips = flip angles (rad). size = (met, time_pt)
+
+ % argument validation
+ arguments
+ args.substrate (1,1) metabolite
+ args.products (1,:) metabolite
+ args.TR (1,1) {mustBeNumeric}
+ args.input_function (1,:) {mustBeNumeric}
+ args.flips (:,:) {mustBeNumeric}
+ end
+
+ n_mets = numel(args.substrate) + numel(args.products);
+ if size(args.flips, 1) ~= n_mets
+ error("Mismatched number of metabolites (substrate + number of products) and rows in `flips`");
+ end
+
+ nt = numel(args.input_function);
+ if size(args.flips, 2) ~= nt
+ error("mismatched number of time points in `input_function` and `flips`");
+ end
+
+ obj.Substrate = args.substrate;
+ obj.Products = args.products;
+ obj.TR = args.TR;
+ obj.InputFunction = args.input_function;
+ obj.Flips = args.flips;
+ end
+
+ % various getters
+ function Mz0 = get_Mz0(pk_params)
+ % Outputs: Mz0 = (1, met)
+ Mz0 = zeros(1, numel(pk_params.Products) + 1);
+ Mz0(1) = pk_params.Substrate.Mz0;
+ for met = 1:numel(pk_params.Products)
+ Mz0(met + 1) = pk_params.Products(met).Mz0;
+ end
+ end
+
+ function R1 = get_R1(pk_params)
+ % Outputs: R1 = (1, met)
+ R1 = zeros(1, numel(pk_params.Products) + 1);
+ R1(1) = pk_params.Substrate.R1;
+ for met = 1:numel(pk_params.Products)
+ R1(met + 1) = pk_params.Products(met).R1;
+ end
+ end
+
+ function flips = get_flips(pk_params)
+ % Outputs: flips = (met, time_pt)
+ flips = pk_params.Flips;
+ end
+
+ function k = get_kinetic_rates(pk_params)
+ % Outputs: kinetic rates = (met, fw/rv)
+ k = zeros(numel(pk_params.Products), 2);
+ for met = 1:numel(pk_params.Products)
+ k(met, :) = pk_params.Products(met).K;
+ end
+ end
+ end
+end
diff --git a/simulations/anatomical_phantoms/tissue_structure.m b/simulations/anatomical_phantoms/tissue_structure.m
new file mode 100644
index 0000000..3da808e
--- /dev/null
+++ b/simulations/anatomical_phantoms/tissue_structure.m
@@ -0,0 +1,220 @@
+classdef tissue_structure
+ properties
+ Name string
+ Mask (:,:,:,:) {mustBeNumeric} % size = (row, col, slice, tissue)
+ Tissues (1,:) string % size = (1, tissue)
+ K_trans_map (:,:,:) {mustBeNumeric} % size = (row, col, slice)
+ end
+ methods
+ function obj = tissue_structure(name, mask, tissues, dims)
+ % Parameters:
+ % name = name of tissue structure. size = (1,1), type = string
+ % mask = tissue masks. size = (row, col, slice, tissue), type = numeric or logical
+ % tissues = names of tissues. size = (1, tissue), type = string. purely semantic right now
+ % dims = (optional) desired size of mask. [rows, cols, slices]
+ arguments
+ name (1,1) string
+ mask (:,:,:,:) {mustBeNumericOrLogical}
+ tissues (1,:) string
+ dims (1,3) {mustBeInteger} = [0,0,0]
+ end
+
+ if numel(tissues) ~= size(mask, 4)
+ error("Mismatched number of tissues in `mask` and `tissues`")
+ end
+
+ obj.Name = name;
+ obj.Tissues = tissues;
+
+ if islogical(mask)
+ % cast to numeric if mask is logical
+ obj.Mask = double(mask);
+ else
+ obj.Mask = mask;
+ end
+
+ if dims ~= [0,0,0]
+ obj = obj.downscale_mask(dims);
+ end
+
+ obj = obj.normalize_mask();
+ end
+
+
+ function obj = create_k_trans_map(obj, k_trans)
+ % Parameters:
+ % k_trans = k_trans values. size = (1, tissue); OR
+ % (2, tissue) where row 1 = min k_trans, row 2 = max k_trans. if this is the case, k_trans will follow a linear gradient
+
+ % argument validation
+ arguments
+ obj
+ k_trans (:,:) {mustBeNumeric}
+ end
+
+ if size(k_trans, 1) > 2
+ error('length of 1st dimension of k_trans must be either 1 or 2');
+ end
+
+ if size(k_trans, 2) ~= size(obj.Mask, 4)
+ error('mismatched array sizes: 2nd dimension of `k_trans` and 4th dimension of `tissue_structure.Mask` must both equal number of tissues')
+ end
+
+ % case where k_trans is constant (not gradient)
+ % mask = (row, col, slice, tissue)
+ if size(k_trans, 1) == 1
+ mask = permute(obj.Mask, [4,1,2,3]);
+ obj.K_trans_map = squeeze(pagemtimes(k_trans, mask));
+ return
+ end
+
+ % case where k_trans is a gradient
+ n_tissues = size(k_trans, 2);
+ mask_size = size(obj.Mask, 1:3);
+
+ k_trans_map = zeros(size(obj.Mask));
+ for i_tissue = 1:n_tissues
+ gradient = generate_linear_gradient(mask_size, k_trans(1, i_tissue), k_trans(2, i_tissue));
+ k_trans_map(:,:,:,i_tissue) = squeeze(obj.Mask(:,:,:,i_tissue)) .* gradient;
+ end
+
+ obj.K_trans_map = sum(k_trans_map, 4);
+
+ % helper function from `brainweb_metabolic_phantom`
+ function grad = generate_linear_gradient(maskSize, kTRANS_low, kTRANS_high)
+ x = linspace(-1, 1, maskSize(1));
+ y = linspace(-1, 1, maskSize(2));
+ z = linspace(-1, 1, maskSize(3));
+ [~, Y, ~] = meshgrid(x, y, z);
+ grad = 0.5*(kTRANS_high - kTRANS_low)*Y + 0.5*(kTRANS_low + kTRANS_high);
+ end
+ end
+
+
+ function obj = downscale_mask(obj, dims)
+ % downscales mask (because large masks can cause issues with memory requests)
+ % Parameters:
+ % dims = desired dimensions. [rows, cols, slices]
+ arguments
+ obj
+ dims (1,3) {mustBeNumeric} = [100,100,100]
+ end
+
+ n_tissues = size(obj.Mask, 4);
+ new_mask = zeros(cat(2, dims, n_tissues));
+
+ for i_tissue = 1:n_tissues
+ new_mask(:,:,:,i_tissue) = imresize3(obj.Mask(:,:,:,i_tissue), dims, "cubic");
+ end
+
+ obj.Mask = new_mask;
+ end
+
+
+ function obj = normalize_mask(obj)
+ % normalizes voxels so that the sum of the masks of each tissue in any given voxel is no more than 1
+ norm_weights = sum(obj.Mask, 4);
+ norm_weights(norm_weights < 1) = 1; % only normalize voxels with a sum > 1
+ obj.Mask = obj.Mask ./ repmat(norm_weights, [1,1,1, size(obj.Mask,4)]);
+ end
+
+
+ function obj = apply_transforms(obj, tform2d, z_translation)
+ % applies transformations to obj.Mask
+ % Parameters:
+ % tform2d = transform to apply to each slice. type = affinetform2d
+ % z_translation = z translation
+ arguments
+ obj
+ tform2d (1,1) affinetform2d
+ z_translation (1,1) {mustBeNumeric}
+ end
+
+ output_view = affineOutputView(size(obj.Mask, [1,2]), tform2d, BoundsStyle="CenterOutput");
+ for i_tissue = 1:size(obj.Mask, 4)
+ obj.Mask(:,:,:,i_tissue) = imwarp(obj.Mask(:,:,:,i_tissue), tform2d, OutputView=output_view);
+ end
+
+ % z translation
+ mask_ztrans = zeros(size(obj.Mask));
+ n_slices = size(obj.Mask,3);
+ cutoff = n_slices - abs(z_translation);
+ if z_translation > 0
+ mask_ztrans(:,:, 1:cutoff, :,:) = obj.Mask(:,:, (z_translation + 1):n_slices ,:,:);
+ obj.Mask = mask_ztrans;
+ elseif z_translation < 0
+ mask_ztrans(:,:, (abs(z_translation) + 1):n_slices, :,:) = obj.Mask(:,:, 1:cutoff, :,:);
+ obj.Mask = mask_ztrans;
+ end
+
+ end
+
+
+ function [rgb, colors, fig] = plot_alpha_composite_image(obj, opts)
+ % plots color visualization of mask
+ % Optional Parameters:
+ % slice = slice to plot. size = (1,1)
+ % order = layer order of each tissue. size = (1, tissue)
+ % Outputs:
+ % rgb = rgb alpha-composited volume. size = (row, col, slice, 3)
+ % colors = rgb triplets of each tissue. size = (tissue, 3)
+ % fig = the figure that this creates
+
+ % https://en.wikipedia.org/wiki/Alpha_compositing
+ % performs the 'over' operation (basically, laying transparent layers on top of each other):
+ % a_0 = a_a + a_b * (1 - a_a)
+ % C_0 = (C_a * a_a + C_b * a_b * (1 - a_a)) / a_0
+ % where a_0, a_a, and a_b are the alpha values of the pixels
+ % and C_0, C_a, and C_b are the color components of the pixels
+
+ arguments
+ obj
+ opts.slice (1,1) {mustBeNumeric} = NaN
+ opts.order (1,:) {mustBeNumeric} = NaN
+ end
+
+ n_tissues = size(obj.Mask, 4);
+
+ if any(isnan(opts.order))
+ opts.order = 1:n_tissues;
+ elseif numel(opts.order) ~= n_tissues
+ error('mismatched number of tissues in `order` and `tissue_structure.Mask`');
+ end
+
+ % find rgb
+ norm_mask = obj.Mask ./ max(sum(obj.Mask, 4), [], 'all');
+
+ colors = lines(n_tissues);
+ rgb = zeros(cat(2, size(norm_mask, 1:3), 3)); % rgb version of this
+ alpha = ones(size(norm_mask, 1:3)); % alpha values (initialized as 1)
+
+ for i_tissue = opts.order
+ mask_alpha = norm_mask(:,:,:,i_tissue);
+ alpha_0 = mask_alpha + alpha .* (1 - mask_alpha);
+ for color_channel = 1:3
+ C_a = colors(i_tissue, color_channel);
+ C_b = rgb(:,:,:,color_channel);
+ alpha_a = mask_alpha;
+ alpha_b = alpha;
+ rgb(:,:,:,color_channel) = (C_a .* alpha_a + C_b .* alpha_b .* (1 - alpha_a)) ./ alpha_0;
+ end
+ alpha = alpha_0;
+ end
+
+ if isnan(opts.slice)
+ return
+ end
+
+ % plot
+ fig = figure;
+ imshow(squeeze(rgb(:,:,opts.slice,:)));
+
+ % legend for this
+ fake_legend_lines = zeros(1, n_tissues);
+ for i_tissue = 1:n_tissues
+ fake_legend_lines(i_tissue) = line(NaN, NaN, 'color', colors(i_tissue, :));
+ end
+ legend(fake_legend_lines, num2cell(obj.Tissues));
+ end
+ end
+end
diff --git a/simulations/anatomical_phantoms/usage/brainweb_metabolic_phantom.m b/simulations/anatomical_phantoms/usage/brainweb_metabolic_phantom.m
new file mode 100644
index 0000000..85ce3c2
--- /dev/null
+++ b/simulations/anatomical_phantoms/usage/brainweb_metabolic_phantom.m
@@ -0,0 +1,99 @@
+clear; close all;
+addpath('../');
+addpath('../../pk_models/');
+addpath('../../../utilities/')
+
+%% PARAMETERS
+% tissue
+mask = load('../util/brainweb/1/brainweb_fuzzy.mat').im_mask;
+
+k_trans = [1, 0.2, 0.2;
+ 3, 0.4, 0.4];
+
+% pk model params
+tr = 3;
+n_t = 20;
+flips = repmat([20; 30; 30;], 1, n_t) .* (pi/180);
+r1 = [1/30, 1/25, 1/20]; % pyr, lac, bic
+k = [0, 0.03, 0.025; % lac, in order [vasc, gm, wm]
+ 0, 0.01, 0.005]; % bic
+t_arrival = [0, 0, 0]; % vasc, gm, wm
+t_bolus = 8;
+
+% input function and mz0
+n_tissues = 3;
+input_function = zeros(n_tissues, n_t);
+for i_tissue = 1:n_tissues
+ input_function(i_tissue, :) = realistic_input_function(n_t, tr, t_arrival(i_tissue), t_bolus);
+end
+mz0 = [input_function(1), input_function(1)*.5, input_function(1)*.5;
+ 0, input_function(1)*.01, input_function(1)*.01;
+ 0, input_function(1)*.005, input_function(1)*.005];
+
+% mri
+coil_lim = [0.2, 0.6];
+augment_params = struct(...
+ "XTranslation", [-1,1], ...
+ "YTranslation", [-1,1], ...
+ "Scale", [0.95,1.1], ...
+ "XReflection", true, ...
+ "Rotation", [-5,5], ...
+ "ZTranslation", [-20, 20]);
+
+sample_size = [32 32 8; 16 16 8; 16 16 8];
+snr = [150 40 20];
+output_size = [64 64 8];
+
+%% RUNNING THE MODEL -----------------------------------------------------------
+
+% tissue
+brain = tissue_structure("brain", mask, ["vasc", "gm", "wm"], [100,100,100]);
+brain = brain.create_k_trans_map(k_trans);
+
+% pk model
+images = pk_model.run_pk_model(mz0, r1, k, flips, tr, brain, input_function=input_function);
+
+% mri
+met_images_mres = mri_system.run_mri_system(images, sample_size, snr, coil_lim, brain, output_size, augment_params, include_bg_noise=false);
+
+%% DISPLAY ---------------------------------------------------------------------
+slices = 10:5:40;
+figure(Name='kTRANS');
+imagescn(brain.K_trans_map(:,:,slices), [0 max(brain.K_trans_map(:,:,slices), [], 'all')], [1 numel(slices)]);
+colormap fire;
+
+k_trans_dwnszd = imresize3(imresize3(brain.K_trans_map, [16 16 8]), [32 32 8]);
+slices = 1:size(k_trans_dwnszd, 3);
+figure(Name='kTRANS downsized');
+imagescn(k_trans_dwnszd(:,:,slices), [0 max(k_trans_dwnszd(:,:,slices), [], 'all')], [1 numel(slices)]);
+colormap fire;
+%%
+slices = 1:size(met_images_mres{1}, 3);
+time_pts = 1:3:n_t;
+figure(Name='Pyruvate (unified)');
+imagescn(met_images_mres{1}(:,:,slices,time_pts), [0, max(met_images_mres{1}(:,:,slices,time_pts), [], 'all')], [numel(slices) numel(time_pts)]);
+colormap fire;
+
+figure(Name='Lactate (unified)');
+imagescn(met_images_mres{2}(:,:,slices,time_pts), [0, max(met_images_mres{2}(:,:,slices,time_pts), [], 'all')], [numel(slices) numel(time_pts)]);
+colormap fire;
+
+figure(Name='Bicarb (unified)');
+imagescn(met_images_mres{3}(:,:,slices,time_pts), [0, max(met_images_mres{3}(:,:,slices,time_pts), [], 'all')], [numel(slices) numel(time_pts)]);
+colormap fire;
+%%
+% AUCs
+pyrAUC = sum(met_images_mres{1}, 4);
+figure(Name='Pyr AUC (unified)');
+imagescn(pyrAUC, [0 max(pyrAUC, [], 'all')], [1 numel(slices)]);
+colormap fire;
+
+lacAUC = sum(met_images_mres{2}, 4);
+figure(Name='Lac AUC (unified)');
+imagescn(lacAUC, [0 max(lacAUC, [], 'all')], [1 numel(slices)]);
+colormap fire;
+
+bicAUC = sum(met_images_mres{3}, 4);
+figure(Name='Bic AUC (unified)');
+imagescn(bicAUC, [0 max(bicAUC, [], 'all')], [1 numel(slices)]);
+colormap fire;
diff --git a/simulations/anatomical_phantoms/usage/cardiac_metabolic_phantom.m b/simulations/anatomical_phantoms/usage/cardiac_metabolic_phantom.m
new file mode 100644
index 0000000..a6d2892
--- /dev/null
+++ b/simulations/anatomical_phantoms/usage/cardiac_metabolic_phantom.m
@@ -0,0 +1,98 @@
+clear; close all;
+addpath('../'); % phantom functions
+addpath('../../pk_models/'); % realistic_input_function, simulate_Nsite_model
+addpath('../../../utilities/'); % fire
+
+%% PARAMETERS ----------------------------------------------------
+% tissue
+mask = load('../util/cardiac/cardiac_mask_10.mat').masks;
+
+k_trans = [1, 1, 0.2, 0.4];
+
+% pk model params
+tr = 3.6;
+n_t = 30;
+flips = repmat([20; 30; 30], 1, n_t) .* (pi/180);
+r1 = [1/30 1/25 1/20];
+k = [0.013, 0.010, 0.025, 0.020;
+ 0.001, 0.001, 0.010, 0.001]; % in order [lv, rv, lv_mc, rv_mc].
+
+t_arrival = [6,0,8,2];
+t_bolus = 1;
+
+% input function and mz0
+n_tissues = size(k, 2);
+n_mets = size(flips, 1);
+
+input_function = zeros(n_tissues, n_t);
+for i_tissue = 1:n_tissues
+ input_function(i_tissue, :) = realistic_input_function(n_t, tr, t_arrival(i_tissue), t_bolus);
+end
+
+mz0_constants = [1, 1, 0.5, 0.5;
+ 0, 0, 0.01, 0.01;
+ 0, 0, 0.005, 0.005];
+
+mz0 = repmat(reshape(input_function(:, 1), 1, n_tissues), 3, 1) .* mz0_constants;
+
+% mri
+coil_lim = [0.4 1.2];
+sample_size = [25,25,5; 13,13,5; 13,13,5];
+snr = [220 70 12];
+output_size = [32,32,5];
+
+%% RUNNING THE MODEL ----------------------------------------------
+% tissue
+heart = tissue_structure("heart", mask, ["lv" "rv" "lvmy" "rvmy"]);
+heart = heart.create_k_trans_map(k_trans);
+
+% pk model
+images = pk_model.run_pk_model(mz0, r1, k, flips, tr, heart, input_function=input_function);
+
+% mri
+met_images_mres = mri_system.run_mri_system(images, sample_size, snr, coil_lim, heart, output_size, include_bg_noise=false);
+
+%% DISPLAY --------------------------------------------------------
+slices = 1:5:46;
+figure(Name='kTRANS');
+imagescn(heart.K_trans_map(:,:,slices), [0 max(heart.K_trans_map(:,:,slices), [], 'all')], [1 numel(slices)]);
+colormap hot;
+
+slices = 1:size(met_images_mres{1}, 3);
+time_pts = 1:n_t;
+figure(Name='Pyruvate');
+imagescn(met_images_mres{1}(:,:,slices,time_pts), [0, max(met_images_mres{1}(:,:,slices,time_pts), [], 'all')], [numel(slices) numel(time_pts)]);
+colormap hot;
+
+figure(Name='Lactate');
+imagescn(met_images_mres{2}(:,:,slices,time_pts), [0, max(met_images_mres{2}(:,:,slices,time_pts), [], 'all')], [numel(slices) numel(time_pts)]);
+colormap hot;
+
+figure(Name='Bicarb (unified)');
+imagescn(met_images_mres{3}(:,:,slices,time_pts), [0, max(met_images_mres{3}(:,:,slices,time_pts), [], 'all')], [numel(slices) numel(time_pts)]);
+colormap hot;
+
+%% AUCs
+pyrAUC = sum(met_images_mres{1}, 4);
+lacAUC = sum(met_images_mres{2}, 4);
+bicAUC = sum(met_images_mres{3}, 4);
+
+% AUC ratios
+lac_to_pyr = lacAUC ./ pyrAUC;
+bic_to_pyr = bicAUC ./ pyrAUC;
+
+% remove the background noise
+parts_to_keep = sum(heart.Mask(), 4);
+parts_to_keep = imresize3(parts_to_keep, output_size, "nearest");
+lac_to_pyr(parts_to_keep == 0) = 0;
+bic_to_pyr(parts_to_keep == 0) = 0;
+
+figure(Name='Lac/Pyr AUC (unified)');
+imagescn(lac_to_pyr, [0, 0.5], [1 numel(slices)]);
+colormap hot;
+
+figure(Name='Bic/Pyr AUC (unified)');
+imagescn(bic_to_pyr, [0, 0.15], [1 numel(slices)]);
+colormap hot;
+
+
diff --git a/simulations/anatomical_phantoms/usage/concise_unified_phantom_test.m b/simulations/anatomical_phantoms/usage/concise_unified_phantom_test.m
new file mode 100644
index 0000000..041d8cd
--- /dev/null
+++ b/simulations/anatomical_phantoms/usage/concise_unified_phantom_test.m
@@ -0,0 +1,56 @@
+clear; close all;
+addpath('../')
+
+% TISSUE STRUCTURE
+mask = load('util/mask.mat').masks;
+heart = tissue_structure("heart", mask, ["lv" "rv" "lvmy" "rvmy"]);
+k_trans = [1, 1, 0.2, 0.4];
+heart = heart.create_k_trans_map(k_trans);
+
+% PK MODEL PARAMETERS
+tr = 3.6;
+n_t = 30;
+flips = repmat([20; 30; 30;], 1, n_t) .* (pi/180);
+
+n_compartments = 4;
+
+% METABOLITE AND/OR TISSUE SPECIFIC PARAMETERS
+mz0 = [0,1,0,0; % pyr
+ 0,0,0,0; % lac
+ 0,0,0,0]; % bic
+
+r1 = [1/30, 1/25, 1/25]; % pyr, lac, bic
+
+k = [0.0075, 0.0045, 0.06, 0.02; % lac
+ 0.0011, 0.0005, 0.04, 0.01]; % bic
+
+t_arrival = [7, 0, 10, 14]; % lv, rv, lvmy, rvmy
+t_bolus = 10;
+
+
+% RUN PK MODEL
+images = pk_model.run_pk_model(mz0, r1, k, flips, tr, heart, t_arrival=t_arrival, t_bolus=t_bolus);
+
+% RUN MRI SYSTEM
+sample_size = [32 32 11; 16 16 11; 24 24 11];
+SNR = [150 40 20];
+coil_lim = [0.4 1.2];
+output_size = [32 32 11; 32 32 11; 32 32 11];
+augmentation_params = struct(...
+ "XTranslation", [-1,1], ...
+ "YTranslation", [-1,1], ...
+ "Scale", [0.95,1.1], ...
+ "XReflection", true, ...
+ "Rotation", [-5,5]);
+
+met_images_mres = mri_system.run_mri_system(images, sample_size, SNR, coil_lim, heart.Mask, output_size, augmentation_params);
+
+%% DISPLAY
+figure;
+imagescn(met_images_mres{1}(:,:,5,:), [0, max(met_images_mres{1}(:,:,5,:), [], 'all')])
+
+figure;
+imagescn(met_images_mres{2}(:,:,5,:), [0, max(met_images_mres{2}(:,:,5,:), [], 'all')])
+
+figure;
+imagescn(met_images_mres{3}(:,:,5,:), [0, max(met_images_mres{3}(:,:,5,:), [], 'all')])
diff --git a/simulations/anatomical_phantoms/usage/generate_brainweb_figures.m b/simulations/anatomical_phantoms/usage/generate_brainweb_figures.m
new file mode 100644
index 0000000..295b210
--- /dev/null
+++ b/simulations/anatomical_phantoms/usage/generate_brainweb_figures.m
@@ -0,0 +1,347 @@
+% copying over brainweb
+clear; close all;
+addpath('../'); % phantom functions
+addpath('../../pk_models/'); % realistic_input_function, simulate_Nsite_model
+addpath('../../../utilities/'); % fire
+
+%% settings for figure generation
+export_path = '';
+
+to_export = ~isempty(export_path); % save a couple function calls
+if to_export
+ disp("exporting to `" + string(export_path) + "`");
+ mkdir(export_path);
+else
+ disp("not exporting")
+end
+
+
+%% PARAMETERS
+disp('setting up...');
+t_all = tic;
+tic
+% tissue
+mask = double(load('../util/brainweb/1/brainweb_fuzzy.mat').im_mask);
+
+k_trans = [1, 0.2, 0.2;
+ 3, 0.4, 0.4];
+
+% pk model params
+tr = 3;
+n_t = 20;
+flips = repmat([20; 30; 30;], 1, n_t) .* (pi/180);
+r1 = [1/30, 1/25, 1/20]; % pyr, lac, bic
+k = [0, 0.03, 0.025; % lac, in order [vasc, gm, wm]
+ 0, 0.01, 0.005]; % bic
+t_arrival = [0, 0, 0]; % vasc, gm, wm
+t_bolus = 8;
+
+% input function and mz0
+n_tissues = 3;
+input_function = zeros(n_tissues, n_t);
+for i_tissue = 1:n_tissues
+ input_function(i_tissue, :) = realistic_input_function(n_t, tr, t_arrival(i_tissue), t_bolus);
+end
+mz0 = [input_function(1), input_function(1)*.5, input_function(1)*.5;
+ 0, input_function(1)*.01, input_function(1)*.01;
+ 0, input_function(1)*.005, input_function(1)*.005];
+
+% mri
+coil_lim = [0.2, 0.6];
+augment_params = struct(...
+ "XTranslation", [5,5], ...
+ "YTranslation", [-7,-7], ...
+ "ZTranslation", [2, 2], ...
+ "Scale", [1.1,1.1], ...
+ "XReflection", true, ...
+ "Rotation", [5,5]);
+
+sample_size = [32 32 8; 16 16 8; 16 16 8];
+snr = [150 40 20]; % pyr_range = [70 320]; lac_range = [15 75]
+output_size = [64 64 8];
+
+
+% VARIATIONS
+% anatomy
+%mask = double(load('../util/brainweb/2/brainweb_fuzzy.mat').im_mask);
+
+% low SNR
+%snr = [70, 15, 10];
+
+% high SNR
+%snr = [320 75 40];
+
+% small sample size
+%sample_size = [24 24 8; 12 12 8; 12 12 8];
+
+% large sample size
+%sample_size = [48 48 8; 24 24 8; 24 24 8];
+
+% augmentations
+%augment_params = struct(...
+% "XTranslation", [5,5], ...
+% "YTranslation", [-1,1], ...
+% "Scale", [0.95,1.1], ...
+% "XReflection", true, ...
+% "Rotation", [-5,5], ...
+% "ZTranslation", [-5, 5]);
+
+
+
+disp(['took ', num2str(toc), 's', newline]);
+
+%% RUNNING THE MODEL -----------------------------------------------------------
+% tissue
+disp('creating tissue structure...'); tic;
+brain = tissue_structure("brain", mask, ["vasc", "gm", "wm"], [100,100,100]);
+brain = brain.create_k_trans_map(k_trans);
+disp(['took ', num2str(toc), 's', newline]);
+
+% pk model
+disp('running pk model...'); tic;
+[met_images, ~, met_dynamics, ~, met_images_no_ktrans] = pk_model.run_pk_model(mz0, r1, k, flips, tr, brain, input_function=input_function);
+disp(['took ', num2str(toc), 's', newline]);
+
+% mri
+disp('running mri system...'); tic;
+cell_augment_params = namedargs2cell(augment_params); % unpack the augmentation parameters
+[met_images_aug, transform] = mri_system.augment(met_images, cell_augment_params{:});
+brain = brain.apply_transforms(transform.tform2d, transform.z_translation);
+[met_images_coil_lim, coil_sens_weights] = mri_system.apply_coil_lim(met_images_aug, coil_lim, brain.Mask);
+met_images_mres = mri_system.make_met_images_multires(met_images_coil_lim, sample_size);
+[met_images_mres_noise, met_images_mres_no_bg] = mri_system.add_rician_noise(met_images_mres, snr);
+
+met_images_upsampled = mri_system.upsample_to_output_size(met_images_mres_noise, output_size);
+met_images_upsampled_no_bg = mri_system.upsample_to_output_size(met_images_mres_no_bg, output_size);
+disp(['took ', num2str(toc), 's', newline]);
+
+
+%% DISPLAY ---------------------------------------------------------------------
+disp('plotting...'); tic;
+
+%% tissue ----------------------------------
+% mask ------
+% alpha composite
+brain.plot_alpha_composite_image(slice=50, order=[2,3,1]); % plot vasculature last
+if to_export; saveas(gcf, fullfile(export_path, 'alpha_composite.png')); end
+
+% multislice tissues
+slices = 10:10:100;
+permuted_masks = permute(brain.Mask(:,:,slices,:), [1,2,4,3]);
+f = display_tiled_images(permuted_masks, false, 'mask', ["Vasc", "GM", "WM"], cmap=@gray);
+f.Position = [0, 0, 1000, 500];
+if to_export; saveas(gcf, fullfile(export_path, 'mask_multislice.png')); end
+
+% middle slice tissues
+slice = round(size(brain.Mask, 3) / 2);
+figure; imshow(brain.Mask(:,:,slice,1)); if to_export; saveas(gcf, fullfile(export_path, 'mask_vasc_middle.png')); end
+figure; imshow(brain.Mask(:,:,slice,2)); if to_export; saveas(gcf, fullfile(export_path, 'mask_gm_middle.png')); end
+figure; imshow(brain.Mask(:,:,slice,3)); if to_export; saveas(gcf, fullfile(export_path, 'mask_wm_middle.png')); end
+
+% kTRANS ------
+% multislice kTRANS
+slices = 10:10:100;
+f = display_tiled_images(brain.K_trans_map(:,:,slices), true, 'ktrans', [], cmap=@parula);
+f.Position = [0, 0, 1440, 185];
+if to_export; saveas(gcf, fullfile(export_path, 'ktrans_multislice.png')); end
+
+% middle slice kTRANS
+slice = round(size(brain.K_trans_map, 3) / 2);
+figure; imshow(brain.K_trans_map(:,:,slice), [0, max(brain.K_trans_map, [], 'all')]);
+colormap parula; colorbar;
+if to_export; saveas(gcf, fullfile(export_path, 'ktrans_middle.png')); end
+
+
+%% pk -----------------------------------------
+% met dynamics ------
+% size(met_dynamics) = [tissue, met, time_pt]
+time_pts = 1:size(met_dynamics, 3);
+
+f = figure(Name='met dynamics');
+
+% construction
+t = tiledlayout(size(met_dynamics, 1), 1);
+tissue_names = ["Vasculature", "Gray Matter", "White Matter"];
+for i_tissue = 1:size(met_dynamics, 1)
+ nexttile;
+ hold on;
+ for i_met = 1:size(met_dynamics, 2)
+ plot(time_pts, squeeze(met_dynamics(i_tissue, i_met, :)));
+ end
+ xlabel('time point');
+ ylabel('signal')
+ leg = legend(["Pyruvate", "Lactate", "Bicarbonate"]);
+ title(tissue_names(i_tissue));
+ hold off;
+end
+f.Position = [0, 0, 1000, 600];
+if to_export; saveas(f, fullfile(export_path, 'met_dynamics.png')); end
+
+
+% met images (no ktrans) ---
+slice = round(size(met_images_no_ktrans, 3) / 2);
+time_pts = 1:3:n_t;
+f = display_tiled_images(met_images_no_ktrans(:,:,slice,:,time_pts), true, 'met images no ktrans', ["Pyruvate", "Lactate", "Bicarbonate"]);
+f.Position = [0, 0, 1440, 475];
+if to_export; saveas(gcf, fullfile(export_path, '1-met_img_no_ktrans.png')); end
+
+% met images (ktrans) ---
+slice = round(size(met_images, 3) / 2);
+time_pts = 1:3:n_t;
+f = display_tiled_images(met_images(:,:,slice,:,time_pts), true, 'met images', ["Pyruvate", "Lactate", "Bicarbonate"]);
+f.Position = [0, 0, 1440, 475];
+if to_export; saveas(gcf, fullfile(export_path, '2-met_img_w_ktrans.png')); end
+
+
+%% met images of various mri steps -----
+
+% augmentations ---
+slice = round(size(met_images_aug, 3) / 2);
+time_pts = 1:3:n_t;
+f = display_tiled_images(met_images_aug(:,:,slice,:,time_pts), true, 'met images (augmentations)', ["Pyruvate", "Lactate", "Bicarbonate"]);
+f.Position = [0, 0, 1440, 475];
+if to_export; saveas(gcf, fullfile(export_path, '3-met_img_w_augs.png')); end
+
+% coil limits ---
+slice = round(size(met_images_coil_lim, 3) / 2);
+time_pts = 1:3:n_t;
+f = display_tiled_images(met_images_coil_lim(:,:,slice,:,time_pts), true, 'met images (coil lim)', ["Pyruvate", "Lactate", "Bicarbonate"]);
+f.Position = [0, 0, 1440, 475];
+if to_export; saveas(gcf, fullfile(export_path, '4-met_img_w_coil_lims.png')); end
+
+% coil limit maps ---
+% multislice
+slices = 10:10:100;
+f = display_tiled_images(coil_sens_weights(:,:,slices), true, 'Coil Sensitivity Map', [], cmap=@parula);
+f.Position = [0, 0, 1440, 185];
+if to_export; saveas(gcf, fullfile(export_path, 'coil_sensitivity.png')); end
+
+% single slice
+slice = round(size(coil_sens_weights, 3) / 2);
+figure; imshow(coil_sens_weights(:,:,slice), [0 max(coil_sens_weights, [], 'all')]);
+colormap parula; colorbar;
+if to_export; saveas(gcf, fullfile(export_path, 'coil_sensitivity_middle.png')); end
+
+% multiresolution ---
+slice = round(size(met_images_mres{1}, 3) / 2);
+time_pts = 1:3:n_t;
+f = display_tiled_images(met_images_mres, true, 'met images multires', ["Pyruvate", "Lactate", "Bicarbonate"], slice, time_pts);
+f.Position = [0, 0, 1440, 475];
+if to_export; saveas(gcf, fullfile(export_path, '5-met_images_mres.png')); end
+
+% noise ---
+slice = round(size(met_images_mres_no_bg{1}, 3) / 2);
+time_pts = 1:3:n_t;
+f = display_tiled_images(met_images_mres_no_bg, true, 'met images noisy', ["Pyruvate", "Lactate", "Bicarbonate"], slice, time_pts);
+f.Position = [0, 0, 1440, 475];
+if to_export; saveas(gcf, fullfile(export_path, '6-met_images_noise.png')); end
+
+
+%% final met images (after mri)
+
+slice = round(size(met_images_upsampled_no_bg{1}, 3) / 2);
+time_pts = 1:3:n_t;
+f = display_tiled_images(met_images_upsampled_no_bg, true, 'final met images!', ["Pyruvate", "Lactate", "Bicarbonate"], slice, time_pts);
+f.Position = [0, 0, 1440, 475];
+if to_export; saveas(gcf, fullfile(export_path, '7-met_images_upsampled_no_bg.png')); end
+
+
+%% AUCs
+aucs = cell(1,3);
+
+for i = 1:3
+ aucs{i} = sum(met_images_upsampled_no_bg{i}, 4);
+ % turn it into (row, col, 1, slice)
+ new_size = cat(2, size(aucs{i}, 1,2), 1, size(aucs{i}, 3));
+ aucs{i} = reshape(aucs{i}, new_size);
+end
+
+f = display_tiled_images(aucs, true, 'aucs', ["Pyruvate", "Lactate", "Bicarbonate"]);
+f.Position = [0, 0, 1440, 565];
+if to_export; saveas(gcf, fullfile(export_path, 'aucs.png')); end
+
+disp(['took ', num2str(toc), 's', newline]);
+disp('done! (plots might take a while to load)');
+disp(['took a total of ', num2str(toc(t_all)), 's']);
+
+
+function [fig, I] = display_tiled_images(I, has_colorbar, figurename, labels, slice, time_pts, opts)
+ % I = (row, col, slice). 1 row, slice columns
+ % I = (row, col, met, time). met rows, time columns
+ % I = {met} --> (row, col, slice, time). met rows, time columns. assumes all have the same number of timesteps
+
+ % stored as:
+ % I = {met} --> (row, col, time/slice). met rows, time/slice columns. assumes all have the same number of timesteps
+
+ % slice and time_pts is only for the 3rd option because there's not a great way to just remove that dimension
+
+ arguments
+ I
+ has_colorbar
+ figurename
+ labels
+ slice (1,1) = 1 % these two are optional, won't be used unless I is a cell
+ time_pts = NaN
+ opts.cmap = @fire
+ end
+
+ % keep the dimensions consistent
+ % in the form {met} --> (row, col, time)
+ if iscell(I)
+ if any(isnan(time_pts))
+ time_pts = 1:size(I{1}, 4);
+ end
+ for row = 1:numel(I)
+ I{row} = squeeze(I{row}(:, :, slice, time_pts));
+ end
+ else
+ % convert (x,y,z) --> (x,y,1,z)
+ I = squeeze(I);
+ if numel(size(I)) == 3
+ new_shape = cat(2, size(I, 1:2), 1, size(I, 3));
+ I = reshape(I, new_shape);
+ end
+ % turn it into cell
+ cell_I = cell([1, size(I, 3)]);
+ for row = 1:size(I, 3)
+ cell_I{row} = squeeze(I(:,:,row,:));
+ end
+
+ I = cell_I;
+ end
+
+
+ % setup
+ fig = figure(Name=figurename);
+
+ if has_colorbar
+ n_cols = size(I{1}, 3) + 1;
+ else
+ n_cols = size(I{1}, 3);
+ end
+
+
+ % construction
+ t = tiledlayout(numel(I), n_cols);
+ t.Padding = 'none';
+ t.TileSpacing = 'none';
+ for row = 1:numel(I)
+ scale = [0, max(I{row}(:,:,:), [], 'all')];
+ for col = 1:size(I{row}, 3)
+ nexttile;
+ imshow(I{row}(:,:,col), scale);
+ if col == 1 && ~isempty(labels)
+ ylabel(labels(row));
+ end
+ end
+
+ if has_colorbar
+ cb_ax = nexttile();
+ axis(cb_ax, 'off');
+ colorbar('location','west');
+ clim(scale);
+ end
+ end
+
+ colormap(opts.cmap());
+end
diff --git a/simulations/anatomical_phantoms/usage/generate_heart_figures.m b/simulations/anatomical_phantoms/usage/generate_heart_figures.m
new file mode 100644
index 0000000..4848b99
--- /dev/null
+++ b/simulations/anatomical_phantoms/usage/generate_heart_figures.m
@@ -0,0 +1,374 @@
+% copying over cardiac
+clear; close all;
+addpath('../'); % phantom functions
+addpath('../../pk_models/'); % realistic_input_function, simulate_Nsite_model
+addpath('../../../utilities/'); % fire
+
+%% settings for figure generation
+export_path = '';
+
+to_export = ~isempty(export_path); % save a couple function calls
+if to_export
+ disp("exporting to `" + string(export_path) + "`");
+ mkdir(export_path);
+else
+ disp("not exporting")
+end
+
+
+%% PARAMETERS
+disp('setting up...');
+t_all = tic;
+tic
+
+% tissue
+mask = load('../util/cardiac/cardiac_mask_1.mat').masks;
+
+k_trans = [1, 1, 0.2, 0.4];
+
+% pk model params
+tr = 3.6;
+n_t = 30;
+flips = repmat([20; 30; 30], 1, n_t) .* (pi/180);
+r1 = [1/30 1/25 1/20];
+k = [0.013, 0.010, 0.025, 0.020;
+ 0.001, 0.001, 0.010, 0.001]; % in order [lv, rv, lv_mc, rv_mc].
+
+t_arrival = [6,0,8,2];
+t_bolus = 1;
+
+% input function and mz0
+n_tissues = size(k, 2);
+n_mets = size(flips, 1);
+
+input_function = zeros(n_tissues, n_t);
+for i_tissue = 1:n_tissues
+ input_function(i_tissue, :) = realistic_input_function(n_t, tr, t_arrival(i_tissue), t_bolus);
+end
+
+mz0_constants = [1, 1, 0.5, 0.5;
+ 0, 0, 0.01, 0.01;
+ 0, 0, 0.005, 0.005];
+
+mz0 = repmat(reshape(input_function(:, 1), 1, n_tissues), 3, 1) .* mz0_constants;
+
+% mri
+% augment_params should be deterministic
+augment_params = struct(...
+ "XTranslation", [5,5], ...
+ "YTranslation", [-7,-7], ...
+ "ZTranslation", [2,2], ...
+ "Scale", [1.1, 1.1], ...
+ "Rotation", [5,5]);
+
+coil_lim = [0.4 1.2];
+sample_size = [25,25,5; 13,13,5; 13,13,5];
+snr = [220 70 12];
+output_size = [32,32,5];
+disp(['took ', num2str(toc), 's', newline]);
+
+
+% VARIATIONS
+% anatomy
+%mask = double(load('../util/cardiac/cardiac_mask_2.mat').masks);
+
+% low SNR
+%snr = [70, 15, 10];
+
+% high SNR
+%snr = [320 75 40];
+
+% small sample size
+%sample_size = [12 12 8; 8 8 8; 8 8 8];
+
+% large sample size
+%sample_size = [48 48 8; 24 24 8; 24 24 8];
+
+
+% augmentations
+%augment_params = struct(...
+% "XTranslation", [-4,-4], ...
+% "YTranslation", [9,9], ...
+% "ZTranslation", [-3,-3], ...
+% "Scale", [0.8, 0.8], ...
+% "Rotation", [12,12]);
+
+
+
+%% RUNNING THE MODEL -----------------------------------------------------------
+% tissue
+disp('creating tissue structure...'); tic;
+heart = tissue_structure("heart", mask, ["lv", "rv", "lvmy", "rvmy"]);
+heart = heart.create_k_trans_map(k_trans);
+disp(['took ', num2str(toc), 's', newline]);
+
+% pk model
+disp('running pk model...'); tic;
+[met_images, ~, met_dynamics, ~, met_images_no_ktrans] = pk_model.run_pk_model(mz0, r1, k, flips, tr, heart, input_function=input_function);
+disp(['took ', num2str(toc), 's', newline]);
+
+% mri
+disp('running mri system...'); tic;
+cell_augment_params = namedargs2cell(augment_params); % unpack the augmentation parameters
+[met_images_aug, transform] = mri_system.augment(met_images, cell_augment_params{:});
+heart = heart.apply_transforms(transform.tform2d, transform.z_translation);
+[met_images_coil_lim, coil_sens_weights] = mri_system.apply_coil_lim(met_images_aug, coil_lim, heart.Mask);
+met_images_mres = mri_system.make_met_images_multires(met_images_coil_lim, sample_size);
+[met_images_mres_noise, met_images_mres_no_bg] = mri_system.add_rician_noise(met_images_mres, snr);
+
+met_images_upsampled = mri_system.upsample_to_output_size(met_images_mres_noise, output_size);
+met_images_upsampled_no_bg = mri_system.upsample_to_output_size(met_images_mres_no_bg, output_size);
+disp(['took ', num2str(toc), 's', newline]);
+
+
+%% DISPLAY ---------------------------------------------------------------------
+disp('plotting...'); tic;
+
+%% tissue ----------------------------------
+% mask ------
+% alpha composite
+heart.plot_alpha_composite_image(slice=23); % plot vasculature last
+if to_export; saveas(gcf, fullfile(export_path, 'mask_alpha_composite.png')); end
+
+% multislice tissues
+slices = 5:5:46;
+permuted_masks = permute(heart.Mask(:,:,slices,:), [1,2,4,3]);
+f = display_tiled_images(permuted_masks, false, 'mask', ["LV", "RV", "LVMY", "RVMY"], cmap=@gray);
+f.Position = [0, 0, 1000, 500];
+if to_export; saveas(gcf, fullfile(export_path, 'mask_multislice.png')); end
+
+% middle slice tissues
+slice = round(size(heart.Mask, 3) / 2);
+figure; imshow(heart.Mask(:,:,slice,1)); if to_export; saveas(gcf, fullfile(export_path, 'mask_lv_middle.png')); end
+figure; imshow(heart.Mask(:,:,slice,2)); if to_export; saveas(gcf, fullfile(export_path, 'mask_rv_middle.png' )); end
+figure; imshow(heart.Mask(:,:,slice,3)); if to_export; saveas(gcf, fullfile(export_path, 'mask_lvmy_middle.png')); end
+figure; imshow(heart.Mask(:,:,slice,4)); if to_export; saveas(gcf,fullfile(export_path, 'mask_rvmy_middle.png')); end
+
+% kTRANS ------
+% multislice kTRANS
+slices = 5:5:46;
+f = display_tiled_images(heart.K_trans_map(:,:,slices), true, 'ktrans', [], cmap=@parula);
+f.Position = [0, 0, 1440, 185];
+if to_export; saveas(gcf, fullfile(export_path, 'ktrans_multislice.png')); end
+
+% middle slice kTRANS
+slice = round(size(heart.K_trans_map, 3) / 2);
+figure; imshow(heart.K_trans_map(:,:,slice), [0, max(heart.K_trans_map, [], 'all')]);
+colormap parula; colorbar;
+if to_export; saveas(gcf, fullfile(export_path, 'ktrans_middle.png')); end
+
+
+
+%% pk -----------------------------------------
+% met dynamics ------
+% size(met_dynamics) = [tissue, met, time_pt]
+time_pts = 1:size(met_dynamics, 3);
+
+f = figure(Name='met dynamics');
+
+% construction
+t = tiledlayout(size(met_dynamics, 1), 1);
+tissue_names = ["LV", "RV", "LVMY", "RVMY"];
+for i_tissue = 1:size(met_dynamics, 1)
+ nexttile;
+ hold on;
+ for i_met = 1:size(met_dynamics, 2)
+ plot(time_pts, squeeze(met_dynamics(i_tissue, i_met, :)));
+ end
+ xlabel('time point');
+ ylabel('signal')
+ leg = legend(["Pyruvate", "Lactate", "Bicarbonate"]);
+ title(tissue_names(i_tissue));
+ hold off;
+end
+f.Position = [0, 0, 1000, 600];
+if to_export; saveas(f, fullfile(export_path, 'met_dynamics.png')); end
+
+
+% met images (no ktrans) ---
+slice = round(size(met_images_no_ktrans, 3) / 2);
+time_pts = 1:3:n_t;
+f = display_tiled_images(met_images_no_ktrans(:,:,slice,:,time_pts), true, 'met images no ktrans', ["Pyruvate", "Lactate", "Bicarbonate"]);
+f.Position = [0, 0, 1440, 475];
+if to_export; saveas(gcf, fullfile(export_path, '1-met_img_no_ktrans.png')); end
+
+% met images (ktrans) ---
+slice = round(size(met_images, 3) / 2);
+time_pts = 1:3:n_t;
+f = display_tiled_images(met_images(:,:,slice,:,time_pts), true, 'met images', ["Pyruvate", "Lactate", "Bicarbonate"]);
+f.Position = [0, 0, 1440, 475];
+if to_export; saveas(gcf, fullfile(export_path, '2-met_img_w_ktrans.png')); end
+
+
+%% met images of various mri steps -----
+
+% augmentations ---
+slice = round(size(met_images_aug, 3) / 2);
+time_pts = 1:3:n_t;
+f = display_tiled_images(met_images_aug(:,:,slice,:,time_pts), true, 'met images (augmentations)', ["Pyruvate", "Lactate", "Bicarbonate"]);
+f.Position = [0, 0, 1440, 475];
+if to_export; saveas(gcf, fullfile(export_path, '3-met_img_w_augs.png')); end
+
+% coil limits ---
+slice = round(size(met_images_coil_lim, 3) / 2);
+time_pts = 1:3:n_t;
+f = display_tiled_images(met_images_coil_lim(:,:,slice,:,time_pts), true, 'met images (coil lim)', ["Pyruvate", "Lactate", "Bicarbonate"]);
+f.Position = [0, 0, 1440, 475];
+if to_export; saveas(gcf, fullfile(export_path, '4-met_img_w_coil_lims.png')); end
+
+% coil limit maps ---
+% multislice
+slices = 5:5:46;
+f = display_tiled_images(coil_sens_weights(:,:,slices), true, 'Coil Sensitivity Map', [], cmap=@parula);
+f.Position = [0, 0, 1440, 185];
+if to_export; saveas(gcf, fullfile(export_path, 'coil_sensitivity_multislice.png')); end
+
+% single slice
+slice = round(size(coil_sens_weights, 3) / 2);
+figure; imshow(coil_sens_weights(:,:,slice), [0 max(coil_sens_weights, [], 'all')]);
+colormap parula; colorbar;
+if to_export; saveas(gcf, fullfile(export_path, 'coil_sensitivity_middle.png')); end
+
+% multiresolution ---
+slice = round(size(met_images_mres{1}, 3) / 2);
+time_pts = 1:3:n_t;
+f = display_tiled_images(met_images_mres, true, 'met images multires', ["Pyruvate", "Lactate", "Bicarbonate"], slice, time_pts);
+f.Position = [0, 0, 1440, 475];
+if to_export; saveas(gcf, fullfile(export_path, '5-met_images_mres.png')); end
+
+% noise ---
+slice = round(size(met_images_mres_no_bg{1}, 3) / 2);
+time_pts = 1:3:n_t;
+f = display_tiled_images(met_images_mres_no_bg, true, 'met images noisy', ["Pyruvate", "Lactate", "Bicarbonate"], slice, time_pts);
+f.Position = [0, 0, 1440, 475];
+if to_export; saveas(gcf, fullfile(export_path, '6-met_images_noise.png')); end
+
+
+%% final met images (after mri) --------
+
+slice = round(size(met_images_upsampled_no_bg{1}, 3) / 2);
+time_pts = 1:3:n_t;
+f = display_tiled_images(met_images_upsampled_no_bg, true, 'final met images!', ["Pyruvate", "Lactate", "Bicarbonate"], slice, time_pts);
+f.Position = [0, 0, 1440, 475];
+if to_export; saveas(gcf, fullfile(export_path, '7-met_images_upsampled_no_bg.png')); end
+
+
+%% AUC (ratios)
+aucs = cell(1,3);
+
+for i = 1:3
+ aucs{i} = sum(met_images_upsampled_no_bg{i}, 4);
+end
+
+lac_to_pyr_AUC = aucs{2} ./ aucs{1};
+lac_to_pyr_AUC(aucs{1} < max(aucs{1}, [], 'all') * 0.1) = 0; % remove the artifacts caused by different sample sizes
+bic_to_pyr_AUC = aucs{3} ./ aucs{1};
+bic_to_pyr_AUC(aucs{1} < max(aucs{1}, [], 'all') * 0.1) = 0; % threshold tuned by hand lol
+
+slice = round(size(lac_to_pyr_AUC, 3) / 2);
+figure(Name="lac-pyr auc"); imshow(lac_to_pyr_AUC(:,:,slice), [0 max(lac_to_pyr_AUC(:,:,slice), [], 'all')]);
+colormap hot; colorbar;
+if to_export; saveas(gcf, fullfile(export_path, 'auc_ratio_lac_pyr.png')); end
+
+
+figure(Name="bic-pyr auc"); imshow(bic_to_pyr_AUC(:,:,slice), [0 max(bic_to_pyr_AUC(:,:,slice), [], 'all')]);
+colormap hot; colorbar;
+if to_export; saveas(gcf, fullfile(export_path, 'auc_ratio_bic_pyr.png')); end
+
+
+% make the aucs cell array play nice with the display function
+for i = 1:3
+ % turn it into (row, col, 1, slice)
+ new_size = cat(2, size(aucs{i}, 1,2), 1, size(aucs{i}, 3));
+ aucs{i} = reshape(aucs{i}, new_size);
+end
+
+f = display_tiled_images(aucs, true, 'aucs', ["Pyruvate", "Lactate", "Bicarbonate"]);
+f.Position = [0, 0, 1440, 565];
+if to_export; saveas(gcf, fullfile(export_path, 'aucs.png')); end
+
+disp(['took ', num2str(toc), 's', newline]);
+disp('done! (plots might take a while to load)');
+disp(['took a total of ', num2str(toc(t_all)), 's']);
+
+
+function [fig, I] = display_tiled_images(I, has_colorbar, figurename, labels, slice, time_pts, opts)
+ % I = (row, col, slice). 1 row, slice columns
+ % I = (row, col, met, time). met rows, time columns
+ % I = {met} --> (row, col, slice, time). met rows, time columns. assumes all have the same number of timesteps
+
+ % stored as:
+ % I = {met} --> (row, col, time/slice). met rows, time/slice columns. assumes all have the same number of timesteps
+
+ % slice and time_pts is only for the 3rd option because there's not a great way to just remove that dimension
+
+ arguments
+ I
+ has_colorbar
+ figurename
+ labels
+ slice (1,1) = 1 % these two are optional, won't be used unless I is a cell
+ time_pts = NaN
+ opts.cmap = @hot
+ end
+
+ % keep the dimensions consistent
+ % in the form {met} --> (row, col, time)
+ if iscell(I)
+ if any(isnan(time_pts))
+ time_pts = 1:size(I{1}, 4);
+ end
+ for row = 1:numel(I)
+ I{row} = squeeze(I{row}(:, :, slice, time_pts));
+ end
+ else
+ % convert (x,y,z) --> (x,y,1,z)
+ I = squeeze(I);
+ if numel(size(I)) == 3
+ new_shape = cat(2, size(I, 1:2), 1, size(I, 3));
+ I = reshape(I, new_shape);
+ end
+ % turn it into cell
+ cell_I = cell([1, size(I, 3)]);
+ for row = 1:size(I, 3)
+ cell_I{row} = squeeze(I(:,:,row,:));
+ end
+
+ I = cell_I;
+ end
+
+
+ % setup
+ fig = figure(Name=figurename);
+
+ if has_colorbar
+ n_cols = size(I{1}, 3) + 1;
+ else
+ n_cols = size(I{1}, 3);
+ end
+
+
+ % construction
+ t = tiledlayout(numel(I), n_cols);
+ t.Padding = 'none';
+ t.TileSpacing = 'none';
+ for row = 1:numel(I)
+ scale = [0, max(I{row}(:,:,:), [], 'all')];
+ for col = 1:size(I{row}, 3)
+ nexttile;
+ imshow(I{row}(:,:,col), scale);
+ if col == 1 && ~isempty(labels)
+ ylabel(labels(row));
+ end
+ end
+
+ if has_colorbar
+ cb_ax = nexttile();
+ axis(cb_ax, 'off');
+ colorbar('location','west');
+ clim(scale);
+ end
+ end
+
+ colormap(opts.cmap());
+end
diff --git a/simulations/anatomical_phantoms/usage/verbose_unified_phantom_test.m b/simulations/anatomical_phantoms/usage/verbose_unified_phantom_test.m
new file mode 100644
index 0000000..74dd9ee
--- /dev/null
+++ b/simulations/anatomical_phantoms/usage/verbose_unified_phantom_test.m
@@ -0,0 +1,239 @@
+clear; close all;
+addpath('../');
+mask = load('util/mask.mat').masks;
+
+create_graphs = true;
+
+% tissue_structure
+heart = tissue_structure("heart", mask, ["lv" "rv" "lvmy" "rvmy"]);
+
+% GLOBAL PK PARAMS
+TR = 3.6;
+Nt = 30;
+flips = repmat([20; 30; 30;], 1, Nt) .* (pi/180);
+
+% LV PK PARAMS ------------------
+disp("LV stuff")
+% - metabolites
+pyr = metabolite( ...
+ Mz0=0, ...
+ R1=1/30, ...
+ k=[0,0]);
+
+lac = metabolite( ...
+ Mz0=0, ...
+ R1=1/25, ...
+ k=0.0075);
+
+bic = metabolite( ...
+ Mz0=0, ...
+ R1=1/25, ...
+ k=0.0011);
+
+% - input function
+Tarrival = 7;
+Tbolus = 10;
+input_function = realistic_input_function(Nt, TR, Tarrival, Tbolus);
+
+% - put it all into pk_params
+lv_pk_params = pk_params(...
+ substrate = pyr, ...
+ products=[lac, bic], ...
+ TR=TR, ...
+ input_function=input_function, ...
+ flips=flips);
+
+% simulate lv metabolite dynamics
+lv_met_dynamics = pk_model.generate_met_dynamics(lv_pk_params);
+
+% plotting
+if create_graphs
+ tpts = 1:30;
+ figure; plot(tpts, lv_met_dynamics(1,:))
+ hold on
+ plot(tpts, lv_met_dynamics(2,:))
+ plot(tpts, lv_met_dynamics(3,:))
+ hold off
+end
+
+
+
+
+% RV PK PARAMS ----------------
+disp("RV stuff")
+% metabolites
+pyr = metabolite( ...
+ Mz0=1, ...
+ R1=1/30, ...
+ k=[0,0]);
+
+lac = metabolite( ...
+ Mz0=0, ...
+ R1=1/25, ...
+ k=[0.0045,0]);
+
+bic = metabolite( ...
+ Mz0=0, ...
+ R1=1/25, ...
+ k=[0.0005,0]);
+
+% - input function
+Tarrival = 0;
+Tbolus = 10;
+input_function = realistic_input_function(Nt, TR, Tarrival, Tbolus);
+
+% - put it all into pk_params
+rv_pk_params = pk_params(...
+ substrate = pyr, ...
+ products=[lac, bic], ...
+ TR=TR, ...
+ input_function=input_function, ...
+ flips=flips);
+
+% simulate lv metabolite dynamics
+rv_met_dynamics = pk_model.generate_met_dynamics(rv_pk_params);
+
+% plotting
+if create_graphs
+ tpts = 1:30;
+ figure; plot(tpts, rv_met_dynamics(1,:))
+ hold on
+ plot(tpts, rv_met_dynamics(2,:))
+ plot(tpts, rv_met_dynamics(3,:))
+ hold off
+end
+
+
+
+
+% LVMY PK PARAMS ----------------
+disp("LVMY stuff")
+% metabolites
+pyr = metabolite( ...
+ Mz0=0, ...
+ R1=1/30, ...
+ k=[0,0]);
+
+lac = metabolite( ...
+ Mz0=0, ...
+ R1=1/25, ...
+ k=[0.06,0]);
+
+bic = metabolite( ...
+ Mz0=0, ...
+ R1=1/25, ...
+ k=[0.04,0]);
+
+% - input function
+Tarrival = 10;
+Tbolus = 10;
+input_function = realistic_input_function(Nt, TR, Tarrival, Tbolus);
+
+
+% - put it all into pk_params
+lvmy_pk_params = pk_params(...
+ substrate = pyr, ...
+ products=[lac, bic], ...
+ TR=TR, ...
+ input_function=input_function, ...
+ flips=flips);
+
+% simulate lv metabolite dynamics
+lvmy_met_dynamics = pk_model.generate_met_dynamics(lvmy_pk_params);
+
+% plotting
+if create_graphs
+ tpts = 1:30;
+ figure; plot(tpts, lvmy_met_dynamics(1,:))
+ hold on
+ plot(tpts, lvmy_met_dynamics(2,:))
+ plot(tpts, lvmy_met_dynamics(3,:))
+ hold off
+end
+
+
+
+
+% RVMY PK PARAMS ----------------
+disp("LVMY stuff")
+% metabolites
+pyr = metabolite( ...
+ Mz0=0, ...
+ R1=1/30, ...
+ k=[0,0]);
+
+lac = metabolite( ...
+ Mz0=0, ...
+ R1=1/25, ...
+ k=[0.02,0]);
+
+bic = metabolite( ...
+ Mz0=0, ...
+ R1=1/25, ...
+ k=[0.01,0]);
+
+% - input function
+Tarrival = 14;
+Tbolus = 10;
+input_function = realistic_input_function(Nt, TR, Tarrival, Tbolus);
+
+% - put it all into pk_params
+rvmy_pk_params = pk_params(...
+ substrate = pyr, ...
+ products=[lac, bic], ...
+ TR=TR, ...
+ input_function=input_function, ...
+ flips=flips);
+
+% simulate lv metabolite dynamics
+rvmy_met_dynamics = pk_model.generate_met_dynamics(rvmy_pk_params);
+
+% plotting
+if create_graphs
+ tpts = 1:30;
+ figure; plot(tpts, rvmy_met_dynamics(1,:))
+ hold on
+ plot(tpts, rvmy_met_dynamics(2,:))
+ plot(tpts, rvmy_met_dynamics(3,:))
+ hold off
+end
+
+
+% PK MODEL ------------------
+disp("pk model time")
+met_dynamics = cat(3, lv_met_dynamics, rv_met_dynamics, lvmy_met_dynamics, rvmy_met_dynamics);
+met_dynamics = permute(met_dynamics, [3,1,2]); % = (tissue, met, time_pt)
+
+met_images = pk_model.generate_met_images(heart, met_dynamics);
+
+% MRI SYSTEM ----------------
+disp("mri time")
+sample_size = [32 32 11; 16 16 11; 24 24 11];
+
+augmentation_params = struct(...
+ "XTranslation", [-1,1], ...
+ "YTranslation", [-1,1], ...
+ "Scale", [0.95,1.1], ...
+ "XReflection", true, ...
+ "Rotation", [-5,5]);
+augmentation_params = namedargs2cell(augmentation_params);
+coil_lim = [0.4, 1.2];
+SNR = [150 40 20];
+output_size = [32 32 11; 32 32 11; 32 32 11];
+
+met_images = mri_system.augment(met_images, augmentation_params{:});
+met_images = mri_system.apply_coil_lim(met_images, coil_lim, heart.Mask);
+met_images_mres = mri_system.make_met_images_multires(met_images, sample_size);
+met_images_mres = mri_system.add_rician_noise(met_images_mres, SNR);
+met_images_mres = mri_system.upsample_to_output_size(met_images_mres, output_size);
+
+
+%% DISPLAY
+figure;
+imagescn(met_images_mres{1}(:,:,5,:), [0, max(met_images_mres{1}(:,:,5,:), [], 'all')])
+
+figure;
+imagescn(met_images_mres{2}(:,:,5,:), [0, max(met_images_mres{2}(:,:,5,:), [], 'all')])
+
+figure;
+imagescn(met_images_mres{3}(:,:,5,:), [0, max(met_images_mres{3}(:,:,5,:), [], 'all')])
diff --git a/simulations/anatomical_phantoms/util/_src_cardiac/1/cardiac_masks.mat b/simulations/anatomical_phantoms/util/_src_cardiac/1/cardiac_masks.mat
deleted file mode 100644
index e61b767..0000000
Binary files a/simulations/anatomical_phantoms/util/_src_cardiac/1/cardiac_masks.mat and /dev/null differ
diff --git a/simulations/anatomical_phantoms/util/_src_cardiac/10/cardiac_masks.mat b/simulations/anatomical_phantoms/util/_src_cardiac/10/cardiac_masks.mat
deleted file mode 100644
index c6e5a31..0000000
Binary files a/simulations/anatomical_phantoms/util/_src_cardiac/10/cardiac_masks.mat and /dev/null differ
diff --git a/simulations/anatomical_phantoms/util/_src_cardiac/11/cardiac_masks.mat b/simulations/anatomical_phantoms/util/_src_cardiac/11/cardiac_masks.mat
deleted file mode 100644
index dc7ce3e..0000000
Binary files a/simulations/anatomical_phantoms/util/_src_cardiac/11/cardiac_masks.mat and /dev/null differ
diff --git a/simulations/anatomical_phantoms/util/_src_cardiac/12/cardiac_masks.mat b/simulations/anatomical_phantoms/util/_src_cardiac/12/cardiac_masks.mat
deleted file mode 100644
index 87c8aa3..0000000
Binary files a/simulations/anatomical_phantoms/util/_src_cardiac/12/cardiac_masks.mat and /dev/null differ
diff --git a/simulations/anatomical_phantoms/util/_src_cardiac/13/cardiac_masks.mat b/simulations/anatomical_phantoms/util/_src_cardiac/13/cardiac_masks.mat
deleted file mode 100644
index 83cf638..0000000
Binary files a/simulations/anatomical_phantoms/util/_src_cardiac/13/cardiac_masks.mat and /dev/null differ
diff --git a/simulations/anatomical_phantoms/util/_src_cardiac/14/cardiac_masks.mat b/simulations/anatomical_phantoms/util/_src_cardiac/14/cardiac_masks.mat
deleted file mode 100644
index bc72e0b..0000000
Binary files a/simulations/anatomical_phantoms/util/_src_cardiac/14/cardiac_masks.mat and /dev/null differ
diff --git a/simulations/anatomical_phantoms/util/_src_cardiac/15/cardiac_masks.mat b/simulations/anatomical_phantoms/util/_src_cardiac/15/cardiac_masks.mat
deleted file mode 100644
index 3a8596b..0000000
Binary files a/simulations/anatomical_phantoms/util/_src_cardiac/15/cardiac_masks.mat and /dev/null differ
diff --git a/simulations/anatomical_phantoms/util/_src_cardiac/16/cardiac_masks.mat b/simulations/anatomical_phantoms/util/_src_cardiac/16/cardiac_masks.mat
deleted file mode 100644
index b373381..0000000
Binary files a/simulations/anatomical_phantoms/util/_src_cardiac/16/cardiac_masks.mat and /dev/null differ
diff --git a/simulations/anatomical_phantoms/util/_src_cardiac/17/cardiac_masks.mat b/simulations/anatomical_phantoms/util/_src_cardiac/17/cardiac_masks.mat
deleted file mode 100644
index 650ea5e..0000000
Binary files a/simulations/anatomical_phantoms/util/_src_cardiac/17/cardiac_masks.mat and /dev/null differ
diff --git a/simulations/anatomical_phantoms/util/_src_cardiac/18/cardiac_masks.mat b/simulations/anatomical_phantoms/util/_src_cardiac/18/cardiac_masks.mat
deleted file mode 100644
index ef85adc..0000000
Binary files a/simulations/anatomical_phantoms/util/_src_cardiac/18/cardiac_masks.mat and /dev/null differ
diff --git a/simulations/anatomical_phantoms/util/_src_cardiac/19/cardiac_masks.mat b/simulations/anatomical_phantoms/util/_src_cardiac/19/cardiac_masks.mat
deleted file mode 100644
index b6aace9..0000000
Binary files a/simulations/anatomical_phantoms/util/_src_cardiac/19/cardiac_masks.mat and /dev/null differ
diff --git a/simulations/anatomical_phantoms/util/_src_cardiac/2/cardiac_masks.mat b/simulations/anatomical_phantoms/util/_src_cardiac/2/cardiac_masks.mat
deleted file mode 100644
index c093aac..0000000
Binary files a/simulations/anatomical_phantoms/util/_src_cardiac/2/cardiac_masks.mat and /dev/null differ
diff --git a/simulations/anatomical_phantoms/util/_src_cardiac/20/cardiac_masks.mat b/simulations/anatomical_phantoms/util/_src_cardiac/20/cardiac_masks.mat
deleted file mode 100644
index 11183c9..0000000
Binary files a/simulations/anatomical_phantoms/util/_src_cardiac/20/cardiac_masks.mat and /dev/null differ
diff --git a/simulations/anatomical_phantoms/util/_src_cardiac/3/cardiac_masks.mat b/simulations/anatomical_phantoms/util/_src_cardiac/3/cardiac_masks.mat
deleted file mode 100644
index 8274a6f..0000000
Binary files a/simulations/anatomical_phantoms/util/_src_cardiac/3/cardiac_masks.mat and /dev/null differ
diff --git a/simulations/anatomical_phantoms/util/_src_cardiac/4/cardiac_masks.mat b/simulations/anatomical_phantoms/util/_src_cardiac/4/cardiac_masks.mat
deleted file mode 100644
index 331c094..0000000
Binary files a/simulations/anatomical_phantoms/util/_src_cardiac/4/cardiac_masks.mat and /dev/null differ
diff --git a/simulations/anatomical_phantoms/util/_src_cardiac/5/cardiac_masks.mat b/simulations/anatomical_phantoms/util/_src_cardiac/5/cardiac_masks.mat
deleted file mode 100644
index c4138f2..0000000
Binary files a/simulations/anatomical_phantoms/util/_src_cardiac/5/cardiac_masks.mat and /dev/null differ
diff --git a/simulations/anatomical_phantoms/util/_src_cardiac/6/cardiac_masks.mat b/simulations/anatomical_phantoms/util/_src_cardiac/6/cardiac_masks.mat
deleted file mode 100644
index 9ad6797..0000000
Binary files a/simulations/anatomical_phantoms/util/_src_cardiac/6/cardiac_masks.mat and /dev/null differ
diff --git a/simulations/anatomical_phantoms/util/_src_cardiac/7/cardiac_masks.mat b/simulations/anatomical_phantoms/util/_src_cardiac/7/cardiac_masks.mat
deleted file mode 100644
index d396202..0000000
Binary files a/simulations/anatomical_phantoms/util/_src_cardiac/7/cardiac_masks.mat and /dev/null differ
diff --git a/simulations/anatomical_phantoms/util/_src_cardiac/8/cardiac_masks.mat b/simulations/anatomical_phantoms/util/_src_cardiac/8/cardiac_masks.mat
deleted file mode 100644
index 7586f5d..0000000
Binary files a/simulations/anatomical_phantoms/util/_src_cardiac/8/cardiac_masks.mat and /dev/null differ
diff --git a/simulations/anatomical_phantoms/util/_src_cardiac/9/cardiac_masks.mat b/simulations/anatomical_phantoms/util/_src_cardiac/9/cardiac_masks.mat
deleted file mode 100644
index 1b4ee7e..0000000
Binary files a/simulations/anatomical_phantoms/util/_src_cardiac/9/cardiac_masks.mat and /dev/null differ
diff --git a/simulations/anatomical_phantoms/util/_src_cardiac/create_cardiac_masks/create_cardiac_masks.m b/simulations/anatomical_phantoms/util/_src_cardiac/create_cardiac_masks/create_cardiac_masks.m
deleted file mode 100644
index d8d6972..0000000
--- a/simulations/anatomical_phantoms/util/_src_cardiac/create_cardiac_masks/create_cardiac_masks.m
+++ /dev/null
@@ -1,127 +0,0 @@
-function [cardiac_masks, layered_masks] = create_cardiac_masks(vertices, tolerance, maskSize)
-% CREATE_CARDIAC_MASKS creates cardiac masks from point cloud data for
-% cardiac_metabolic_phantom
-% Parameters:
-% vertices = struct with fields mc, lv, rv, each of which are Nx3
-% matrices of xyz coordinates
-% tolerance = how "off" a point can be to be included in a
-% slice. defaults to 1.
-% maskSize = how large the masks should be. [xmin, xmax, xres;
-% ymin, ymax, yres; zmin, zmax, zres;]. default =
-% size chosen based on point cloud data
-%
-% Outputs:
-% cardiac_masks = 4d array of masks (nx, ny, nz, tissue)
-% layered_masks = 3d array of unseparated masks
-
-
- arguments
- vertices struct
- tolerance (1,1) double = 1
- maskSize (3,3) double = zeros(3)
- end
-
- % default maskSize
- if ~any(maskSize,'all')
- all_vertices = cat(1, vertices.mc, vertices.lv, vertices.rv);
- % get reasonable "window size"
- x_range = max(all_vertices(:,1),[],'all') - min(all_vertices(:,1),[],'all');
- y_range = max(all_vertices(:,2),[],'all') - min(all_vertices(:,2),[],'all');
- % get x y bounds
- ranges = [x_range, y_range];
- for dim = 1:numel(ranges)
- offset = 0.25 * ranges(1);
- maskSize(dim,1) = min(all_vertices(:,dim),[],'all') - offset;
- maskSize(dim,2) = max(all_vertices(:,dim),[],'all') + offset;
- maskSize(dim,3) = round(maskSize(dim,2) - maskSize(dim,1) + 1);
- end
- % get z bounds
- maskSize(3,1) = min(all_vertices(:,3),[],'all');
- maskSize(3,2) = max(all_vertices(:,3),[],'all');
- maskSize(3,3) = round(maskSize(3,2) - maskSize(3,1) + 1);
- end
-
-
- % read points into 3d array
- point_map = zeros(maskSize(2,3), maskSize(1,3), maskSize(3,3), 3);
- tissues = fieldnames(vertices);
-
- x = linspace(maskSize(1,1),maskSize(1,2),maskSize(1,3));
- y = linspace(maskSize(2,1),maskSize(2,2),maskSize(2,3));
- z = linspace(maskSize(3,1),maskSize(3,2),maskSize(3,3));
- [X,Y,Z] = meshgrid(x,y,z);
-
- for tissue = 1:numel(tissues)
- tissue_name = tissues{tissue}; % TODO: tissue vs tissue name is bad
- tissue_vertices = vertices.(tissue_name);
- tissue_point_map = zeros(size(X));
-
- % plot each point on the map
- for point = 1:size(tissue_vertices,1)
- % find distance from each point from the map
- xDiff = abs(X - tissue_vertices(point,1));
- yDiff = abs(Y - tissue_vertices(point,2));
- zDiff = abs(Z - tissue_vertices(point,3));
- totalDiff = xDiff + yDiff + zDiff;
- % add points within tolerance to map
- tissue_point_map(totalDiff <= tolerance) = 1;
- end
- point_map(:,:,:,tissue) = tissue_point_map;
- end
-
-
- % create convex hulls of each slice
- conv_hulls = zeros(size(point_map));
- slices = size(point_map, 3);
- for tissue = 1:numel(tissues)
- for slice = 1:slices
- conv_hulls(:,:,slice,tissue) = bwconvhull(point_map(:,:,slice,tissue));
- end
- end
-
- % layer hulls
- % mc = 1, lv = 2, rv = 3
- layered_masks = int8(conv_hulls(:,:,:,1)); % mc
- layered_masks(conv_hulls(:,:,:,2) == 1) = 2; % lv
- layered_masks(conv_hulls(:,:,:,3) == 1) = 3; % rv
-
- % separate rv and lv myocardium
- old_layered_masks = zeros(size(layered_masks));
- while ~isequal(old_layered_masks, layered_masks)
- old_layered_masks = layered_masks;
- for z = 1:size(layered_masks, 3)
- % get maps rv lv and mc maps
- slice = layered_masks(:,:,z);
- mc_map = slice == 1;
- lv_map = (slice == 2) | (slice == 4);
- rv_map = (slice == 3) | (slice == 5);
- kernel = [1,1,1 ; 1,0,1 ; 1,1,1];
-
- % get pixels around the lv/rv
- lv_conv_result = conv2(lv_map, kernel, "same");
- rv_conv_result = conv2(rv_map,kernel,"same");
- lv_mc = (lv_conv_result > 0) & mc_map;
- rv_mc = (rv_conv_result > 0) & mc_map;
-
- % update layered masks
- new_slice = slice;
- new_slice(lv_mc == 1) = 4;
- new_slice(rv_mc == 1) = 5;
- layered_masks(:,:,z) = new_slice;
- end
- end
-
- % assume non-labeled myocardium is rv myocardium (TODO: maybe add more convolutions along the z axis)
- layered_masks(layered_masks == 1) = 4;
-
- layered_masks = layered_masks - 1;
- layered_masks(layered_masks < 0) = 0;
-
- % separate masks
- cardiac_masks = zeros(cat(2,size(layered_masks),4));
- cardiac_masks(:,:,:,1) = layered_masks == 1;
- cardiac_masks(:,:,:,2) = layered_masks == 2;
- cardiac_masks(:,:,:,3) = layered_masks == 3;
- cardiac_masks(:,:,:,4) = layered_masks == 4;
-
-end
\ No newline at end of file
diff --git a/simulations/anatomical_phantoms/util/_src_cardiac/create_cardiac_masks/create_cardiac_masks_test.m b/simulations/anatomical_phantoms/util/_src_cardiac/create_cardiac_masks/create_cardiac_masks_test.m
deleted file mode 100644
index 554f217..0000000
--- a/simulations/anatomical_phantoms/util/_src_cardiac/create_cardiac_masks/create_cardiac_masks_test.m
+++ /dev/null
@@ -1,57 +0,0 @@
-% testing script for create_cardiac_masks
-clear; close all;
-% PCA modes are from the Cardiac Atlas Project and was derived from the UK
-% Biobank Study
-
-% the HDF5 files are too large for GitHub, but can be found here:
-% https://www.cardiacatlas.org/biventricular-modes/
-% after download, place the .h5 file in the same directory as this script
-
-% read point cloud data
-sourceFile = './UKBRVLV_All.h5';
-PCA_mode = 20;
-pc = h5read(sourceFile, '/COEFF');
-ev = h5read(sourceFile, '/LATENT');
-mu = h5read(sourceFile, '/MU');
-S = mu + (1.5 .* sqrt(ev(1)) .* pc(:,PCA_mode)');
-N = length(S);
-ed = reshape(S(1:N/2), 3, [])';
-es = reshape(S((N/2+1):end), 3, [])';
-
-vertices = struct;
-% define areas of the heart
-% these was separated by hand
-lv = ed(1:1428,:);
-rv = ed(1429:3056,:);
-mc = ed(3057:end,:);
-
-figure('Color', 'w');
-plot3(lv(:,1), lv(:,2), lv(:,3), 'b.');
-hold on;
-plot3(rv(:,1), rv(:,2), rv(:,3), 'r.');
-plot3(mc(:,1), mc(:,2), mc(:,3), 'g.');
-axis vis3d
-axis equal
-
-% put it all in a struct
-vertices.mc = mc;
-vertices.lv = lv;
-vertices.rv = rv;
-
-maskSize = [-100,100,201;
- -100,100,201;
- -50,50,11];
-
-[im_mask, layered_masks] = create_cardiac_masks(vertices, 2, maskSize);
-
-slices = 1:round(size(im_mask,3)/10):size(im_mask,3);
-
-%% visualize im_mask
-
-figure;
-imagescn(im_mask(:,:,slices,:), [0, 1], [numel(slices), size(im_mask,4)]);
-
-%% visualize layered_masks
-
-figure;
-imagescn(layered_masks(:,:,slices,:),[0 max(layered_masks(:,:,slices,:),[],'all')], [1, numel(slices)]);
\ No newline at end of file
diff --git a/simulations/anatomical_phantoms/util/1/brainweb.mat b/simulations/anatomical_phantoms/util/brainweb/1/brainweb.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/1/brainweb.mat
rename to simulations/anatomical_phantoms/util/brainweb/1/brainweb.mat
diff --git a/simulations/anatomical_phantoms/util/1/brainweb_fuzzy.mat b/simulations/anatomical_phantoms/util/brainweb/1/brainweb_fuzzy.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/1/brainweb_fuzzy.mat
rename to simulations/anatomical_phantoms/util/brainweb/1/brainweb_fuzzy.mat
diff --git a/simulations/anatomical_phantoms/util/10/brainweb.mat b/simulations/anatomical_phantoms/util/brainweb/10/brainweb.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/10/brainweb.mat
rename to simulations/anatomical_phantoms/util/brainweb/10/brainweb.mat
diff --git a/simulations/anatomical_phantoms/util/10/brainweb_fuzzy.mat b/simulations/anatomical_phantoms/util/brainweb/10/brainweb_fuzzy.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/10/brainweb_fuzzy.mat
rename to simulations/anatomical_phantoms/util/brainweb/10/brainweb_fuzzy.mat
diff --git a/simulations/anatomical_phantoms/util/11/brainweb.mat b/simulations/anatomical_phantoms/util/brainweb/11/brainweb.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/11/brainweb.mat
rename to simulations/anatomical_phantoms/util/brainweb/11/brainweb.mat
diff --git a/simulations/anatomical_phantoms/util/11/brainweb_fuzzy.mat b/simulations/anatomical_phantoms/util/brainweb/11/brainweb_fuzzy.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/11/brainweb_fuzzy.mat
rename to simulations/anatomical_phantoms/util/brainweb/11/brainweb_fuzzy.mat
diff --git a/simulations/anatomical_phantoms/util/12/brainweb.mat b/simulations/anatomical_phantoms/util/brainweb/12/brainweb.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/12/brainweb.mat
rename to simulations/anatomical_phantoms/util/brainweb/12/brainweb.mat
diff --git a/simulations/anatomical_phantoms/util/12/brainweb_fuzzy.mat b/simulations/anatomical_phantoms/util/brainweb/12/brainweb_fuzzy.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/12/brainweb_fuzzy.mat
rename to simulations/anatomical_phantoms/util/brainweb/12/brainweb_fuzzy.mat
diff --git a/simulations/anatomical_phantoms/util/13/brainweb.mat b/simulations/anatomical_phantoms/util/brainweb/13/brainweb.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/13/brainweb.mat
rename to simulations/anatomical_phantoms/util/brainweb/13/brainweb.mat
diff --git a/simulations/anatomical_phantoms/util/13/brainweb_fuzzy.mat b/simulations/anatomical_phantoms/util/brainweb/13/brainweb_fuzzy.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/13/brainweb_fuzzy.mat
rename to simulations/anatomical_phantoms/util/brainweb/13/brainweb_fuzzy.mat
diff --git a/simulations/anatomical_phantoms/util/14/brainweb.mat b/simulations/anatomical_phantoms/util/brainweb/14/brainweb.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/14/brainweb.mat
rename to simulations/anatomical_phantoms/util/brainweb/14/brainweb.mat
diff --git a/simulations/anatomical_phantoms/util/14/brainweb_fuzzy.mat b/simulations/anatomical_phantoms/util/brainweb/14/brainweb_fuzzy.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/14/brainweb_fuzzy.mat
rename to simulations/anatomical_phantoms/util/brainweb/14/brainweb_fuzzy.mat
diff --git a/simulations/anatomical_phantoms/util/15/brainweb.mat b/simulations/anatomical_phantoms/util/brainweb/15/brainweb.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/15/brainweb.mat
rename to simulations/anatomical_phantoms/util/brainweb/15/brainweb.mat
diff --git a/simulations/anatomical_phantoms/util/15/brainweb_fuzzy.mat b/simulations/anatomical_phantoms/util/brainweb/15/brainweb_fuzzy.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/15/brainweb_fuzzy.mat
rename to simulations/anatomical_phantoms/util/brainweb/15/brainweb_fuzzy.mat
diff --git a/simulations/anatomical_phantoms/util/16/brainweb.mat b/simulations/anatomical_phantoms/util/brainweb/16/brainweb.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/16/brainweb.mat
rename to simulations/anatomical_phantoms/util/brainweb/16/brainweb.mat
diff --git a/simulations/anatomical_phantoms/util/16/brainweb_fuzzy.mat b/simulations/anatomical_phantoms/util/brainweb/16/brainweb_fuzzy.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/16/brainweb_fuzzy.mat
rename to simulations/anatomical_phantoms/util/brainweb/16/brainweb_fuzzy.mat
diff --git a/simulations/anatomical_phantoms/util/17/brainweb.mat b/simulations/anatomical_phantoms/util/brainweb/17/brainweb.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/17/brainweb.mat
rename to simulations/anatomical_phantoms/util/brainweb/17/brainweb.mat
diff --git a/simulations/anatomical_phantoms/util/17/brainweb_fuzzy.mat b/simulations/anatomical_phantoms/util/brainweb/17/brainweb_fuzzy.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/17/brainweb_fuzzy.mat
rename to simulations/anatomical_phantoms/util/brainweb/17/brainweb_fuzzy.mat
diff --git a/simulations/anatomical_phantoms/util/18/brainweb.mat b/simulations/anatomical_phantoms/util/brainweb/18/brainweb.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/18/brainweb.mat
rename to simulations/anatomical_phantoms/util/brainweb/18/brainweb.mat
diff --git a/simulations/anatomical_phantoms/util/18/brainweb_fuzzy.mat b/simulations/anatomical_phantoms/util/brainweb/18/brainweb_fuzzy.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/18/brainweb_fuzzy.mat
rename to simulations/anatomical_phantoms/util/brainweb/18/brainweb_fuzzy.mat
diff --git a/simulations/anatomical_phantoms/util/19/brainweb.mat b/simulations/anatomical_phantoms/util/brainweb/19/brainweb.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/19/brainweb.mat
rename to simulations/anatomical_phantoms/util/brainweb/19/brainweb.mat
diff --git a/simulations/anatomical_phantoms/util/19/brainweb_fuzzy.mat b/simulations/anatomical_phantoms/util/brainweb/19/brainweb_fuzzy.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/19/brainweb_fuzzy.mat
rename to simulations/anatomical_phantoms/util/brainweb/19/brainweb_fuzzy.mat
diff --git a/simulations/anatomical_phantoms/util/2/brainweb.mat b/simulations/anatomical_phantoms/util/brainweb/2/brainweb.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/2/brainweb.mat
rename to simulations/anatomical_phantoms/util/brainweb/2/brainweb.mat
diff --git a/simulations/anatomical_phantoms/util/2/brainweb_fuzzy.mat b/simulations/anatomical_phantoms/util/brainweb/2/brainweb_fuzzy.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/2/brainweb_fuzzy.mat
rename to simulations/anatomical_phantoms/util/brainweb/2/brainweb_fuzzy.mat
diff --git a/simulations/anatomical_phantoms/util/3/brainweb.mat b/simulations/anatomical_phantoms/util/brainweb/3/brainweb.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/3/brainweb.mat
rename to simulations/anatomical_phantoms/util/brainweb/3/brainweb.mat
diff --git a/simulations/anatomical_phantoms/util/3/brainweb_fuzzy.mat b/simulations/anatomical_phantoms/util/brainweb/3/brainweb_fuzzy.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/3/brainweb_fuzzy.mat
rename to simulations/anatomical_phantoms/util/brainweb/3/brainweb_fuzzy.mat
diff --git a/simulations/anatomical_phantoms/util/4/brainweb.mat b/simulations/anatomical_phantoms/util/brainweb/4/brainweb.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/4/brainweb.mat
rename to simulations/anatomical_phantoms/util/brainweb/4/brainweb.mat
diff --git a/simulations/anatomical_phantoms/util/4/brainweb_fuzzy.mat b/simulations/anatomical_phantoms/util/brainweb/4/brainweb_fuzzy.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/4/brainweb_fuzzy.mat
rename to simulations/anatomical_phantoms/util/brainweb/4/brainweb_fuzzy.mat
diff --git a/simulations/anatomical_phantoms/util/5/brainweb.mat b/simulations/anatomical_phantoms/util/brainweb/5/brainweb.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/5/brainweb.mat
rename to simulations/anatomical_phantoms/util/brainweb/5/brainweb.mat
diff --git a/simulations/anatomical_phantoms/util/5/brainweb_fuzzy.mat b/simulations/anatomical_phantoms/util/brainweb/5/brainweb_fuzzy.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/5/brainweb_fuzzy.mat
rename to simulations/anatomical_phantoms/util/brainweb/5/brainweb_fuzzy.mat
diff --git a/simulations/anatomical_phantoms/util/6/brainweb.mat b/simulations/anatomical_phantoms/util/brainweb/6/brainweb.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/6/brainweb.mat
rename to simulations/anatomical_phantoms/util/brainweb/6/brainweb.mat
diff --git a/simulations/anatomical_phantoms/util/6/brainweb_fuzzy.mat b/simulations/anatomical_phantoms/util/brainweb/6/brainweb_fuzzy.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/6/brainweb_fuzzy.mat
rename to simulations/anatomical_phantoms/util/brainweb/6/brainweb_fuzzy.mat
diff --git a/simulations/anatomical_phantoms/util/7/brainweb.mat b/simulations/anatomical_phantoms/util/brainweb/7/brainweb.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/7/brainweb.mat
rename to simulations/anatomical_phantoms/util/brainweb/7/brainweb.mat
diff --git a/simulations/anatomical_phantoms/util/7/brainweb_fuzzy.mat b/simulations/anatomical_phantoms/util/brainweb/7/brainweb_fuzzy.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/7/brainweb_fuzzy.mat
rename to simulations/anatomical_phantoms/util/brainweb/7/brainweb_fuzzy.mat
diff --git a/simulations/anatomical_phantoms/util/8/brainweb.mat b/simulations/anatomical_phantoms/util/brainweb/8/brainweb.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/8/brainweb.mat
rename to simulations/anatomical_phantoms/util/brainweb/8/brainweb.mat
diff --git a/simulations/anatomical_phantoms/util/8/brainweb_fuzzy.mat b/simulations/anatomical_phantoms/util/brainweb/8/brainweb_fuzzy.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/8/brainweb_fuzzy.mat
rename to simulations/anatomical_phantoms/util/brainweb/8/brainweb_fuzzy.mat
diff --git a/simulations/anatomical_phantoms/util/9/brainweb.mat b/simulations/anatomical_phantoms/util/brainweb/9/brainweb.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/9/brainweb.mat
rename to simulations/anatomical_phantoms/util/brainweb/9/brainweb.mat
diff --git a/simulations/anatomical_phantoms/util/9/brainweb_fuzzy.mat b/simulations/anatomical_phantoms/util/brainweb/9/brainweb_fuzzy.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/9/brainweb_fuzzy.mat
rename to simulations/anatomical_phantoms/util/brainweb/9/brainweb_fuzzy.mat
diff --git a/simulations/anatomical_phantoms/util/brainweb04_fuzzy_hires.mat b/simulations/anatomical_phantoms/util/brainweb/brainweb04_fuzzy_hires.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/brainweb04_fuzzy_hires.mat
rename to simulations/anatomical_phantoms/util/brainweb/brainweb04_fuzzy_hires.mat
diff --git a/simulations/anatomical_phantoms/util/brainweb04_hi_res.mat b/simulations/anatomical_phantoms/util/brainweb/brainweb04_hi_res.mat
similarity index 100%
rename from simulations/anatomical_phantoms/util/brainweb04_hi_res.mat
rename to simulations/anatomical_phantoms/util/brainweb/brainweb04_hi_res.mat
diff --git a/simulations/anatomical_phantoms/util/cardiac/cardiac_mask_1.mat b/simulations/anatomical_phantoms/util/cardiac/cardiac_mask_1.mat
new file mode 100644
index 0000000..36db9ba
Binary files /dev/null and b/simulations/anatomical_phantoms/util/cardiac/cardiac_mask_1.mat differ
diff --git a/simulations/anatomical_phantoms/util/cardiac/cardiac_mask_10.mat b/simulations/anatomical_phantoms/util/cardiac/cardiac_mask_10.mat
new file mode 100644
index 0000000..8659c9a
Binary files /dev/null and b/simulations/anatomical_phantoms/util/cardiac/cardiac_mask_10.mat differ
diff --git a/simulations/anatomical_phantoms/util/cardiac/cardiac_mask_2.mat b/simulations/anatomical_phantoms/util/cardiac/cardiac_mask_2.mat
new file mode 100644
index 0000000..8be0626
Binary files /dev/null and b/simulations/anatomical_phantoms/util/cardiac/cardiac_mask_2.mat differ
diff --git a/simulations/anatomical_phantoms/util/cardiac/cardiac_mask_3.mat b/simulations/anatomical_phantoms/util/cardiac/cardiac_mask_3.mat
new file mode 100644
index 0000000..53349e7
Binary files /dev/null and b/simulations/anatomical_phantoms/util/cardiac/cardiac_mask_3.mat differ
diff --git a/simulations/anatomical_phantoms/util/cardiac/cardiac_mask_4.mat b/simulations/anatomical_phantoms/util/cardiac/cardiac_mask_4.mat
new file mode 100644
index 0000000..901d514
Binary files /dev/null and b/simulations/anatomical_phantoms/util/cardiac/cardiac_mask_4.mat differ
diff --git a/simulations/anatomical_phantoms/util/cardiac/cardiac_mask_5.mat b/simulations/anatomical_phantoms/util/cardiac/cardiac_mask_5.mat
new file mode 100644
index 0000000..1b6b485
Binary files /dev/null and b/simulations/anatomical_phantoms/util/cardiac/cardiac_mask_5.mat differ
diff --git a/simulations/anatomical_phantoms/util/cardiac/cardiac_mask_6.mat b/simulations/anatomical_phantoms/util/cardiac/cardiac_mask_6.mat
new file mode 100644
index 0000000..d20c8e1
Binary files /dev/null and b/simulations/anatomical_phantoms/util/cardiac/cardiac_mask_6.mat differ
diff --git a/simulations/anatomical_phantoms/util/cardiac/cardiac_mask_7.mat b/simulations/anatomical_phantoms/util/cardiac/cardiac_mask_7.mat
new file mode 100644
index 0000000..7d971dd
Binary files /dev/null and b/simulations/anatomical_phantoms/util/cardiac/cardiac_mask_7.mat differ
diff --git a/simulations/anatomical_phantoms/util/cardiac/cardiac_mask_8.mat b/simulations/anatomical_phantoms/util/cardiac/cardiac_mask_8.mat
new file mode 100644
index 0000000..2a1deb8
Binary files /dev/null and b/simulations/anatomical_phantoms/util/cardiac/cardiac_mask_8.mat differ
diff --git a/simulations/anatomical_phantoms/util/cardiac/cardiac_mask_9.mat b/simulations/anatomical_phantoms/util/cardiac/cardiac_mask_9.mat
new file mode 100644
index 0000000..5cc5019
Binary files /dev/null and b/simulations/anatomical_phantoms/util/cardiac/cardiac_mask_9.mat differ
diff --git a/simulations/anatomical_phantoms/util/cardiac/create_cardiac_masks/bresenham.m b/simulations/anatomical_phantoms/util/cardiac/create_cardiac_masks/bresenham.m
new file mode 100644
index 0000000..f9e7a58
--- /dev/null
+++ b/simulations/anatomical_phantoms/util/cardiac/create_cardiac_masks/bresenham.m
@@ -0,0 +1,39 @@
+function [x, y]=bresenham(x1,y1,x2,y2)
+
+%Matlab optmized version of Bresenham line algorithm. No loops.
+%Format:
+% [x y]=bham(x1,y1,x2,y2)
+%
+%Input:
+% (x1,y1): Start position
+% (x2,y2): End position
+%
+%Output:
+% x y: the line coordinates from (x1,y1) to (x2,y2)
+%
+%Usage example:
+% [x y]=bham(1,1, 10,-5);
+% plot(x,y,'or');
+x1=round(x1); x2=round(x2);
+y1=round(y1); y2=round(y2);
+dx=abs(x2-x1);
+dy=abs(y2-y1);
+steep=abs(dy)>abs(dx);
+if steep t=dx;dx=dy;dy=t; end
+
+%The main algorithm goes here.
+if dy==0
+ q=zeros(dx+1,1);
+else
+ q=[0;diff(mod([floor(dx/2):-dy:-dy*dx+floor(dx/2)]',dx))>=0];
+end
+
+%and ends here.
+
+if steep
+ if y1<=y2 y=[y1:y2]'; else y=[y1:-1:y2]'; end
+ if x1<=x2 x=x1+cumsum(q);else x=x1-cumsum(q); end
+else
+ if x1<=x2 x=[x1:x2]'; else x=[x1:-1:x2]'; end
+ if y1<=y2 y=y1+cumsum(q);else y=y1-cumsum(q); end
+end
diff --git a/simulations/anatomical_phantoms/util/cardiac/create_cardiac_masks/check_connection.m b/simulations/anatomical_phantoms/util/cardiac/create_cardiac_masks/check_connection.m
new file mode 100644
index 0000000..a1ce4a5
--- /dev/null
+++ b/simulations/anatomical_phantoms/util/cardiac/create_cardiac_masks/check_connection.m
@@ -0,0 +1,49 @@
+function isconnected = check_connection(BW, pt1, pt2)
+ % checks if 2 points are connected by 1s on a black and white image.
+ % basically just a breadth-first search pathfinding algorithm that
+ % returns true if a path exists and false if path doesn't exist.
+ %
+ % ARGS:
+ % BW = binary image. size [N x M]
+ % pt1 = coordinates of the first point. size [1 2]
+ % pt2 = coordinates of the second point. size [1 2]
+
+ % if the 2 points are the same, just say they're connected
+ if pt1 == pt2
+ isconnected = true;
+ return
+ end
+
+ isconnected = false;
+ directions = [0 1; 0 -1; 1 0; -1 0; ... % 4 cardinal directions
+ 1 1; 1 -1; -1 1; -1 -1]; % 4 corners
+
+ queue = {pt1};
+
+ visited = zeros(size(BW));
+ visited(pt1(1), pt1(2)) = 1; % mark initial point as visited
+
+ while ~isempty(queue)
+ current_point = queue{1};
+ % check each direction
+ for direction_n = 1:size(directions, 1)
+ neighbor_idx = current_point + directions(direction_n, :);
+ % ensure valid idx
+ if any(neighbor_idx < 1) || any(neighbor_idx > size(BW))
+ continue
+ end
+ % add to queue if unsearched point
+ if BW(neighbor_idx(1), neighbor_idx(2)) == 1 & ...
+ visited(neighbor_idx(1), neighbor_idx(2)) == 0
+ queue{end + 1} = neighbor_idx;
+ visited(neighbor_idx(1), neighbor_idx(2)) = 1;
+ if neighbor_idx == pt2
+ isconnected = true;
+ return
+ end
+ end
+ end
+ % pop point of queue off the queue
+ queue = queue(2:end);
+ end
+end
diff --git a/simulations/anatomical_phantoms/util/cardiac/create_cardiac_masks/connectivity.txt b/simulations/anatomical_phantoms/util/cardiac/create_cardiac_masks/connectivity.txt
new file mode 100644
index 0000000..6693e7a
--- /dev/null
+++ b/simulations/anatomical_phantoms/util/cardiac/create_cardiac_masks/connectivity.txt
@@ -0,0 +1,11616 @@
+1487 749 1432
+1487 1432 20
+749 1132 332
+749 332 1432
+1133 182 1132
+1133 1132 749
+359 1133 749
+359 749 1487
+1132 748 1433
+1132 1433 332
+748 5629 5589
+748 5589 1433
+1131 5605 5629
+1131 5629 748
+182 1131 748
+182 748 1132
+1130 747 1131
+1130 1131 182
+747 5628 5605
+747 5605 1131
+1380 5591 5628
+1380 5628 747
+306 1380 747
+306 747 1130
+1486 746 1133
+1486 1133 359
+746 1130 182
+746 182 1133
+1381 306 1130
+1381 1130 746
+1 1381 746
+1 746 1486
+1467 745 50
+745 1498 50
+745 1128 365
+745 365 1498
+1129 181 1128
+1129 1128 745
+349 1129 745
+349 745 1467
+1128 744 1499
+1128 1499 365
+744 1464 38
+744 38 1499
+1127 348 1464
+1127 1464 744
+181 1127 744
+181 744 1128
+1126 743 1127
+1126 1127 181
+743 1465 348
+743 348 1127
+1241 37 743
+37 1465 743
+236 1241 1126
+1241 743 1126
+1466 742 1129
+1466 1129 349
+742 1126 181
+742 181 1129
+1240 236 742
+236 1126 742
+5 1240 1466
+1240 742 1466
+1498 741 50
+741 1468 50
+741 1124 1468
+1124 350 1468
+1125 180 741
+180 1124 741
+365 1125 1498
+1125 741 1498
+1124 740 350
+740 1469 350
+740 1496 49
+740 49 1469
+1123 364 740
+364 1496 740
+180 1123 1124
+1123 740 1124
+1122 739 180
+739 1123 180
+739 1497 1123
+1497 364 1123
+1474 51 739
+51 1497 739
+353 1474 1122
+1474 739 1122
+1499 738 365
+738 1125 365
+738 1122 1125
+1122 180 1125
+1475 353 738
+353 1122 738
+38 1475 1499
+1475 738 1499
+1495 737 1470
+1495 1470 35
+737 1120 351
+737 351 1470
+1121 179 1120
+1121 1120 737
+363 1121 737
+363 737 1495
+1120 736 1471
+1120 1471 351
+736 1497 1471
+1497 51 1471
+1119 364 736
+364 1497 736
+179 1119 736
+179 736 1120
+1118 735 1119
+1118 1119 179
+735 1496 364
+735 364 1119
+1460 49 1496
+1460 1496 735
+346 1460 735
+346 735 1118
+1494 734 1121
+1494 1121 363
+734 1118 179
+734 179 1121
+1461 346 1118
+1461 1118 734
+4 1461 734
+4 734 1494
+1421 733 26
+733 1492 26
+733 1116 1492
+1116 362 1492
+1117 178 733
+178 1116 733
+326 1117 1421
+1117 733 1421
+1116 732 362
+732 1493 362
+732 1404 1493
+1404 40 1493
+1115 318 732
+318 1404 732
+178 1115 1116
+1115 732 1116
+1114 731 178
+731 1115 178
+731 1405 1115
+1405 318 1115
+1495 35 731
+35 1405 731
+363 1495 731
+363 731 1114
+1420 730 326
+730 1117 326
+730 1114 1117
+1114 178 1117
+1494 363 730
+363 1114 730
+4 1494 1420
+1494 730 1420
+1491 729 1400
+1491 1400 36
+729 1112 316
+729 316 1400
+1113 177 1112
+1113 1112 729
+361 1113 729
+361 729 1491
+1112 728 1401
+1112 1401 316
+728 1493 40
+728 40 1401
+1111 362 1493
+1111 1493 728
+177 1111 728
+177 728 1112
+1110 727 1111
+1110 1111 177
+727 1492 362
+727 362 1111
+1422 26 1492
+1422 1492 727
+327 1422 727
+327 727 1110
+1490 726 1113
+1490 1113 361
+726 1110 177
+726 177 1113
+1423 327 1110
+1423 1110 726
+6 1423 726
+6 726 1490
+1411 725 1488
+1411 1488 24
+725 1108 1488
+1108 360 1488
+1109 176 725
+176 1108 725
+321 1109 725
+321 725 1411
+1108 724 360
+724 1489 360
+724 1396 1489
+1396 39 1489
+1107 314 724
+314 1396 724
+176 1107 1108
+1107 724 1108
+1106 723 176
+723 1107 176
+723 1397 1107
+1397 314 1107
+1491 36 723
+36 1397 723
+361 1491 1106
+1491 723 1106
+1410 722 321
+722 1109 321
+722 1106 1109
+1106 176 1109
+1490 361 722
+361 1106 722
+6 1490 1410
+1490 722 1410
+1391 721 39
+721 1489 39
+721 1104 1489
+1104 360 1489
+1105 175 721
+175 1104 721
+311 1105 1391
+1105 721 1391
+1104 720 360
+720 1488 360
+720 1414 24
+720 24 1488
+1103 323 1414
+1103 1414 720
+175 1103 720
+175 720 1104
+1102 719 1103
+1102 1103 175
+719 1415 323
+719 323 1103
+1487 20 1415
+1487 1415 719
+359 1487 1102
+1487 719 1102
+1390 718 311
+718 1105 311
+718 1102 1105
+1102 175 1105
+1486 359 718
+359 1102 718
+1 1486 1390
+1486 718 1390
+1485 717 1370
+1485 1370 23
+717 1100 1370
+1100 301 1370
+1101 174 1100
+1101 1100 717
+358 1101 717
+358 717 1485
+1100 716 301
+716 1371 301
+716 1336 1371
+1336 14 1371
+1099 284 716
+284 1336 716
+174 1099 1100
+1099 716 1100
+1098 715 1099
+1098 1099 174
+715 1337 1099
+1337 284 1099
+1394 8 1337
+1394 1337 715
+313 1394 715
+313 715 1098
+1484 714 1101
+1484 1101 358
+714 1098 174
+714 174 1101
+1395 313 1098
+1395 1098 714
+21 1395 714
+21 714 1484
+1483 713 1364
+1483 1364 11
+713 1096 298
+713 298 1364
+1097 173 1096
+1097 1096 713
+357 1097 713
+357 713 1483
+1096 712 1365
+1096 1365 298
+712 1485 23
+712 23 1365
+1095 358 1485
+1095 1485 712
+173 1095 712
+173 712 1096
+1094 711 1095
+1094 1095 173
+711 1484 358
+711 358 1095
+1388 21 1484
+1388 1484 711
+310 1388 711
+310 711 1094
+1482 710 1097
+1482 1097 357
+710 1094 173
+710 173 1097
+1389 310 1094
+1389 1094 710
+2 1389 710
+2 710 1482
+1355 709 11
+709 1483 11
+709 1092 1483
+1092 357 1483
+1093 172 709
+172 1092 709
+293 1093 1355
+1093 709 1355
+1092 708 357
+708 1482 357
+708 1384 1482
+1384 2 1482
+1091 308 708
+308 1384 708
+172 1091 1092
+1091 708 1092
+1090 707 172
+707 1091 172
+707 1385 1091
+1385 308 1091
+5627 5585 707
+5585 1385 707
+5604 5627 1090
+5627 707 1090
+1354 706 293
+706 1093 293
+706 1090 1093
+1090 172 1093
+5626 5604 706
+5604 1090 706
+5584 5626 1354
+5626 706 1354
+1162 705 1480
+1162 1480 19
+705 1088 356
+705 356 1480
+1089 171 1088
+1089 1088 705
+197 1089 705
+197 705 1162
+1088 704 1481
+1088 1481 356
+704 5653 5635
+704 5635 1481
+1087 5641 5653
+1087 5653 704
+171 1087 704
+171 704 1088
+1086 703 1087
+1086 1087 171
+703 5652 5641
+703 5641 1087
+1440 5633 5652
+1440 5652 703
+336 1440 703
+336 703 1086
+1163 702 1089
+1163 1089 197
+702 1086 171
+702 171 1089
+1441 336 1086
+1441 1086 702
+18 1441 702
+18 702 1163
+1479 701 5651
+1479 5651 5634
+701 1084 5640
+701 5640 5651
+1085 170 1084
+1085 1084 701
+355 1085 701
+355 701 1479
+1084 700 5640
+700 5650 5640
+700 1481 5650
+1481 5635 5650
+1083 356 700
+356 1481 700
+170 1083 1084
+1083 700 1084
+1082 699 170
+699 1083 170
+699 1480 1083
+1480 356 1083
+1155 19 699
+19 1480 699
+193 1155 1082
+1155 699 1082
+1478 698 355
+698 1085 355
+698 1082 170
+698 170 1085
+1154 193 1082
+1154 1082 698
+17 1154 1478
+1154 698 1478
+5648 697 5634
+697 1479 5634
+697 1080 355
+697 355 1479
+1081 169 1080
+1081 1080 697
+5639 1081 5648
+1081 697 5648
+1080 696 1478
+1080 1478 355
+696 1183 17
+696 17 1478
+1079 207 1183
+1079 1183 696
+169 1079 696
+169 696 1080
+1078 695 1079
+1078 1079 169
+695 1182 207
+695 207 1079
+1476 31 1182
+1476 1182 695
+354 1476 1078
+1476 695 1078
+5649 694 5639
+694 1081 5639
+694 1078 1081
+1078 169 1081
+1477 354 694
+354 1078 694
+5630 1477 5649
+1477 694 5649
+1351 693 15
+693 1436 15
+693 1076 1436
+1076 334 1436
+1077 168 693
+168 1076 693
+291 1077 1351
+1077 693 1351
+1076 692 334
+692 1437 334
+692 5647 1437
+5647 5631 1437
+1075 5638 692
+5638 5647 692
+168 1075 1076
+1075 692 1076
+1074 691 168
+691 1075 168
+691 5646 1075
+5646 5638 1075
+1477 5630 691
+5630 5646 691
+354 1477 1074
+1477 691 1074
+1350 690 291
+690 1077 291
+690 1074 1077
+1074 168 1077
+1476 354 690
+354 1074 690
+31 1476 1350
+1476 690 1350
+1474 689 1472
+1474 1472 51
+689 1072 1472
+1072 352 1472
+1073 167 689
+167 1072 689
+353 1073 689
+353 689 1474
+1072 688 352
+688 1473 352
+688 1376 1473
+1376 13 1473
+1071 304 688
+304 1376 688
+167 1071 1072
+1071 688 1072
+1070 687 167
+687 1071 167
+687 1377 1071
+1377 304 1071
+1462 0 687
+0 1377 687
+347 1462 1070
+1462 687 1070
+1475 686 1073
+1475 1073 353
+686 1070 167
+686 167 1073
+1463 347 1070
+1463 1070 686
+38 1463 686
+38 686 1475
+1341 685 13
+685 1473 13
+685 1068 1473
+1068 352 1473
+1069 166 685
+166 1068 685
+286 1069 1341
+1069 685 1341
+1068 684 352
+684 1472 352
+684 1471 1472
+1471 51 1472
+1067 351 684
+351 1471 684
+166 1067 1068
+1067 684 1068
+1066 683 166
+683 1067 166
+683 1470 1067
+1470 351 1067
+1402 35 683
+35 1470 683
+317 1402 1066
+1402 683 1066
+1340 682 286
+682 1069 286
+682 1066 1069
+1066 166 1069
+1403 317 682
+317 1066 682
+7 1403 1340
+1403 682 1340
+1459 681 1469
+1459 1469 49
+681 1064 350
+681 350 1469
+1065 165 1064
+1065 1064 681
+345 1065 681
+345 681 1459
+1064 680 1468
+1064 1468 350
+680 1467 50
+680 50 1468
+1063 349 1467
+1063 1467 680
+165 1063 680
+165 680 1064
+1062 679 1063
+1062 1063 165
+679 1466 349
+679 349 1063
+1213 5 1466
+1213 1466 679
+222 1213 679
+222 679 1062
+1458 678 1065
+1458 1065 345
+678 1062 165
+678 165 1065
+1212 222 1062
+1212 1062 678
+12 1212 678
+12 678 1458
+1220 677 37
+677 1465 37
+677 1060 1465
+1060 348 1465
+1061 164 677
+164 1060 677
+226 1061 1220
+1061 677 1220
+1060 676 348
+676 1464 348
+676 1463 1464
+1463 38 1464
+1059 347 676
+347 1463 676
+164 1059 1060
+1059 676 1060
+1058 675 164
+675 1059 164
+675 1462 347
+675 347 1059
+1456 0 1462
+1456 1462 675
+344 1456 1058
+1456 675 1058
+1221 674 226
+674 1061 226
+674 1058 1061
+1058 164 1061
+1457 344 674
+344 1058 674
+9 1457 1221
+1457 674 1221
+1460 673 49
+673 1459 49
+673 1056 1459
+1056 345 1459
+1057 163 673
+163 1056 673
+346 1057 1460
+1057 673 1460
+1056 672 345
+672 1458 345
+672 1235 1458
+1235 12 1458
+1055 233 672
+233 1235 672
+163 1055 1056
+1055 672 1056
+1054 671 163
+671 1055 163
+671 1234 1055
+1234 233 1055
+1418 41 671
+41 1234 671
+325 1418 1054
+1418 671 1054
+1461 670 346
+670 1057 346
+670 1054 1057
+1054 163 1057
+1419 325 670
+325 1054 670
+4 1419 1461
+1419 670 1461
+1345 669 1450
+1345 1450 30
+669 1052 341
+669 341 1450
+1053 162 1052
+1053 1052 669
+288 1053 669
+288 669 1345
+1052 668 1451
+1052 1451 341
+668 1358 48
+668 48 1451
+1051 295 1358
+1051 1358 668
+162 1051 668
+162 668 1052
+1050 667 1051
+1050 1051 162
+667 1359 295
+667 295 1051
+5625 5590 1359
+5625 1359 667
+5603 5625 667
+5603 667 1050
+1344 666 1053
+1344 1053 288
+666 1050 162
+666 162 1053
+5624 5603 1050
+5624 1050 666
+5583 5624 666
+5583 666 1344
+1379 665 1454
+1379 1454 25
+665 1048 343
+665 343 1454
+1049 161 1048
+1049 1048 665
+305 1049 665
+305 665 1379
+1048 664 343
+664 1455 343
+664 1229 1455
+1229 28 1455
+1047 230 664
+230 1229 664
+161 1047 1048
+1047 664 1048
+1046 663 161
+663 1047 161
+663 1228 1047
+1228 230 1047
+1457 9 663
+9 1228 663
+344 1457 1046
+1457 663 1046
+1378 662 1049
+1378 1049 305
+662 1046 161
+662 161 1049
+1456 344 1046
+1456 1046 662
+0 1456 662
+0 662 1378
+1375 661 1452
+1375 1452 3
+661 1044 342
+661 342 1452
+1045 160 1044
+1045 1044 661
+303 1045 661
+303 661 1375
+1044 660 1453
+1044 1453 342
+660 1269 1453
+1269 10 1453
+1043 250 660
+250 1269 660
+160 1043 660
+160 660 1044
+1042 659 1043
+1042 1043 160
+659 1268 1043
+1268 250 1043
+1455 28 659
+28 1268 659
+343 1455 1042
+1455 659 1042
+1374 658 1045
+1374 1045 303
+658 1042 160
+658 160 1045
+1454 343 1042
+1454 1042 658
+25 1454 658
+25 658 1374
+1369 657 1448
+1369 1448 47
+657 1040 340
+657 340 1448
+1041 159 1040
+1041 1040 657
+300 1041 657
+300 657 1369
+1040 656 1449
+1040 1449 340
+656 1291 1449
+1291 22 1449
+1039 261 656
+261 1291 656
+159 1039 656
+159 656 1040
+1038 655 1039
+1038 1039 159
+655 1290 1039
+1290 261 1039
+1453 10 655
+10 1290 655
+342 1453 655
+342 655 1038
+1368 654 1041
+1368 1041 300
+654 1038 159
+654 159 1041
+1452 342 1038
+1452 1038 654
+3 1452 654
+3 654 1368
+1363 653 1451
+1363 1451 48
+653 1036 341
+653 341 1451
+1037 158 1036
+1037 1036 653
+297 1037 653
+297 653 1363
+1036 652 1450
+1036 1450 341
+652 1297 30
+652 30 1450
+1035 264 1297
+1035 1297 652
+158 1035 652
+158 652 1036
+1034 651 1035
+1034 1035 158
+651 1296 264
+651 264 1035
+1449 22 1296
+1449 1296 651
+340 1449 651
+340 651 1034
+1362 650 1037
+1362 1037 297
+650 1034 158
+650 158 1037
+1448 340 1034
+1448 1034 650
+47 1448 650
+47 650 1362
+1447 649 5593
+649 5623 5593
+649 1032 5623
+1032 5602 5623
+1033 157 649
+157 1032 649
+339 1033 1447
+1033 649 1447
+1032 648 5602
+648 5622 5602
+648 1348 5622
+1348 5588 5622
+1031 290 648
+290 1348 648
+157 1031 1032
+1031 648 1032
+1030 647 157
+647 1031 157
+647 1349 1031
+1349 290 1031
+1149 31 647
+31 1349 647
+190 1149 1030
+1149 647 1030
+1446 646 339
+646 1033 339
+646 1030 1033
+1030 157 1033
+1148 190 646
+190 1030 646
+46 1148 1446
+1148 646 1446
+1347 645 5582
+645 5621 5582
+645 1028 5621
+1028 5601 5621
+1029 156 645
+156 1028 645
+289 1029 1347
+1029 645 1347
+1028 644 5601
+644 5620 5601
+644 1447 5620
+1447 5593 5620
+1027 339 644
+339 1447 644
+156 1027 1028
+1027 644 1028
+1026 643 156
+643 1027 156
+643 1446 1027
+1446 339 1027
+1143 46 643
+46 1446 643
+187 1143 1026
+1143 643 1026
+1346 642 289
+642 1029 289
+642 1026 1029
+1026 156 1029
+1142 187 642
+187 1026 642
+32 1142 1346
+1142 642 1346
+1174 641 1444
+1174 1444 34
+641 1024 338
+641 338 1444
+1025 155 1024
+1025 1024 641
+203 1025 641
+203 641 1174
+1024 640 1445
+1024 1445 338
+640 1434 1445
+1434 45 1445
+1023 333 640
+333 1434 640
+155 1023 640
+155 640 1024
+1022 639 1023
+1022 1023 155
+639 1435 1023
+1435 333 1023
+1412 20 639
+20 1435 639
+322 1412 639
+322 639 1022
+1175 638 1025
+1175 1025 203
+638 1022 155
+638 155 1025
+1413 322 1022
+1413 1022 638
+33 1413 638
+33 638 1175
+1429 637 45
+637 1445 45
+637 1020 338
+637 338 1445
+1021 154 1020
+1021 1020 637
+330 1021 1429
+1021 637 1429
+1020 636 1444
+1020 1444 338
+636 1169 34
+636 34 1444
+1019 200 1169
+1019 1169 636
+154 1019 636
+154 636 1020
+1018 635 1019
+1018 1019 154
+635 1168 200
+635 200 1019
+1442 18 1168
+1442 1168 635
+337 1442 1018
+1442 635 1018
+1428 634 330
+634 1021 330
+634 1018 1021
+1018 154 1021
+1443 337 634
+337 1018 634
+16 1443 1428
+1443 634 1428
+1442 633 1441
+1442 1441 18
+633 1016 336
+633 336 1441
+1017 153 1016
+1017 1016 633
+337 1017 633
+337 633 1442
+1016 632 1440
+1016 1440 336
+632 5645 5633
+632 5633 1440
+1015 5637 5645
+1015 5645 632
+153 1015 632
+153 632 1016
+1014 631 1015
+1014 1015 153
+631 5644 5637
+631 5637 1015
+1438 5632 5644
+1438 5644 631
+335 1438 631
+335 631 1014
+1443 630 1017
+1443 1017 337
+630 1014 153
+630 153 1017
+1439 335 1014
+1439 1014 630
+16 1439 630
+16 630 1443
+1425 629 1439
+1425 1439 16
+629 1012 335
+629 335 1439
+1013 152 1012
+1013 1012 629
+328 1013 629
+328 629 1425
+1012 628 1438
+1012 1438 335
+628 5643 5632
+628 5632 1438
+1011 5636 5643
+1011 5643 628
+152 1011 628
+152 628 1012
+1010 627 1011
+1010 1011 152
+627 5642 5636
+627 5636 1011
+1437 5631 627
+5631 5642 627
+334 1437 1010
+1437 627 1010
+1424 626 328
+626 1013 328
+626 1010 152
+626 152 1013
+1436 334 626
+334 1010 626
+15 1436 1424
+1436 626 1424
+1434 625 45
+625 1430 45
+625 1008 1430
+1008 331 1430
+1009 151 625
+151 1008 625
+333 1009 1434
+1009 625 1434
+1008 624 331
+624 1431 331
+624 5619 1431
+5619 5592 1431
+1007 5600 624
+5600 5619 624
+151 1007 1008
+1007 624 1008
+1006 623 151
+623 1007 151
+623 5618 1007
+5618 5600 1007
+1433 5589 5618
+1433 5618 623
+332 1433 1006
+1433 623 1006
+1435 622 333
+622 1009 333
+622 1006 1009
+1006 151 1009
+1432 332 622
+332 1006 622
+20 1432 1435
+1432 622 1435
+5616 621 5592
+621 1431 5592
+621 1004 1431
+1004 331 1431
+1005 150 621
+150 1004 621
+5599 1005 5616
+1005 621 5616
+1004 620 331
+620 1430 331
+620 1429 1430
+1429 45 1430
+1003 330 620
+330 1429 620
+150 1003 1004
+1003 620 1004
+1002 619 150
+619 1003 150
+619 1428 1003
+1428 330 1003
+1426 16 619
+16 1428 619
+329 1426 1002
+1426 619 1002
+5617 618 5599
+618 1005 5599
+618 1002 1005
+1002 150 1005
+1427 329 618
+329 1002 618
+5587 1427 5617
+1427 618 5617
+5614 617 5587
+617 1427 5587
+617 1000 1427
+1000 329 1427
+1001 149 617
+149 1000 617
+5598 1001 5614
+1001 617 5614
+1000 616 329
+616 1426 329
+616 1425 1426
+1425 16 1426
+999 328 616
+328 1425 616
+149 999 1000
+999 616 1000
+998 615 149
+615 999 149
+615 1424 999
+1424 328 999
+1352 15 615
+15 1424 615
+292 1352 998
+1352 615 998
+5615 614 5598
+614 1001 5598
+614 998 1001
+998 149 1001
+1353 292 614
+292 998 614
+5586 1353 5615
+1353 614 5615
+1422 613 26
+613 1416 26
+613 996 1416
+996 324 1416
+997 148 613
+148 996 613
+327 997 1422
+997 613 1422
+996 612 324
+612 1417 324
+612 1271 1417
+1271 44 1417
+995 251 612
+251 1271 612
+148 995 996
+995 612 996
+994 611 148
+611 995 148
+611 1270 995
+1270 251 995
+1408 42 611
+42 1270 611
+320 1408 994
+1408 611 994
+1423 610 327
+610 997 327
+610 994 997
+994 148 997
+1409 320 610
+320 994 610
+6 1409 1423
+1409 610 1423
+1420 609 4
+609 1419 4
+609 992 1419
+992 325 1419
+993 147 609
+147 992 609
+326 993 1420
+993 609 1420
+992 608 325
+608 1418 325
+608 1249 1418
+1249 41 1418
+991 240 608
+240 1249 608
+147 991 992
+991 608 992
+990 607 147
+607 991 147
+607 1248 991
+1248 240 991
+1417 44 607
+44 1248 607
+324 1417 990
+1417 607 990
+1421 606 326
+606 993 326
+606 990 993
+990 147 993
+1416 324 606
+324 990 606
+26 1416 1421
+1416 606 1421
+1414 605 1406
+1414 1406 24
+605 988 1406
+988 319 1406
+989 146 605
+146 988 605
+323 989 1414
+989 605 1414
+988 604 319
+604 1407 319
+604 1301 1407
+1301 43 1407
+987 266 604
+266 1301 604
+146 987 988
+987 604 988
+986 603 146
+603 987 146
+603 1300 987
+1300 266 987
+1413 33 603
+33 1300 603
+322 1413 986
+1413 603 986
+1415 602 323
+602 989 323
+602 986 989
+986 146 989
+1412 322 602
+322 986 602
+20 1412 1415
+1412 602 1415
+1410 601 1409
+1410 1409 6
+601 984 320
+601 320 1409
+985 145 984
+985 984 601
+321 985 601
+321 601 1410
+984 600 320
+600 1408 320
+600 1309 1408
+1309 42 1408
+983 270 600
+270 1309 600
+145 983 984
+983 600 984
+982 599 145
+599 983 145
+599 1308 983
+1308 270 983
+1407 43 599
+43 1308 599
+319 1407 982
+1407 599 982
+1411 598 985
+1411 985 321
+598 982 145
+598 145 985
+1406 319 982
+1406 982 598
+24 1406 598
+24 598 1411
+1404 597 40
+597 1398 40
+597 980 1398
+980 315 1398
+981 144 597
+144 980 597
+318 981 1404
+981 597 1404
+980 596 315
+596 1399 315
+596 1338 1399
+1338 27 1399
+979 285 596
+285 1338 596
+144 979 980
+979 596 980
+978 595 144
+595 979 144
+595 1339 979
+1339 285 979
+1403 7 595
+7 1339 595
+317 1403 978
+1403 595 978
+1405 594 318
+594 981 318
+594 978 981
+978 144 981
+1402 317 594
+317 978 594
+35 1402 1405
+1402 594 1405
+1400 593 36
+593 1392 36
+593 976 1392
+976 312 1392
+977 143 593
+143 976 593
+316 977 1400
+977 593 1400
+976 592 312
+592 1393 312
+592 1330 1393
+1330 8 1393
+975 281 592
+281 1330 592
+143 975 976
+975 592 976
+974 591 143
+591 975 143
+591 1331 975
+1331 281 975
+1399 27 591
+27 1331 591
+315 1399 974
+1399 591 974
+1401 590 316
+590 977 316
+590 974 977
+974 143 977
+1398 315 590
+315 974 590
+40 1398 1401
+1398 590 1401
+1396 589 39
+589 1386 39
+589 972 1386
+972 309 1386
+973 142 589
+142 972 589
+314 973 1396
+973 589 1396
+972 588 309
+588 1387 309
+588 1395 1387
+1395 21 1387
+971 313 588
+313 1395 588
+142 971 972
+971 588 972
+970 587 142
+587 971 142
+587 1394 971
+1394 313 971
+1393 8 587
+8 1394 587
+312 1393 970
+1393 587 970
+1397 586 314
+586 973 314
+586 970 973
+970 142 973
+1392 312 586
+312 970 586
+36 1392 1397
+1392 586 1397
+1390 585 1
+585 1382 1
+585 968 1382
+968 307 1382
+969 141 585
+141 968 585
+311 969 1390
+969 585 1390
+968 584 307
+584 1383 307
+584 1389 1383
+1389 2 1383
+967 310 584
+310 1389 584
+141 967 968
+967 584 968
+966 583 141
+583 967 141
+583 1388 967
+1388 310 967
+1387 21 583
+21 1388 583
+309 1387 966
+1387 583 966
+1391 582 311
+582 969 311
+582 966 969
+966 141 969
+1386 309 582
+309 966 582
+39 1386 1391
+1386 582 1391
+1384 581 2
+581 1383 2
+581 964 1383
+964 307 1383
+965 140 581
+140 964 581
+308 965 1384
+965 581 1384
+964 580 307
+580 1382 307
+580 1381 1382
+1381 1 1382
+963 306 580
+306 1381 580
+140 963 964
+963 580 964
+962 579 140
+579 963 140
+579 1380 963
+1380 306 963
+5613 5591 579
+5591 1380 579
+5597 5613 962
+5613 579 962
+1385 578 308
+578 965 308
+578 962 965
+962 140 965
+5612 5597 578
+5597 962 578
+5585 5612 1385
+5612 578 1385
+1343 577 1372
+1343 1372 29
+577 960 302
+577 302 1372
+961 139 960
+961 960 577
+287 961 577
+287 577 1343
+960 576 1373
+960 1373 302
+576 1379 25
+576 25 1373
+959 305 1379
+959 1379 576
+139 959 576
+139 576 960
+958 575 959
+958 959 139
+575 1378 305
+575 305 959
+1377 0 1378
+1377 1378 575
+304 1377 575
+304 575 958
+1342 574 961
+1342 961 287
+574 958 139
+574 139 961
+1376 304 958
+1376 958 574
+13 1376 574
+13 574 1342
+1335 573 1366
+1335 1366 14
+573 956 299
+573 299 1366
+957 138 956
+957 956 573
+283 957 573
+283 573 1335
+956 572 1367
+956 1367 299
+572 1375 3
+572 3 1367
+955 303 1375
+955 1375 572
+138 955 572
+138 572 956
+954 571 955
+954 955 138
+571 1374 303
+571 303 955
+1373 25 1374
+1373 1374 571
+302 1373 571
+302 571 954
+1334 570 957
+1334 957 283
+570 954 138
+570 138 957
+1372 302 954
+1372 954 570
+29 1372 570
+29 570 1334
+1370 569 1360
+1370 1360 23
+569 952 296
+569 296 1360
+953 137 952
+953 952 569
+301 953 569
+301 569 1370
+952 568 1361
+952 1361 296
+568 1369 47
+568 47 1361
+951 300 1369
+951 1369 568
+137 951 568
+137 568 952
+950 567 951
+950 951 137
+567 1368 300
+567 300 951
+1367 3 1368
+1367 1368 567
+299 1367 567
+299 567 950
+1371 566 953
+1371 953 301
+566 950 137
+566 137 953
+1366 299 950
+1366 950 566
+14 1366 566
+14 566 1371
+1364 565 11
+565 1356 11
+565 948 1356
+948 294 1356
+949 136 948
+949 948 565
+298 949 1364
+949 565 1364
+948 564 1357
+948 1357 294
+564 1363 48
+564 48 1357
+947 297 1363
+947 1363 564
+136 947 564
+136 564 948
+946 563 947
+946 947 136
+563 1362 297
+563 297 947
+1361 47 1362
+1361 1362 563
+296 1361 563
+296 563 946
+1365 562 298
+562 949 298
+562 946 136
+562 136 949
+1360 296 946
+1360 946 562
+23 1360 562
+23 562 1365
+1358 561 1357
+1358 1357 48
+561 944 294
+561 294 1357
+945 135 944
+945 944 561
+295 945 561
+295 561 1358
+944 560 294
+560 1356 294
+560 1355 1356
+1355 11 1356
+943 293 560
+293 1355 560
+135 943 944
+943 560 944
+942 559 135
+559 943 135
+559 1354 943
+1354 293 943
+5611 5584 559
+5584 1354 559
+5596 5611 942
+5611 559 942
+1359 558 945
+1359 945 295
+558 942 135
+558 135 945
+5610 5596 942
+5610 942 558
+5590 5610 558
+5590 558 1359
+1352 557 1351
+1352 1351 15
+557 940 291
+557 291 1351
+941 134 557
+134 940 557
+292 941 1352
+941 557 1352
+940 556 291
+556 1350 291
+556 1349 1350
+1349 31 1350
+939 290 556
+290 1349 556
+134 939 940
+939 556 940
+938 555 134
+555 939 134
+555 1348 939
+1348 290 939
+5609 5588 555
+5588 1348 555
+5595 5609 938
+5609 555 938
+1353 554 292
+554 941 292
+554 938 941
+938 134 941
+5608 5595 554
+5595 938 554
+5586 5608 1353
+5608 554 1353
+1346 553 32
+553 1135 32
+553 936 1135
+936 183 1135
+937 133 553
+133 936 553
+289 937 1346
+937 553 1346
+936 552 183
+552 1134 183
+552 1345 1134
+1345 30 1134
+935 288 552
+288 1345 552
+133 935 936
+935 552 936
+934 551 133
+551 935 133
+551 1344 288
+551 288 935
+5607 5583 1344
+5607 1344 551
+5594 5607 551
+5594 551 934
+1347 550 289
+550 937 289
+550 934 937
+934 133 937
+5606 5594 550
+5594 934 550
+5582 5606 1347
+5606 550 1347
+1333 549 29
+549 1343 29
+549 932 1343
+932 287 1343
+933 132 549
+132 932 549
+282 933 1333
+933 549 1333
+932 548 287
+548 1342 287
+548 1341 1342
+1341 13 1342
+931 286 548
+286 1341 548
+132 931 932
+931 548 932
+930 547 132
+547 931 132
+547 1340 931
+1340 286 931
+1339 7 547
+7 1340 547
+285 1339 930
+1339 547 930
+1332 546 282
+546 933 282
+546 930 933
+930 132 933
+1338 285 546
+285 930 546
+27 1338 1332
+1338 546 1332
+1336 545 14
+545 1335 14
+545 928 1335
+928 283 1335
+929 131 545
+131 928 545
+284 929 1336
+929 545 1336
+928 544 283
+544 1334 283
+544 1333 1334
+1333 29 1334
+927 282 544
+282 1333 544
+131 927 928
+927 544 928
+926 543 131
+543 927 131
+543 1332 927
+1332 282 927
+1331 27 543
+27 1332 543
+281 1331 926
+1331 543 926
+1337 542 284
+542 929 284
+542 926 929
+926 131 929
+1330 281 542
+281 926 542
+8 1330 1337
+1330 542 1337
+1283 80 541
+541 80 1306
+541 1306 924
+924 1306 269
+925 541 130
+130 541 924
+257 1283 925
+925 1283 541
+924 269 540
+540 269 1307
+540 1307 1314
+1314 1307 82
+923 540 273
+273 540 1314
+130 924 923
+923 924 540
+922 130 539
+539 130 923
+539 923 1315
+1315 923 273
+1328 539 83
+83 539 1315
+280 922 1328
+1328 922 539
+1282 257 538
+538 257 925
+538 925 922
+922 925 130
+1329 538 280
+280 538 922
+79 1282 1329
+1329 1282 538
+1327 1322 537
+1327 84 1322
+537 1322 920
+920 1322 277
+921 537 129
+129 537 920
+279 537 921
+279 1327 537
+920 277 536
+536 277 1323
+536 1323 1324
+1324 1323 85
+919 536 278
+278 536 1324
+129 920 919
+919 920 536
+918 129 535
+535 129 919
+535 919 1325
+1325 919 278
+1288 535 81
+81 535 1325
+260 918 1288
+1288 918 535
+1326 921 534
+1326 279 921
+534 921 918
+918 921 129
+1289 534 260
+260 534 918
+78 534 1289
+78 1326 534
+1287 79 533
+533 79 1329
+533 1329 916
+916 1329 280
+917 533 128
+128 533 916
+259 1287 917
+917 1287 533
+916 280 532
+532 280 1328
+532 1328 1318
+1318 1328 83
+915 532 275
+275 532 1318
+128 916 915
+915 916 532
+914 128 531
+531 128 915
+531 915 1319
+1319 915 275
+1327 531 84
+84 531 1319
+279 914 1327
+1327 914 531
+1286 259 530
+530 259 917
+530 917 914
+914 917 128
+1326 530 279
+279 530 914
+78 1286 1326
+1326 1286 530
+1277 1325 529
+1277 81 1325
+529 278 912
+529 1325 278
+913 912 127
+913 529 912
+254 529 913
+254 1277 529
+912 1324 528
+912 278 1324
+528 85 1312
+528 1324 85
+911 1312 272
+911 528 1312
+127 528 911
+127 912 528
+910 911 527
+910 127 911
+527 272 1313
+527 911 272
+1294 1313 86
+1294 527 1313
+263 527 1294
+263 910 527
+1276 913 526
+1276 254 913
+526 127 910
+526 913 127
+1295 910 263
+1295 526 910
+77 526 1295
+77 1276 526
+1211 1310 525
+1211 66 1310
+525 271 908
+525 1310 271
+909 908 126
+909 525 908
+221 525 909
+221 1211 525
+908 1311 524
+908 271 1311
+524 85 1323
+524 1311 85
+907 1323 277
+907 524 1323
+126 524 907
+126 908 524
+906 907 523
+906 126 907
+523 277 1322
+523 907 277
+1320 523 84
+84 523 1322
+276 523 1320
+276 906 523
+1210 909 522
+1210 221 909
+522 126 906
+522 909 126
+1321 906 276
+1321 522 906
+64 522 1321
+64 1210 522
+1197 1321 521
+1197 64 1321
+521 1321 904
+904 1321 276
+905 521 125
+125 521 904
+214 521 905
+214 1197 521
+904 276 520
+520 276 1320
+520 1320 1319
+1319 1320 84
+903 520 275
+275 520 1319
+125 904 903
+903 904 520
+902 125 519
+519 125 903
+519 903 1318
+1318 903 275
+1316 519 83
+83 519 1318
+274 902 1316
+1316 902 519
+1196 214 518
+518 214 905
+518 905 902
+902 905 125
+1317 518 274
+274 518 902
+62 1196 1317
+1317 1196 518
+1189 62 517
+517 62 1317
+517 1317 900
+900 1317 274
+901 517 124
+124 517 900
+210 1189 901
+901 1189 517
+900 274 516
+516 274 1316
+516 1316 1315
+1315 1316 83
+899 516 273
+273 516 1315
+124 900 899
+899 900 516
+898 124 515
+515 124 899
+515 899 1314
+1314 899 273
+1304 515 82
+82 515 1314
+268 898 1304
+1304 898 515
+1188 210 514
+514 210 901
+514 901 898
+898 901 124
+1305 514 268
+268 514 898
+59 1188 1305
+1305 1188 514
+1299 86 513
+513 86 1313
+513 1313 896
+896 1313 272
+897 513 123
+123 513 896
+265 1299 897
+897 1299 513
+896 272 512
+512 272 1312
+512 1312 1311
+1311 1312 85
+895 512 271
+271 512 1311
+123 896 895
+895 896 512
+894 123 511
+511 123 895
+511 895 1310
+1310 895 271
+1206 511 66
+66 511 1310
+219 894 1206
+1206 894 511
+1298 265 510
+510 265 897
+510 897 894
+894 897 123
+1207 510 219
+219 510 894
+52 1298 1207
+1207 1298 510
+1308 1302 509
+1308 43 1302
+509 267 892
+509 1302 267
+893 892 122
+893 509 892
+270 509 893
+270 1308 509
+892 1303 508
+892 267 1303
+508 82 1307
+508 1303 82
+891 1307 269
+891 508 1307
+122 508 891
+122 892 508
+890 891 507
+890 122 891
+507 269 1306
+507 891 269
+1274 1306 80
+1274 507 1306
+253 507 1274
+253 890 507
+1309 893 506
+1309 270 893
+506 122 890
+506 893 122
+1275 890 253
+1275 506 890
+42 506 1275
+42 1309 506
+1177 59 505
+505 59 1305
+505 1305 888
+888 1305 268
+889 505 121
+121 505 888
+204 1177 889
+889 1177 505
+888 268 504
+504 268 1304
+504 1304 1303
+1303 1304 82
+887 504 267
+267 504 1303
+121 888 887
+887 888 504
+886 121 503
+503 121 887
+503 887 1302
+1302 887 267
+1301 503 43
+43 503 1302
+266 886 1301
+1301 886 503
+1176 204 502
+502 204 889
+502 889 886
+886 889 121
+1300 502 266
+266 502 886
+33 1176 1300
+1300 1176 502
+1293 1299 501
+1293 86 1299
+501 265 884
+501 1299 265
+885 884 120
+885 501 884
+262 501 885
+262 1293 501
+884 1298 500
+884 265 1298
+500 52 1140
+500 1298 52
+883 1140 186
+883 500 1140
+120 500 883
+120 884 500
+882 883 499
+882 120 883
+499 186 1141
+499 883 186
+1297 1141 30
+1297 499 1141
+264 499 1297
+264 882 499
+1292 885 498
+1292 262 885
+498 120 882
+498 885 120
+1296 882 264
+1296 498 882
+22 498 1296
+22 1292 498
+1265 77 497
+497 77 1295
+497 263 880
+497 1295 263
+881 497 119
+119 497 880
+248 1265 881
+881 1265 497
+880 1294 496
+880 263 1294
+496 86 1293
+496 1294 86
+879 1293 262
+879 496 1293
+119 496 879
+119 880 496
+878 119 495
+495 119 879
+495 262 1292
+495 879 262
+1291 495 22
+22 495 1292
+261 878 1291
+1291 878 495
+1264 248 494
+494 248 881
+494 881 878
+878 881 119
+1290 494 261
+261 494 878
+10 1264 1290
+1290 1264 494
+1285 1289 493
+1285 78 1289
+493 1289 876
+876 1289 260
+877 493 118
+118 493 876
+258 493 877
+258 1285 493
+876 260 492
+492 260 1288
+492 1288 1278
+1278 1288 81
+875 492 255
+255 492 1278
+118 876 875
+875 876 492
+874 118 491
+491 118 875
+491 875 1279
+1279 875 255
+1258 491 76
+76 491 1279
+245 874 1258
+1258 874 491
+1284 877 490
+1284 258 877
+490 877 874
+874 877 118
+1259 490 245
+245 490 874
+75 1284 1259
+1259 1284 490
+1281 1287 489
+1281 79 1287
+489 259 872
+489 1287 259
+873 872 117
+873 489 872
+256 489 873
+256 1281 489
+872 1286 488
+872 259 1286
+488 78 1285
+488 1286 78
+871 1285 258
+871 488 1285
+117 488 871
+117 872 488
+870 871 487
+870 117 871
+487 258 1284
+487 871 258
+1252 487 75
+75 487 1284
+242 487 1252
+242 870 487
+1280 873 486
+1280 256 873
+486 117 870
+486 873 117
+1253 870 242
+1253 486 870
+74 486 1253
+74 1280 486
+1273 1283 485
+1273 80 1283
+485 257 868
+485 1283 257
+869 868 116
+869 485 868
+252 485 869
+252 1273 485
+868 1282 484
+868 257 1282
+484 79 1281
+484 1282 79
+867 1281 256
+867 484 1281
+116 484 867
+116 868 484
+866 867 483
+866 116 867
+483 256 1280
+483 867 256
+1262 1280 74
+1262 483 1280
+247 483 1262
+247 866 483
+1272 869 482
+1272 252 869
+482 116 866
+482 869 116
+1263 866 247
+1263 482 866
+73 482 1263
+73 1272 482
+1261 1279 481
+1261 76 1279
+481 255 864
+481 1279 255
+865 864 115
+865 481 864
+246 481 865
+246 1261 481
+864 1278 480
+864 255 1278
+480 81 1277
+480 1278 81
+863 1277 254
+863 480 1277
+115 480 863
+115 864 480
+862 863 479
+862 115 863
+479 254 1276
+479 863 254
+1266 1276 77
+1266 479 1276
+249 479 1266
+249 862 479
+1260 865 478
+1260 246 865
+478 115 862
+478 865 115
+1267 478 249
+249 478 862
+72 1260 1267
+1267 1260 478
+1274 80 477
+477 80 1273
+477 1273 860
+860 1273 252
+861 477 114
+114 477 860
+253 1274 861
+861 1274 477
+860 252 476
+476 252 1272
+476 1272 1246
+1246 1272 73
+859 476 239
+239 476 1246
+114 860 859
+859 860 476
+858 114 475
+475 114 859
+475 859 1247
+1247 859 239
+1271 475 44
+44 475 1247
+251 858 1271
+1271 858 475
+1275 253 474
+474 253 861
+474 861 858
+858 861 114
+1270 474 251
+251 474 858
+42 1275 1270
+1270 1275 474
+1268 1230 473
+1268 28 1230
+473 231 856
+473 1230 231
+857 856 113
+857 473 856
+250 473 857
+250 1268 473
+856 1231 472
+856 231 1231
+472 72 1267
+472 1231 72
+855 1267 249
+855 472 1267
+113 472 855
+113 856 472
+854 855 471
+854 113 855
+471 249 1266
+471 855 249
+1265 1266 77
+1265 471 1266
+248 471 1265
+248 854 471
+1269 857 470
+1269 250 857
+470 113 854
+470 857 113
+1264 854 248
+1264 470 854
+10 470 1264
+10 1269 470
+1237 71 469
+469 71 1244
+469 1244 852
+852 1244 238
+853 469 112
+112 469 852
+234 1237 853
+853 1237 469
+852 238 468
+468 238 1245
+468 1245 1263
+1263 1245 73
+851 468 247
+247 468 1263
+112 852 851
+851 852 468
+850 112 467
+467 112 851
+467 851 1262
+1262 851 247
+1254 467 74
+74 467 1262
+243 850 1254
+1254 850 467
+1236 234 466
+466 234 853
+466 853 850
+850 853 112
+1255 466 243
+243 466 850
+69 1236 1255
+1255 1236 466
+1225 70 465
+465 70 1256
+465 244 848
+465 1256 244
+849 465 111
+111 465 848
+228 1225 849
+849 1225 465
+848 1257 464
+848 244 1257
+464 76 1261
+464 1257 76
+847 1261 246
+847 464 1261
+111 464 847
+111 848 464
+846 111 463
+463 111 847
+463 847 1260
+1260 847 246
+1232 463 72
+72 463 1260
+232 846 1232
+1232 846 463
+1224 228 462
+462 228 849
+462 849 846
+846 849 111
+1233 462 232
+232 462 846
+68 1224 1233
+1233 1224 462
+1251 75 461
+461 75 1259
+461 1259 844
+844 1259 245
+845 461 110
+110 461 844
+241 1251 845
+845 1251 461
+844 245 460
+460 245 1258
+460 1258 1257
+1257 1258 76
+843 460 244
+244 460 1257
+110 844 843
+843 844 460
+842 843 459
+842 110 843
+459 244 1256
+459 843 244
+1242 1256 70
+1242 459 1256
+237 459 1242
+237 842 459
+1250 241 458
+458 241 845
+458 845 842
+842 845 110
+1243 842 237
+1243 458 842
+67 458 1243
+67 1250 458
+1217 1255 457
+1217 69 1255
+457 243 840
+457 1255 243
+841 840 109
+841 457 840
+224 457 841
+224 1217 457
+840 1254 456
+840 243 1254
+456 1254 1253
+1253 1254 74
+839 1253 242
+839 456 1253
+109 456 839
+109 840 456
+838 839 455
+838 109 839
+455 242 1252
+455 839 242
+1251 1252 75
+1251 455 1252
+241 455 1251
+241 838 455
+1216 841 454
+1216 224 841
+454 109 838
+454 841 109
+1250 838 241
+1250 454 838
+67 454 1250
+67 1216 454
+1248 1247 453
+1248 44 1247
+453 239 836
+453 1247 239
+837 836 108
+837 453 836
+240 453 837
+240 1248 453
+836 1246 452
+836 239 1246
+452 73 1245
+452 1246 73
+835 1245 238
+835 452 1245
+108 452 835
+108 836 452
+834 835 451
+834 108 835
+451 238 1244
+451 835 238
+1238 451 71
+71 451 1244
+235 834 1238
+1238 834 451
+1249 837 450
+1249 240 837
+450 108 834
+450 837 108
+1239 834 235
+1239 450 834
+41 450 1239
+41 1249 450
+1215 1243 449
+1215 67 1243
+449 237 832
+449 1243 237
+833 832 107
+833 449 832
+223 449 833
+223 1215 449
+832 1242 448
+832 237 1242
+448 70 1226
+448 1242 70
+831 1226 229
+831 448 1226
+107 448 831
+107 832 448
+830 831 447
+830 107 831
+447 229 1227
+447 831 229
+1241 1227 37
+1241 447 1227
+236 447 1241
+236 830 447
+1214 833 446
+1214 223 833
+446 107 830
+446 833 107
+1240 830 236
+1240 446 830
+5 446 1240
+5 1214 446
+1238 1237 445
+1238 71 1237
+445 234 828
+445 1237 234
+829 828 106
+829 445 828
+235 445 829
+235 1238 445
+828 1236 444
+828 234 1236
+444 69 1218
+444 1236 69
+827 1218 225
+827 444 1218
+106 444 827
+106 828 444
+826 827 443
+826 106 827
+443 225 1219
+443 827 225
+1235 1219 12
+1235 443 1219
+233 826 1235
+1235 826 443
+1239 829 442
+1239 235 829
+442 106 826
+442 829 106
+1234 442 233
+233 442 826
+41 1239 1234
+1234 1239 442
+1223 68 441
+441 68 1233
+441 1233 824
+824 1233 232
+825 441 105
+105 441 824
+227 1223 825
+825 1223 441
+824 232 440
+440 232 1232
+440 1232 1231
+1231 1232 72
+823 440 231
+231 440 1231
+105 824 823
+823 824 440
+822 105 439
+439 105 823
+439 823 1230
+1230 823 231
+1229 439 28
+28 439 1230
+230 822 1229
+1229 822 439
+1222 227 438
+438 227 825
+438 825 822
+822 825 105
+1228 438 230
+230 438 822
+9 1222 1228
+1228 1222 438
+1226 1225 437
+1226 70 1225
+437 228 820
+437 1225 228
+821 437 104
+104 437 820
+229 437 821
+229 1226 437
+820 228 436
+436 228 1224
+436 1224 1223
+1223 1224 68
+819 436 227
+227 436 1223
+104 820 819
+819 820 436
+818 104 435
+435 104 819
+435 819 1222
+1222 819 227
+1221 435 9
+9 435 1222
+226 818 1221
+1221 818 435
+1227 821 434
+1227 229 821
+434 821 818
+818 821 104
+1220 434 226
+226 434 818
+37 1227 1220
+1220 1227 434
+1218 1217 433
+1218 69 1217
+433 1217 816
+816 1217 224
+817 816 103
+817 433 816
+225 433 817
+225 1218 433
+816 224 432
+432 224 1216
+432 67 1215
+432 1216 67
+815 1215 223
+815 432 1215
+103 432 815
+103 816 432
+814 815 431
+814 103 815
+431 223 1214
+431 815 223
+1213 1214 5
+1213 431 1214
+222 431 1213
+222 814 431
+1219 817 430
+1219 225 817
+430 103 814
+430 817 103
+1212 814 222
+1212 430 814
+12 430 1212
+12 1219 430
+1209 1204 429
+1209 65 1204
+429 218 812
+429 1204 218
+813 812 102
+813 429 812
+220 429 813
+220 1209 429
+812 1205 428
+812 218 1205
+428 66 1211
+428 1205 66
+811 1211 221
+811 428 1211
+102 428 811
+102 812 428
+810 811 427
+810 102 811
+427 221 1210
+427 811 221
+1198 1210 64
+1198 427 1210
+215 427 1198
+215 810 427
+1208 813 426
+1208 220 813
+426 102 810
+426 813 102
+1199 810 215
+1199 426 810
+63 426 1199
+63 1208 426
+1201 65 425
+425 65 1209
+425 1209 808
+808 1209 220
+809 425 101
+101 425 808
+216 1201 809
+809 1201 425
+808 220 424
+424 220 1208
+424 1208 1194
+1194 1208 63
+807 424 213
+213 424 1194
+101 808 807
+807 808 424
+806 101 423
+423 101 807
+423 807 1195
+1195 807 213
+1180 423 56
+56 423 1195
+206 806 1180
+1180 806 423
+1200 216 422
+422 216 809
+422 809 806
+806 809 101
+1181 422 206
+206 422 806
+53 1200 1181
+1181 1200 422
+1206 1205 421
+1206 66 1205
+421 218 804
+421 1205 218
+805 804 100
+805 421 804
+219 421 805
+219 1206 421
+804 1204 420
+804 218 1204
+420 65 1202
+420 1204 65
+803 1202 217
+803 420 1202
+100 420 803
+100 804 420
+802 803 419
+802 100 803
+419 217 1203
+419 803 217
+1138 1203 54
+1138 419 1203
+185 419 1138
+185 802 419
+1207 805 418
+1207 219 805
+418 100 802
+418 805 100
+1139 802 185
+1139 418 802
+52 418 1139
+52 1207 418
+1153 1146 417
+1153 55 1146
+417 189 800
+417 1146 189
+801 800 99
+801 417 800
+192 417 801
+192 1153 417
+800 1147 416
+800 189 1147
+416 54 1203
+416 1147 54
+799 1203 217
+799 416 1203
+99 416 799
+99 800 416
+798 799 415
+798 99 799
+415 217 1202
+415 799 217
+1201 1202 65
+1201 415 1202
+216 415 1201
+216 798 415
+1152 801 414
+1152 192 801
+414 99 798
+414 801 99
+1200 798 216
+1200 414 798
+53 414 1200
+53 1152 414
+1193 1199 413
+1193 63 1199
+413 215 796
+413 1199 215
+797 796 98
+797 413 796
+212 413 797
+212 1193 413
+796 1198 412
+796 215 1198
+412 64 1197
+412 1198 64
+795 1197 214
+795 412 1197
+98 412 795
+98 796 412
+794 795 411
+794 98 795
+411 214 1196
+411 795 214
+1190 1196 62
+1190 411 1196
+211 411 1190
+211 794 411
+1192 797 410
+1192 212 797
+410 98 794
+410 797 98
+1191 794 211
+1191 410 794
+61 410 1191
+61 1192 410
+1194 63 409
+409 63 1193
+409 1193 792
+792 1193 212
+793 409 97
+97 409 792
+213 1194 793
+793 1194 409
+792 212 408
+408 212 1192
+408 1192 1186
+1186 1192 61
+791 408 209
+209 408 1186
+97 792 791
+791 792 408
+790 97 407
+407 97 791
+407 791 1187
+1187 791 209
+1158 407 58
+58 407 1187
+195 790 1158
+1158 790 407
+1195 213 406
+406 213 793
+406 793 790
+790 793 97
+1159 406 195
+195 406 790
+56 1195 1159
+1159 1195 406
+1179 60 405
+405 60 1184
+405 1184 788
+788 1184 208
+789 405 96
+96 405 788
+205 1179 789
+789 1179 405
+788 208 404
+404 208 1185
+404 1185 1191
+1191 1185 61
+787 404 211
+211 404 1191
+96 788 787
+787 788 404
+786 96 403
+403 96 787
+403 787 1190
+1190 787 211
+1189 403 62
+62 403 1190
+210 786 1189
+1189 786 403
+1178 205 402
+402 205 789
+402 789 786
+786 789 96
+1188 402 210
+210 402 786
+59 1178 1188
+1188 1178 402
+1167 1187 401
+1167 58 1187
+401 209 784
+401 1187 209
+785 784 95
+785 401 784
+199 401 785
+199 1167 401
+784 1186 400
+784 209 1186
+400 61 1185
+400 1186 61
+783 1185 208
+783 400 1185
+95 400 783
+95 784 400
+782 783 399
+782 95 783
+399 208 1184
+399 783 208
+1172 1184 60
+1172 399 1184
+202 399 1172
+202 782 399
+1166 785 398
+1166 199 785
+398 95 782
+398 785 95
+1173 782 202
+1173 398 782
+57 398 1173
+57 1166 398
+1182 31 397
+397 31 1150
+397 1150 780
+780 1150 191
+781 397 94
+94 397 780
+207 1182 781
+781 1182 397
+780 191 396
+396 191 1151
+396 53 1181
+396 1151 53
+779 1181 206
+779 396 1181
+94 780 779
+779 780 396
+778 94 395
+395 94 779
+395 206 1180
+395 779 206
+1160 1180 56
+1160 395 1180
+196 395 1160
+196 778 395
+1183 207 394
+394 207 781
+394 781 778
+778 781 94
+1161 394 196
+196 394 778
+17 1183 1161
+1161 1183 394
+1171 1179 393
+1171 60 1179
+393 205 776
+393 1179 205
+777 776 93
+777 393 776
+201 393 777
+201 1171 393
+776 1178 392
+776 205 1178
+392 1178 1177
+1177 1178 59
+775 1177 204
+775 392 1177
+93 392 775
+93 776 392
+774 775 391
+774 93 775
+391 204 1176
+391 775 204
+1175 1176 33
+1175 391 1176
+203 391 1175
+203 774 391
+1170 777 390
+1170 201 777
+390 93 774
+390 777 93
+1174 774 203
+1174 390 774
+34 390 1174
+34 1170 390
+1165 1173 389
+1165 57 1173
+389 202 772
+389 1173 202
+773 772 92
+773 389 772
+198 389 773
+198 1165 389
+772 1172 388
+772 202 1172
+388 60 1171
+388 1172 60
+771 1171 201
+771 388 1171
+92 388 771
+92 772 388
+770 771 387
+770 92 771
+387 201 1170
+387 771 201
+1169 1170 34
+1169 387 1170
+200 387 1169
+200 770 387
+1164 773 386
+1164 198 773
+386 92 770
+386 773 92
+1168 770 200
+1168 386 770
+18 386 1168
+18 1164 386
+1157 58 385
+385 58 1167
+385 1167 768
+768 1167 199
+769 385 91
+91 385 768
+194 1157 769
+769 1157 385
+768 199 384
+384 199 1166
+384 57 1165
+384 1166 57
+767 1165 198
+767 384 1165
+91 384 767
+91 768 384
+766 767 383
+766 91 767
+383 198 1164
+383 767 198
+1163 1164 18
+1163 383 1164
+197 383 1163
+197 766 383
+1156 194 382
+382 194 769
+382 91 766
+382 769 91
+1162 766 197
+1162 382 766
+19 382 1162
+19 1156 382
+1160 56 381
+381 56 1159
+381 1159 764
+764 1159 195
+765 381 90
+90 381 764
+196 1160 765
+765 1160 381
+764 195 380
+380 195 1158
+380 1158 1157
+1157 1158 58
+763 380 194
+194 380 1157
+90 764 763
+763 764 380
+762 90 379
+379 90 763
+379 763 1156
+1156 763 194
+1155 379 19
+19 379 1156
+193 762 1155
+1155 762 379
+1161 196 378
+378 196 765
+378 765 762
+762 765 90
+1154 378 193
+193 378 762
+17 1161 1154
+1154 1161 378
+1145 55 377
+377 55 1153
+377 1153 760
+760 1153 192
+761 377 89
+89 377 760
+188 377 761
+188 1145 377
+760 192 376
+376 192 1152
+376 1152 1151
+1151 1152 53
+759 1151 191
+759 376 1151
+89 376 759
+89 760 376
+758 759 375
+758 89 759
+375 191 1150
+375 759 191
+1149 1150 31
+1149 375 1150
+190 375 1149
+190 758 375
+1144 761 374
+1144 188 761
+374 89 758
+374 761 89
+1148 758 190
+1148 374 758
+46 374 1148
+46 1144 374
+1137 1147 373
+1137 54 1147
+373 189 756
+373 1147 189
+757 756 88
+757 373 756
+184 373 757
+184 1137 373
+756 1146 372
+756 189 1146
+372 55 1145
+372 1146 55
+755 1145 188
+755 372 1145
+88 372 755
+88 756 372
+754 755 371
+754 88 755
+371 188 1144
+371 755 188
+1143 1144 46
+1143 371 1144
+187 371 1143
+187 754 371
+1136 757 370
+1136 184 757
+370 88 754
+370 757 88
+1142 754 187
+1142 370 754
+32 370 1142
+32 1136 370
+1140 1139 369
+1140 52 1139
+369 185 752
+369 1139 185
+753 752 87
+753 369 752
+186 369 753
+186 1140 369
+752 1138 368
+752 185 1138
+368 54 1137
+368 1138 54
+751 1137 184
+751 368 1137
+87 368 751
+87 752 368
+750 751 367
+750 87 751
+367 184 1136
+367 751 184
+1135 1136 32
+1135 367 1136
+183 367 1135
+183 750 367
+1141 753 366
+1141 186 753
+366 87 750
+366 753 87
+1134 750 183
+1134 366 750
+30 366 1134
+30 1141 366
+2078 1832 1517
+1832 2095 1517
+1832 2007 2095
+2007 1622 2095
+2008 1578 1832
+1578 2007 1832
+1613 2008 2078
+2008 1832 2078
+2007 1831 2096
+2007 2096 1622
+1831 2075 1518
+1831 1518 2096
+2006 1612 2075
+2006 2075 1831
+1578 2006 1831
+1578 1831 2007
+2005 1830 2006
+2005 2006 1578
+1830 2076 1612
+1830 1612 2006
+5805 5738 2076
+5805 2076 1830
+5765 5805 1830
+5765 1830 2005
+2077 1829 1613
+1829 2008 1613
+1829 2005 2008
+2005 1578 2008
+5804 5765 1829
+5765 2005 1829
+5737 5804 2077
+5804 1829 2077
+2162 1828 1531
+1828 2151 1531
+1828 2003 2151
+2003 1650 2151
+2004 1577 1828
+1577 2003 1828
+1655 2004 2162
+2004 1828 2162
+2003 1827 1650
+1827 2152 1650
+1827 2141 2152
+2141 1530 2152
+2002 1645 1827
+1645 2141 1827
+1577 2002 2003
+2002 1827 2003
+2001 1826 1577
+1826 2002 1577
+1826 2142 2002
+2142 1645 2002
+2123 1528 1826
+1528 2142 1826
+1636 2123 2001
+2123 1826 2001
+2161 1825 1655
+1825 2004 1655
+1825 2001 2004
+2001 1577 2004
+2124 1636 1825
+1636 2001 1825
+1527 2124 2161
+2124 1825 2161
+2130 1824 1529
+1824 2159 1529
+1824 1999 2159
+1999 1654 2159
+2000 1576 1824
+1576 1999 1824
+1639 2000 2130
+2000 1824 2130
+1999 1823 1654
+1823 2160 1654
+1823 2157 2160
+2157 1533 2160
+1998 1653 1823
+1653 2157 1823
+1576 1998 1999
+1998 1823 1999
+1997 1822 1998
+1997 1998 1576
+1822 2158 1998
+2158 1653 1998
+2163 1532 2158
+2163 2158 1822
+1656 2163 1822
+1656 1822 1997
+2129 1821 2000
+2129 2000 1639
+1821 1997 1576
+1821 1576 2000
+2164 1656 1997
+2164 1997 1821
+1526 2164 1821
+1526 1821 2129
+2163 1820 1532
+1820 2155 1532
+1820 1995 2155
+1995 1652 2155
+1996 1575 1820
+1575 1995 1820
+1656 1996 2163
+1996 1820 2163
+1995 1819 1652
+1819 2156 1652
+1819 2162 2156
+2162 1531 2156
+1994 1655 1819
+1655 2162 1819
+1575 1994 1995
+1994 1819 1995
+1993 1818 1575
+1818 1994 1575
+1818 2161 1994
+2161 1655 1994
+2131 1527 1818
+1527 2161 1818
+1640 2131 1993
+2131 1818 1993
+2164 1817 1656
+1817 1996 1656
+1817 1993 1996
+1993 1575 1996
+2132 1640 1817
+1640 1993 1817
+1526 2132 2164
+2132 1817 2164
+2134 1816 2145
+2134 2145 1534
+1816 1991 1647
+1816 1647 2145
+1992 1574 1991
+1992 1991 1816
+1641 1992 1816
+1641 1816 2134
+1991 1815 2146
+1991 2146 1647
+1815 2160 1533
+1815 1533 2146
+1990 1654 2160
+1990 2160 1815
+1574 1990 1815
+1574 1815 1991
+1989 1814 1990
+1989 1990 1574
+1814 2159 1654
+1814 1654 1990
+2121 1529 2159
+2121 2159 1814
+1635 2121 1814
+1635 1814 1989
+2133 1813 1992
+2133 1992 1641
+1813 1989 1574
+1813 1574 1992
+2122 1635 1989
+2122 1989 1813
+1525 2122 1813
+1525 1813 2133
+2154 1812 1532
+1812 2158 1532
+1812 1987 1653
+1812 1653 2158
+1988 1573 1987
+1988 1987 1812
+1651 1988 1812
+1651 1812 2154
+1987 1811 2157
+1987 2157 1653
+1811 2147 1533
+1811 1533 2157
+1986 1648 2147
+1986 2147 1811
+1573 1986 1811
+1573 1811 1987
+1985 1810 1986
+1985 1986 1573
+1810 2148 1648
+1810 1648 1986
+2069 1514 2148
+2069 2148 1810
+1609 2069 1810
+1609 1810 1985
+2153 1809 1988
+2153 1988 1651
+1809 1985 1573
+1809 1573 1988
+2070 1609 1985
+2070 1985 1809
+1512 2070 1809
+1512 1809 2153
+2150 1808 1531
+1808 2156 1531
+1808 1983 2156
+1983 1652 2156
+1984 1572 1808
+1572 1983 1808
+1649 1984 2150
+1984 1808 2150
+1983 1807 1652
+1807 2155 1652
+1807 2154 2155
+2154 1532 2155
+1982 1651 1807
+1651 2154 1807
+1572 1982 1983
+1982 1807 1983
+1981 1806 1572
+1806 1982 1572
+1806 2153 1982
+2153 1651 1982
+2057 1512 2153
+2057 2153 1806
+1603 2057 1806
+1603 1806 1981
+2149 1805 1649
+1805 1984 1649
+1805 1981 1984
+1981 1572 1984
+2058 1603 1805
+1603 1981 1805
+1510 2058 2149
+2058 1805 2149
+2144 1804 1530
+1804 2152 1530
+1804 1979 2152
+1979 1650 2152
+1980 1571 1804
+1571 1979 1804
+1646 1980 2144
+1980 1804 2144
+1979 1803 1650
+1803 2151 1650
+1803 2150 2151
+2150 1531 2151
+1978 1649 1803
+1649 2150 1803
+1571 1978 1979
+1978 1803 1979
+1977 1802 1571
+1802 1978 1571
+1802 2149 1978
+2149 1649 1978
+2049 1510 1802
+1510 2149 1802
+1599 2049 1977
+2049 1802 1977
+2143 1801 1646
+1801 1980 1646
+1801 1977 1980
+1977 1571 1980
+2050 1599 1801
+1599 1977 1801
+1508 2050 2143
+2050 1801 2143
+2064 1800 1514
+1800 2148 1514
+1800 1975 2148
+1975 1648 2148
+1976 1570 1800
+1570 1975 1800
+1606 1976 2064
+1976 1800 2064
+1975 1799 1648
+1799 2147 1648
+1799 2146 2147
+2146 1533 2147
+1974 1647 1799
+1647 2146 1799
+1570 1974 1975
+1974 1799 1975
+1973 1798 1570
+1798 1974 1570
+1798 2145 1974
+2145 1647 1974
+2137 1534 1798
+1534 2145 1798
+1643 2137 1973
+2137 1798 1973
+2063 1797 1606
+1797 1976 1606
+1797 1973 1976
+1973 1570 1976
+2138 1643 1797
+1643 1973 1797
+1502 2138 2063
+2138 1797 2063
+2140 1796 2144
+2140 2144 1530
+1796 1971 1646
+1796 1646 2144
+1972 1569 1971
+1972 1971 1796
+1644 1972 1796
+1644 1796 2140
+1971 1795 2143
+1971 2143 1646
+1795 2039 1508
+1795 1508 2143
+1970 1594 2039
+1970 2039 1795
+1569 1970 1795
+1569 1795 1971
+1969 1794 1970
+1969 1970 1569
+1794 2040 1594
+1794 1594 1970
+5775 5744 2040
+5775 2040 1794
+5750 5775 1794
+5750 1794 1969
+2139 1793 1972
+2139 1972 1644
+1793 1969 1569
+1793 1569 1972
+5774 5750 1969
+5774 1969 1793
+5739 5774 1793
+5739 1793 2139
+2116 1792 2142
+2116 2142 1528
+1792 1967 1645
+1792 1645 2142
+1968 1568 1967
+1968 1967 1792
+1632 1968 1792
+1632 1792 2116
+1967 1791 2141
+1967 2141 1645
+1791 2140 1530
+1791 1530 2141
+1966 1644 2140
+1966 2140 1791
+1568 1966 1791
+1568 1791 1967
+1965 1790 1966
+1965 1966 1568
+1790 2139 1644
+1790 1644 1966
+5773 5739 2139
+5773 2139 1790
+5749 5773 1790
+5749 1790 1965
+2115 1789 1968
+2115 1968 1632
+1789 1965 1568
+1789 1568 1968
+5772 5749 1965
+5772 1965 1789
+5736 5772 1789
+5736 1789 2115
+5802 1788 2009
+5802 2009 5731
+1788 1963 1579
+1788 1579 2009
+1964 1567 1963
+1964 1963 1788
+5764 1964 1788
+5764 1788 5802
+1963 1787 2010
+1963 2010 1579
+1787 2138 1502
+1787 1502 2010
+1962 1643 2138
+1962 2138 1787
+1567 1962 1787
+1567 1787 1963
+1961 1786 1962
+1961 1962 1567
+1786 2137 1643
+1786 1643 1962
+2135 1534 2137
+2135 2137 1786
+1642 2135 1786
+1642 1786 1961
+5803 1785 1964
+5803 1964 5764
+1785 1961 1567
+1785 1567 1964
+2136 1642 1961
+2136 1961 1785
+5730 2136 1785
+5730 1785 5803
+5800 1784 2136
+5800 2136 5730
+1784 1959 1642
+1784 1642 2136
+1960 1566 1959
+1960 1959 1784
+5763 1960 1784
+5763 1784 5800
+1959 1783 2135
+1959 2135 1642
+1783 2134 1534
+1783 1534 2135
+1958 1641 2134
+1958 2134 1783
+1566 1958 1783
+1566 1783 1959
+1957 1782 1958
+1957 1958 1566
+1782 2133 1641
+1782 1641 1958
+2113 1525 2133
+2113 2133 1782
+1631 2113 1782
+1631 1782 1957
+5801 1781 1960
+5801 1960 5763
+1781 1957 1566
+1781 1566 1960
+2114 1631 1957
+2114 1957 1781
+5728 2114 1781
+5728 1781 5801
+2128 1780 1526
+1780 2132 1526
+1780 1955 2132
+1955 1640 2132
+1956 1565 1780
+1565 1955 1780
+1638 1956 2128
+1956 1780 2128
+1955 1779 1640
+1779 2131 1640
+1779 2125 2131
+2125 1527 2131
+1954 1637 1779
+1637 2125 1779
+1565 1954 1955
+1954 1779 1955
+1953 1778 1565
+1778 1954 1565
+1778 2126 1954
+2126 1637 1954
+2097 1524 1778
+1524 2126 1778
+1623 2097 1953
+2097 1778 1953
+2127 1777 1638
+1777 1956 1638
+1777 1953 1956
+1953 1565 1956
+2098 1623 1777
+1623 1953 1777
+1523 2098 2127
+2098 1777 2127
+2120 1776 2130
+2120 2130 1529
+1776 1951 1639
+1776 1639 2130
+1952 1564 1951
+1952 1951 1776
+1634 1952 1776
+1634 1776 2120
+1951 1775 1639
+1775 2129 1639
+1775 2128 2129
+2128 1526 2129
+1950 1638 1775
+1638 2128 1775
+1564 1950 1951
+1950 1775 1951
+1949 1774 1564
+1774 1950 1564
+1774 2127 1950
+2127 1638 1950
+2107 1523 1774
+1523 2127 1774
+1628 2107 1949
+2107 1774 1949
+2119 1773 1952
+2119 1952 1634
+1773 1949 1952
+1949 1564 1952
+2108 1628 1773
+1628 1949 1773
+1522 2108 1773
+1522 1773 2119
+2092 1772 2126
+2092 2126 1524
+1772 1947 1637
+1772 1637 2126
+1948 1563 1947
+1948 1947 1772
+1620 1948 1772
+1620 1772 2092
+1947 1771 2125
+1947 2125 1637
+1771 2124 1527
+1771 1527 2125
+1946 1636 2124
+1946 2124 1771
+1563 1946 1771
+1563 1771 1947
+1945 1770 1946
+1945 1946 1563
+1770 2123 1636
+1770 1636 1946
+2117 1528 2123
+2117 2123 1770
+1633 2117 1770
+1633 1770 1945
+2091 1769 1948
+2091 1948 1620
+1769 1945 1563
+1769 1563 1948
+2118 1633 1945
+2118 1945 1769
+1521 2118 1769
+1521 1769 2091
+2112 1768 2122
+2112 2122 1525
+1768 1943 1635
+1768 1635 2122
+1944 1562 1943
+1944 1943 1768
+1630 1944 1768
+1630 1768 2112
+1943 1767 2121
+1943 2121 1635
+1767 2120 1529
+1767 1529 2121
+1942 1634 2120
+1942 2120 1767
+1562 1942 1767
+1562 1767 1943
+1941 1766 1942
+1941 1942 1562
+1766 2119 1634
+1766 1634 1942
+2103 1522 2119
+2103 2119 1766
+1626 2103 1766
+1626 1766 1941
+2111 1765 1944
+2111 1944 1630
+1765 1941 1562
+1765 1562 1944
+2104 1626 1941
+2104 1941 1765
+1520 2104 1765
+1520 1765 2111
+5778 1764 5740
+1764 2087 5740
+1764 1939 2087
+1939 1618 2087
+1940 1561 1764
+1561 1939 1764
+5752 1940 5778
+1940 1764 5778
+1939 1763 1618
+1763 2088 1618
+1763 2118 2088
+2118 1521 2088
+1938 1633 1763
+1633 2118 1763
+1561 1938 1939
+1938 1763 1939
+1937 1762 1561
+1762 1938 1561
+1762 2117 1938
+2117 1633 1938
+2116 1528 1762
+1528 2117 1762
+1632 2116 1937
+2116 1762 1937
+5779 1761 5752
+1761 1940 5752
+1761 1937 1940
+1937 1561 1940
+2115 1632 1761
+1632 1937 1761
+5736 2115 5779
+2115 1761 5779
+2113 1760 1525
+1760 2112 1525
+1760 1935 2112
+1935 1630 2112
+1936 1560 1760
+1560 1935 1760
+1631 1936 2113
+1936 1760 2113
+1935 1759 1630
+1759 2111 1630
+1759 2109 2111
+2109 1520 2111
+1934 1629 2109
+1934 2109 1759
+1560 1934 1935
+1934 1759 1935
+1933 1758 1560
+1758 1934 1560
+1758 2110 1629
+1758 1629 1934
+5799 5729 2110
+5799 2110 1758
+5762 5799 1933
+5799 1758 1933
+2114 1757 1631
+1757 1936 1631
+1757 1933 1936
+1933 1560 1936
+5798 5762 1757
+5762 1933 1757
+5728 5798 2114
+5798 1757 2114
+2109 1756 2105
+2109 2105 1520
+1756 1931 1627
+1756 1627 2105
+1932 1559 1931
+1932 1931 1756
+1629 1932 1756
+1629 1756 2109
+1931 1755 2106
+1931 2106 1627
+1755 2085 1515
+1755 1515 2106
+1930 1617 2085
+1930 2085 1755
+1559 1930 1755
+1559 1755 1931
+1929 1754 1930
+1929 1930 1559
+1754 2086 1617
+1754 1617 1930
+5797 5732 2086
+5797 2086 1754
+5761 5797 1754
+5761 1754 1929
+2110 1753 1932
+2110 1932 1629
+1753 1929 1559
+1753 1559 1932
+5796 5761 1929
+5796 1929 1753
+5729 5796 1753
+5729 1753 2110
+2080 1752 2101
+2080 2101 1519
+1752 1927 1625
+1752 1625 2101
+1928 1558 1927
+1928 1927 1752
+1614 1928 1752
+1614 1752 2080
+1927 1751 2102
+1927 2102 1625
+1751 2108 1522
+1751 1522 2102
+1926 1628 2108
+1926 2108 1751
+1558 1926 1751
+1558 1751 1927
+1925 1750 1926
+1925 1926 1558
+1750 2107 1628
+1750 1628 1926
+2099 1523 2107
+2099 2107 1750
+1624 2099 1750
+1624 1750 1925
+2079 1749 1928
+2079 1928 1614
+1749 1925 1558
+1749 1558 1928
+2100 1624 1925
+2100 1925 1749
+1517 2100 1749
+1517 1749 2079
+2105 1748 2104
+2105 2104 1520
+1748 1923 1626
+1748 1626 2104
+1924 1557 1923
+1924 1923 1748
+1627 1924 1748
+1627 1748 2105
+1923 1747 2103
+1923 2103 1626
+1747 2102 1522
+1747 1522 2103
+1922 1625 2102
+1922 2102 1747
+1557 1922 1747
+1557 1747 1923
+1921 1746 1922
+1921 1922 1557
+1746 2101 1625
+1746 1625 1922
+2083 1519 2101
+2083 2101 1746
+1616 2083 1746
+1616 1746 1921
+2106 1745 1924
+2106 1924 1627
+1745 1921 1557
+1745 1557 1924
+2084 1616 1921
+2084 1921 1745
+1515 2084 1745
+1515 1745 2106
+2099 1744 1523
+1744 2098 1523
+1744 1919 2098
+1919 1623 2098
+1920 1556 1744
+1556 1919 1744
+1624 1920 2099
+1920 1744 2099
+1919 1743 1623
+1743 2097 1623
+1743 2093 2097
+2093 1524 2097
+1918 1621 1743
+1621 2093 1743
+1556 1918 1919
+1918 1743 1919
+1917 1742 1556
+1742 1918 1556
+1742 2094 1918
+2094 1621 1918
+2096 1518 1742
+1518 2094 1742
+1622 2096 1917
+2096 1742 1917
+2100 1741 1624
+1741 1920 1624
+1741 1917 1920
+1917 1556 1920
+2095 1622 1741
+1622 1917 1741
+1517 2095 2100
+2095 1741 2100
+2074 1740 2094
+2074 2094 1518
+1740 1915 1621
+1740 1621 2094
+1916 1555 1915
+1916 1915 1740
+1611 1916 1740
+1611 1740 2074
+1915 1739 2093
+1915 2093 1621
+1739 2092 1524
+1739 1524 2093
+1914 1620 2092
+1914 2092 1739
+1555 1914 1739
+1555 1739 1915
+1913 1738 1914
+1913 1914 1555
+1738 2091 1620
+1738 1620 1914
+2089 1521 2091
+2089 2091 1738
+1619 2089 1738
+1619 1738 1913
+2073 1737 1916
+2073 1916 1611
+1737 1913 1555
+1737 1555 1916
+2090 1619 1913
+2090 1913 1737
+1516 2090 1737
+1516 1737 2073
+2072 1736 2090
+2072 2090 1516
+1736 1911 1619
+1736 1619 2090
+1912 1554 1911
+1912 1911 1736
+1610 1912 1736
+1610 1736 2072
+1911 1735 2089
+1911 2089 1619
+1735 2088 1521
+1735 1521 2089
+1910 1618 2088
+1910 2088 1735
+1554 1910 1735
+1554 1735 1911
+1909 1734 1910
+1909 1910 1554
+1734 2087 1618
+1734 1618 1910
+5777 5740 2087
+5777 2087 1734
+5751 5777 1734
+5751 1734 1909
+2071 1733 1912
+2071 1912 1610
+1733 1909 1554
+1733 1554 1912
+5776 5751 1909
+5776 1909 1733
+5735 5776 1733
+5735 1733 2071
+2085 1732 2084
+2085 2084 1515
+1732 1907 1616
+1732 1616 2084
+1908 1553 1907
+1908 1907 1732
+1617 1908 1732
+1617 1732 2085
+1907 1731 2083
+1907 2083 1616
+1731 2081 1519
+1731 1519 2083
+1906 1615 2081
+1906 2081 1731
+1553 1906 1731
+1553 1731 1907
+1905 1730 1906
+1905 1906 1553
+1730 2082 1615
+1730 1615 1906
+5795 5742 2082
+5795 2082 1730
+5760 5795 1730
+5760 1730 1905
+2086 1729 1908
+2086 1908 1617
+1729 1905 1553
+1729 1553 1908
+5794 5760 1905
+5794 1905 1729
+5732 5794 1729
+5732 1729 2086
+2081 1728 1519
+1728 2080 1519
+1728 1903 2080
+1903 1614 2080
+1904 1552 1728
+1552 1903 1728
+1615 1904 2081
+1904 1728 2081
+1903 1727 1614
+1727 2079 1614
+1727 2078 2079
+2078 1517 2079
+1902 1613 1727
+1613 2078 1727
+1552 1902 1903
+1902 1727 1903
+1901 1726 1552
+1726 1902 1552
+1726 2077 1902
+2077 1613 1902
+5793 5737 1726
+5737 2077 1726
+5759 5793 1901
+5793 1726 1901
+2082 1725 1615
+1725 1904 1615
+1725 1901 1904
+1901 1552 1904
+5792 5759 1725
+5759 1901 1725
+5742 5792 2082
+5792 1725 2082
+2075 1724 2074
+2075 2074 1518
+1724 1899 2074
+1899 1611 2074
+1900 1551 1899
+1900 1899 1724
+1612 1900 1724
+1612 1724 2075
+1899 1723 1611
+1723 2073 1611
+1723 2072 1516
+1723 1516 2073
+1898 1610 2072
+1898 2072 1723
+1551 1898 1723
+1551 1723 1899
+1897 1722 1898
+1897 1898 1551
+1722 2071 1610
+1722 1610 1898
+5771 5735 2071
+5771 2071 1722
+5748 5771 1722
+5748 1722 1897
+2076 1721 1900
+2076 1900 1612
+1721 1897 1551
+1721 1551 1900
+5770 5748 1897
+5770 1897 1721
+5738 5770 1721
+5738 1721 2076
+2042 1720 1504
+1720 2051 1504
+1720 1895 2051
+1895 1600 2051
+1896 1550 1720
+1550 1895 1720
+1595 1896 2042
+1896 1720 2042
+1895 1719 1600
+1719 2052 1600
+1719 2067 2052
+2067 1511 2052
+1894 1608 1719
+1608 2067 1719
+1550 1894 1895
+1894 1719 1895
+1893 1718 1550
+1718 1894 1550
+1718 2068 1894
+2068 1608 1894
+2061 1513 1718
+1513 2068 1718
+1605 2061 1893
+2061 1718 1893
+2041 1717 1595
+1717 1896 1595
+1717 1893 1896
+1893 1550 1896
+2062 1605 1717
+1605 1893 1717
+1501 2062 2041
+2062 1717 2041
+2056 1716 2070
+2056 2070 1512
+1716 1891 1609
+1716 1609 2070
+1892 1549 1891
+1892 1891 1716
+1602 1892 1716
+1602 1716 2056
+1891 1715 2069
+1891 2069 1609
+1715 2065 1514
+1715 1514 2069
+1890 1607 2065
+1890 2065 1715
+1549 1890 1715
+1549 1715 1891
+1889 1714 1890
+1889 1890 1549
+1714 2066 1607
+1714 1607 1890
+2068 1513 2066
+2068 2066 1714
+1608 2068 1714
+1608 1714 1889
+2055 1713 1892
+2055 1892 1602
+1713 1889 1549
+1713 1549 1892
+2067 1608 1889
+2067 1889 1713
+1511 2067 1713
+1511 1713 2055
+2060 1712 1513
+1712 2066 1513
+1712 1887 2066
+1887 1607 2066
+1888 1548 1712
+1548 1887 1712
+1604 1888 2060
+1888 1712 2060
+1887 1711 1607
+1711 2065 1607
+1711 2064 2065
+2064 1514 2065
+1886 1606 1711
+1606 2064 1711
+1548 1886 1887
+1886 1711 1887
+1885 1710 1548
+1710 1886 1548
+1710 2063 1886
+2063 1606 1886
+2011 1502 1710
+1502 2063 1710
+1580 2011 1885
+2011 1710 1885
+2059 1709 1604
+1709 1888 1604
+1709 1885 1888
+1885 1548 1888
+2012 1580 1709
+1580 1885 1709
+1500 2012 2059
+2012 1709 2059
+2016 1708 1503
+1708 2019 1503
+1708 1883 1584
+1708 1584 2019
+1884 1547 1883
+1884 1883 1708
+1582 1884 1708
+1582 1708 2016
+1883 1707 2020
+1883 2020 1584
+1707 2062 1501
+1707 1501 2020
+1882 1605 2062
+1882 2062 1707
+1547 1882 1707
+1547 1707 1883
+1881 1706 1882
+1881 1882 1547
+1706 2061 1605
+1706 1605 1882
+2060 1513 2061
+2060 2061 1706
+1604 2060 1706
+1604 1706 1881
+2015 1705 1884
+2015 1884 1582
+1705 1881 1547
+1705 1547 1884
+2059 1604 1881
+2059 1881 1705
+1500 2059 1705
+1500 1705 2015
+2048 1704 2058
+2048 2058 1510
+1704 1879 1603
+1704 1603 2058
+1880 1546 1879
+1880 1879 1704
+1598 1880 1704
+1598 1704 2048
+1879 1703 2057
+1879 2057 1603
+1703 2056 1512
+1703 1512 2057
+1878 1602 2056
+1878 2056 1703
+1546 1878 1703
+1546 1703 1879
+1877 1702 1878
+1877 1878 1546
+1702 2055 1602
+1702 1602 1878
+2053 1511 2055
+2053 2055 1702
+1601 2053 1702
+1601 1702 1877
+2047 1701 1880
+2047 1880 1598
+1701 1877 1546
+1701 1546 1880
+2054 1601 1877
+2054 1877 1701
+1509 2054 1701
+1509 1701 2047
+2026 1700 1505
+1700 2043 1505
+1700 1875 2043
+1875 1596 2043
+1876 1545 1700
+1545 1875 1700
+1587 1876 2026
+1876 1700 2026
+1875 1699 1596
+1699 2044 1596
+1699 2054 2044
+2054 1509 2044
+1874 1601 1699
+1601 2054 1699
+1545 1874 1875
+1874 1699 1875
+1873 1698 1545
+1698 1874 1545
+1698 2053 1874
+2053 1601 1874
+2052 1511 1698
+1511 2053 1698
+1600 2052 1873
+2052 1698 1873
+2025 1697 1587
+1697 1876 1587
+1697 1873 1876
+1873 1545 1876
+2051 1600 1697
+1600 1873 1697
+1504 2051 2025
+2051 1697 2025
+2038 1696 2050
+2038 2050 1508
+1696 1871 1599
+1696 1599 2050
+1872 1544 1871
+1872 1871 1696
+1593 1872 1696
+1593 1696 2038
+1871 1695 2049
+1871 2049 1599
+1695 2048 1510
+1695 1510 2049
+1870 1598 2048
+1870 2048 1695
+1544 1870 1695
+1544 1695 1871
+1869 1694 1870
+1869 1870 1544
+1694 2047 1598
+1694 1598 1870
+2045 1509 2047
+2045 2047 1694
+1597 2045 1694
+1597 1694 1869
+2037 1693 1872
+2037 1872 1593
+1693 1869 1544
+1693 1544 1872
+2046 1597 1869
+2046 1869 1693
+1507 2046 1693
+1507 1693 2037
+2030 1692 1506
+1692 2033 1506
+1692 1867 2033
+1867 1591 2033
+1868 1543 1692
+1543 1867 1692
+1589 1868 2030
+1868 1692 2030
+1867 1691 1591
+1691 2034 1591
+1691 2046 2034
+2046 1507 2034
+1866 1597 1691
+1597 2046 1691
+1543 1866 1867
+1866 1691 1867
+1865 1690 1543
+1690 1866 1543
+1690 2045 1866
+2045 1597 1866
+2044 1509 1690
+1509 2045 1690
+1596 2044 1865
+2044 1690 1865
+2029 1689 1589
+1689 1868 1589
+1689 1865 1868
+1865 1543 1868
+2043 1596 1689
+1596 1865 1689
+1505 2043 2029
+2043 1689 2029
+5766 1688 5733
+1688 2023 5733
+1688 1863 2023
+1863 1586 2023
+1864 1542 1688
+1542 1863 1688
+5746 1864 1688
+5746 1688 5766
+1863 1687 1586
+1687 2024 1586
+1687 2042 2024
+2042 1504 2024
+1862 1595 1687
+1595 2042 1687
+1542 1862 1863
+1862 1687 1863
+1861 1686 1542
+1686 1862 1542
+1686 2041 1862
+2041 1595 1862
+2021 1501 1686
+1501 2041 1686
+1585 2021 1861
+2021 1686 1861
+5767 1685 1864
+5767 1864 5746
+1685 1861 1542
+1685 1542 1864
+2022 1585 1861
+2022 1861 1685
+5727 2022 1685
+5727 1685 5767
+2039 1684 1508
+1684 2038 1508
+1684 1859 2038
+1859 1593 2038
+1860 1541 1684
+1541 1859 1684
+1594 1860 2039
+1860 1684 2039
+1859 1683 1593
+1683 2037 1593
+1683 2035 2037
+2035 1507 2037
+1858 1592 1683
+1592 2035 1683
+1541 1858 1859
+1858 1683 1859
+1857 1682 1541
+1682 1858 1541
+1682 2036 1858
+2036 1592 1858
+5791 5743 1682
+5743 2036 1682
+5758 5791 1857
+5791 1682 1857
+2040 1681 1860
+2040 1860 1594
+1681 1857 1860
+1857 1541 1860
+5790 5758 1681
+5758 1857 1681
+5744 5790 1681
+5744 1681 2040
+2035 1680 1507
+1680 2034 1507
+1680 1855 2034
+1855 1591 2034
+1856 1540 1680
+1540 1855 1680
+1592 1856 2035
+1856 1680 2035
+1855 1679 1591
+1679 2033 1591
+1679 2031 2033
+2031 1506 2033
+1854 1590 1679
+1590 2031 1679
+1540 1854 1855
+1854 1679 1855
+1853 1678 1540
+1678 1854 1540
+1678 2032 1854
+2032 1590 1854
+5789 5741 1678
+5741 2032 1678
+5757 5789 1853
+5789 1678 1853
+2036 1677 1592
+1677 1856 1592
+1677 1853 1856
+1853 1540 1856
+5788 5757 1677
+5757 1853 1677
+5743 5788 2036
+5788 1677 2036
+2031 1676 1506
+1676 2030 1506
+1676 1851 1589
+1676 1589 2030
+1852 1539 1676
+1539 1851 1676
+1590 1852 2031
+1852 1676 2031
+1851 1675 2029
+1851 2029 1589
+1675 2027 1505
+1675 1505 2029
+1850 1588 2027
+1850 2027 1675
+1539 1850 1675
+1539 1675 1851
+1849 1674 1850
+1849 1850 1539
+1674 2028 1588
+1674 1588 1850
+5787 5734 2028
+5787 2028 1674
+5756 5787 1674
+5756 1674 1849
+2032 1673 1590
+1673 1852 1590
+1673 1849 1852
+1849 1539 1852
+5786 5756 1673
+5756 1849 1673
+5741 5786 2032
+5786 1673 2032
+2027 1672 2026
+2027 2026 1505
+1672 1847 1587
+1672 1587 2026
+1848 1538 1847
+1848 1847 1672
+1588 1848 1672
+1588 1672 2027
+1847 1671 2025
+1847 2025 1587
+1671 2024 1504
+1671 1504 2025
+1846 1586 2024
+1846 2024 1671
+1538 1846 1671
+1538 1671 1847
+1845 1670 1846
+1845 1846 1538
+1670 2023 1586
+1670 1586 1846
+5769 5733 2023
+5769 2023 1670
+5747 5769 1670
+5747 1670 1845
+2028 1669 1848
+2028 1848 1588
+1669 1845 1538
+1669 1538 1848
+5768 5747 1845
+5768 1845 1669
+5734 5768 1669
+5734 1669 2028
+2021 1668 2020
+2021 2020 1501
+1668 1843 1584
+1668 1584 2020
+1844 1537 1843
+1844 1843 1668
+1585 1844 1668
+1585 1668 2021
+1843 1667 2019
+1843 2019 1584
+1667 2017 1503
+1667 1503 2019
+1842 1583 2017
+1842 2017 1667
+1537 1842 1667
+1537 1667 1843
+1841 1666 1842
+1841 1842 1537
+1666 2018 1583
+1666 1583 1842
+5783 5745 2018
+5783 2018 1666
+5754 5783 1666
+5754 1666 1841
+2022 1665 1844
+2022 1844 1585
+1665 1841 1537
+1665 1537 1844
+5782 5754 1841
+5782 1841 1665
+5727 5782 2022
+5782 1665 2022
+2017 1664 1503
+1664 2016 1503
+1664 1839 2016
+1839 1582 2016
+1840 1536 1664
+1536 1839 1664
+1583 1840 1664
+1583 1664 2017
+1839 1663 1582
+1663 2015 1582
+1663 2013 2015
+2013 1500 2015
+1838 1581 1663
+1581 2013 1663
+1536 1838 1839
+1838 1663 1839
+1837 1662 1536
+1662 1838 1536
+1662 2014 1838
+2014 1581 1838
+5781 5726 1662
+5726 2014 1662
+5753 5781 1662
+5753 1662 1837
+2018 1661 1840
+2018 1840 1583
+1661 1837 1536
+1661 1536 1840
+5780 5753 1837
+5780 1837 1661
+5745 5780 1661
+5745 1661 2018
+2013 1660 1500
+1660 2012 1500
+1660 1835 2012
+1835 1580 2012
+1836 1535 1660
+1535 1835 1660
+1581 1836 2013
+1836 1660 2013
+1835 1659 1580
+1659 2011 1580
+1659 2010 2011
+2010 1502 2011
+1834 1579 1659
+1579 2010 1659
+1535 1834 1835
+1834 1659 1835
+1833 1658 1535
+1658 1834 1535
+1658 2009 1834
+2009 1579 1834
+5785 5731 1658
+5731 2009 1658
+5755 5785 1833
+5785 1658 1833
+2014 1657 1581
+1657 1836 1581
+1657 1833 1836
+1833 1535 1836
+5784 5755 1657
+5755 1833 1657
+5726 5784 2014
+5784 1657 2014
+3222 2215 2693
+2693 2215 3220
+2693 3220 2976
+2976 3220 2408
+2977 2693 2286
+2286 2693 2976
+2409 3222 2977
+2977 3222 2693
+2976 2408 2692
+2692 2408 3221
+2692 3221 3093
+3093 3221 2194
+2975 2692 2344
+2344 2692 3093
+2286 2976 2975
+2975 2976 2692
+2974 2286 2691
+2691 2286 2975
+2691 2975 3092
+3092 2975 2344
+5786 2691 5741
+5741 2691 3092
+5756 2974 5786
+5786 2974 2691
+3223 2409 2690
+2690 2409 2977
+2690 2977 2974
+2974 2977 2286
+5787 2690 5756
+5756 2690 2974
+5734 3223 5787
+5787 3223 2690
+3043 2689 3223
+3043 3223 5734
+2689 2972 2409
+2689 2409 3223
+2973 2285 2972
+2973 2972 2689
+2319 2973 2689
+2319 2689 3043
+2972 2688 2409
+2688 3222 2409
+2688 3217 3222
+3217 2215 3222
+2971 2406 2688
+2406 3217 2688
+2285 2971 2972
+2971 2688 2972
+2970 2687 2285
+2687 2971 2285
+2687 3216 2971
+3216 2406 2971
+3200 2191 2687
+2191 3216 2687
+2398 3200 2970
+3200 2687 2970
+3042 2686 2973
+3042 2973 2319
+2686 2970 2285
+2686 2285 2973
+3201 2398 2686
+2398 2970 2686
+2173 3201 3042
+3201 2686 3042
+3088 2194 2685
+2685 2194 3221
+2685 3221 2968
+2968 3221 2408
+2969 2685 2284
+2284 2685 2968
+2342 3088 2969
+2969 3088 2685
+2968 2408 2684
+2684 2408 3220
+2684 3220 3218
+3218 3220 2215
+2967 2684 2407
+2407 2684 3218
+2284 2968 2967
+2967 2968 2684
+2966 2284 2683
+2683 2284 2967
+2683 2967 3219
+3219 2967 2407
+5725 2683 5698
+5698 2683 3219
+5709 2966 5725
+5725 2966 2683
+3089 2342 2682
+2682 2342 2969
+2682 2969 2966
+2966 2969 2284
+5724 2682 5709
+5709 2682 2966
+5696 3089 5724
+5724 3089 2682
+5722 3219 2681
+5722 5698 3219
+2681 2407 2964
+2681 3219 2407
+2965 2964 2283
+2965 2681 2964
+5708 2681 2965
+5708 5722 2681
+2964 3218 2680
+2964 2407 3218
+2680 2215 3217
+2680 3218 2215
+2963 3217 2406
+2963 2680 3217
+2283 2680 2963
+2283 2964 2680
+2962 2963 2679
+2962 2283 2963
+2679 2406 3216
+2679 2963 2406
+3205 3216 2191
+3205 2679 3216
+2400 2679 3205
+2400 2962 2679
+5723 2965 2678
+5723 5708 2965
+2678 2283 2962
+2678 2965 2283
+3204 2962 2400
+3204 2678 2962
+5697 2678 3204
+5697 5723 2678
+3007 2677 2172
+2677 3184 2172
+2677 2960 3184
+2960 2390 3184
+2961 2282 2677
+2282 2960 2677
+2301 2961 3007
+2961 2677 3007
+2960 2676 2390
+2676 3185 2390
+2676 3210 3185
+3210 2200 3185
+2959 2403 2676
+2403 3210 2676
+2282 2959 2960
+2959 2676 2960
+2958 2675 2282
+2675 2959 2282
+2675 3211 2959
+3211 2403 2959
+3214 2214 2675
+2214 3211 2675
+2405 3214 2958
+3214 2675 2958
+3006 2674 2301
+2674 2961 2301
+2674 2958 2961
+2958 2282 2961
+3215 2405 2674
+2405 2958 2674
+2165 3215 3006
+3215 2674 3006
+3213 2673 2180
+2673 2980 2180
+2673 2956 2980
+2956 2288 2980
+2957 2281 2673
+2281 2956 2673
+2404 2957 3213
+2957 2673 3213
+2956 2672 2288
+2672 2981 2288
+2672 3038 2981
+3038 2179 2981
+2955 2317 2672
+2317 3038 2672
+2281 2955 2956
+2955 2672 2956
+2954 2671 2281
+2671 2955 2281
+2671 3039 2955
+3039 2317 2955
+3215 2165 2671
+2165 3039 2671
+2405 3215 2954
+3215 2671 2954
+3212 2670 2404
+2670 2957 2404
+2670 2954 2957
+2954 2281 2957
+3214 2405 2670
+2405 2954 2670
+2214 3214 3212
+3214 2670 3212
+3212 2669 2214
+2669 3211 2214
+2669 2952 2403
+2669 2403 3211
+2953 2280 2669
+2280 2952 2669
+2404 2953 3212
+2953 2669 3212
+2952 2668 2403
+2668 3210 2403
+2668 3108 3210
+3108 2200 3210
+2951 2352 2668
+2352 3108 2668
+2280 2951 2952
+2951 2668 2952
+2950 2667 2280
+2667 2951 2280
+2667 3109 2951
+3109 2352 2951
+3102 2198 2667
+2198 3109 2667
+2349 3102 2950
+3102 2667 2950
+3213 2666 2404
+2666 2953 2404
+2666 2950 2953
+2950 2280 2953
+3103 2349 2666
+2349 2950 2666
+2180 3103 3213
+3103 2666 3213
+3077 2665 2195
+2665 3208 2195
+2665 2948 3208
+2948 2402 3208
+2949 2279 2665
+2279 2948 2665
+2336 2949 3077
+2949 2665 3077
+2948 2664 2402
+2664 3209 2402
+2664 3202 3209
+3202 2170 3209
+2947 2399 2664
+2399 3202 2664
+2279 2947 2948
+2947 2664 2948
+2946 2663 2279
+2663 2947 2279
+2663 3203 2947
+3203 2399 2947
+5721 5699 2663
+5699 3203 2663
+5707 5721 2946
+5721 2663 2946
+3076 2662 2336
+2662 2949 2336
+2662 2946 2949
+2946 2279 2949
+5720 5707 2662
+5707 2946 2662
+5694 5720 3076
+5720 2662 3076
+3208 2661 3072
+3208 3072 2195
+2661 2944 2334
+2661 2334 3072
+2945 2278 2944
+2945 2944 2661
+2402 2945 2661
+2402 2661 3208
+2944 2660 3073
+2944 3073 2334
+2660 3116 2174
+2660 2174 3073
+2943 2356 3116
+2943 3116 2660
+2278 2943 2660
+2278 2660 2944
+2942 2659 2943
+2942 2943 2278
+2659 3117 2356
+2659 2356 2943
+3192 2201 3117
+3192 3117 2659
+2394 3192 2659
+2394 2659 2942
+3209 2658 2945
+3209 2945 2402
+2658 2942 2278
+2658 2278 2945
+3193 2394 2942
+3193 2942 2658
+2170 3193 2658
+2170 2658 3209
+3207 2657 3180
+3207 3180 2212
+2657 2940 2388
+2657 2388 3180
+2941 2277 2940
+2941 2940 2657
+2401 2941 2657
+2401 2657 3207
+2940 2656 3181
+2940 3181 2388
+2656 3140 2205
+2656 2205 3181
+2939 2368 3140
+2939 3140 2656
+2277 2939 2656
+2277 2656 2940
+2938 2655 2939
+2938 2939 2277
+2655 3141 2368
+2655 2368 2939
+5785 5731 3141
+5785 3141 2655
+5755 5785 2655
+5755 2655 2938
+3206 2654 2941
+3206 2941 2401
+2654 2938 2277
+2654 2277 2941
+5784 5755 2938
+5784 2938 2654
+5726 5784 2654
+5726 2654 3206
+5692 2653 3178
+5692 3178 5663
+2653 2936 2387
+2653 2387 3178
+2937 2276 2936
+2937 2936 2653
+5673 2937 2653
+5673 2653 5692
+2936 2652 3179
+2936 3179 2387
+2652 3207 2212
+2652 2212 3179
+2935 2401 3207
+2935 3207 2652
+2276 2935 2652
+2276 2652 2936
+2934 2651 2935
+2934 2935 2276
+2651 3206 2401
+2651 2401 2935
+3066 5726 3206
+3066 3206 2651
+2331 3066 2651
+2331 2651 2934
+5693 2650 2937
+5693 2937 5673
+2650 2934 2276
+2650 2276 2937
+3067 2331 2934
+3067 2934 2650
+5656 3067 2650
+5656 2650 5693
+3199 2649 2191
+2649 3205 2191
+2649 2932 3205
+2932 2400 3205
+2933 2275 2649
+2275 2932 2649
+2397 2933 3199
+2933 2649 3199
+2932 2648 2400
+2648 3204 2400
+2648 5719 3204
+5719 5697 3204
+2931 5706 2648
+5706 5719 2648
+2275 2931 2932
+2931 2648 2932
+2930 2647 2275
+2647 2931 2275
+2647 5718 5706
+2647 5706 2931
+3203 5699 5718
+3203 5718 2647
+2399 3203 2647
+2399 2647 2930
+3198 2646 2397
+2646 2933 2397
+2646 2930 2933
+2930 2275 2933
+3202 2399 2930
+3202 2930 2646
+2170 3202 3198
+3202 2646 3198
+3191 2645 3196
+3191 3196 2213
+2645 2928 2396
+2645 2396 3196
+2929 2274 2928
+2929 2928 2645
+2393 2929 2645
+2393 2645 3191
+2928 2644 3197
+2928 3197 2396
+2644 3201 2173
+2644 2173 3197
+2927 2398 3201
+2927 3201 2644
+2274 2927 2644
+2274 2644 2928
+2926 2643 2927
+2926 2927 2274
+2643 3200 2398
+2643 2398 2927
+3199 2191 3200
+3199 3200 2643
+2397 3199 2643
+2397 2643 2926
+3190 2642 2929
+3190 2929 2393
+2642 2926 2274
+2642 2274 2929
+3198 2397 2926
+3198 2926 2642
+2170 3198 2642
+2170 2642 3190
+5690 2641 3040
+5690 3040 5660
+2641 2924 2318
+2641 2318 3040
+2925 2273 2641
+2273 2924 2641
+5672 2925 5690
+2925 2641 5690
+2924 2640 2318
+2640 3041 2318
+2640 3197 3041
+3197 2173 3041
+2923 2396 2640
+2396 3197 2640
+2273 2923 2924
+2923 2640 2924
+2922 2639 2273
+2639 2923 2273
+2639 3196 2923
+3196 2396 2923
+3194 2213 2639
+2213 3196 2639
+2395 3194 2922
+3194 2639 2922
+5691 2638 5672
+2638 2925 5672
+2638 2922 2925
+2922 2273 2925
+3195 2395 2638
+2395 2922 2638
+5659 3195 5691
+3195 2638 5691
+3194 2637 3188
+3194 3188 2213
+2637 2920 2392
+2637 2392 3188
+2921 2272 2920
+2921 2920 2637
+2395 2921 2637
+2395 2637 3194
+2920 2636 3189
+2920 3189 2392
+2636 3130 2203
+2636 2203 3189
+2919 2363 3130
+2919 3130 2636
+2272 2919 2636
+2272 2636 2920
+2918 2635 2919
+2918 2919 2272
+2635 3131 2363
+2635 2363 2919
+5689 5661 3131
+5689 3131 2635
+5671 5689 2635
+5671 2635 2918
+3195 2634 2921
+3195 2921 2395
+2634 2918 2272
+2634 2272 2921
+5688 5671 2918
+5688 2918 2634
+5659 5688 2634
+5659 2634 3195
+3192 2633 2201
+2633 3120 2201
+2633 2916 3120
+2916 2358 3120
+2917 2271 2633
+2271 2916 2633
+2394 2917 3192
+2917 2633 3192
+2916 2632 2358
+2632 3121 2358
+2632 3186 3121
+3186 2202 3121
+2915 2391 2632
+2391 3186 2632
+2271 2915 2916
+2915 2632 2916
+2914 2631 2271
+2631 2915 2271
+2631 3187 2915
+3187 2391 2915
+3191 2213 2631
+2213 3187 2631
+2393 3191 2914
+3191 2631 2914
+3193 2630 2394
+2630 2917 2394
+2630 2914 2917
+2914 2271 2917
+3190 2393 2630
+2393 2914 2630
+2170 3190 3193
+3190 2630 3193
+3135 2629 2203
+2629 3189 2203
+2629 2912 3189
+2912 2392 3189
+2913 2270 2629
+2270 2912 2629
+2365 2913 3135
+2913 2629 3135
+2912 2628 2392
+2628 3188 2392
+2628 3187 3188
+3187 2213 3188
+2911 2391 2628
+2391 3187 2628
+2270 2911 2912
+2911 2628 2912
+2910 2627 2270
+2627 2911 2270
+2627 3186 2911
+3186 2391 2911
+3124 2202 2627
+2202 3186 2627
+2360 3124 2910
+3124 2627 2910
+3134 2626 2365
+2626 2913 2365
+2626 2910 2913
+2910 2270 2913
+3125 2360 2626
+2360 2910 2626
+2186 3125 3134
+3125 2626 3134
+3182 2625 3172
+3182 3172 2211
+2625 2908 2384
+2625 2384 3172
+2909 2269 2908
+2909 2908 2625
+2389 2909 2625
+2389 2625 3182
+2908 2624 3173
+2908 3173 2384
+2624 3106 2182
+2624 2182 3173
+2907 2351 3106
+2907 3106 2624
+2269 2907 2624
+2269 2624 2908
+2906 2623 2907
+2906 2907 2269
+2623 3107 2351
+2623 2351 2907
+3185 2200 3107
+3185 3107 2623
+2390 3185 2623
+2390 2623 2906
+3183 2622 2389
+2622 2909 2389
+2622 2906 2269
+2622 2269 2909
+3184 2390 2622
+2390 2906 2622
+2172 3184 3183
+3184 2622 3183
+3182 3175 2621
+3182 2211 3175
+2621 2385 2904
+2621 3175 2385
+2905 2904 2268
+2905 2621 2904
+2389 2621 2905
+2389 3182 2621
+2904 3174 2620
+2904 2385 3174
+2620 5737 5804
+2620 3174 5737
+2903 5804 5765
+2903 2620 5804
+2268 2620 2903
+2268 2904 2620
+2902 2903 2619
+2902 2268 2903
+2619 5765 5805
+2619 2903 5765
+3009 5805 5738
+3009 2619 5805
+2302 2619 3009
+2302 2902 2619
+3183 2905 2618
+3183 2389 2905
+2618 2268 2902
+2618 2905 2268
+3008 2902 2302
+3008 2618 2902
+2172 2618 3008
+2172 3183 2618
+3133 2617 2166
+2617 3144 2166
+2617 2900 3144
+2900 2370 3144
+2901 2267 2617
+2267 2900 2617
+2364 2901 3133
+2901 2617 3133
+2900 2616 2370
+2616 3145 2370
+2616 3181 3145
+3181 2205 3145
+2899 2388 2616
+2388 3181 2616
+2267 2899 2900
+2899 2616 2900
+2898 2615 2267
+2615 2899 2267
+2615 3180 2899
+3180 2388 2899
+3176 2212 2615
+2212 3180 2615
+2386 3176 2898
+3176 2615 2898
+3132 2614 2364
+2614 2901 2364
+2614 2898 2901
+2898 2267 2901
+3177 2386 2614
+2386 2898 2614
+2204 3177 3132
+3177 2614 3132
+3178 2613 5663
+2613 5687 5663
+2613 2896 5670
+2613 5670 5687
+2897 2266 2896
+2897 2896 2613
+2387 2897 3178
+2897 2613 3178
+2896 2612 5686
+2896 5686 5670
+2612 3126 5655
+2612 5655 5686
+2895 2361 3126
+2895 3126 2612
+2266 2895 2612
+2266 2612 2896
+2894 2611 2895
+2894 2895 2266
+2611 3127 2361
+2611 2361 2895
+3177 2204 3127
+3177 3127 2611
+2386 3177 2611
+2386 2611 2894
+3179 2610 2387
+2610 2897 2387
+2610 2894 2266
+2610 2266 2897
+3176 2386 2610
+2386 2894 2610
+2212 3176 3179
+3176 2610 3179
+3171 2609 2211
+2609 3175 2211
+2609 2892 3175
+2892 2385 3175
+2893 2265 2609
+2265 2892 2609
+2383 2893 3171
+2893 2609 3171
+2892 2608 2385
+2608 3174 2385
+2608 5793 3174
+5793 5737 3174
+2891 5759 5793
+2891 5793 2608
+2265 2891 2892
+2891 2608 2892
+2890 2607 2265
+2607 2891 2265
+2607 5792 5759
+2607 5759 2891
+3168 5742 5792
+3168 5792 2607
+2382 3168 2890
+3168 2607 2890
+3170 2606 2383
+2606 2893 2383
+2606 2890 2893
+2890 2265 2893
+3169 2382 2606
+2382 2890 2606
+2210 3169 3170
+3169 2606 3170
+3031 2605 3173
+3031 3173 2182
+2605 2888 2384
+2605 2384 3173
+2889 2264 2605
+2264 2888 2605
+2313 2889 2605
+2313 2605 3031
+2888 2604 3172
+2888 3172 2384
+2604 3171 3172
+3171 2211 3172
+2887 2383 2604
+2383 3171 2604
+2264 2887 2888
+2887 2604 2888
+2886 2603 2264
+2603 2887 2264
+2603 3170 2887
+3170 2383 2887
+3166 2210 2603
+2210 3170 2603
+2381 3166 2886
+3166 2603 2886
+3030 2602 2313
+2602 2889 2313
+2602 2886 2889
+2886 2264 2889
+3167 2381 2602
+2381 2886 2602
+2189 3167 3030
+3167 2602 3030
+3165 2601 2210
+2601 3169 2210
+2601 2884 3169
+2884 2382 3169
+2885 2263 2601
+2263 2884 2601
+2380 2885 3165
+2885 2601 3165
+2884 2600 2382
+2600 3168 2382
+2600 5795 3168
+5795 5742 3168
+2883 5760 2600
+5760 5795 2600
+2263 2883 2884
+2883 2600 2884
+2882 2599 2263
+2599 2883 2263
+2599 5794 5760
+2599 5760 2883
+3158 5732 5794
+3158 5794 2599
+2377 3158 2599
+2377 2599 2882
+3164 2598 2380
+2598 2885 2380
+2598 2882 2885
+2882 2263 2885
+3159 2377 2882
+3159 2882 2598
+2209 3159 3164
+3159 2598 3164
+3061 2597 2189
+2597 3167 2189
+2597 2880 3167
+2880 2381 3167
+2881 2262 2597
+2262 2880 2597
+2328 2881 3061
+2881 2597 3061
+2880 2596 2381
+2596 3166 2381
+2596 3165 3166
+3165 2210 3166
+2879 2380 2596
+2380 3165 2596
+2262 2879 2880
+2879 2596 2880
+2878 2595 2262
+2595 2879 2262
+2595 3164 2879
+3164 2380 2879
+3162 2209 2595
+2209 3164 2595
+2379 3162 2878
+3162 2595 2878
+3060 2594 2328
+2594 2881 2328
+2594 2878 2881
+2878 2262 2881
+3163 2379 2594
+2379 2878 2594
+2168 3163 3060
+3163 2594 3060
+3161 2593 2208
+2593 3156 2208
+2593 2876 3156
+2876 2376 3156
+2877 2261 2593
+2261 2876 2593
+2378 2877 3161
+2877 2593 3161
+2876 2592 2376
+2592 3157 2376
+2592 3062 3157
+3062 2184 3157
+2875 2329 2592
+2329 3062 2592
+2261 2875 2876
+2875 2592 2876
+2874 2591 2261
+2591 2875 2261
+2591 3063 2875
+3063 2329 2875
+3163 2168 2591
+2168 3063 2591
+2379 3163 2874
+3163 2591 2874
+3160 2590 2378
+2590 2877 2378
+2590 2874 2877
+2874 2261 2877
+3162 2379 2590
+2379 2874 2590
+2209 3162 3160
+3162 2590 3160
+5796 2589 3152
+5796 3152 5729
+2589 2872 2374
+2589 2374 3152
+2873 2260 2872
+2873 2872 2589
+5761 2873 2589
+5761 2589 5796
+2872 2588 3153
+2872 3153 2374
+2588 3161 3153
+3161 2208 3153
+2871 2378 3161
+2871 3161 2588
+2260 2871 2588
+2260 2588 2872
+2870 2587 2871
+2870 2871 2260
+2587 3160 2378
+2587 2378 2871
+3159 2209 2587
+2209 3160 2587
+2377 3159 2587
+2377 2587 2870
+5797 2586 2873
+5797 2873 5761
+2586 2870 2260
+2586 2260 2873
+3158 2377 2870
+3158 2870 2586
+5732 3158 2586
+5732 2586 5797
+3155 2585 2206
+2585 3150 2206
+2585 2868 3150
+2868 2373 3150
+2869 2259 2585
+2259 2868 2585
+2375 2869 3155
+2869 2585 3155
+2868 2584 2373
+2584 3151 2373
+2584 3058 3151
+3058 2181 3151
+2867 2327 2584
+2327 3058 2584
+2259 2867 2868
+2867 2584 2868
+2866 2583 2259
+2583 2867 2259
+2583 3059 2867
+3059 2327 2867
+3157 2184 2583
+2184 3059 2583
+2376 3157 2866
+3157 2583 2866
+3154 2582 2375
+2582 2869 2375
+2582 2866 2869
+2866 2259 2869
+3156 2376 2582
+2376 2866 2582
+2208 3156 3154
+3156 2582 3154
+5798 2581 5728
+2581 3146 5728
+2581 2864 3146
+2864 2371 3146
+2865 2258 2581
+2258 2864 2581
+5762 2865 2581
+5762 2581 5798
+2864 2580 2371
+2580 3147 2371
+2580 3155 3147
+3155 2206 3147
+2863 2375 2580
+2375 3155 2580
+2258 2863 2864
+2863 2580 2864
+2862 2579 2258
+2579 2863 2258
+2579 3154 2863
+3154 2375 2863
+3153 2208 2579
+2208 3154 2579
+2374 3153 2579
+2374 2579 2862
+5799 2578 2865
+5799 2865 5762
+2578 2862 2258
+2578 2258 2865
+3152 2374 2862
+3152 2862 2578
+5729 3152 2578
+5729 2578 5799
+3149 2577 2207
+2577 3142 2207
+2577 2860 3142
+2860 2369 3142
+2861 2257 2577
+2257 2860 2577
+2372 2861 3149
+2861 2577 3149
+2860 2576 2369
+2576 3143 2369
+2576 3054 3143
+3054 2175 3143
+2859 2325 2576
+2325 3054 2576
+2257 2859 2860
+2859 2576 2860
+2858 2575 2257
+2575 2859 2257
+2575 3055 2859
+3055 2325 2859
+3151 2181 2575
+2181 3055 2575
+2373 3151 2858
+3151 2575 2858
+3148 2574 2372
+2574 2861 2372
+2574 2858 2861
+2858 2257 2861
+3150 2373 2574
+2373 2858 2574
+2206 3150 3148
+3150 2574 3148
+5800 2573 5730
+2573 3136 5730
+2573 2856 3136
+2856 2366 3136
+2857 2256 2573
+2256 2856 2573
+5763 2857 5800
+2857 2573 5800
+2856 2572 2366
+2572 3137 2366
+2572 3149 3137
+3149 2207 3137
+2855 2372 2572
+2372 3149 2572
+2256 2855 2856
+2855 2572 2856
+2854 2571 2256
+2571 2855 2256
+2571 3148 2855
+3148 2372 2855
+3147 2206 2571
+2206 3148 2571
+2371 3147 2854
+3147 2571 2854
+5801 2570 5763
+2570 2857 5763
+2570 2854 2857
+2854 2256 2857
+3146 2371 2570
+2371 2854 2570
+5728 3146 5801
+3146 2570 5801
+3139 2569 2205
+2569 3145 2205
+2569 2852 3145
+2852 2370 3145
+2853 2255 2569
+2255 2852 2569
+2367 2853 3139
+2853 2569 3139
+2852 2568 2370
+2568 3144 2370
+2568 3050 3144
+3050 2166 3144
+2851 2323 2568
+2323 3050 2568
+2255 2851 2852
+2851 2568 2852
+2850 2567 2255
+2567 2851 2255
+2567 3051 2851
+3051 2323 2851
+3143 2175 2567
+2175 3051 2567
+2369 3143 2850
+3143 2567 2850
+3138 2566 2367
+2566 2853 2367
+2566 2850 2853
+2850 2255 2853
+3142 2369 2566
+2369 2850 2566
+2207 3142 3138
+3142 2566 3138
+5802 2565 5731
+2565 3141 5731
+2565 2848 3141
+2848 2368 3141
+2849 2254 2565
+2254 2848 2565
+5764 2849 5802
+2849 2565 5802
+2848 2564 2368
+2564 3140 2368
+2564 3139 3140
+3139 2205 3140
+2847 2367 2564
+2367 3139 2564
+2254 2847 2848
+2847 2564 2848
+2846 2563 2254
+2563 2847 2254
+2563 3138 2847
+3138 2367 2847
+3137 2207 2563
+2207 3138 2563
+2366 3137 2846
+3137 2563 2846
+5803 2562 5764
+2562 2849 5764
+2562 2846 2849
+2846 2254 2849
+3136 2366 2562
+2366 2846 2562
+5730 3136 5803
+3136 2562 5803
+3129 2561 2203
+2561 3135 2203
+2561 2844 2365
+2561 2365 3135
+2845 2253 2844
+2845 2844 2561
+2362 2845 3129
+2845 2561 3129
+2844 2560 3134
+2844 3134 2365
+2560 3048 2186
+2560 2186 3134
+2843 2322 3048
+2843 3048 2560
+2253 2843 2560
+2253 2560 2844
+2842 2559 2843
+2842 2843 2253
+2559 3049 2322
+2559 2322 2843
+3133 2166 3049
+3133 3049 2559
+2364 3133 2559
+2364 2559 2842
+3128 2558 2362
+2558 2845 2362
+2558 2842 2253
+2558 2253 2845
+3132 2364 2842
+3132 2842 2558
+2204 3132 3128
+3132 2558 3128
+5684 2557 5661
+2557 3131 5661
+2557 2840 3131
+2840 2363 3131
+2841 2252 2557
+2252 2840 2557
+5669 2841 5684
+2841 2557 5684
+2840 2556 2363
+2556 3130 2363
+2556 3129 3130
+3129 2203 3130
+2839 2362 2556
+2362 3129 2556
+2252 2839 2840
+2839 2556 2840
+2838 2555 2252
+2555 2839 2252
+2555 3128 2839
+3128 2362 2839
+3127 2204 2555
+2204 3128 2555
+2361 3127 2838
+3127 2555 2838
+5685 2554 5669
+2554 2841 5669
+2554 2838 2841
+2838 2252 2841
+3126 2361 2554
+2361 2838 2554
+5655 3126 5685
+3126 2554 5685
+3124 2553 3122
+3124 3122 2202
+2553 2836 2359
+2553 2359 3122
+2837 2251 2836
+2837 2836 2553
+2360 2837 2553
+2360 2553 3124
+2836 2552 3123
+2836 3123 2359
+2552 3010 2178
+2552 2178 3123
+2835 2303 2552
+2303 3010 2552
+2251 2835 2552
+2251 2552 2836
+2834 2551 2835
+2834 2835 2251
+2551 3011 2303
+2551 2303 2835
+3046 2187 3011
+3046 3011 2551
+2321 3046 2551
+2321 2551 2834
+3125 2550 2837
+3125 2837 2360
+2550 2834 2251
+2550 2251 2837
+3047 2321 2834
+3047 2834 2550
+2186 3047 2550
+2186 2550 3125
+3113 2549 3123
+3113 3123 2178
+2549 2832 2359
+2549 2359 3123
+2833 2250 2832
+2833 2832 2549
+2354 2833 2549
+2354 2549 3113
+2832 2548 3122
+2832 3122 2359
+2548 3121 2202
+2548 2202 3122
+2831 2358 3121
+2831 3121 2548
+2250 2831 2548
+2250 2548 2832
+2830 2547 2831
+2830 2831 2250
+2547 3120 2358
+2547 2358 2831
+3118 2201 3120
+3118 3120 2547
+2357 3118 2547
+2357 2547 2830
+3112 2546 2833
+3112 2833 2354
+2546 2830 2250
+2546 2250 2833
+3119 2357 2830
+3119 2830 2546
+2199 3119 2546
+2199 2546 3112
+2987 2545 2177
+2545 3114 2177
+2545 2828 3114
+2828 2355 3114
+2829 2249 2545
+2249 2828 2545
+2291 2829 2987
+2829 2545 2987
+2828 2544 2355
+2544 3115 2355
+2544 3119 3115
+3119 2199 3115
+2827 2357 2544
+2357 3119 2544
+2249 2827 2828
+2827 2544 2828
+2826 2543 2249
+2543 2827 2249
+2543 3118 2827
+3118 2357 2827
+3117 2201 2543
+2201 3118 2543
+2356 3117 2826
+3117 2543 2826
+2986 2542 2291
+2542 2829 2291
+2542 2826 2829
+2826 2249 2829
+3116 2356 2542
+2356 2826 2542
+2174 3116 2986
+3116 2542 2986
+3111 2541 2199
+2541 3115 2199
+2541 2824 3115
+2824 2355 3115
+2825 2248 2541
+2248 2824 2541
+2353 2825 3111
+2825 2541 3111
+2824 2540 2355
+2540 3114 2355
+2540 2994 3114
+2994 2177 3114
+2823 2295 2540
+2295 2994 2540
+2248 2823 2824
+2823 2540 2824
+2822 2539 2248
+2539 2823 2248
+2539 2995 2823
+2995 2295 2823
+3104 2169 2539
+2169 2995 2539
+2350 3104 2822
+3104 2539 2822
+3110 2538 2353
+2538 2825 2353
+2538 2822 2825
+2822 2248 2825
+3105 2350 2538
+2350 2822 2538
+2197 3105 3110
+3105 2538 3110
+3017 2537 2178
+2537 3113 2178
+2537 2820 3113
+2820 2354 3113
+2821 2247 2537
+2247 2820 2537
+2306 2821 3017
+2821 2537 3017
+2820 2536 2354
+2536 3112 2354
+2536 3111 3112
+3111 2199 3112
+2819 2353 2536
+2353 3111 2536
+2247 2819 2820
+2819 2536 2820
+2818 2535 2247
+2535 2819 2247
+2535 3110 2819
+3110 2353 2819
+3100 2197 2535
+2197 3110 2535
+2348 3100 2818
+3100 2535 2818
+3016 2534 2306
+2534 2821 2306
+2534 2818 2821
+2818 2247 2821
+3101 2348 2534
+2348 2818 2534
+2185 3101 3016
+3101 2534 3016
+3033 2533 2183
+2533 3096 2183
+2533 2816 3096
+2816 2346 3096
+2817 2246 2533
+2246 2816 2533
+2314 2817 3033
+2817 2533 3033
+2816 2532 2346
+2532 3097 2346
+2532 3109 3097
+3109 2198 3097
+2815 2352 2532
+2352 3109 2532
+2246 2815 2816
+2815 2532 2816
+2814 2531 2246
+2531 2815 2246
+2531 3108 2815
+3108 2352 2815
+3107 2200 2531
+2200 3108 2531
+2351 3107 2814
+3107 2531 2814
+3032 2530 2314
+2530 2817 2314
+2530 2814 2817
+2814 2246 2817
+3106 2351 2530
+2351 2814 2530
+2182 3106 3032
+3106 2530 3032
+3099 2529 2197
+2529 3105 2197
+2529 2812 3105
+2812 2350 3105
+2813 2245 2529
+2245 2812 2529
+2347 2813 3099
+2813 2529 3099
+2812 2528 2350
+2528 3104 2350
+2528 2978 3104
+2978 2169 3104
+2811 2287 2528
+2287 2978 2528
+2245 2811 2812
+2811 2528 2812
+2810 2527 2245
+2527 2811 2245
+2527 2979 2811
+2979 2287 2811
+3103 2180 2527
+2180 2979 2527
+2349 3103 2810
+3103 2527 2810
+3098 2526 2347
+2526 2813 2347
+2526 2810 2813
+2810 2245 2813
+3102 2349 2526
+2349 2810 2526
+2198 3102 3098
+3102 2526 3098
+3027 2525 2185
+2525 3101 2185
+2525 2808 3101
+2808 2348 3101
+2809 2244 2525
+2244 2808 2525
+2311 2809 3027
+2809 2525 3027
+2808 2524 2348
+2524 3100 2348
+2524 3099 3100
+3099 2197 3100
+2807 2347 2524
+2347 3099 2524
+2244 2807 2808
+2807 2524 2808
+2806 2523 2244
+2523 2807 2244
+2523 3098 2807
+3098 2347 2807
+3097 2198 2523
+2198 3098 2523
+2346 3097 2806
+3097 2523 2806
+3026 2522 2311
+2522 2809 2311
+2522 2806 2809
+2806 2244 2809
+3096 2346 2522
+2346 2806 2522
+2183 3096 3026
+3096 2522 3026
+3095 2521 2196
+2521 3090 2196
+2521 2804 3090
+2804 2343 3090
+2805 2243 2521
+2243 2804 2521
+2345 2805 3095
+2805 2521 3095
+2804 2520 2343
+2520 3091 2343
+2520 5791 3091
+5791 5743 3091
+2803 5758 2520
+5758 5791 2520
+2243 2803 2804
+2803 2520 2804
+2802 2519 2243
+2519 2803 2243
+2519 5790 5758
+2519 5758 2803
+3082 5744 5790
+3082 5790 2519
+2339 3082 2802
+3082 2519 2802
+3094 2518 2345
+2518 2805 2345
+2518 2802 2805
+2802 2243 2805
+3083 2339 2518
+2339 2802 2518
+2193 3083 3094
+3083 2518 3094
+5716 2517 5701
+2517 3084 5701
+2517 2800 3084
+2800 2340 3084
+2801 2242 2517
+2242 2800 2517
+5705 2801 5716
+2801 2517 5716
+2800 2516 2340
+2516 3085 2340
+2516 3095 3085
+3095 2196 3085
+2799 2345 2516
+2345 3095 2516
+2242 2799 2800
+2799 2516 2800
+2798 2515 2242
+2515 2799 2242
+2515 3094 2799
+3094 2345 2799
+3080 2193 2515
+2193 3094 2515
+2338 3080 2798
+3080 2515 2798
+5717 2514 5705
+2514 2801 5705
+2514 2798 2801
+2798 2242 2801
+3081 2338 2514
+2338 2798 2514
+5695 3081 5717
+3081 2514 5717
+3087 2513 2194
+2513 3093 2194
+2513 2796 3093
+2796 2344 3093
+2797 2241 2513
+2241 2796 2513
+2341 2797 3087
+2797 2513 3087
+2796 2512 2344
+2512 3092 2344
+2512 5789 3092
+5789 5741 3092
+2795 5757 2512
+5757 5789 2512
+2241 2795 2796
+2795 2512 2796
+2794 2511 2241
+2511 2795 2241
+2511 5788 2795
+5788 5757 2795
+3091 5743 2511
+5743 5788 2511
+2343 3091 2794
+3091 2511 2794
+3086 2510 2341
+2510 2797 2341
+2510 2794 2797
+2794 2241 2797
+3090 2343 2510
+2343 2794 2510
+2196 3090 3086
+3090 2510 3086
+5714 2509 5696
+2509 3089 5696
+2509 2792 3089
+2792 2342 3089
+2793 2240 2509
+2240 2792 2509
+5704 2793 5714
+2793 2509 5714
+2792 2508 2342
+2508 3088 2342
+2508 3087 3088
+3087 2194 3088
+2791 2341 2508
+2341 3087 2508
+2240 2791 2792
+2791 2508 2792
+2790 2507 2240
+2507 2791 2240
+2507 3086 2791
+3086 2341 2791
+3085 2196 2507
+2196 3086 2507
+2340 3085 2790
+3085 2507 2790
+5715 2506 5704
+2506 2793 5704
+2506 2790 2793
+2790 2240 2793
+3084 2340 2506
+2340 2790 2506
+5701 3084 5715
+3084 2506 5715
+3079 2505 2193
+2505 3083 2193
+2505 2788 3083
+2788 2339 3083
+2789 2239 2505
+2239 2788 2505
+2337 2789 3079
+2789 2505 3079
+2788 2504 2339
+2504 3082 2339
+2504 3022 3082
+3022 5744 3082
+2787 2309 2504
+2309 3022 2504
+2239 2787 2788
+2787 2504 2788
+2786 2503 2239
+2503 2787 2239
+2503 3023 2787
+3023 2309 2787
+3068 2171 2503
+2171 3023 2503
+2332 3068 2786
+3068 2503 2786
+3078 2502 2337
+2502 2789 2337
+2502 2786 2789
+2786 2239 2789
+3069 2332 2502
+2332 2786 2502
+2192 3069 2502
+2192 2502 3078
+5712 2501 5695
+2501 3081 5695
+2501 2784 3081
+2784 2338 3081
+2785 2238 2501
+2238 2784 2501
+5703 2785 5712
+2785 2501 5712
+2784 2500 2338
+2500 3080 2338
+2500 3079 3080
+3079 2193 3080
+2783 2337 2500
+2337 3079 2500
+2238 2783 2784
+2783 2500 2784
+2782 2499 2783
+2782 2783 2238
+2499 3078 2337
+2499 2337 2783
+3074 2192 3078
+3074 3078 2499
+2335 3074 2499
+2335 2499 2782
+5713 2498 5703
+2498 2785 5703
+2498 2782 2785
+2782 2238 2785
+3075 2335 2782
+3075 2782 2498
+5700 3075 5713
+3075 2498 5713
+3071 2497 3077
+3071 3077 2195
+2497 2780 2336
+2497 2336 3077
+2781 2237 2780
+2781 2780 2497
+2333 2781 2497
+2333 2497 3071
+2780 2496 3076
+2780 3076 2336
+2496 5711 5694
+2496 5694 3076
+2779 5702 5711
+2779 5711 2496
+2237 2779 2496
+2237 2496 2780
+2778 2495 2779
+2778 2779 2237
+2495 5710 5702
+2495 5702 2779
+3075 5700 5710
+3075 5710 2495
+2335 3075 2495
+2335 2495 2778
+3070 2494 2781
+3070 2781 2333
+2494 2778 2237
+2494 2237 2781
+3074 2335 2778
+3074 2778 2494
+2192 3074 2494
+2192 2494 3070
+2993 2493 3073
+2993 3073 2174
+2493 2776 2334
+2493 2334 3073
+2777 2236 2776
+2777 2776 2493
+2294 2777 2493
+2294 2493 2993
+2776 2492 3072
+2776 3072 2334
+2492 3071 2195
+2492 2195 3072
+2775 2333 3071
+2775 3071 2492
+2236 2775 2492
+2236 2492 2776
+2774 2491 2775
+2774 2775 2236
+2491 3070 2333
+2491 2333 2775
+3069 2192 3070
+3069 3070 2491
+2332 3069 2491
+2332 2491 2774
+2992 2490 2294
+2490 2777 2294
+2490 2774 2236
+2490 2236 2777
+3068 2332 2490
+2332 2774 2490
+2171 3068 2992
+3068 2490 2992
+3065 2489 5745
+2489 5783 5745
+2489 2772 5783
+2772 5754 5783
+2773 2235 2489
+2235 2772 2489
+2330 2773 3065
+2773 2489 3065
+2772 2488 5754
+2488 5782 5754
+2488 3000 5782
+3000 5727 5782
+2771 2298 2488
+2298 3000 2488
+2235 2771 2772
+2771 2488 2772
+2770 2487 2235
+2487 2771 2235
+2487 3001 2771
+3001 2298 2771
+5683 5657 2487
+5657 3001 2487
+5668 5683 2770
+5683 2487 2770
+3064 2486 2330
+2486 2773 2330
+2486 2770 2773
+2770 2235 2773
+5682 5668 2486
+5668 2770 2486
+5662 5682 3064
+5682 2486 3064
+3066 2485 5781
+3066 5781 5726
+2485 2768 5753
+2485 5753 5781
+2769 2234 2768
+2769 2768 2485
+2331 2769 3066
+2769 2485 3066
+2768 2484 5780
+2768 5780 5753
+2484 3065 5745
+2484 5745 5780
+2767 2330 2484
+2330 3065 2484
+2234 2767 2484
+2234 2484 2768
+2766 2483 2234
+2483 2767 2234
+2483 3064 2767
+3064 2330 2767
+5681 5662 2483
+5662 3064 2483
+5667 5681 2766
+5681 2483 2766
+3067 2482 2331
+2482 2769 2331
+2482 2766 2769
+2766 2234 2769
+5680 5667 2482
+5667 2766 2482
+5656 5680 3067
+5680 2482 3067
+3062 2481 2184
+2481 3056 2184
+2481 2764 3056
+2764 2326 3056
+2765 2233 2481
+2233 2764 2481
+2329 2765 3062
+2765 2481 3062
+2764 2480 2326
+2480 3057 2326
+2480 3034 3057
+3034 2188 3057
+2763 2315 2480
+2315 3034 2480
+2233 2763 2764
+2763 2480 2764
+2762 2479 2763
+2762 2763 2233
+2479 3035 2315
+2479 2315 2763
+3061 2189 3035
+3061 3035 2479
+2328 3061 2479
+2328 2479 2762
+3063 2478 2329
+2478 2765 2329
+2478 2762 2765
+2762 2233 2765
+3060 2328 2762
+3060 2762 2478
+2168 3060 2478
+2168 2478 3063
+3058 2477 2181
+2477 3052 2181
+2477 2760 3052
+2760 2324 3052
+2761 2232 2477
+2232 2760 2477
+2327 2761 3058
+2761 2477 3058
+2760 2476 2324
+2476 3053 2324
+2476 3028 3053
+3028 2190 3053
+2759 2312 2476
+2312 3028 2476
+2232 2759 2760
+2759 2476 2760
+2758 2475 2232
+2475 2759 2232
+2475 3029 2759
+3029 2312 2759
+3057 2188 2475
+2188 3029 2475
+2326 3057 2758
+3057 2475 2758
+3059 2474 2327
+2474 2761 2327
+2474 2758 2761
+2758 2232 2761
+3056 2326 2474
+2326 2758 2474
+2184 3056 3059
+3056 2474 3059
+3054 2473 2175
+2473 3044 2175
+2473 2756 3044
+2756 2320 3044
+2757 2231 2473
+2231 2756 2473
+2325 2757 3054
+2757 2473 3054
+2756 2472 2320
+2472 3045 2320
+2472 3012 3045
+3012 2187 3045
+2755 2304 2472
+2304 3012 2472
+2231 2755 2756
+2755 2472 2756
+2754 2471 2231
+2471 2755 2231
+2471 3013 2755
+3013 2304 2755
+3053 2190 2471
+2190 3013 2471
+2324 3053 2754
+3053 2471 2754
+3055 2470 2325
+2470 2757 2325
+2470 2754 2757
+2754 2231 2757
+3052 2324 2470
+2324 2754 2470
+2181 3052 3055
+3052 2470 3055
+3050 2469 2166
+2469 3049 2166
+2469 2752 3049
+2752 2322 3049
+2753 2230 2469
+2230 2752 2469
+2323 2753 3050
+2753 2469 3050
+2752 2468 2322
+2468 3048 2322
+2468 3047 3048
+3047 2186 3048
+2751 2321 2468
+2321 3047 2468
+2230 2751 2752
+2751 2468 2752
+2750 2467 2230
+2467 2751 2230
+2467 3046 2751
+3046 2321 2751
+3045 2187 2467
+2187 3046 2467
+2320 3045 2750
+3045 2467 2750
+3051 2466 2323
+2466 2753 2323
+2466 2750 2753
+2750 2230 2753
+3044 2320 2466
+2320 2750 2466
+2175 3044 3051
+3044 2466 3051
+3003 2465 3043
+3003 3043 5734
+2465 2748 3043
+2748 2319 3043
+2749 2229 2465
+2229 2748 2465
+2299 2749 3003
+2749 2465 3003
+2748 2464 2319
+2464 3042 2319
+2464 3041 3042
+3041 2173 3042
+2747 2318 2464
+2318 3041 2464
+2229 2747 2748
+2747 2464 2748
+2746 2463 2229
+2463 2747 2229
+2463 3040 2747
+3040 2318 2747
+5679 5660 2463
+5660 3040 2463
+5666 5679 2746
+5679 2463 2746
+3002 2462 2299
+2462 2749 2299
+2462 2746 2749
+2746 2229 2749
+5678 5666 2462
+5666 2746 2462
+5654 5678 3002
+5678 2462 3002
+5778 2461 3036
+5778 3036 5740
+2461 2744 2316
+2461 2316 3036
+2745 2228 2744
+2745 2744 2461
+5752 2745 2461
+5752 2461 5778
+2744 2460 3037
+2744 3037 2316
+2460 2982 2179
+2460 2179 3037
+2743 2289 2982
+2743 2982 2460
+2228 2743 2460
+2228 2460 2744
+2742 2459 2743
+2742 2743 2228
+2459 2983 2289
+2459 2289 2743
+3020 2167 2983
+3020 2983 2459
+2308 3020 2459
+2308 2459 2742
+5779 2458 2745
+5779 2745 5752
+2458 2742 2228
+2458 2228 2745
+3021 2308 2742
+3021 2742 2458
+5736 3021 2458
+5736 2458 5779
+3038 2457 3037
+3038 3037 2179
+2457 2740 2316
+2457 2316 3037
+2741 2227 2740
+2741 2740 2457
+2317 2741 3038
+2741 2457 3038
+2740 2456 3036
+2740 3036 2316
+2456 5777 5740
+2456 5740 3036
+2739 5751 2456
+5751 5777 2456
+2227 2739 2456
+2227 2456 2740
+2738 2455 2227
+2455 2739 2227
+2455 5776 2739
+5776 5751 2739
+3004 5735 2455
+5735 5776 2455
+2300 3004 2738
+3004 2455 2738
+3039 2454 2317
+2454 2741 2317
+2454 2738 2741
+2738 2227 2741
+3005 2300 2454
+2300 2738 2454
+2165 3005 3039
+3005 2454 3039
+3034 2453 2188
+2453 3024 2188
+2453 2736 3024
+2736 2310 3024
+2737 2226 2453
+2226 2736 2453
+2315 2737 3034
+2737 2453 3034
+2736 2452 2310
+2452 3025 2310
+2452 3033 3025
+3033 2183 3025
+2735 2314 2452
+2314 3033 2452
+2226 2735 2736
+2735 2452 2736
+2734 2451 2226
+2451 2735 2226
+2451 3032 2735
+3032 2314 2735
+3031 2182 2451
+2182 3032 2451
+2313 3031 2734
+3031 2451 2734
+3035 2450 2737
+3035 2737 2315
+2450 2734 2737
+2734 2226 2737
+3030 2313 2734
+3030 2734 2450
+2189 3030 2450
+2189 2450 3035
+3028 2449 2190
+2449 3014 2190
+2449 2732 3014
+2732 2305 3014
+2733 2225 2449
+2225 2732 2449
+2312 2733 3028
+2733 2449 3028
+2732 2448 2305
+2448 3015 2305
+2448 3027 3015
+3027 2185 3015
+2731 2311 2448
+2311 3027 2448
+2225 2731 2732
+2731 2448 2732
+2730 2447 2225
+2447 2731 2225
+2447 3026 2731
+3026 2311 2731
+3025 2183 2447
+2183 3026 2447
+2310 3025 2730
+3025 2447 2730
+3029 2446 2312
+2446 2733 2312
+2446 2730 2733
+2730 2225 2733
+3024 2310 2446
+2310 2730 2446
+2188 3024 3029
+3024 2446 3029
+5774 2445 5739
+2445 3018 5739
+2445 2728 3018
+2728 2307 3018
+2729 2224 2445
+2224 2728 2445
+5750 2729 5774
+2729 2445 5774
+2728 2444 2307
+2444 3019 2307
+2444 2990 3019
+2990 2176 3019
+2727 2293 2444
+2293 2990 2444
+2224 2727 2728
+2727 2444 2728
+2726 2443 2224
+2443 2727 2224
+2443 2991 2727
+2991 2293 2727
+3023 2171 2443
+2171 2991 2443
+2309 3023 2726
+3023 2443 2726
+5775 2442 5750
+2442 2729 5750
+2442 2726 2729
+2726 2224 2729
+3022 2309 2442
+2309 2726 2442
+5744 3022 5775
+3022 2442 5775
+5772 2441 5736
+2441 3021 5736
+2441 2724 2308
+2441 2308 3021
+2725 2223 2441
+2223 2724 2441
+5749 2725 5772
+2725 2441 5772
+2724 2440 3020
+2724 3020 2308
+2440 2996 3020
+2996 2167 3020
+2723 2296 2440
+2296 2996 2440
+2223 2723 2724
+2723 2440 2724
+2722 2439 2223
+2439 2723 2223
+2439 2997 2723
+2997 2296 2723
+3019 2176 2439
+2176 2997 2439
+2307 3019 2722
+3019 2439 2722
+5773 2438 5749
+2438 2725 5749
+2438 2722 2725
+2722 2223 2725
+3018 2307 2438
+2307 2722 2438
+5739 3018 5773
+3018 2438 5773
+3016 2437 2185
+2437 3015 2185
+2437 2720 3015
+2720 2305 3015
+2721 2222 2437
+2222 2720 2437
+2306 2721 3016
+2721 2437 3016
+2720 2436 2305
+2436 3014 2305
+2436 3013 3014
+3013 2190 3014
+2719 2304 2436
+2304 3013 2436
+2222 2719 2720
+2719 2436 2720
+2718 2435 2222
+2435 2719 2222
+2435 3012 2719
+3012 2304 2719
+3011 2187 2435
+2187 3012 2435
+2303 3011 2718
+3011 2435 2718
+3017 2434 2306
+2434 2721 2306
+2434 2718 2222
+2434 2222 2721
+3010 2303 2718
+3010 2718 2434
+2178 3010 2434
+2178 2434 3017
+5770 2433 5738
+2433 3009 5738
+2433 2716 3009
+2716 2302 3009
+2717 2221 2433
+2221 2716 2433
+5748 2717 5770
+2717 2433 5770
+2716 2432 2302
+2432 3008 2302
+2432 3007 3008
+3007 2172 3008
+2715 2301 2432
+2301 3007 2432
+2221 2715 2716
+2715 2432 2716
+2714 2431 2221
+2431 2715 2221
+2431 3006 2715
+3006 2301 2715
+3005 2165 2431
+2165 3006 2431
+2300 3005 2714
+3005 2431 2714
+5771 2430 5748
+2430 2717 5748
+2430 2714 2717
+2714 2221 2717
+3004 2300 2430
+2300 2714 2430
+5735 3004 5771
+3004 2430 5771
+5676 2429 2998
+5676 2998 5658
+2429 2712 2297
+2429 2297 2998
+2713 2220 2712
+2713 2712 2429
+5665 2713 2429
+5665 2429 5676
+2712 2428 2999
+2712 2999 2297
+2428 5769 5733
+2428 5733 2999
+2711 5747 5769
+2711 5769 2428
+2220 2711 2428
+2220 2428 2712
+2710 2427 2711
+2710 2711 2220
+2427 5768 5747
+2427 5747 2711
+3003 5734 5768
+3003 5768 2427
+2299 3003 2427
+2299 2427 2710
+5677 2426 2713
+5677 2713 5665
+2426 2710 2220
+2426 2220 2713
+3002 2299 2710
+3002 2710 2426
+5654 3002 2426
+5654 2426 5677
+3000 2425 5727
+2425 5767 5727
+2425 2708 5767
+2708 5746 5767
+2709 2219 2425
+2219 2708 2425
+2298 2709 3000
+2709 2425 3000
+2708 2424 5746
+2424 5766 5746
+2424 2999 5766
+2999 5733 5766
+2707 2297 2424
+2297 2999 2424
+2219 2707 2708
+2707 2424 2708
+2706 2423 2219
+2423 2707 2219
+2423 2998 2707
+2998 2297 2707
+5675 5658 2423
+5658 2998 2423
+5664 5675 2706
+5675 2423 2706
+3001 2422 2298
+2422 2709 2298
+2422 2706 2709
+2706 2219 2709
+5674 5664 2422
+5664 2706 2422
+5657 5674 3001
+5674 2422 3001
+2989 2421 2997
+2989 2997 2176
+2421 2704 2296
+2421 2296 2997
+2705 2218 2704
+2705 2704 2421
+2292 2705 2421
+2292 2421 2989
+2704 2420 2996
+2704 2996 2296
+2420 2984 2167
+2420 2167 2996
+2703 2290 2984
+2703 2984 2420
+2218 2703 2420
+2218 2420 2704
+2702 2419 2703
+2702 2703 2218
+2419 2985 2290
+2419 2290 2703
+2995 2169 2985
+2995 2985 2419
+2295 2995 2419
+2295 2419 2702
+2988 2418 2705
+2988 2705 2292
+2418 2702 2218
+2418 2218 2705
+2994 2295 2702
+2994 2702 2418
+2177 2994 2418
+2177 2418 2988
+2992 2417 2171
+2417 2991 2171
+2417 2700 2293
+2417 2293 2991
+2701 2217 2700
+2701 2700 2417
+2294 2701 2992
+2701 2417 2992
+2700 2416 2990
+2700 2990 2293
+2416 2989 2176
+2416 2176 2990
+2699 2292 2989
+2699 2989 2416
+2217 2699 2416
+2217 2416 2700
+2698 2415 2699
+2698 2699 2217
+2415 2988 2292
+2415 2292 2699
+2987 2177 2988
+2987 2988 2415
+2291 2987 2415
+2291 2415 2698
+2993 2414 2701
+2993 2701 2294
+2414 2698 2217
+2414 2217 2701
+2986 2291 2698
+2986 2698 2414
+2174 2986 2414
+2174 2414 2993
+2984 2413 2983
+2984 2983 2167
+2413 2696 2289
+2413 2289 2983
+2697 2216 2696
+2697 2696 2413
+2290 2697 2413
+2290 2413 2984
+2696 2412 2982
+2696 2982 2289
+2412 2981 2179
+2412 2179 2982
+2695 2288 2981
+2695 2981 2412
+2216 2695 2412
+2216 2412 2696
+2694 2411 2695
+2694 2695 2216
+2411 2980 2288
+2411 2288 2695
+2979 2180 2980
+2979 2980 2411
+2287 2979 2411
+2287 2411 2694
+2985 2410 2697
+2985 2697 2290
+2410 2694 2216
+2410 2216 2697
+2978 2287 2694
+2978 2694 2410
+2169 2978 2410
+2169 2410 2985
+5439 4401 5462
+5439 5462 3364
+4401 4972 3770
+4401 3770 5462
+4973 3525 4972
+4973 4972 4401
+3758 4973 4401
+3758 4401 5439
+4972 4400 5463
+4972 5463 3770
+4400 5450 3365
+4400 3365 5463
+4971 3764 5450
+4971 5450 4400
+3525 4971 4400
+3525 4400 4972
+4970 4399 4971
+4970 4971 3525
+4399 5451 3764
+4399 3764 4971
+5580 3265 5451
+5580 5451 4399
+3829 5580 4399
+3829 4399 4970
+5438 4398 4973
+5438 4973 3758
+4398 4970 3525
+4398 3525 4973
+5581 3829 4970
+5581 4970 4398
+3363 5581 4398
+3363 4398 5438
+5131 4397 5172
+5131 5172 3278
+4397 4968 3625
+4397 3625 5172
+4969 3524 4968
+4969 4968 4397
+3604 4969 4397
+3604 4397 5131
+4968 4396 5173
+4968 5173 3625
+4396 5432 3346
+4396 3346 5173
+4967 3755 5432
+4967 5432 4396
+3524 4967 4396
+3524 4396 4968
+4966 4395 4967
+4966 4967 3524
+4395 5433 3755
+4395 3755 4967
+5581 3363 5433
+5581 5433 4395
+3829 5581 4395
+3829 4395 4966
+5130 4394 3604
+4394 4969 3604
+4394 4966 4969
+4966 3524 4969
+5580 3829 4394
+3829 4966 4394
+3265 5580 5130
+5580 4394 5130
+5167 4393 3257
+4393 5574 3257
+4393 4964 5574
+4964 3826 5574
+4965 3523 4393
+3523 4964 4393
+3622 4965 5167
+4965 4393 5167
+4964 4392 3826
+4392 5575 3826
+4392 5578 5575
+5578 3382 5575
+4963 3828 4392
+3828 5578 4392
+3523 4963 4964
+4963 4392 4964
+4962 4391 3523
+4391 4963 3523
+4391 5579 4963
+5579 3828 4963
+5108 3267 4391
+3267 5579 4391
+3593 5108 4962
+5108 4391 4962
+5166 4390 3622
+4390 4965 3622
+4390 4962 4965
+4962 3523 4965
+5109 3593 4390
+3593 4962 4390
+3266 5109 5166
+5109 4390 5166
+5578 4389 3382
+4389 5576 3382
+4389 4960 5576
+4960 3827 5576
+4961 3522 4389
+3522 4960 4389
+3828 4961 5578
+4961 4389 5578
+4960 4388 3827
+4388 5577 3827
+4388 5472 5577
+5472 3369 5577
+4959 3775 4388
+3775 5472 4388
+3522 4959 4960
+4959 4388 4960
+4958 4387 3522
+4387 4959 3522
+4387 5473 4959
+5473 3775 4959
+5460 3367 4387
+3367 5473 4387
+3769 5460 4958
+5460 4387 4958
+5579 4386 3828
+4386 4961 3828
+4386 4958 4961
+4958 3522 4961
+5461 3769 4386
+3769 4958 4386
+3267 5461 5579
+5461 4386 5579
+5465 4385 3261
+4385 5560 3261
+4385 4956 5560
+4956 3819 5560
+4957 3521 4385
+3521 4956 4385
+3771 4957 5465
+4957 4385 5465
+4956 4384 3819
+4384 5561 3819
+4384 5577 5561
+5577 3369 5561
+4955 3827 4384
+3827 5577 4384
+3521 4955 4956
+4955 4384 4956
+4954 4383 3521
+4383 4955 3521
+4383 5576 4955
+5576 3827 4955
+5575 3382 4383
+3382 5576 4383
+3826 5575 4954
+5575 4383 4954
+5464 4382 3771
+4382 4957 3771
+4382 4954 4957
+4954 3521 4957
+5574 3826 4382
+3826 4954 4382
+3257 5574 5464
+5574 4382 5464
+5572 4381 5344
+5572 5344 3339
+4381 4952 3711
+4381 3711 5344
+4953 3520 4952
+4953 4952 4381
+3825 4953 4381
+3825 4381 5572
+4952 4380 5345
+4952 5345 3711
+4380 5540 3334
+4380 3334 5345
+4951 3809 5540
+4951 5540 4380
+3520 4951 4380
+3520 4380 4952
+4950 4379 4951
+4950 4951 3520
+4379 5541 3809
+4379 3809 4951
+5326 3328 5541
+5326 5541 4379
+3702 5326 4950
+5326 4379 4950
+5573 4378 4953
+5573 4953 3825
+4378 4950 3520
+4378 3520 4953
+5327 3702 4378
+3702 4950 4378
+3327 5327 5573
+5327 4378 5573
+5570 4377 5534
+5570 5534 3380
+4377 4948 3806
+4377 3806 5534
+4949 3519 4948
+4949 4948 4377
+3824 4949 4377
+3824 4377 5570
+4948 4376 5535
+4948 5535 3806
+4376 5568 3381
+4376 3381 5535
+4947 3823 5568
+4947 5568 4376
+3519 4947 4376
+3519 4376 4948
+4946 4375 4947
+4946 4947 3519
+4375 5569 3823
+4375 3823 4947
+5320 3324 5569
+5320 5569 4375
+3699 5320 4375
+3699 4375 4946
+5571 4374 4949
+5571 4949 3824
+4374 4946 3519
+4374 3519 4949
+5321 3699 4946
+5321 4946 4374
+3322 5321 4374
+3322 4374 5571
+5568 4373 5536
+5568 5536 3381
+4373 4944 3807
+4373 3807 5536
+4945 3518 4944
+4945 4944 4373
+3823 4945 4373
+3823 4373 5568
+4944 4372 5537
+4944 5537 3807
+4372 5492 3374
+4372 3374 5537
+4943 3785 5492
+4943 5492 4372
+3518 4943 4372
+3518 4372 4944
+4942 4371 4943
+4942 4943 3518
+4371 5493 3785
+4371 3785 4943
+5566 3345 5493
+5566 5493 4371
+3822 5566 4371
+3822 4371 4942
+5569 4370 4945
+5569 4945 3823
+4370 4942 3518
+4370 3518 4945
+5567 3822 4370
+3822 4942 4370
+3324 5567 5569
+5567 4370 5569
+5566 4369 3345
+4369 5116 3345
+4369 4940 5116
+4940 3597 5116
+4941 3517 4369
+3517 4940 4369
+3822 4941 5566
+4941 4369 5566
+4940 4368 3597
+4368 5117 3597
+4368 5564 3337
+4368 3337 5117
+4939 3821 5564
+4939 5564 4368
+3517 4939 4368
+3517 4368 4940
+4938 4367 4939
+4938 4939 3517
+4367 5565 3821
+4367 3821 4939
+5312 3325 5565
+5312 5565 4367
+3695 5312 4367
+3695 4367 4938
+5567 4366 3822
+4366 4941 3822
+4366 4938 4941
+4938 3517 4941
+5313 3695 4938
+5313 4938 4366
+3324 5313 4366
+3324 4366 5567
+5317 4365 3325
+4365 5565 3325
+4365 4936 5565
+4936 3821 5565
+4937 3516 4365
+3516 4936 4365
+3697 4937 5317
+4937 4365 5317
+4936 4364 3821
+4364 5564 3821
+4364 5348 5564
+5348 3337 5564
+4935 3713 4364
+3713 5348 4364
+3516 4935 4936
+4935 4364 4936
+4934 4363 3516
+4363 4935 3516
+4363 5349 4935
+5349 3713 4935
+5563 3331 5349
+5563 5349 4363
+3820 5563 4934
+5563 4363 4934
+5316 4362 3697
+4362 4937 3697
+4362 4934 4937
+4934 3516 4937
+5562 3820 4362
+3820 4934 4362
+3323 5562 5316
+5562 4362 5316
+5559 4361 3378
+4361 5524 3378
+4361 4932 5524
+4932 3801 5524
+4933 3515 4361
+3515 4932 4361
+3818 4933 5559
+4933 4361 5559
+4932 4360 3801
+4360 5525 3801
+4360 5470 3269
+4360 3269 5525
+4931 3774 5470
+4931 5470 4360
+3515 4931 4932
+4931 4360 4932
+4930 4359 3515
+4359 4931 3515
+4359 5471 3774
+4359 3774 4931
+5561 3369 4359
+3369 5471 4359
+3819 5561 4930
+5561 4359 4930
+5558 4358 3818
+4358 4933 3818
+4358 4930 4933
+4930 3515 4933
+5560 3819 4358
+3819 4930 4358
+3261 5560 5558
+5560 4358 5558
+5467 4357 5556
+5467 5556 3368
+4357 4928 3817
+4357 3817 5556
+4929 3514 4928
+4929 4928 4357
+3772 4929 4357
+3772 4357 5467
+4928 4356 5557
+4928 5557 3817
+4356 5528 3284
+4356 3284 5557
+4927 3803 5528
+4927 5528 4356
+3514 4927 4356
+3514 4356 4928
+4926 4355 4927
+4926 4927 3514
+4355 5529 3803
+4355 3803 4927
+5559 3378 5529
+5559 5529 4355
+3818 5559 4355
+3818 4355 4926
+5466 4354 4929
+5466 4929 3772
+4354 4926 3514
+4354 3514 4929
+5558 3818 4926
+5558 4926 4354
+3261 5558 4354
+3261 4354 5466
+5556 4353 3368
+4353 5474 3368
+4353 4924 5474
+4924 3776 5474
+4925 3513 4353
+3513 4924 4353
+3817 4925 5556
+4925 4353 5556
+4924 4352 3776
+4352 5475 3776
+4352 5482 5475
+5482 3370 5475
+4923 3780 4352
+3780 5482 4352
+3513 4923 4924
+4923 4352 4924
+4922 4351 3513
+4351 4923 3513
+4351 5483 4923
+5483 3780 4923
+5554 3371 4351
+3371 5483 4351
+3816 5554 4922
+5554 4351 4922
+5557 4350 3817
+4350 4925 3817
+4350 4922 4925
+4922 3513 4925
+5555 3816 4350
+3816 4922 4350
+3284 5555 5557
+5555 4350 5557
+5191 4349 3285
+4349 5526 3285
+4349 4920 5526
+4920 3802 5526
+4921 3512 4349
+3512 4920 4349
+3634 4921 5191
+4921 4349 5191
+4920 4348 5527
+4920 5527 3802
+4348 5555 3284
+4348 3284 5527
+4919 3816 5555
+4919 5555 4348
+3512 4919 4920
+4919 4348 4920
+4918 4347 3512
+4347 4919 3512
+4347 5554 3816
+4347 3816 4919
+5552 3371 5554
+5552 5554 4347
+3815 5552 4918
+5552 4347 4918
+5190 4346 3634
+4346 4921 3634
+4346 4918 4921
+4918 3512 4921
+5553 3815 4346
+3815 4918 4346
+3248 5553 5190
+5553 4346 5190
+5552 4345 3371
+4345 5484 3371
+4345 4916 5484
+4916 3781 5484
+4917 3511 4345
+3511 4916 4345
+3815 4917 5552
+4917 4345 5552
+4916 4344 3781
+4344 5485 3781
+4344 5550 5485
+5550 3251 5485
+4915 3814 4344
+3814 5550 4344
+3511 4915 4916
+4915 4344 4916
+4914 4343 3511
+4343 4915 3511
+4343 5551 4915
+5551 3814 4915
+5056 3249 4343
+3249 5551 4343
+3567 5056 4914
+5056 4343 4914
+5553 4342 4917
+5553 4917 3815
+4342 4914 4917
+4914 3511 4917
+5057 3567 4342
+3567 4914 4342
+3248 5057 4342
+3248 4342 5553
+5550 4341 3251
+4341 5486 3251
+4341 4912 5486
+4912 3782 5486
+4913 3510 4341
+3510 4912 4341
+3814 4913 5550
+4913 4341 5550
+4912 4340 3782
+4340 5487 3782
+4340 5548 3250
+4340 3250 5487
+4911 3813 4340
+3813 5548 4340
+3510 4911 4912
+4911 4340 4912
+4910 4339 3510
+4339 4911 3510
+4339 5549 4911
+5549 3813 4911
+5064 3252 4339
+3252 5549 4339
+3571 5064 4910
+5064 4339 4910
+5551 4338 3814
+4338 4913 3814
+4338 4910 4913
+4910 3510 4913
+5065 3571 4338
+3571 4910 4338
+3249 5065 5551
+5065 4338 5551
+5547 4337 5060
+5547 5060 3247
+4337 4908 3569
+4337 3569 5060
+4909 3509 4908
+4909 4908 4337
+3812 4909 4337
+3812 4337 5547
+4908 4336 5061
+4908 5061 3569
+4336 5549 3252
+4336 3252 5061
+4907 3813 5549
+4907 5549 4336
+3509 4907 4336
+3509 4336 4908
+4906 4335 4907
+4906 4907 3509
+4335 5548 3813
+4335 3813 4907
+5480 3250 5548
+5480 5548 4335
+3779 5480 4335
+3779 4335 4906
+5546 4334 4909
+5546 4909 3812
+4334 4906 3509
+4334 3509 4909
+5481 3779 4906
+5481 4906 4334
+3243 5481 4334
+3243 4334 5546
+5545 4333 5048
+5545 5048 3240
+4333 4904 3563
+4333 3563 5048
+4905 3508 4904
+4905 4904 4333
+3811 4905 5545
+4905 4333 5545
+4904 4332 5049
+4904 5049 3563
+4332 5547 3247
+4332 3247 5049
+4903 3812 5547
+4903 5547 4332
+3508 4903 4332
+3508 4332 4904
+4902 4331 4903
+4902 4903 3508
+4331 5546 3812
+4331 3812 4903
+5086 3243 5546
+5086 5546 4331
+3582 5086 4331
+3582 4331 4902
+5544 4330 4905
+5544 4905 3811
+4330 4902 3508
+4330 3508 4905
+5087 3582 4902
+5087 4902 4330
+3234 5087 4330
+3234 4330 5544
+5543 4329 5020
+5543 5020 3238
+4329 4900 5020
+4900 3549 5020
+4901 3507 4329
+3507 4900 4329
+3810 4901 5543
+4901 4329 5543
+4900 4328 3549
+4328 5021 3549
+4328 5545 5021
+5545 3240 5021
+4899 3811 4328
+3811 5545 4328
+3507 4899 4900
+4899 4328 4900
+4898 4327 3507
+4327 4899 3507
+4327 5544 4899
+5544 3811 4899
+5090 3234 5544
+5090 5544 4327
+3584 5090 4327
+3584 4327 4898
+5542 4326 4901
+5542 4901 3810
+4326 4898 3507
+4326 3507 4901
+5091 3584 4898
+5091 4898 4326
+3225 5091 4326
+3225 4326 5542
+5073 4325 3232
+4325 5538 3232
+4325 4896 5538
+4896 3808 5538
+4897 3506 4325
+3506 4896 4325
+3575 4897 5073
+4897 4325 5073
+4896 4324 3808
+4324 5539 3808
+4324 5016 5539
+5016 3239 5539
+4895 3547 4324
+3547 5016 4324
+3506 4895 4896
+4895 4324 4896
+4894 4323 3506
+4323 4895 3506
+4323 5017 4895
+5017 3547 4895
+5543 3238 4323
+3238 5017 4323
+3810 5543 4894
+5543 4323 4894
+5072 4322 3575
+4322 4897 3575
+4322 4894 4897
+4894 3506 4897
+5542 3810 4322
+3810 4894 4322
+3225 5542 5072
+5542 4322 5072
+5079 4321 5541
+5079 5541 3328
+4321 4892 5541
+4892 3809 5541
+4893 3505 4321
+3505 4892 4321
+3578 4893 5079
+4893 4321 5079
+4892 4320 3809
+4320 5540 3809
+4320 5012 5540
+5012 3334 5540
+4891 3545 4320
+3545 5012 4320
+3505 4891 4892
+4891 4320 4892
+4890 4319 3505
+4319 4891 3505
+4319 5013 4891
+5013 3545 4891
+5539 3239 4319
+3239 5013 4319
+3808 5539 4890
+5539 4319 4890
+5078 4318 3578
+4318 4893 3578
+4318 4890 4893
+4890 3505 4893
+5538 3808 4318
+3808 4890 4318
+3232 5538 5078
+5538 4318 5078
+5429 4317 3342
+4317 5496 3342
+4317 4888 5496
+4888 3787 5496
+4889 3504 4317
+3504 4888 4317
+3753 4889 5429
+4889 4317 5429
+4888 4316 3787
+4316 5497 3787
+4316 5537 5497
+5537 3374 5497
+4887 3807 4316
+3807 5537 4316
+3504 4887 4888
+4887 4316 4888
+4886 4315 3504
+4315 4887 3504
+4315 5536 4887
+5536 3807 4887
+5530 3381 4315
+3381 5536 4315
+3804 5530 4886
+5530 4315 4886
+5428 4314 3753
+4314 4889 3753
+4314 4886 4889
+4886 3504 4889
+5531 3804 4314
+3804 4886 4314
+3361 5531 5428
+5531 4314 5428
+5534 4313 3380
+4313 5533 3380
+4313 4884 3805
+4313 3805 5533
+4885 3503 4884
+4885 4884 4313
+3806 4885 5534
+4885 4313 5534
+4884 4312 5532
+4884 5532 3805
+4312 5420 3341
+4312 3341 5532
+4883 3749 5420
+4883 5420 4312
+3503 4883 4312
+3503 4312 4884
+4882 4311 4883
+4882 4883 3503
+4311 5421 3749
+4311 3749 4883
+5531 3361 5421
+5531 5421 4311
+3804 5531 4311
+3804 4311 4882
+5535 4310 3806
+4310 4885 3806
+4310 4882 3503
+4310 3503 4885
+5530 3804 4310
+3804 4882 4310
+3381 5530 5535
+5530 4310 5535
+5523 4309 3378
+4309 5529 3378
+4309 4880 5529
+4880 3803 5529
+4881 3502 4309
+3502 4880 4309
+3800 4881 5523
+4881 4309 5523
+4880 4308 3803
+4308 5528 3803
+4308 5527 5528
+5527 3284 5528
+4879 3802 4308
+3802 5527 4308
+3502 4879 4880
+4879 4308 4880
+4878 4307 3502
+4307 4879 3502
+4307 5526 4879
+5526 3802 4879
+5520 3285 5526
+5520 5526 4307
+3799 5520 4878
+5520 4307 4878
+5522 4306 3800
+4306 4881 3800
+4306 4878 4881
+4878 3502 4881
+5521 3799 4306
+3799 4878 4306
+3379 5521 5522
+5521 4306 5522
+5155 4305 3269
+4305 5525 3269
+4305 4876 5525
+4876 3801 5525
+4877 3501 4305
+3501 4876 4305
+3616 4877 5155
+4877 4305 5155
+4876 4304 3801
+4304 5524 3801
+4304 5523 5524
+5523 3378 5524
+4875 3800 4304
+3800 5523 4304
+3501 4875 4876
+4875 4304 4876
+4874 4303 3501
+4303 4875 3501
+4303 5522 4875
+5522 3800 4875
+5518 3379 4303
+3379 5522 4303
+3798 5518 4874
+5518 4303 4874
+5154 4302 3616
+4302 4877 3616
+4302 4874 4877
+4874 3501 4877
+5519 3798 4302
+3798 4874 4302
+3282 5519 5154
+5519 4302 5154
+5517 4301 3379
+4301 5521 3379
+4301 4872 5521
+4872 3799 5521
+4873 3500 4872
+4873 4872 4301
+3797 4873 4301
+3797 4301 5517
+4872 4300 5520
+4872 5520 3799
+4300 5192 3285
+4300 3285 5520
+4871 3635 5192
+4871 5192 4300
+3500 4871 4300
+3500 4300 4872
+4870 4299 4871
+4870 4871 3500
+4299 5193 3635
+4299 3635 4871
+5510 3275 5193
+5510 5193 4299
+3794 5510 4299
+3794 4299 4870
+5516 4298 4873
+5516 4873 3797
+4298 4870 3500
+4298 3500 4873
+5511 3794 4870
+5511 4870 4298
+3377 5511 4298
+3377 4298 5516
+5187 4297 3282
+4297 5519 3282
+4297 4868 5519
+4868 3798 5519
+4869 3499 4297
+3499 4868 4297
+3632 4869 5187
+4869 4297 5187
+4868 4296 3798
+4296 5518 3798
+4296 5517 5518
+5517 3379 5518
+4867 3797 4296
+3797 5517 4296
+3499 4867 4868
+4867 4296 4868
+4866 4295 3499
+4295 4867 3499
+4295 5516 3797
+4295 3797 4867
+5514 3377 5516
+5514 5516 4295
+3796 5514 4866
+5514 4295 4866
+5186 4294 3632
+4294 4869 3632
+4294 4866 4869
+4866 3499 4869
+5515 3796 4294
+3796 4866 4294
+3259 5515 4294
+3259 4294 5186
+5513 4293 3376
+4293 5508 3376
+4293 4864 5508
+4864 3793 5508
+4865 3498 4293
+3498 4864 4293
+3795 4865 5513
+4865 4293 5513
+4864 4292 3793
+4292 5509 3793
+4292 5188 5509
+5188 3271 5509
+4863 3633 4292
+3633 5188 4292
+3498 4863 4864
+4863 4292 4864
+4862 4291 3498
+4291 4863 3498
+4291 5189 4863
+5189 3633 4863
+5515 3259 4291
+3259 5189 4291
+3796 5515 4862
+5515 4291 4862
+5512 4290 3795
+4290 4865 3795
+4290 4862 4865
+4862 3498 4865
+5514 3796 4290
+3796 4862 4290
+3377 5514 5512
+5514 4290 5512
+5129 4289 5504
+5129 5504 3273
+4289 4860 3791
+4289 3791 5504
+4861 3497 4860
+4861 4860 4289
+3603 4861 4289
+3603 4289 5129
+4860 4288 5505
+4860 5505 3791
+4288 5513 5505
+5513 3376 5505
+4859 3795 5513
+4859 5513 4288
+3497 4859 4288
+3497 4288 4860
+4858 4287 4859
+4858 4859 3497
+4287 5512 3795
+4287 3795 4859
+5511 3377 5512
+5511 5512 4287
+3794 5511 4287
+3794 4287 4858
+5128 4286 4861
+5128 4861 3603
+4286 4858 3497
+4286 3497 4861
+5510 3794 4858
+5510 4858 4286
+3275 5510 4286
+3275 4286 5128
+5507 4285 3375
+4285 5502 3375
+4285 4856 5502
+4856 3790 5502
+4857 3496 4285
+3496 4856 4285
+3792 4857 5507
+4857 4285 5507
+4856 4284 3790
+4284 5503 3790
+4284 5184 5503
+5184 3268 5503
+4855 3631 4284
+3631 5184 4284
+3496 4855 4856
+4855 4284 4856
+4854 4283 3496
+4283 4855 3496
+4283 5185 4855
+5185 3631 4855
+5509 3271 4283
+3271 5185 4283
+3793 5509 4854
+5509 4283 4854
+5506 4282 3792
+4282 4857 3792
+4282 4854 4857
+4854 3496 4857
+5508 3793 4282
+3793 4854 4282
+3376 5508 5506
+5508 4282 5506
+5125 4281 3272
+4281 5498 3272
+4281 4852 5498
+4852 3788 5498
+4853 3495 4281
+3495 4852 4281
+3601 4853 5125
+4853 4281 5125
+4852 4280 3788
+4280 5499 3788
+4280 5507 5499
+5507 3375 5499
+4851 3792 4280
+3792 5507 4280
+3495 4851 4852
+4851 4280 4852
+4850 4279 3495
+4279 4851 3495
+4279 5506 4851
+5506 3792 4851
+5505 3376 4279
+3376 5506 4279
+3791 5505 4850
+5505 4279 4850
+5124 4278 3601
+4278 4853 3601
+4278 4850 4853
+4850 3495 4853
+5504 3791 4850
+5504 4850 4278
+3273 5504 4278
+3273 4278 5124
+5501 4277 3373
+4277 5494 3373
+4277 4848 5494
+4848 3786 5494
+4849 3494 4277
+3494 4848 4277
+3789 4849 5501
+4849 4277 5501
+4848 4276 3786
+4276 5495 3786
+4276 5180 5495
+5180 3262 5495
+4847 3629 4276
+3629 5180 4276
+3494 4847 4848
+4847 4276 4848
+4846 4275 3494
+4275 4847 3494
+4275 5181 4847
+5181 3629 4847
+5503 3268 4275
+3268 5181 4275
+3790 5503 4846
+5503 4275 4846
+5500 4274 3789
+4274 4849 3789
+4274 4846 4849
+4846 3494 4849
+5502 3790 4274
+3790 4846 4274
+3375 5502 5500
+5502 4274 5500
+5121 4273 3274
+4273 5488 3274
+4273 4844 5488
+4844 3783 5488
+4845 3493 4273
+3493 4844 4273
+3599 4845 5121
+4845 4273 5121
+4844 4272 3783
+4272 5489 3783
+4272 5501 5489
+5501 3373 5489
+4843 3789 4272
+3789 5501 4272
+3493 4843 4844
+4843 4272 4844
+4842 4271 3493
+4271 4843 3493
+4271 5500 4843
+5500 3789 4843
+5499 3375 4271
+3375 5500 4271
+3788 5499 4842
+5499 4271 4842
+5120 4270 3599
+4270 4845 3599
+4270 4842 4845
+4842 3493 4845
+5498 3788 4270
+3788 4842 4270
+3272 5498 5120
+5498 4270 5120
+5491 4269 3374
+4269 5497 3374
+4269 4840 5497
+4840 3787 5497
+4841 3492 4269
+3492 4840 4269
+3784 4841 5491
+4841 4269 5491
+4840 4268 3787
+4268 5496 3787
+4268 5176 5496
+5176 3342 5496
+4839 3627 4268
+3627 5176 4268
+3492 4839 4840
+4839 4268 4840
+4838 4267 3492
+4267 4839 3492
+4267 5177 4839
+5177 3627 4839
+5495 3262 4267
+3262 5177 4267
+3786 5495 4838
+5495 4267 4838
+5490 4266 3784
+4266 4841 3784
+4266 4838 4841
+4838 3492 4841
+5494 3786 4266
+3786 4838 4266
+3373 5494 5490
+5494 4266 5490
+5115 4265 3345
+4265 5493 3345
+4265 4836 5493
+4836 3785 5493
+4837 3491 4265
+3491 4836 4265
+3596 4837 5115
+4837 4265 5115
+4836 4264 3785
+4264 5492 3785
+4264 5491 5492
+5491 3374 5492
+4835 3784 4264
+3784 5491 4264
+3491 4835 4836
+4835 4264 4836
+4834 4263 3491
+4263 4835 3491
+4263 5490 4835
+5490 3784 4835
+5489 3373 4263
+3373 5490 4263
+3783 5489 4834
+5489 4263 4834
+5114 4262 3596
+4262 4837 3596
+4262 4834 4837
+4834 3491 4837
+5488 3783 4262
+3783 4834 4262
+3274 5488 5114
+5488 4262 5114
+5486 4261 3251
+4261 5485 3251
+4261 4832 5485
+4832 3781 5485
+4833 3490 4261
+3490 4832 4261
+3782 4833 5486
+4833 4261 5486
+4832 4260 3781
+4260 5484 3781
+4260 5483 5484
+5483 3371 5484
+4831 3780 4260
+3780 5483 4260
+3490 4831 4832
+4831 4260 4832
+4830 4259 3490
+4259 4831 3490
+4259 5482 4831
+5482 3780 4831
+5478 3370 4259
+3370 5482 4259
+3778 5478 4830
+5478 4259 4830
+5487 4258 3782
+4258 4833 3782
+4258 4830 4833
+4830 3490 4833
+5479 3778 4258
+3778 4830 4258
+3250 5479 5487
+5479 4258 5487
+5480 4257 3250
+4257 5479 3250
+4257 4828 5479
+4828 3778 5479
+4829 3489 4257
+3489 4828 4257
+3779 4829 5480
+4829 4257 5480
+4828 4256 3778
+4256 5478 3778
+4256 5476 5478
+5476 3370 5478
+4827 3777 4256
+3777 5476 4256
+3489 4827 4828
+4827 4256 4828
+4826 4255 3489
+4255 4827 3489
+4255 5477 4827
+5477 3777 4827
+5084 3253 4255
+3253 5477 4255
+3581 5084 4826
+5084 4255 4826
+5481 4254 3779
+4254 4829 3779
+4254 4826 4829
+4826 3489 4829
+5085 3581 4254
+3581 4826 4254
+3243 5085 5481
+5085 4254 5481
+5476 4253 3370
+4253 5475 3370
+4253 4824 5475
+4824 3776 5475
+4825 3488 4253
+3488 4824 4253
+3777 4825 5476
+4825 4253 5476
+4824 4252 3776
+4252 5474 3776
+4252 5468 5474
+5468 3368 5474
+4823 3773 4252
+3773 5468 4252
+3488 4823 4824
+4823 4252 4824
+4822 4251 3488
+4251 4823 3488
+4251 5469 4823
+5469 3773 4823
+5196 3372 4251
+3372 5469 4251
+3637 5196 4822
+5196 4251 4822
+5477 4250 3777
+4250 4825 3777
+4250 4822 4825
+4822 3488 4825
+5197 3637 4250
+3637 4822 4250
+3253 5197 5477
+5197 4250 5477
+5157 4249 3270
+4249 5456 3270
+4249 4820 5456
+4820 3767 5456
+4821 3487 4249
+3487 4820 4249
+3617 4821 5157
+4821 4249 5157
+4820 4248 3767
+4248 5457 3767
+4248 5473 5457
+5473 3367 5457
+4819 3775 4248
+3775 5473 4248
+3487 4819 4820
+4819 4248 4820
+4818 4247 3487
+4247 4819 3487
+4247 5472 4819
+5472 3775 4819
+5471 3369 4247
+3369 5472 4247
+3774 5471 4818
+5471 4247 4818
+5156 4246 3617
+4246 4821 3617
+4246 4818 4821
+4818 3487 4821
+5470 3774 4246
+3774 4818 4246
+3269 5470 5156
+5470 4246 5156
+5161 4245 5469
+5161 5469 3372
+4245 4816 3773
+4245 3773 5469
+4817 3486 4816
+4817 4816 4245
+3619 4817 4245
+3619 4245 5161
+4816 4244 5468
+4816 5468 3773
+4244 5467 3368
+4244 3368 5468
+4815 3772 5467
+4815 5467 4244
+3486 4815 4244
+3486 4244 4816
+4814 4243 4815
+4814 4815 3486
+4243 5466 3772
+4243 3772 4815
+5465 3261 5466
+5465 5466 4243
+3771 5465 4243
+3771 4243 4814
+5160 4242 4817
+5160 4817 3619
+4242 4814 3486
+4242 3486 4817
+5464 3771 4814
+5464 4814 4242
+3257 5464 4242
+3257 4242 5160
+5455 4241 5463
+5455 5463 3365
+4241 4812 3770
+4241 3770 5463
+4813 3485 4812
+4813 4812 4241
+3766 4813 4241
+3766 4241 5455
+4812 4240 5462
+4812 5462 3770
+4240 5442 3364
+4240 3364 5462
+4811 3760 5442
+4811 5442 4240
+3485 4811 4240
+3485 4240 4812
+4810 4239 4811
+4810 4811 3485
+4239 5443 3760
+4239 3760 4811
+5092 3350 5443
+5092 5443 4239
+3585 5092 4239
+3585 4239 4810
+5454 4238 4813
+5454 4813 3766
+4238 4810 3485
+4238 3485 4813
+5093 3585 4810
+5093 4810 4238
+3264 5093 4238
+3264 4238 5454
+5459 4237 3366
+4237 5452 3366
+4237 4808 5452
+4808 3765 5452
+4809 3484 4237
+3484 4808 4237
+3768 4809 5459
+4809 4237 5459
+4808 4236 3765
+4236 5453 3765
+4236 5106 5453
+5106 3260 5453
+4807 3592 4236
+3592 5106 4236
+3484 4807 4808
+4807 4236 4808
+4806 4235 3484
+4235 4807 3484
+4235 5107 4807
+5107 3592 4807
+5461 3267 4235
+3267 5107 4235
+3769 5461 4806
+5461 4235 4806
+5458 4234 3768
+4234 4809 3768
+4234 4806 4809
+4806 3484 4809
+5460 3769 4234
+3769 4806 4234
+3367 5460 5458
+5460 4234 5458
+5151 4233 3276
+4233 5446 3276
+4233 4804 5446
+4804 3762 5446
+4805 3483 4233
+3483 4804 4233
+3614 4805 5151
+4805 4233 5151
+4804 4232 3762
+4232 5447 3762
+4232 5459 5447
+5459 3366 5447
+4803 3768 4232
+3768 5459 4232
+3483 4803 4804
+4803 4232 4804
+4802 4231 3483
+4231 4803 3483
+4231 5458 4803
+5458 3768 4803
+5457 3367 4231
+3367 5458 4231
+3767 5457 4802
+5457 4231 4802
+5150 4230 3614
+4230 4805 3614
+4230 4802 4805
+4802 3483 4805
+5456 3767 4230
+3767 4802 4230
+3270 5456 5150
+5456 4230 5150
+5449 4229 3365
+4229 5455 3365
+4229 4800 5455
+4800 3766 5455
+4801 3482 4229
+3482 4800 4229
+3763 4801 5449
+4801 4229 5449
+4800 4228 3766
+4228 5454 3766
+4228 5100 5454
+5100 3264 5454
+4799 3589 4228
+3589 5100 4228
+3482 4799 4800
+4799 4228 4800
+4798 4227 3482
+4227 4799 3482
+4227 5101 4799
+5101 3589 4799
+5453 3260 4227
+3260 5101 4227
+3765 5453 4798
+5453 4227 4798
+5448 4226 3763
+4226 4801 3763
+4226 4798 4801
+4798 3482 4801
+5452 3765 4226
+3765 4798 4226
+3366 5452 5448
+5452 4226 5448
+5137 4225 3265
+4225 5451 3265
+4225 4796 5451
+4796 3764 5451
+4797 3481 4225
+3481 4796 4225
+3607 4797 5137
+4797 4225 5137
+4796 4224 3764
+4224 5450 3764
+4224 5449 5450
+5449 3365 5450
+4795 3763 4224
+3763 5449 4224
+3481 4795 4796
+4795 4224 4796
+4794 4223 3481
+4223 4795 3481
+4223 5448 4795
+5448 3763 4795
+5447 3366 4223
+3366 5448 4223
+3762 5447 4794
+5447 4223 4794
+5136 4222 3607
+4222 4797 3607
+4222 4794 4797
+4794 3481 4797
+5446 3762 4222
+3762 4794 4222
+3276 5446 5136
+5446 4222 5136
+5437 4221 3362
+4221 5424 3362
+4221 4792 5424
+4792 3751 5424
+4793 3480 4221
+3480 4792 4221
+3757 4793 5437
+4793 4221 5437
+4792 4220 3751
+4220 5425 3751
+4220 5445 5425
+5445 3347 5425
+4791 3761 4220
+3761 5445 4220
+3480 4791 4792
+4791 4220 4792
+4790 4219 3480
+4219 4791 3480
+4219 5444 4791
+5444 3761 4791
+5353 3344 4219
+3344 5444 4219
+3715 5353 4790
+5353 4219 4790
+5436 4218 3757
+4218 4793 3757
+4218 4790 4793
+4790 3480 4793
+5352 3715 4218
+3715 4790 4218
+3343 5352 5436
+5352 4218 5436
+5442 4217 5440
+5442 5440 3364
+4217 4788 3759
+4217 3759 5440
+4789 3479 4788
+4789 4788 4217
+3760 4789 4217
+3760 4217 5442
+4788 4216 5441
+4788 5441 3759
+4216 5412 3360
+4216 3360 5441
+4787 3745 5412
+4787 5412 4216
+3479 4787 4216
+3479 4216 4788
+4786 4215 4787
+4786 4787 3479
+4215 5413 3745
+4215 3745 4787
+5396 3359 5413
+5396 5413 4215
+3737 5396 4215
+3737 4215 4786
+5443 4214 4789
+5443 4789 3760
+4214 4786 3479
+4214 3479 4789
+5397 3737 4786
+5397 4786 4214
+3350 5397 4214
+3350 4214 5443
+5418 4213 5441
+5418 5441 3360
+4213 4784 3759
+4213 3759 5441
+4785 3478 4784
+4785 4784 4213
+3748 4785 4213
+3748 4213 5418
+4784 4212 5440
+4784 5440 3759
+4212 5439 3364
+4212 3364 5440
+4783 3758 5439
+4783 5439 4212
+3478 4783 4212
+3478 4212 4784
+4782 4211 4783
+4782 4783 3478
+4211 5438 3758
+4211 3758 4783
+5434 3363 5438
+5434 5438 4211
+3756 5434 4211
+3756 4211 4782
+5419 4210 4785
+5419 4785 3748
+4210 4782 3478
+4210 3478 4785
+5435 3756 4782
+5435 4782 4210
+3343 5435 4210
+3343 4210 5419
+5431 4209 3362
+4209 5437 3362
+4209 4780 5437
+4780 3757 5437
+4781 3477 4209
+3477 4780 4209
+3754 4781 5431
+4781 4209 5431
+4780 4208 3757
+4208 5436 3757
+4208 5435 5436
+5435 3343 5436
+4779 3756 4208
+3756 5435 4208
+3477 4779 4780
+4779 4208 4780
+4778 4207 3477
+4207 4779 3477
+4207 5434 4779
+5434 3756 4779
+5433 3363 4207
+3363 5434 4207
+3755 5433 4778
+5433 4207 4778
+5430 4206 3754
+4206 4781 3754
+4206 4778 4781
+4778 3477 4781
+5432 3755 4206
+3755 4778 4206
+3346 5432 5430
+5432 4206 5430
+5423 4205 5431
+5423 5431 3362
+4205 4776 3754
+4205 3754 5431
+4777 3476 4776
+4777 4776 4205
+3750 4777 5423
+4777 4205 5423
+4776 4204 5430
+4776 5430 3754
+4204 5174 3346
+4204 3346 5430
+4775 3626 5174
+4775 5174 4204
+3476 4775 4204
+3476 4204 4776
+4774 4203 4775
+4774 4775 3476
+4203 5175 3626
+4203 3626 4775
+5429 3342 5175
+5429 5175 4203
+3753 5429 4203
+3753 4203 4774
+5422 4202 3750
+4202 4777 3750
+4202 4774 3476
+4202 3476 4777
+5428 3753 4774
+5428 4774 4202
+3361 5428 5422
+5428 4202 5422
+5426 4201 3347
+4201 5425 3347
+4201 4772 5425
+4772 3751 5425
+4773 3475 4201
+3475 4772 4201
+3752 4773 5426
+4773 4201 5426
+4772 4200 3751
+4200 5424 3751
+4200 5423 5424
+5423 3362 5424
+4771 3750 4200
+3750 5423 4200
+3475 4771 4772
+4771 4200 4772
+4770 4199 3475
+4199 4771 3475
+4199 5422 4771
+5422 3750 4771
+5421 3361 4199
+3361 5422 4199
+3749 5421 4770
+5421 4199 4770
+5427 4198 3752
+4198 4773 3752
+4198 4770 4773
+4770 3475 4773
+5420 3749 4198
+3749 4770 4198
+3341 5420 5427
+5420 4198 5427
+5415 5367 4197
+5415 3353 5367
+4197 3722 4768
+4197 5367 3722
+4769 4768 3474
+4769 4197 4768
+3746 4197 4769
+3746 5415 4197
+4768 5366 4196
+4768 3722 5366
+4196 3306 5350
+4196 5366 3306
+4767 5350 3714
+4767 4196 5350
+3474 4196 4767
+3474 4768 4196
+4766 4767 4195
+4766 3474 4767
+4195 3714 5351
+4195 4767 3714
+5419 5351 3343
+5419 4195 5351
+3748 4195 5419
+3748 4766 4195
+5414 4769 4194
+5414 3746 4769
+4194 3474 4766
+4194 4769 3474
+5418 4766 3748
+5418 4194 4766
+3360 4194 5418
+3360 5414 4194
+5416 5361 4193
+5416 3304 5361
+4193 3719 4764
+4193 5361 3719
+4765 4764 3473
+4765 4193 4764
+3747 4193 4765
+3747 5416 4193
+4764 5360 4192
+4764 3719 5360
+4192 3353 5415
+4192 5360 3353
+4763 5415 3746
+4763 4192 5415
+3473 4192 4763
+3473 4764 4192
+4762 4763 4191
+4762 3473 4763
+4191 3746 5414
+4191 4763 3746
+5411 5414 3360
+5411 4191 5414
+3744 4191 5411
+3744 4762 4191
+5417 3747 4190
+4190 3747 4765
+4190 3473 4762
+4190 4765 3473
+5410 4190 3744
+3744 4190 4762
+3351 5417 5410
+5410 5417 4190
+5412 4189 5411
+5412 5411 3360
+4189 4760 3744
+4189 3744 5411
+4761 3472 4760
+4761 4760 4189
+3745 4761 4189
+3745 4189 5412
+4760 4188 5410
+4760 5410 3744
+4188 5409 3351
+4188 3351 5410
+4759 3743 5409
+4759 5409 4188
+3472 4759 4188
+3472 4188 4760
+4758 4187 4759
+4758 4759 3472
+4187 5408 3743
+4187 3743 4759
+5402 3348 5408
+5402 5408 4187
+3740 5402 4187
+3740 4187 4758
+5413 4186 4761
+5413 4761 3745
+4186 4758 3472
+4186 3472 4761
+5403 3740 4758
+5403 4758 4186
+3359 5403 4186
+3359 4186 5413
+5405 4185 3358
+4185 5390 3358
+4185 4756 5390
+4756 3734 5390
+4757 3471 4185
+3471 4756 4185
+3741 4757 5405
+4757 4185 5405
+4756 4184 3734
+4184 5391 3734
+4184 5144 5391
+5144 3330 5391
+4755 3611 5144
+4755 5144 4184
+3471 4755 4756
+4755 4184 4756
+4754 4183 3471
+4183 4755 3471
+4183 5145 3611
+4183 3611 4755
+5392 3349 4183
+3349 5145 4183
+3735 5392 4754
+5392 4183 4754
+5404 4182 4757
+5404 4757 3741
+4182 4754 4757
+4754 3471 4757
+5393 3735 4182
+3735 4754 4182
+3357 5393 4182
+3357 4182 5404
+5406 4181 3326
+4181 5384 3326
+4181 4752 5384
+4752 3731 5384
+4753 3470 4181
+3470 4752 4181
+3742 4753 5406
+4753 4181 5406
+4752 4180 3731
+4180 5385 3731
+4180 5405 5385
+5405 3358 5385
+4751 3741 4180
+3741 5405 4180
+3470 4751 4752
+4751 4180 4752
+4750 4179 4751
+4750 4751 3470
+4179 5404 3741
+4179 3741 4751
+5398 3357 5404
+5398 5404 4179
+3738 5398 4179
+3738 4179 4750
+5407 4178 3742
+4178 4753 3742
+4178 4750 4753
+4750 3470 4753
+5399 3738 4750
+5399 4750 4178
+3352 5399 5407
+5399 4178 5407
+5395 4177 5403
+5395 5403 3359
+4177 4748 3740
+4177 3740 5403
+4749 3469 4748
+4749 4748 4177
+3736 4749 4177
+3736 4177 5395
+4748 4176 5402
+4748 5402 3740
+4176 5401 3348
+4176 3348 5402
+4747 3739 5401
+4747 5401 4176
+3469 4747 4176
+3469 4176 4748
+4746 4175 4747
+4746 4747 3469
+4175 5400 3739
+4175 3739 4747
+5399 3352 5400
+5399 5400 4175
+3738 5399 4175
+3738 4175 4746
+5394 4174 4749
+5394 4749 3736
+4174 4746 3469
+4174 3469 4749
+5398 3738 4746
+5398 4746 4174
+3357 5398 4174
+3357 4174 5394
+5099 4173 5397
+5099 5397 3350
+4173 4744 3737
+4173 3737 5397
+4745 3468 4744
+4745 4744 4173
+3588 4745 5099
+4745 4173 5099
+4744 4172 5396
+4744 5396 3737
+4172 5395 3359
+4172 3359 5396
+4743 3736 5395
+4743 5395 4172
+3468 4743 4172
+3468 4172 4744
+4742 4171 4743
+4742 4743 3468
+4171 5394 3736
+4171 3736 4743
+5393 3357 5394
+5393 5394 4171
+3735 5393 4171
+3735 4171 4742
+5098 4170 3588
+4170 4745 3588
+4170 4742 4745
+4742 3468 4745
+5392 3735 4170
+3735 4742 4170
+3349 5392 5098
+5392 4170 5098
+5387 4169 3356
+4169 5382 3356
+4169 4740 5382
+4740 3730 5382
+4741 3467 4169
+3467 4740 4169
+3732 4741 5387
+4741 4169 5387
+4740 4168 3730
+4168 5383 3730
+4168 5324 5383
+5324 3315 5383
+4739 3701 4168
+3701 5324 4168
+3467 4739 4740
+4739 4168 4740
+4738 4167 4739
+4738 4739 3467
+4167 5325 4739
+5325 3701 4739
+5391 3330 5325
+5391 5325 4167
+3734 5391 4167
+3734 4167 4738
+5386 4166 4741
+5386 4741 3732
+4166 4738 3467
+4166 3467 4741
+5390 3734 4738
+5390 4738 4166
+3358 5390 4166
+3358 4166 5386
+5388 4165 3307
+4165 5376 3307
+4165 4736 5376
+4736 3727 5376
+4737 3466 4165
+3466 4736 4165
+3733 4737 5388
+4737 4165 5388
+4736 4164 3727
+4164 5377 3727
+4164 5387 5377
+5387 3356 5377
+4735 3732 4164
+3732 5387 4164
+3466 4735 4736
+4735 4164 4736
+4734 4163 3466
+4163 4735 3466
+4163 5386 4735
+5386 3732 4735
+5385 3358 4163
+3358 5386 4163
+3731 5385 4734
+5385 4163 4734
+5389 4162 3733
+4162 4737 3733
+4162 4734 4737
+4734 3466 4737
+5384 3731 4162
+3731 4734 4162
+3326 5384 5389
+5384 4162 5389
+5379 4161 3354
+4161 5374 3354
+4161 4732 5374
+4732 3726 5374
+4733 3465 4161
+3465 4732 4161
+3728 4733 5379
+4733 4161 5379
+4732 4160 3726
+4160 5375 3726
+4160 5266 5375
+5266 3314 5375
+4731 3672 4160
+3672 5266 4160
+3465 4731 4732
+4731 4160 4732
+4730 4159 3465
+4159 4731 3465
+4159 5267 4731
+5267 3672 4731
+5383 3315 4159
+3315 5267 4159
+3730 5383 4730
+5383 4159 4730
+5378 4158 3728
+4158 4733 3728
+4158 4730 4733
+4730 3465 4733
+5382 3730 4158
+3730 4730 4158
+3356 5382 5378
+5382 4158 5378
+5380 4157 3293
+4157 5368 3293
+4157 4728 5368
+4728 3723 5368
+4729 3464 4157
+3464 4728 4157
+3729 4729 5380
+4729 4157 5380
+4728 4156 3723
+4156 5369 3723
+4156 5379 5369
+5379 3354 5369
+4727 3728 4156
+3728 5379 4156
+3464 4727 4728
+4727 4156 4728
+4726 4155 3464
+4155 4727 3464
+4155 5378 4727
+5378 3728 4727
+5377 3356 4155
+3356 5378 4155
+3727 5377 4726
+5377 4155 4726
+5381 4154 3729
+4154 4729 3729
+4154 4726 4729
+4726 3464 4729
+5376 3727 4154
+3727 4726 4154
+3307 5376 5381
+5376 4154 5381
+5371 4153 3355
+4153 5364 3355
+4153 4724 5364
+4724 3721 5364
+4725 3463 4153
+3463 4724 4153
+3724 4725 5371
+4725 4153 5371
+4724 4152 3721
+4152 5365 3721
+4152 5262 5365
+5262 3312 5365
+4723 3670 4152
+3670 5262 4152
+3463 4723 4724
+4723 4152 4724
+4722 4151 3463
+4151 4723 3463
+4151 5263 4723
+5263 3670 4723
+5375 3314 4151
+3314 5263 4151
+3726 5375 4722
+5375 4151 4722
+5370 4150 3724
+4150 4725 3724
+4150 4722 4725
+4722 3463 4725
+5374 3726 4150
+3726 4722 4150
+3354 5374 5370
+5374 4150 5370
+5372 4149 3305
+4149 5356 3305
+4149 4720 5356
+4720 3717 5356
+4721 3462 4149
+3462 4720 4149
+3725 4721 5372
+4721 4149 5372
+4720 4148 3717
+4148 5357 3717
+4148 5371 5357
+5371 3355 5357
+4719 3724 4148
+3724 5371 4148
+3462 4719 4720
+4719 4148 4720
+4718 4147 3462
+4147 4719 3462
+4147 5370 4719
+5370 3724 4719
+5369 3354 4147
+3354 5370 4147
+3723 5369 4718
+5369 4147 4718
+5373 4146 3725
+4146 4721 3725
+4146 4718 4721
+4718 3462 4721
+5368 3723 4146
+3723 4718 4146
+3293 5368 5373
+5368 4146 5373
+5359 4145 3353
+4145 5367 3353
+4145 4716 5367
+4716 3722 5367
+4717 3461 4145
+3461 4716 4145
+3718 4717 5359
+4717 4145 5359
+4716 4144 3722
+4144 5366 3722
+4144 5258 5366
+5258 3306 5366
+4715 3668 5258
+4715 5258 4144
+3461 4715 4716
+4715 4144 4716
+4714 4143 4715
+4714 4715 3461
+4143 5259 3668
+4143 3668 4715
+5365 3312 5259
+5365 5259 4143
+3721 5365 4714
+5365 4143 4714
+5358 4142 3718
+4142 4717 3718
+4142 4714 4717
+4714 3461 4717
+5364 3721 4142
+3721 4714 4142
+3355 5364 5358
+5364 4142 5358
+5362 4141 3304
+4141 5361 3304
+4141 4712 5361
+4712 3719 5361
+4713 3460 4141
+3460 4712 4141
+3720 4713 5362
+4713 4141 5362
+4712 4140 3719
+4140 5360 3719
+4140 5359 5360
+5359 3353 5360
+4711 3718 4140
+3718 5359 4140
+3460 4711 4712
+4711 4140 4712
+4710 4139 3460
+4139 4711 3460
+4139 5358 4711
+5358 3718 4711
+5357 3355 4139
+3355 5358 4139
+3717 5357 4710
+5357 4139 4710
+5363 4138 3720
+4138 4713 3720
+4138 4710 4713
+4710 3460 4713
+5356 3717 4138
+3717 4710 4138
+3305 5356 5363
+5356 4138 5363
+5354 5353 4137
+5354 3344 5353
+4137 3715 4708
+4137 5353 3715
+4709 4708 3459
+4709 4137 4708
+3716 5354 4709
+4709 5354 4137
+4708 5352 4136
+4708 3715 5352
+4136 3343 5351
+4136 5352 3343
+4707 5351 3714
+4707 4136 5351
+3459 4136 4707
+3459 4708 4136
+4706 4707 4135
+4706 3459 4707
+4135 3714 5350
+4135 4707 3714
+5257 5350 3306
+5257 4135 5350
+3667 4706 5257
+5257 4706 4135
+5355 3716 4134
+4134 3716 4709
+4134 4709 4706
+4706 4709 3459
+5256 4134 3667
+3667 4134 4706
+3303 5355 5256
+5256 5355 4134
+5348 4133 5026
+5348 5026 3337
+4133 4704 3552
+4133 3552 5026
+4705 3458 4704
+4705 4704 4133
+3713 4705 4133
+3713 4133 5348
+4704 4132 5027
+4704 5027 3552
+4132 5340 3340
+4132 3340 5027
+4703 3709 5340
+4703 5340 4132
+3458 4703 4132
+3458 4132 4704
+4702 4131 4703
+4702 4703 3458
+4131 5341 3709
+4131 3709 4703
+5347 3338 5341
+5347 5341 4131
+3712 5347 4131
+3712 4131 4702
+5349 4130 4705
+5349 4705 3713
+4130 4702 3458
+4130 3458 4705
+5346 3712 4702
+5346 4702 4130
+3331 5346 4130
+3331 4130 5349
+5335 4129 3335
+4129 5010 3335
+4129 4700 5010
+4700 3544 5010
+4701 3457 4129
+3457 4700 4129
+3706 4701 5335
+4701 4129 5335
+4700 4128 3544
+4128 5011 3544
+4128 5345 5011
+5345 3334 5011
+4699 3711 4128
+3711 5345 4128
+3457 4699 4700
+4699 4128 4700
+4698 4127 3457
+4127 4699 3457
+4127 5344 4699
+5344 3711 4699
+5343 3339 4127
+3339 5344 4127
+3710 5343 4698
+5343 4127 4698
+5334 4126 3706
+4126 4701 3706
+4126 4698 4701
+4698 3457 4701
+5342 3710 4126
+3710 4698 4126
+3333 5342 5334
+5342 4126 5334
+5340 4125 4998
+5340 4998 3340
+4125 4696 4998
+4696 3538 4998
+4697 3456 4125
+3456 4696 4125
+3709 4697 4125
+3709 4125 5340
+4696 4124 3538
+4124 4999 3538
+4124 5336 4999
+5336 3336 4999
+4695 3707 4124
+3707 5336 4124
+3456 4695 4696
+4695 4124 4696
+4694 4123 3456
+4123 4695 3456
+4123 5337 4695
+5337 3707 4695
+5339 3332 4123
+3332 5337 4123
+3708 5339 4694
+5339 4123 4694
+5341 4122 4697
+5341 4697 3709
+4122 4694 4697
+4694 3456 4697
+5338 3708 4122
+3708 4694 4122
+3338 5338 5341
+5338 4122 5341
+5336 4121 3336
+4121 4980 3336
+4121 4692 4980
+4692 3529 4980
+4693 3455 4121
+3455 4692 4121
+3707 4693 5336
+4693 4121 5336
+4692 4120 3529
+4120 4981 3529
+4120 5335 4981
+5335 3335 4981
+4691 3706 4120
+3706 5335 4120
+3455 4691 4692
+4691 4120 4692
+4690 4119 3455
+4119 4691 3455
+4119 5334 4691
+5334 3706 4691
+5333 3333 4119
+3333 5334 4119
+3705 5333 4690
+5333 4119 4690
+5337 4118 3707
+4118 4693 3707
+4118 4690 4693
+4690 3455 4693
+5332 3705 4118
+3705 4690 4118
+3332 5332 5337
+5332 4118 5337
+5323 4117 5292
+5323 5292 3313
+4117 4688 3685
+4117 3685 5292
+4689 3454 4688
+4689 4688 4117
+3700 4689 4117
+3700 4117 5323
+4688 4116 5293
+4688 5293 3685
+4116 5330 3317
+4116 3317 5293
+4687 3704 4116
+3704 5330 4116
+3454 4687 4116
+3454 4116 4688
+4686 4115 4687
+4686 4687 3454
+4115 5331 4687
+5331 3704 4687
+5074 3328 5331
+5074 5331 4115
+3576 5074 4115
+3576 4115 4686
+5322 4114 4689
+5322 4689 3700
+4114 4686 3454
+4114 3454 4689
+5075 3576 4686
+5075 4686 4114
+3329 5075 4114
+3329 4114 5322
+5330 4113 3317
+4113 5280 3317
+4113 4684 5280
+4684 3679 5280
+4685 3453 4113
+3453 4684 4113
+3704 4685 5330
+4685 4113 5330
+4684 4112 3679
+4112 5281 3679
+4112 5329 5281
+5329 3316 5281
+4683 3703 4112
+3703 5329 4112
+3453 4683 4684
+4683 4112 4684
+4682 4111 3453
+4111 4683 3453
+4111 5328 4683
+5328 3703 4683
+5327 3327 4111
+3327 5328 4111
+3702 5327 4682
+5327 4111 4682
+5331 4110 3704
+4110 4685 3704
+4110 4682 4685
+4682 3453 4685
+5326 3702 4110
+3702 4682 4110
+3328 5326 5331
+5326 4110 5331
+5203 4109 5325
+5203 5325 3330
+4109 4680 3701
+4109 3701 5325
+4681 3452 4680
+4681 4680 4109
+3640 4681 4109
+3640 4109 5203
+4680 4108 5324
+4680 5324 3701
+4108 5268 3315
+4108 3315 5324
+4679 3673 4108
+3673 5268 4108
+3452 4679 4108
+3452 4108 4680
+4678 4107 3452
+4107 4679 3452
+4107 5269 4679
+5269 3673 4679
+5323 3313 4107
+3313 5269 4107
+3700 5323 4678
+5323 4107 4678
+5202 4106 4681
+5202 4681 3640
+4106 4678 3452
+4106 3452 4681
+5322 3700 4106
+3700 4678 4106
+3329 5322 4106
+3329 4106 5202
+5320 4105 5308
+5320 5308 3324
+4105 4676 5308
+4676 3693 5308
+4677 3451 4676
+4677 4676 4105
+3699 4677 5320
+4677 4105 5320
+4676 4104 3693
+4104 5309 3693
+4104 5306 5309
+5306 3321 5309
+4675 3692 4104
+3692 5306 4104
+3451 4675 4104
+3451 4104 4676
+4674 4103 4675
+4674 4675 3451
+4103 5307 3692
+4103 3692 4675
+5319 3319 5307
+5319 5307 4103
+3698 5319 4103
+3698 4103 4674
+5321 4102 3699
+4102 4677 3699
+4102 4674 3451
+4102 3451 4677
+5318 3698 4674
+5318 4674 4102
+3322 5318 5321
+5318 4102 5321
+5316 4101 3323
+4101 5315 3323
+4101 4672 5315
+4672 3696 5315
+4673 3450 4101
+3450 4672 4101
+3697 4673 5316
+4673 4101 5316
+4672 4100 3696
+4100 5314 3696
+4100 5302 5314
+5302 3318 5314
+4671 3690 4100
+3690 5302 4100
+3450 4671 4672
+4671 4100 4672
+4670 4099 3450
+4099 4671 3450
+4099 5303 4671
+5303 3690 4671
+5310 3320 4099
+3320 5303 4099
+3694 5310 4670
+5310 4099 4670
+5317 4098 3697
+4098 4673 3697
+4098 4670 4673
+4670 3450 4673
+5311 3694 4098
+3694 4670 4098
+3325 5311 5317
+5311 4098 5317
+5312 4097 3325
+4097 5311 3325
+4097 4668 5311
+4668 3694 5311
+4669 3449 4097
+3449 4668 4097
+3695 4669 5312
+4669 4097 5312
+4668 4096 3694
+4096 5310 3694
+4096 5298 5310
+5298 3320 5310
+4667 3688 4096
+3688 5298 4096
+3449 4667 4668
+4667 4096 4668
+4666 4095 3449
+4095 4667 3449
+4095 5299 4667
+5299 3688 4667
+5309 3321 4095
+3321 5299 4095
+3693 5309 4666
+5309 4095 4666
+5313 4094 3695
+4094 4669 3695
+4094 4666 4669
+4666 3449 4669
+5308 3693 4094
+3693 4666 4094
+3324 5308 5313
+5308 4094 5313
+5306 4093 3321
+4093 5294 3321
+4093 4664 5294
+4664 3686 5294
+4665 3448 4093
+3448 4664 4093
+3692 4665 5306
+4665 4093 5306
+4664 4092 3686
+4092 5295 3686
+4092 5242 5295
+5242 3310 5295
+4663 3660 4092
+3660 5242 4092
+3448 4663 4664
+4663 4092 4664
+4662 4091 3448
+4091 4663 3448
+4091 5243 4663
+5243 3660 4663
+5305 3290 4091
+3290 5243 4091
+3691 5305 4662
+5305 4091 4662
+5307 4090 3692
+4090 4665 3692
+4090 4662 4665
+4662 3448 4665
+5304 3691 4090
+3691 4662 4090
+3319 5304 4090
+3319 4090 5307
+5302 4089 3318
+4089 5301 3318
+4089 4660 5301
+4660 3689 5301
+4661 3447 4089
+3447 4660 4089
+3690 4661 5302
+4661 4089 5302
+4660 4088 3689
+4088 5300 3689
+4088 5232 5300
+5232 3289 5300
+4659 3655 4088
+3655 5232 4088
+3447 4659 4660
+4659 4088 4660
+4658 4087 3447
+4087 4659 3447
+4087 5233 4659
+5233 3655 4659
+5296 3309 4087
+3309 5233 4087
+3687 5296 4658
+5296 4087 4658
+5303 4086 3690
+4086 4661 3690
+4086 4658 4661
+4658 3447 4661
+5297 3687 4086
+3687 4658 4086
+3320 5297 5303
+5297 4086 5303
+5298 4085 3320
+4085 5297 3320
+4085 4656 5297
+4656 3687 5297
+4657 3446 4085
+3446 4656 4085
+3688 4657 5298
+4657 4085 5298
+4656 4084 3687
+4084 5296 3687
+4084 5250 5296
+5250 3309 5296
+4655 3664 4084
+3664 5250 4084
+3446 4655 4656
+4655 4084 4656
+4654 4083 3446
+4083 4655 3446
+4083 5251 4655
+5251 3664 4655
+5295 3310 4083
+3310 5251 4083
+3686 5295 4654
+5295 4083 4654
+5299 4082 3688
+4082 4657 3688
+4082 4654 4657
+4654 3446 4657
+5294 3686 4082
+3686 4654 4082
+3321 5294 5299
+5294 4082 5299
+5279 4081 5293
+5279 5293 3317
+4081 4652 3685
+4081 3685 5293
+4653 3445 4652
+4653 4652 4081
+3678 4653 5279
+4653 4081 5279
+4652 4080 5292
+4652 5292 3685
+4080 5270 3313
+4080 3313 5292
+4651 3674 5270
+4651 5270 4080
+3445 4651 4080
+3445 4080 4652
+4650 4079 4651
+4650 4651 3445
+4079 5271 3674
+4079 3674 4651
+5290 3301 5271
+5290 5271 4079
+3684 5290 4079
+3684 4079 4650
+5278 4078 3678
+4078 4653 3678
+4078 4650 3445
+4078 3445 4653
+5291 3684 4078
+3684 4650 4078
+3292 5291 5278
+5291 4078 5278
+5290 4077 5224
+5290 5224 3301
+4077 4648 3651
+4077 3651 5224
+4649 3444 4648
+4649 4648 4077
+3684 4649 4077
+3684 4077 5290
+4648 4076 5225
+4648 5225 3651
+4076 5289 3298
+4076 3298 5225
+4647 3683 5289
+4647 5289 4076
+3444 4647 4076
+3444 4076 4648
+4646 4075 4647
+4646 4647 3444
+4075 5288 3683
+4075 3683 4647
+5286 3297 5288
+5286 5288 4075
+3682 5286 4075
+3682 4075 4646
+5291 4074 4649
+5291 4649 3684
+4074 4646 3444
+4074 3444 4649
+5287 3682 4646
+5287 4646 4074
+3292 5287 4074
+3292 4074 5291
+5273 4073 5287
+5273 5287 3292
+4073 4644 3682
+4073 3682 5287
+4645 3443 4644
+4645 4644 4073
+3675 4645 4073
+3675 4073 5273
+4644 4072 5286
+4644 5286 3682
+4072 5285 3297
+4072 3297 5286
+4643 3681 5285
+4643 5285 4072
+3443 4643 4072
+3443 4072 4644
+4642 4071 4643
+4642 4643 3443
+4071 5284 3681
+4071 3681 4643
+5208 3296 5284
+5208 5284 4071
+3643 5208 4071
+3643 4071 4642
+5272 4070 4645
+5272 4645 3675
+4070 4642 3443
+4070 3443 4645
+5209 3643 4642
+5209 4642 4070
+3291 5209 5272
+5209 4070 5272
+5282 4069 3316
+4069 5281 3316
+4069 4640 5281
+4640 3679 5281
+4641 3442 4069
+3442 4640 4069
+3680 4641 5282
+4641 4069 5282
+4640 4068 3679
+4068 5280 3679
+4068 5279 5280
+5279 3317 5280
+4639 3678 4068
+3678 5279 4068
+3442 4639 4640
+4639 4068 4640
+4638 4067 3442
+4067 4639 3442
+4067 5278 4639
+5278 3678 4639
+5274 3292 4067
+3292 5278 4067
+3676 5274 4638
+5274 4067 4638
+5283 4066 3680
+4066 4641 3680
+4066 4638 4641
+4638 3442 4641
+5275 3676 4066
+3676 4638 4066
+3288 5275 5283
+5275 4066 5283
+5276 4065 3288
+4065 5275 3288
+4065 4636 5275
+4636 3676 5275
+4637 3441 4065
+3441 4636 4065
+3677 4637 5276
+4637 4065 5276
+4636 4064 3676
+4064 5274 3676
+4064 5273 5274
+5273 3292 5274
+4635 3675 4064
+3675 5273 4064
+3441 4635 4636
+4635 4064 4636
+4634 4063 3441
+4063 4635 3441
+4063 5272 4635
+5272 3675 4635
+5234 3291 4063
+3291 5272 4063
+3656 5234 4634
+5234 4063 4634
+5277 4062 3677
+4062 4637 3677
+4062 4634 4637
+4634 3441 4637
+5235 3656 4062
+3656 4634 4062
+3287 5235 5277
+5235 4062 5277
+5270 4061 5269
+5270 5269 3313
+4061 4632 3673
+4061 3673 5269
+4633 3440 4632
+4633 4632 4061
+3674 4633 4061
+3674 4061 5270
+4632 4060 5268
+4632 5268 3673
+4060 5267 3315
+4060 3315 5268
+4631 3672 5267
+4631 5267 4060
+3440 4631 4060
+3440 4060 4632
+4630 4059 4631
+4630 4631 3440
+4059 5266 3672
+4059 3672 4631
+5264 3314 5266
+5264 5266 4059
+3671 5264 4059
+3671 4059 4630
+5271 4058 4633
+5271 4633 3674
+4058 4630 3440
+4058 3440 4633
+5265 3671 4630
+5265 4630 4058
+3301 5265 4058
+3301 4058 5271
+5264 4057 3314
+4057 5263 3314
+4057 4628 5263
+4628 3670 5263
+4629 3439 4057
+3439 4628 4057
+3671 4629 5264
+4629 4057 5264
+4628 4056 3670
+4056 5262 3670
+4056 5260 5262
+5260 3312 5262
+4627 3669 4056
+3669 5260 4056
+3439 4627 4628
+4627 4056 4628
+4626 4055 3439
+4055 4627 3439
+4055 5261 4627
+5261 3669 4627
+5228 3302 4055
+3302 5261 4055
+3653 5228 4626
+5228 4055 4626
+5265 4054 3671
+4054 4629 3671
+4054 4626 4629
+4626 3439 4629
+5229 3653 4054
+3653 4626 4054
+3301 5229 5265
+5229 4054 5265
+5219 4053 5261
+5219 5261 3302
+4053 4624 3669
+4053 3669 5261
+4625 3438 4624
+4625 4624 4053
+3648 4625 4053
+3648 4053 5219
+4624 4052 5260
+4624 5260 3669
+4052 5246 5260
+5246 3312 5260
+4623 3662 5246
+4623 5246 4052
+3438 4623 4052
+3438 4052 4624
+4622 4051 4623
+4622 4623 3438
+4051 5247 3662
+4051 3662 4623
+5252 3311 5247
+5252 5247 4051
+3665 5252 4622
+5252 4051 4622
+5218 4050 4625
+5218 4625 3648
+4050 4622 3438
+4050 3438 4625
+5253 3665 4050
+3665 4622 4050
+3300 5253 4050
+3300 4050 5218
+5245 4049 5259
+5245 5259 3312
+4049 4620 5259
+4620 3668 5259
+4621 3437 4049
+3437 4620 4049
+3661 4621 5245
+4621 4049 5245
+4620 4048 3668
+4048 5258 3668
+4048 5257 5258
+5257 3306 5258
+4619 3667 4048
+3667 5257 4048
+3437 4619 4620
+4619 4048 4620
+4618 4047 3437
+4047 4619 3437
+4047 5256 4619
+5256 3667 4619
+5255 3303 4047
+3303 5256 4047
+3666 5255 4618
+5255 4047 4618
+5244 4046 3661
+4046 4621 3661
+4046 4618 4621
+4618 3437 4621
+5254 3666 4046
+3666 4618 4046
+3286 5254 5244
+5254 4046 5244
+5213 4045 5253
+5213 5253 3300
+4045 4616 5253
+4616 3665 5253
+4617 3436 4045
+3436 4616 4045
+3645 4617 4045
+3645 4045 5213
+4616 4044 3665
+4044 5252 3665
+4044 5240 3311
+4044 3311 5252
+4615 3659 5240
+4615 5240 4044
+3436 4615 4616
+4615 4044 4616
+4614 4043 4615
+4614 4615 3436
+4043 5241 3659
+4043 3659 4615
+5251 3310 5241
+5251 5241 4043
+3664 5251 4043
+3664 4043 4614
+5212 4042 4617
+5212 4617 3645
+4042 4614 3436
+4042 3436 4617
+5250 3664 4614
+5250 4614 4042
+3309 5250 4042
+3309 4042 5212
+5248 4041 5238
+5248 5238 3294
+4041 4612 3658
+4041 3658 5238
+4613 3435 4612
+4613 4612 4041
+3663 4613 4041
+3663 4041 5248
+4612 4040 5239
+4612 5239 3658
+4040 5247 3311
+4040 3311 5239
+4611 3662 5247
+4611 5247 4040
+3435 4611 4040
+3435 4040 4612
+4610 4039 4611
+4610 4611 3435
+4039 5246 3662
+4039 3662 4611
+5245 3312 5246
+5245 5246 4039
+3661 5245 4039
+3661 4039 4610
+5249 4038 4613
+5249 4613 3663
+4038 4610 3435
+4038 3435 4613
+5244 3661 4610
+5244 4610 4038
+3286 5244 4038
+3286 4038 5249
+5242 4037 3310
+4037 5241 3310
+4037 4608 5241
+4608 3659 5241
+4609 3434 4037
+3434 4608 4037
+3660 4609 5242
+4609 4037 5242
+4608 4036 3659
+4036 5240 3659
+4036 5239 5240
+5239 3311 5240
+4607 3658 4036
+3658 5239 4036
+3434 4607 4608
+4607 4036 4608
+4606 4035 3434
+4035 4607 3434
+4035 5238 4607
+5238 3658 4607
+5237 3294 4035
+3294 5238 4035
+3657 5237 4606
+5237 4035 4606
+5243 4034 3660
+4034 4609 3660
+4034 4606 4609
+4606 3434 4609
+5236 3657 4034
+3657 4606 4034
+3290 5236 5243
+5236 4034 5243
+5234 4033 5210
+5234 5210 3291
+4033 4604 3644
+4033 3644 5210
+4605 3433 4033
+3433 4604 4033
+3656 4605 4033
+3656 4033 5234
+4604 4032 3644
+4032 5211 3644
+4032 5233 5211
+5233 3309 5211
+4603 3655 4032
+3655 5233 4032
+3433 4603 4604
+4603 4032 4604
+4602 4031 3433
+4031 4603 3433
+4031 5232 4603
+5232 3655 4603
+5231 3289 4031
+3289 5232 4031
+3654 5231 4602
+5231 4031 4602
+5235 4030 4605
+5235 4605 3656
+4030 4602 4605
+4602 3433 4605
+5230 3654 4030
+3654 4602 4030
+3287 5230 4030
+3287 4030 5235
+5228 4029 5220
+5228 5220 3302
+4029 4600 3649
+4029 3649 5220
+4601 3432 4600
+4601 4600 4029
+3653 4601 4029
+3653 4029 5228
+4600 4028 5221
+4600 5221 3649
+4028 5227 3308
+4028 3308 5221
+4599 3652 5227
+4599 5227 4028
+3432 4599 4028
+3432 4028 4600
+4598 4027 4599
+4598 4599 3432
+4027 5226 3652
+4027 3652 4599
+5225 3298 5226
+5225 5226 4027
+3651 5225 4027
+3651 4027 4598
+5229 4026 4601
+5229 4601 3653
+4026 4598 3432
+4026 3432 4601
+5224 3651 4598
+5224 4598 4026
+3301 5224 4026
+3301 4026 5229
+5215 4025 3299
+4025 5223 3299
+4025 4596 5223
+4596 3650 5223
+4597 3431 4025
+3431 4596 4025
+3646 4597 5215
+4597 4025 5215
+4596 4024 3650
+4024 5222 3650
+4024 5221 5222
+5221 3308 5222
+4595 3649 4024
+3649 5221 4024
+3431 4595 4596
+4595 4024 4596
+4594 4023 3431
+4023 4595 3431
+4023 5220 4595
+5220 3649 4595
+5219 3302 4023
+3302 5220 4023
+3648 5219 4594
+5219 4023 4594
+5214 4022 3646
+4022 4597 3646
+4022 4594 4597
+4594 3431 4597
+5218 3648 4022
+3648 4594 4022
+3300 5218 5214
+5218 4022 5214
+5216 4021 5215
+5216 5215 3299
+4021 4592 3646
+4021 3646 5215
+4593 3430 4592
+4593 4592 4021
+3647 4593 4021
+3647 4021 5216
+4592 4020 5214
+4592 5214 3646
+4020 5213 3300
+4020 3300 5214
+4591 3645 5213
+4591 5213 4020
+3430 4591 4020
+3430 4020 4592
+4590 4019 4591
+4590 4591 3430
+4019 5212 3645
+4019 3645 4591
+5204 3309 5212
+5204 5212 4019
+3641 5204 4590
+5204 4019 4590
+5217 4018 3647
+4018 4593 3647
+4018 4590 4593
+4590 3430 4593
+5205 3641 4018
+3641 4590 4018
+3295 5205 5217
+5205 4018 5217
+5210 4017 3291
+4017 5209 3291
+4017 4588 5209
+4588 3643 5209
+4589 3429 4017
+3429 4588 4017
+3644 4589 5210
+4589 4017 5210
+4588 4016 5208
+4588 5208 3643
+4016 5207 3296
+4016 3296 5208
+4587 3642 5207
+4587 5207 4016
+3429 4587 4588
+4587 4016 4588
+4586 4015 3429
+4015 4587 3429
+4015 5206 4587
+5206 3642 4587
+5205 3295 4015
+3295 5206 4015
+3641 5205 4586
+5205 4015 4586
+5211 4014 3644
+4014 4589 3644
+4014 4586 4589
+4586 3429 4589
+5204 3641 4014
+3641 4586 4014
+3309 5204 5211
+5204 4014 5211
+5077 4013 3255
+4013 5200 3255
+4013 4584 5200
+4584 3639 5200
+4585 3428 4013
+3428 4584 4013
+3577 4585 5077
+4585 4013 5077
+4584 4012 3639
+4012 5201 3639
+4012 5146 5201
+5146 3279 5201
+4583 3612 4012
+3612 5146 4012
+3428 4583 4584
+4583 4012 4584
+4582 4011 3428
+4011 4583 3428
+4011 5147 4583
+5147 3612 4583
+5203 3330 4011
+3330 5147 4011
+3640 5203 4582
+5203 4011 4582
+5076 4010 3577
+4010 4585 3577
+4010 4582 4585
+4582 3428 4585
+5202 3640 4010
+3640 4582 4010
+3329 5202 5076
+5202 4010 5076
+5199 4009 5142
+5199 5142 3277
+4009 4580 3610
+4009 3610 5142
+4581 3427 4580
+4581 4580 4009
+3638 4581 4009
+3638 4009 5199
+4580 4008 5143
+4580 5143 3610
+4008 5201 3279
+4008 3279 5143
+4579 3639 5201
+4579 5201 4008
+3427 4579 4008
+3427 4008 4580
+4578 4007 4579
+4578 4579 3427
+4007 5200 3639
+4007 3639 4579
+5068 3255 5200
+5068 5200 4007
+3573 5068 4007
+3573 4007 4578
+5198 4006 4581
+5198 4581 3638
+4006 4578 3427
+4006 3427 4581
+5069 3573 4578
+5069 4578 4006
+3254 5069 4006
+3254 4006 5198
+5089 4005 3256
+4005 5194 3256
+4005 4576 5194
+4576 3636 5194
+4577 3426 4005
+3426 4576 4005
+3583 4577 5089
+4577 4005 5089
+4576 4004 3636
+4004 5195 3636
+4004 5168 5195
+5168 3281 5195
+4575 3623 4004
+3623 5168 4004
+3426 4575 4576
+4575 4004 4576
+4574 4003 3426
+4003 4575 3426
+4003 5169 4575
+5169 3623 4575
+5199 3277 4003
+3277 5169 4003
+3638 5199 4574
+5199 4003 4574
+5088 4002 3583
+4002 4577 3583
+4002 4574 4577
+4574 3426 4577
+5198 3638 4002
+3638 4574 4002
+3254 5198 5088
+5198 4002 5088
+5196 4001 5162
+5196 5162 3372
+4001 4572 3620
+4001 3620 5162
+4573 3425 4572
+4573 4572 4001
+3637 4573 4001
+3637 4001 5196
+4572 4000 5163
+4572 5163 3620
+4000 5195 3281
+4000 3281 5163
+4571 3636 5195
+4571 5195 4000
+3425 4571 4000
+3425 4000 4572
+4570 3999 4571
+4570 4571 3425
+3999 5194 3636
+3999 3636 4571
+5082 3256 5194
+5082 5194 3999
+3580 5082 3999
+3580 3999 4570
+5197 3998 4573
+5197 4573 3637
+3998 4570 3425
+3998 3425 4573
+5083 3580 4570
+5083 4570 3998
+3253 5083 3998
+3253 3998 5197
+5127 3997 3275
+3997 5193 3275
+3997 4568 5193
+4568 3635 5193
+4569 3424 3997
+3424 4568 3997
+3602 4569 5127
+4569 3997 5127
+4568 3996 3635
+3996 5192 3635
+3996 5191 5192
+5191 3285 5192
+4567 3634 3996
+3634 5191 3996
+3424 4567 4568
+4567 3996 4568
+4566 3995 3424
+3995 4567 3424
+3995 5190 4567
+5190 3634 4567
+5058 3248 3995
+3248 5190 3995
+3568 5058 4566
+5058 3995 4566
+5126 3994 3602
+3994 4569 3602
+3994 4566 4569
+4566 3424 4569
+5059 3568 3994
+3568 4566 3994
+3245 5059 5126
+5059 3994 5126
+5188 3993 3271
+3993 5182 3271
+3993 4564 5182
+4564 3630 5182
+4565 3423 3993
+3423 4564 3993
+3633 4565 5188
+4565 3993 5188
+4564 3992 3630
+3992 5183 3630
+3992 5158 5183
+5158 3280 5183
+4563 3618 3992
+3618 5158 3992
+3423 4563 4564
+4563 3992 4564
+4562 3991 3423
+3991 4563 3423
+3991 5159 4563
+5159 3618 4563
+5187 3282 5159
+5187 5159 3991
+3632 5187 3991
+3632 3991 4562
+5189 3990 3633
+3990 4565 3633
+3990 4562 3423
+3990 3423 4565
+5186 3632 4562
+5186 4562 3990
+3259 5186 3990
+3259 3990 5189
+5184 3989 3268
+3989 5178 3268
+3989 4560 5178
+4560 3628 5178
+4561 3422 3989
+3422 4560 3989
+3631 4561 5184
+4561 3989 5184
+4560 3988 3628
+3988 5179 3628
+3988 5152 5179
+5152 3283 5179
+4559 3615 3988
+3615 5152 3988
+3422 4559 4560
+4559 3988 4560
+4558 3987 3422
+3987 4559 3422
+3987 5153 4559
+5153 3615 4559
+5183 3280 3987
+3280 5153 3987
+3630 5183 4558
+5183 3987 4558
+5185 3986 3631
+3986 4561 3631
+3986 4558 4561
+4558 3422 4561
+5182 3630 3986
+3630 4558 3986
+3271 5182 5185
+5182 3986 5185
+5180 3985 3262
+3985 5170 3262
+3985 4556 5170
+4556 3624 5170
+4557 3421 3985
+3421 4556 3985
+3629 4557 5180
+4557 3985 5180
+4556 3984 3624
+3984 5171 3624
+3984 5132 5171
+5132 3278 5171
+4555 3605 3984
+3605 5132 3984
+3421 4555 4556
+4555 3984 4556
+4554 3983 3421
+3983 4555 3421
+3983 5133 4555
+5133 3605 4555
+5179 3283 3983
+3283 5133 3983
+3628 5179 4554
+5179 3983 4554
+5181 3982 3629
+3982 4557 3629
+3982 4554 4557
+4554 3421 4557
+5178 3628 3982
+3628 4554 3982
+3268 5178 5181
+5178 3982 5181
+5176 3981 3342
+3981 5175 3342
+3981 4552 5175
+4552 3626 5175
+4553 3420 3981
+3420 4552 3981
+3627 4553 5176
+4553 3981 5176
+4552 3980 3626
+3980 5174 3626
+3980 5173 5174
+5173 3346 5174
+4551 3625 3980
+3625 5173 3980
+3420 4551 4552
+4551 3980 4552
+4550 3979 3420
+3979 4551 3420
+3979 5172 4551
+5172 3625 4551
+5171 3278 3979
+3278 5172 3979
+3624 5171 4550
+5171 3979 4550
+5177 3978 3627
+3978 4553 3627
+3978 4550 4553
+4550 3420 4553
+5170 3624 3978
+3624 4550 3978
+3262 5170 5177
+5170 3978 5177
+5168 3977 3281
+3977 5164 3281
+3977 4548 5164
+4548 3621 5164
+4549 3419 3977
+3419 4548 3977
+3623 4549 5168
+4549 3977 5168
+4548 3976 3621
+3976 5165 3621
+3976 5110 5165
+5110 3266 5165
+4547 3594 3976
+3594 5110 3976
+3419 4547 4548
+4547 3976 4548
+4546 3975 3419
+3975 4547 3419
+3975 5111 4547
+5111 3594 4547
+5140 3258 3975
+3258 5111 3975
+3609 5140 4546
+5140 3975 4546
+5169 3974 3623
+3974 4549 3623
+3974 4546 4549
+4546 3419 4549
+5141 3609 3974
+3609 4546 3974
+3277 5141 5169
+5141 3974 5169
+5166 3973 3266
+3973 5165 3266
+3973 4544 5165
+4544 3621 5165
+4545 3418 3973
+3418 4544 3973
+3622 4545 5166
+4545 3973 5166
+4544 3972 3621
+3972 5164 3621
+3972 5163 5164
+5163 3281 5164
+4543 3620 3972
+3620 5163 3972
+3418 4543 4544
+4543 3972 4544
+4542 3971 3418
+3971 4543 3418
+3971 5162 4543
+5162 3620 4543
+5161 3372 3971
+3372 5162 3971
+3619 5161 4542
+5161 3971 4542
+5167 3970 3622
+3970 4545 3622
+3970 4542 4545
+4542 3418 4545
+5160 3619 3970
+3619 4542 3970
+3257 5160 5167
+5160 3970 5167
+5158 3969 3280
+3969 5148 3280
+3969 4540 5148
+4540 3613 5148
+4541 3417 3969
+3417 4540 3969
+3618 4541 5158
+4541 3969 5158
+4540 3968 3613
+3968 5149 3613
+3968 5157 5149
+5157 3270 5149
+4539 3617 3968
+3617 5157 3968
+3417 4539 4540
+4539 3968 4540
+4538 3967 3417
+3967 4539 3417
+3967 5156 4539
+5156 3617 4539
+5155 3269 3967
+3269 5156 3967
+3616 5155 4538
+5155 3967 4538
+5159 3966 3618
+3966 4541 3618
+3966 4538 4541
+4538 3417 4541
+5154 3616 4538
+5154 4538 3966
+3282 5154 3966
+3282 3966 5159
+5152 3965 3283
+3965 5134 3283
+3965 4536 5134
+4536 3606 5134
+4537 3416 3965
+3416 4536 3965
+3615 4537 5152
+4537 3965 5152
+4536 3964 3606
+3964 5135 3606
+3964 5151 5135
+5151 3276 5135
+4535 3614 3964
+3614 5151 3964
+3416 4535 4536
+4535 3964 4536
+4534 3963 3416
+3963 4535 3416
+3963 5150 4535
+5150 3614 4535
+5149 3270 3963
+3270 5150 3963
+3613 5149 4534
+5149 3963 4534
+5153 3962 3615
+3962 4537 3615
+3962 4534 4537
+4534 3416 4537
+5148 3613 3962
+3613 4534 3962
+3280 5148 5153
+5148 3962 5153
+5146 3961 3279
+3961 5138 3279
+3961 4532 5138
+4532 3608 5138
+4533 3415 3961
+3415 4532 3961
+3612 4533 5146
+4533 3961 5146
+4532 3960 3608
+3960 5139 3608
+3960 5096 5139
+5096 3263 5139
+4531 3587 3960
+3587 5096 3960
+3415 4531 4532
+4531 3960 4532
+4530 3959 3415
+3959 4531 3415
+3959 5097 4531
+5097 3587 4531
+5145 3349 3959
+3349 5097 3959
+3611 5145 4530
+5145 3959 4530
+5147 3958 3612
+3958 4533 3612
+3958 4530 4533
+4530 3415 4533
+5144 3611 3958
+3611 4530 3958
+3330 5144 5147
+5144 3958 5147
+5142 3957 3277
+3957 5141 3277
+3957 4528 5141
+4528 3609 5141
+4529 3414 3957
+3414 4528 3957
+3610 4529 5142
+4529 3957 5142
+4528 3956 3609
+3956 5140 3609
+3956 5104 5140
+5104 3258 5140
+4527 3591 3956
+3591 5104 3956
+3414 4527 4528
+4527 3956 4528
+4526 3955 3414
+3955 4527 3414
+3955 5105 4527
+5105 3591 4527
+5139 3263 3955
+3263 5105 3955
+3608 5139 4526
+5139 3955 4526
+5143 3954 3610
+3954 4529 3610
+3954 4526 4529
+4526 3414 4529
+5138 3608 3954
+3608 4526 3954
+3279 5138 5143
+5138 3954 5143
+5136 3953 3276
+3953 5135 3276
+3953 4524 5135
+4524 3606 5135
+4525 3413 4524
+4525 4524 3953
+3607 4525 5136
+4525 3953 5136
+4524 3952 3606
+3952 5134 3606
+3952 5133 5134
+5133 3283 5134
+4523 3605 3952
+3605 5133 3952
+3413 4523 4524
+4523 3952 4524
+4522 3951 3413
+3951 4523 3413
+3951 5132 4523
+5132 3605 4523
+5131 3278 3951
+3278 5132 3951
+3604 5131 3951
+3604 3951 4522
+5137 3950 3607
+3950 4525 3607
+3950 4522 3413
+3950 3413 4525
+5130 3604 4522
+5130 4522 3950
+3265 5130 3950
+3265 3950 5137
+5053 3949 5122
+5053 5122 3236
+3949 4520 3600
+3949 3600 5122
+4521 3412 4520
+4521 4520 3949
+3565 4521 3949
+3565 3949 5053
+4520 3948 5123
+4520 5123 3600
+3948 5129 3273
+3948 3273 5123
+4519 3603 5129
+4519 5129 3948
+3412 4519 3948
+3412 3948 4520
+4518 3947 4519
+4518 4519 3412
+3947 5128 3603
+3947 3603 4519
+5127 3275 5128
+5127 5128 3947
+3602 5127 3947
+3602 3947 4518
+5052 3946 4521
+5052 4521 3565
+3946 4518 3412
+3946 3412 4521
+5126 3602 4518
+5126 4518 3946
+3245 5126 3946
+3245 3946 5052
+5035 3945 3227
+3945 5118 3227
+3945 4516 5118
+4516 3598 5118
+4517 3411 3945
+3411 4516 3945
+3556 4517 5035
+4517 3945 5035
+4516 3944 3598
+3944 5119 3598
+3944 5125 5119
+5125 3272 5119
+4515 3601 3944
+3601 5125 3944
+3411 4515 4516
+4515 3944 4516
+4514 3943 3411
+3943 4515 3411
+3943 5124 4515
+5124 3601 4515
+5123 3273 3943
+3273 5124 3943
+3600 5123 4514
+5123 3943 4514
+5034 3942 3556
+3942 4517 3556
+3942 4514 4517
+4514 3411 4517
+5122 3600 3942
+3600 4514 3942
+3236 5122 5034
+5122 3942 5034
+5031 3941 3230
+3941 5112 3230
+3941 4512 5112
+4512 3595 5112
+4513 3410 3941
+3410 4512 3941
+3554 4513 5031
+4513 3941 5031
+4512 3940 3595
+3940 5113 3595
+3940 5121 5113
+5121 3274 5113
+4511 3599 3940
+3599 5121 3940
+3410 4511 4512
+4511 3940 4512
+4510 3939 3410
+3939 4511 3410
+3939 5120 4511
+5120 3599 4511
+5119 3272 3939
+3272 5120 3939
+3598 5119 4510
+5119 3939 4510
+5030 3938 3554
+3938 4513 3554
+3938 4510 4513
+4510 3410 4513
+5118 3598 3938
+3598 4510 3938
+3227 5118 5030
+5118 3938 5030
+5025 3937 5117
+5025 5117 3337
+3937 4508 5117
+4508 3597 5117
+4509 3409 3937
+3409 4508 3937
+3551 4509 5025
+4509 3937 5025
+4508 3936 3597
+3936 5116 3597
+3936 5115 5116
+5115 3345 5116
+4507 3596 3936
+3596 5115 3936
+3409 4507 4508
+4507 3936 4508
+4506 3935 3409
+3935 4507 3409
+3935 5114 4507
+5114 3596 4507
+5113 3274 3935
+3274 5114 3935
+3595 5113 4506
+5113 3935 4506
+5024 3934 3551
+3934 4509 3551
+3934 4506 4509
+4506 3409 4509
+5112 3595 3934
+3595 4506 3934
+3230 5112 5024
+5112 3934 5024
+5103 3933 5111
+5103 5111 3258
+3933 4504 3594
+3933 3594 5111
+4505 3408 4504
+4505 4504 3933
+3590 4505 3933
+3590 3933 5103
+4504 3932 5110
+4504 5110 3594
+3932 5109 3266
+3932 3266 5110
+4503 3593 5109
+4503 5109 3932
+3408 4503 3932
+3408 3932 4504
+4502 3931 4503
+4502 4503 3408
+3931 5108 3593
+3931 3593 4503
+5107 3267 5108
+5107 5108 3931
+3592 5107 3931
+3592 3931 4502
+5102 3930 4505
+5102 4505 3590
+3930 4502 3408
+3930 3408 4505
+5106 3592 4502
+5106 4502 3930
+3260 5106 3930
+3260 3930 5102
+5095 3929 5105
+5095 5105 3263
+3929 4500 3591
+3929 3591 5105
+4501 3407 4500
+4501 4500 3929
+3586 4501 3929
+3586 3929 5095
+4500 3928 5104
+4500 5104 3591
+3928 5103 3258
+3928 3258 5104
+4499 3590 5103
+4499 5103 3928
+3407 4499 3928
+3407 3928 4500
+4498 3927 4499
+4498 4499 3407
+3927 5102 3590
+3927 3590 4499
+5101 3260 5102
+5101 5102 3927
+3589 5101 3927
+3589 3927 4498
+5094 3926 4501
+5094 4501 3586
+3926 4498 3407
+3926 3407 4501
+5100 3589 4498
+5100 4498 3926
+3264 5100 3926
+3264 3926 5094
+5098 3925 3349
+3925 5097 3349
+3925 4496 3587
+3925 3587 5097
+4497 3406 3925
+3406 4496 3925
+3588 4497 5098
+4497 3925 5098
+4496 3924 5096
+4496 5096 3587
+3924 5095 3263
+3924 3263 5096
+4495 3586 5095
+4495 5095 3924
+3406 4495 3924
+3406 3924 4496
+4494 3923 4495
+4494 4495 3406
+3923 5094 3586
+3923 3586 4495
+5093 3264 5094
+5093 5094 3923
+3585 5093 3923
+3585 3923 4494
+5099 3922 3588
+3922 4497 3588
+3922 4494 3406
+3922 3406 4497
+5092 3585 4494
+5092 4494 3922
+3350 5092 3922
+3350 3922 5099
+5090 3921 3234
+3921 5080 3234
+3921 4492 5080
+4492 3579 5080
+4493 3405 3921
+3405 4492 3921
+3584 4493 5090
+4493 3921 5090
+4492 3920 3579
+3920 5081 3579
+3920 5089 5081
+5089 3256 5081
+4491 3583 3920
+3583 5089 3920
+3405 4491 4492
+4491 3920 4492
+4490 3919 3405
+3919 4491 3405
+3919 5088 4491
+5088 3583 4491
+5070 3254 3919
+3254 5088 3919
+3574 5070 4490
+5070 3919 4490
+5091 3918 3584
+3918 4493 3584
+3918 4490 4493
+4490 3405 4493
+5071 3574 3918
+3574 4490 3918
+3225 5071 5091
+5071 3918 5091
+5086 3917 3243
+3917 5085 3243
+3917 4488 5085
+4488 3581 5085
+4489 3404 3917
+3404 4488 3917
+3582 4489 5086
+4489 3917 5086
+4488 3916 3581
+3916 5084 3581
+3916 5083 5084
+5083 3253 5084
+4487 3580 3916
+3580 5083 3916
+3404 4487 4488
+4487 3916 4488
+4486 3915 3404
+3915 4487 3404
+3915 5082 4487
+5082 3580 4487
+5081 3256 3915
+3256 5082 3915
+3579 5081 4486
+5081 3915 4486
+5087 3914 3582
+3914 4489 3582
+3914 4486 4489
+4486 3404 4489
+5080 3579 3914
+3579 4486 3914
+3234 5080 5087
+5080 3914 5087
+5078 3913 3232
+3913 5066 3232
+3913 4484 5066
+4484 3572 5066
+4485 3403 3913
+3403 4484 3913
+3578 4485 5078
+4485 3913 5078
+4484 3912 3572
+3912 5067 3572
+3912 5077 5067
+5077 3255 5067
+4483 3577 3912
+3577 5077 3912
+3403 4483 4484
+4483 3912 4484
+4482 3911 3403
+3911 4483 3403
+3911 5076 4483
+5076 3577 4483
+5075 3329 3911
+3329 5076 3911
+3576 5075 4482
+5075 3911 4482
+5079 3910 3578
+3910 4485 3578
+3910 4482 4485
+4482 3403 4485
+5074 3576 3910
+3576 4482 3910
+3328 5074 5079
+5074 3910 5079
+5072 3909 3225
+3909 5071 3225
+3909 4480 5071
+4480 3574 5071
+4481 3402 3909
+3402 4480 3909
+3575 4481 5072
+4481 3909 5072
+4480 3908 3574
+3908 5070 3574
+3908 5069 5070
+5069 3254 5070
+4479 3573 3908
+3573 5069 3908
+3402 4479 4480
+4479 3908 4480
+4478 3907 3402
+3907 4479 3402
+3907 5068 4479
+5068 3573 4479
+5067 3255 3907
+3255 5068 3907
+3572 5067 4478
+5067 3907 4478
+5073 3906 3575
+3906 4481 3575
+3906 4478 4481
+4478 3402 4481
+5066 3572 3906
+3572 4478 3906
+3232 5066 5073
+5066 3906 5073
+5043 3905 3242
+3905 5054 3242
+3905 4476 5054
+4476 3566 5054
+4477 3401 3905
+3401 4476 3905
+3560 4477 5043
+4477 3905 5043
+4476 3904 5055
+4476 5055 3566
+3904 5065 3249
+3904 3249 5055
+4475 3571 5065
+4475 5065 3904
+3401 4475 3904
+3401 3904 4476
+4474 3903 4475
+4474 4475 3401
+3903 5064 3571
+3903 3571 4475
+5062 3252 5064
+5062 5064 3903
+3570 5062 4474
+5062 3903 4474
+5042 3902 3560
+3902 4477 3560
+3902 4474 4477
+4474 3401 4477
+5063 3570 3902
+3570 4474 3902
+3246 5063 5042
+5063 3902 5042
+5039 3901 3246
+3901 5063 3246
+3901 4472 5063
+4472 3570 5063
+4473 3400 3901
+3400 4472 3901
+3558 4473 5039
+4473 3901 5039
+4472 3900 3570
+3900 5062 3570
+3900 5061 5062
+5061 3252 5062
+4471 3569 3900
+3569 5061 3900
+3400 4471 4472
+4471 3900 4472
+4470 3899 3400
+3899 4471 3400
+3899 5060 4471
+5060 3569 4471
+5046 3247 3899
+3247 5060 3899
+3562 5046 4470
+5046 3899 4470
+5038 3898 3558
+3898 4473 3558
+3898 4470 4473
+4470 3400 4473
+5047 3562 3898
+3562 4470 3898
+3244 5047 5038
+5047 3898 5038
+5058 3897 5057
+5058 5057 3248
+3897 4468 5057
+4468 3567 5057
+4469 3399 4468
+4469 4468 3897
+3568 4469 3897
+3568 3897 5058
+4468 3896 3567
+3896 5056 3567
+3896 5055 5056
+5055 3249 5056
+4467 3566 3896
+3566 5055 3896
+3399 4467 4468
+4467 3896 4468
+4466 3895 4467
+4466 4467 3399
+3895 5054 3566
+3895 3566 4467
+5050 3242 5054
+5050 5054 3895
+3564 5050 3895
+3564 3895 4466
+5059 3894 4469
+5059 4469 3568
+3894 4466 3399
+3894 3399 4469
+5051 3564 4466
+5051 4466 3894
+3245 5051 3894
+3245 3894 5059
+5045 3893 5032
+5045 5032 3233
+3893 4464 3555
+3893 3555 5032
+4465 3398 4464
+4465 4464 3893
+3561 4465 3893
+3561 3893 5045
+4464 3892 5033
+4464 5033 3555
+3892 5053 3236
+3892 3236 5033
+4463 3565 5053
+4463 5053 3892
+3398 4463 3892
+3398 3892 4464
+4462 3891 4463
+4462 4463 3398
+3891 5052 3565
+3891 3565 4463
+5051 3245 5052
+5051 5052 3891
+3564 5051 3891
+3564 3891 4462
+5044 3890 4465
+5044 4465 3561
+3890 4462 3398
+3890 3398 4465
+5050 3564 4462
+5050 4462 3890
+3242 5050 3890
+3242 3890 5044
+5048 3889 3240
+3889 5018 3240
+3889 4460 5018
+4460 3548 5018
+4461 3397 3889
+3397 4460 3889
+3563 4461 5048
+4461 3889 5048
+4460 3888 3548
+3888 5019 3548
+3888 5036 5019
+5036 3235 5019
+4459 3557 3888
+3557 5036 3888
+3397 4459 4460
+4459 3888 4460
+4458 3887 3397
+3887 4459 3397
+3887 5037 4459
+5037 3557 4459
+5047 3244 3887
+3244 5037 3887
+3562 5047 4458
+5047 3887 4458
+5049 3886 3563
+3886 4461 3563
+3886 4458 4461
+4458 3397 4461
+5046 3562 3886
+3562 4458 3886
+3247 5046 5049
+5046 3886 5049
+5041 3885 5004
+5041 5004 3237
+3885 4456 3541
+3885 3541 5004
+4457 3396 4456
+4457 4456 3885
+3559 4457 3885
+3559 3885 5041
+4456 3884 5005
+4456 5005 3541
+3884 5045 3233
+3884 3233 5005
+4455 3561 5045
+4455 5045 3884
+3396 4455 3884
+3396 3884 4456
+4454 3883 4455
+4454 4455 3396
+3883 5044 3561
+3883 3561 4455
+5043 3242 5044
+5043 5044 3883
+3560 5043 3883
+3560 3883 4454
+5040 3882 4457
+5040 4457 3559
+3882 4454 3396
+3882 3396 4457
+5042 3560 4454
+5042 4454 3882
+3246 5042 3882
+3246 3882 5040
+4991 3881 3237
+3881 5041 3237
+3881 4452 5041
+4452 3559 5041
+4453 3395 3881
+3395 4452 3881
+3534 4453 4991
+4453 3881 4991
+4452 3880 3559
+3880 5040 3559
+3880 5039 5040
+5039 3246 5040
+4451 3558 3880
+3558 5039 3880
+3395 4451 4452
+4451 3880 4452
+4450 3879 3395
+3879 4451 3395
+3879 5038 4451
+5038 3558 4451
+5037 3244 3879
+3244 5038 3879
+3557 5037 4450
+5037 3879 4450
+4990 3878 3534
+3878 4453 3534
+3878 4450 4453
+4450 3395 4453
+5036 3557 3878
+3557 4450 3878
+3235 5036 3878
+3235 3878 4990
+5034 3877 5033
+5034 5033 3236
+3877 4448 3555
+3877 3555 5033
+4449 3394 4448
+4449 4448 3877
+3556 4449 3877
+3556 3877 5034
+4448 3876 5032
+4448 5032 3555
+3876 5006 3233
+3876 3233 5032
+4447 3542 5006
+4447 5006 3876
+3394 4447 3876
+3394 3876 4448
+4446 3875 4447
+4446 4447 3394
+3875 5007 3542
+3875 3542 4447
+5028 3224 5007
+5028 5007 3875
+3553 5028 3875
+3553 3875 4446
+5035 3874 4449
+5035 4449 3556
+3874 4446 3394
+3874 3394 4449
+5029 3553 4446
+5029 4446 3874
+3227 5029 5035
+5029 3874 5035
+5003 3873 5022
+5003 5022 3241
+3873 4444 3550
+3873 3550 5022
+4445 3393 4444
+4445 4444 3873
+3540 4445 3873
+3540 3873 5003
+4444 3872 3550
+3872 5023 3550
+3872 5031 5023
+5031 3230 5023
+4443 3554 3872
+3554 5031 3872
+3393 4443 3872
+3393 3872 4444
+4442 3871 4443
+4442 4443 3393
+3871 5030 4443
+5030 3554 4443
+5029 3227 3871
+3227 5030 3871
+3553 5029 3871
+3553 3871 4442
+5002 3870 4445
+5002 4445 3540
+3870 4442 3393
+3870 3393 4445
+5028 3553 4442
+5028 4442 3870
+3224 5028 3870
+3224 3870 5002
+4997 3869 5027
+4997 5027 3340
+3869 4440 3552
+3869 3552 5027
+4441 3392 4440
+4441 4440 3869
+3537 4441 3869
+3537 3869 4997
+4440 3868 5026
+4440 5026 3552
+3868 5025 3337
+3868 3337 5026
+4439 3551 5025
+4439 5025 3868
+3392 4439 3868
+3392 3868 4440
+4438 3867 4439
+4438 4439 3392
+3867 5024 4439
+5024 3551 4439
+5023 3230 3867
+3230 5024 3867
+3550 5023 3867
+3550 3867 4438
+4996 3866 4441
+4996 4441 3537
+3866 4438 3392
+3866 3392 4441
+5022 3550 4438
+5022 4438 3866
+3241 5022 3866
+3241 3866 4996
+5020 3865 3238
+3865 5014 3238
+3865 4436 5014
+4436 3546 5014
+4437 3391 3865
+3391 4436 3865
+3549 4437 5020
+4437 3865 5020
+4436 3864 3546
+3864 5015 3546
+3864 4988 5015
+4988 3226 5015
+4435 3533 3864
+3533 4988 3864
+3391 4435 4436
+4435 3864 4436
+4434 3863 3391
+3863 4435 3391
+3863 4989 4435
+4989 3533 4435
+5019 3235 3863
+3235 4989 3863
+3548 5019 4434
+5019 3863 4434
+5021 3862 3549
+3862 4437 3549
+3862 4434 4437
+4434 3391 4437
+5018 3548 3862
+3548 4434 3862
+3240 5018 5021
+5018 3862 5021
+5016 3861 3239
+3861 5008 3239
+3861 4432 5008
+4432 3543 5008
+4433 3390 3861
+3390 4432 3861
+3547 4433 5016
+4433 3861 5016
+4432 3860 3543
+3860 5009 3543
+3860 4982 5009
+4982 3229 5009
+4431 3530 3860
+3530 4982 3860
+3390 4431 4432
+4431 3860 4432
+4430 3859 3390
+3859 4431 3390
+3859 4983 4431
+4983 3530 4431
+5015 3226 3859
+3226 4983 3859
+3546 5015 4430
+5015 3859 4430
+5017 3858 3547
+3858 4433 3547
+3858 4430 4433
+4430 3390 4433
+5014 3546 3858
+3546 4430 3858
+3238 5014 5017
+5014 3858 5017
+5012 3857 3334
+3857 5011 3334
+3857 4428 5011
+4428 3544 5011
+4429 3389 3857
+3389 4428 3857
+3545 4429 5012
+4429 3857 5012
+4428 3856 3544
+3856 5010 3544
+3856 4974 5010
+4974 3335 5010
+4427 3526 3856
+3526 4974 3856
+3389 4427 4428
+4427 3856 4428
+4426 3855 3389
+3855 4427 3389
+3855 4975 4427
+4975 3526 4427
+5009 3229 3855
+3229 4975 3855
+3543 5009 4426
+5009 3855 4426
+5013 3854 3545
+3854 4429 3545
+3854 4426 4429
+4426 3389 4429
+5008 3543 3854
+3543 4426 3854
+3239 5008 5013
+5008 3854 5013
+5006 3853 5005
+5006 5005 3233
+3853 4424 3541
+3853 3541 5005
+4425 3388 4424
+4425 4424 3853
+3542 4425 3853
+3542 3853 5006
+4424 3852 5004
+4424 5004 3541
+3852 4992 3237
+3852 3237 5004
+4423 3535 4992
+4423 4992 3852
+3388 4423 3852
+3388 3852 4424
+4422 3851 4423
+4422 4423 3388
+3851 4993 3535
+3851 3535 4423
+5000 3228 4993
+5000 4993 3851
+3539 5000 3851
+3539 3851 4422
+5007 3850 4425
+5007 4425 3542
+3850 4422 3388
+3850 3388 4425
+5001 3539 4422
+5001 4422 3850
+3224 5001 3850
+3224 3850 5007
+4987 3849 3231
+3849 4994 3231
+3849 4420 3536
+3849 3536 4994
+4421 3387 4420
+4421 4420 3849
+3532 4421 4987
+4421 3849 4987
+4420 3848 4995
+4420 4995 3536
+3848 5003 3241
+3848 3241 4995
+4419 3540 5003
+4419 5003 3848
+3387 4419 3848
+3387 3848 4420
+4418 3847 4419
+4418 4419 3387
+3847 5002 3540
+3847 3540 4419
+5001 3224 5002
+5001 5002 3847
+3539 5001 3847
+3539 3847 4418
+4986 3846 3532
+3846 4421 3532
+3846 4418 3387
+3846 3387 4421
+5000 3539 4418
+5000 4418 3846
+3228 5000 3846
+3228 3846 4986
+4979 3845 3336
+3845 4999 3336
+3845 4416 4999
+4416 3538 4999
+4417 3386 4416
+4417 4416 3845
+3528 4417 4979
+4417 3845 4979
+4416 3844 4998
+4416 4998 3538
+3844 4997 3340
+3844 3340 4998
+4415 3537 4997
+4415 4997 3844
+3386 4415 3844
+3386 3844 4416
+4414 3843 4415
+4414 4415 3386
+3843 4996 3537
+3843 3537 4415
+4995 3241 4996
+4995 4996 3843
+3536 4995 3843
+3536 3843 4414
+4978 3842 3528
+3842 4417 3528
+3842 4414 3386
+3842 3386 4417
+4994 3536 4414
+4994 4414 3842
+3231 4994 4978
+4994 3842 4978
+4985 3841 4993
+4985 4993 3228
+3841 4412 4993
+4412 3535 4993
+4413 3385 4412
+4413 4412 3841
+3531 4413 3841
+3531 3841 4985
+4412 3840 3535
+3840 4992 3535
+3840 4991 4992
+4991 3237 4992
+4411 3534 3840
+3534 4991 3840
+3385 4411 4412
+4411 3840 4412
+4410 3839 4411
+4410 4411 3385
+3839 4990 4411
+4990 3534 4411
+4989 3235 4990
+4989 4990 3839
+3533 4989 3839
+3533 3839 4410
+4984 3838 4413
+4984 4413 3531
+3838 4410 3385
+3838 3385 4413
+4988 3533 4410
+4988 4410 3838
+3226 4988 3838
+3226 3838 4984
+4977 3837 4987
+4977 4987 3231
+3837 4408 3532
+3837 3532 4987
+4409 3384 4408
+4409 4408 3837
+3527 4409 3837
+3527 3837 4977
+4408 3836 4986
+4408 4986 3532
+3836 4985 3228
+3836 3228 4986
+4407 3531 4985
+4407 4985 3836
+3384 4407 3836
+3384 3836 4408
+4406 3835 4407
+4406 4407 3384
+3835 4984 3531
+3835 3531 4407
+4983 3226 4984
+4983 4984 3835
+3530 4983 3835
+3530 3835 4406
+4976 3834 4409
+4976 4409 3527
+3834 4406 3384
+3834 3384 4409
+4982 3530 4406
+4982 4406 3834
+3229 4982 3834
+3229 3834 4976
+4980 3833 4979
+4980 4979 3336
+3833 4404 3528
+3833 3528 4979
+4405 3383 4404
+4405 4404 3833
+3529 4405 3833
+3529 3833 4980
+4404 3832 4978
+4404 4978 3528
+3832 4977 3231
+3832 3231 4978
+4403 3527 4977
+4403 4977 3832
+3383 4403 3832
+3383 3832 4404
+4402 3831 4403
+4402 4403 3383
+3831 4976 3527
+3831 3527 4403
+4975 3229 4976
+4975 4976 3831
+3526 4975 3831
+3526 3831 4402
+4981 3830 4405
+4981 4405 3529
+3830 4402 3383
+3830 3383 4405
+4974 3526 4402
+4974 4402 3830
+3335 4974 3830
+3335 3830 4981
+3332 5339 5584
+5339 5611 5584
+3332 5584 5626
+3332 5626 5332
+3705 5332 5604
+5332 5626 5604
+3705 5604 5627
+3708 5611 5339
+5231 5609 5588
+3677 5615 5277
+3677 5276 5598
+3677 5598 5615
+3288 5614 5276
+5614 5598 5276
+3288 5283 5587
+3288 5587 5614
+3680 5617 5283
+5617 5587 5283
+3680 5282 5599
+3680 5599 5617
+3316 5616 5282
+5616 5599 5282
+3316 5329 5592
+3316 5592 5616
+3703 5619 5329
+5619 5592 5329
+3703 5328 5600
+3703 5600 5619
+3327 5618 5328
+5618 5600 5328
+3327 5573 5589
+3327 5589 5618
+3825 5629 5573
+5629 5589 5573
+3825 5572 5605
+3825 5605 5629
+3339 5628 5572
+5628 5605 5572
+3339 5343 5591
+3339 5591 5628
+3710 5613 5343
+5613 5591 5343
+3710 5342 5597
+3710 5597 5613
+3333 5612 5342
+5612 5597 5342
+3333 5333 5585
+3333 5585 5612
+3705 5627 5333
+5627 5585 5333
+5586 3287 5615
+5615 3287 5277
+3287 5586 5230
+5230 5586 5608
+3654 5608 5595
+3654 5230 5608
+3654 5595 5231
+5231 5595 5609
+3289 5588 5622
+3289 5231 5588
+3289 5622 5300
+5300 5622 5602
+3689 5602 5623
+3689 5300 5602
+3689 5623 5301
+5301 5623 5593
+3318 5593 5620
+3318 5301 5593
+3318 5620 5314
+5314 5620 5601
+3696 5601 5621
+3696 5314 5601
+3696 5621 5315
+5315 5621 5582
+3323 5582 5606
+3323 5315 5582
+3323 5606 5562
+5562 5606 5594
+3820 5594 5607
+3820 5562 5594
+3820 5607 5563
+5563 5607 5583
+3331 5583 5624
+3331 5563 5583
+3331 5624 5346
+5346 5624 5603
+3712 5603 5625
+3712 5346 5603
+3712 5625 5347
+5347 5625 5590
+3338 5590 5610
+3338 5347 5590
+3338 5610 5338
+5338 5610 5596
+3708 5596 5611
+3708 5338 5596
+5662 5304 3319
+5662 5682 5304
+3691 5682 5668
+3691 5304 5682
+3691 5668 5305
+5305 5668 5683
+3290 5305 5657
+5657 5305 5683
+3319 5681 5662
+3319 5319 5681
+3698 5667 5319
+5319 5667 5681
+3698 5318 5667
+5667 5318 5680
+3322 5680 5318
+3322 5656 5680
+3322 5571 5656
+5656 5571 5693
+3824 5693 5571
+3824 5673 5693
+3824 5570 5673
+5673 5570 5692
+3380 5692 5570
+3380 5663 5692
+3380 5533 5663
+5663 5533 5687
+3805 5687 5533
+3805 5670 5687
+3290 5674 5236
+3290 5657 5674
+3805 5686 5670
+3805 5532 5686
+3341 5655 5532
+5532 5655 5686
+3341 5685 5655
+3341 5427 5685
+3752 5669 5427
+5427 5669 5685
+3752 5684 5669
+3752 5426 5684
+3347 5661 5426
+5426 5661 5684
+3347 5689 5661
+3347 5445 5689
+3761 5671 5445
+5445 5671 5689
+3761 5444 5671
+5671 5444 5688
+3344 5688 5444
+3344 5659 5688
+3344 5354 5659
+5659 5354 5691
+3716 5691 5354
+3716 5672 5691
+3716 5690 5672
+3716 5355 5690
+3303 5660 5355
+5355 5660 5690
+3303 5679 5660
+3303 5255 5679
+3666 5666 5255
+5255 5666 5679
+3666 5678 5666
+3666 5254 5678
+3286 5654 5254
+5254 5654 5678
+3286 5677 5654
+3286 5249 5677
+3663 5677 5249
+3663 5665 5677
+3657 5236 5664
+5664 5236 5674
+3657 5675 5237
+3657 5664 5675
+3294 5237 5658
+5658 5237 5675
+3294 5676 5248
+3294 5658 5676
+3663 5248 5665
+5665 5248 5676
+5637 5645 5289
+5637 5289 3683
+3683 5288 5644
+3683 5644 5637
+3297 5632 5288
+5632 5644 5288
+3297 5285 5643
+3297 5643 5632
+3298 5289 5645
+3298 5645 5633
+3681 5636 5285
+5636 5643 5285
+3681 5284 5642
+3681 5642 5636
+3298 5633 5226
+5633 5652 5226
+3652 5226 5652
+3652 5652 5641
+3652 5641 5227
+5641 5653 5227
+3308 5227 5653
+3308 5653 5635
+3308 5635 5222
+5635 5650 5222
+3650 5222 5650
+3650 5650 5640
+3650 5640 5223
+5640 5651 5223
+3299 5223 5634
+5223 5651 5634
+3299 5634 5648
+3299 5648 5216
+3647 5216 5639
+5216 5648 5639
+3647 5639 5649
+3647 5649 5217
+3295 5217 5630
+5217 5649 5630
+3296 5631 5284
+5631 5642 5284
+3296 5207 5647
+3296 5647 5631
+3642 5638 5207
+5638 5647 5207
+3642 5206 5646
+3642 5646 5638
+3295 5630 5206
+5630 5646 5206
+3720 5362 5708
+3348 5694 5720
+5701 5381 5715
+5701 3307 5381
+3307 5716 5388
+3307 5701 5716
+3729 5704 5715
+3729 5715 5381
+3729 5380 5704
+5380 5714 5704
+3733 5388 5705
+5705 5388 5716
+3733 5717 5389
+3733 5705 5717
+3326 5717 5695
+3326 5389 5717
+3293 5696 5714
+3293 5714 5380
+3293 5373 5696
+5373 5724 5696
+3725 5709 5724
+3725 5724 5373
+3725 5372 5709
+5372 5725 5709
+3305 5698 5725
+3305 5725 5372
+3305 5363 5698
+5363 5722 5698
+3326 5695 5406
+5406 5695 5712
+3742 5712 5703
+3742 5406 5712
+3742 5713 5407
+3742 5703 5713
+3352 5407 5700
+5700 5407 5713
+3352 5710 5400
+3352 5700 5710
+3739 5400 5702
+5702 5400 5710
+3739 5702 5401
+5401 5702 5711
+3348 5711 5694
+3348 5401 5711
+3720 5708 5722
+3720 5722 5363
+3348 5720 5408
+5408 5720 5707
+3743 5707 5721
+3743 5408 5707
+3304 5723 5362
+5723 5708 5362
+3304 5697 5723
+3304 5416 5697
+3747 5719 5416
+5416 5719 5697
+3743 5721 5409
+5409 5721 5699
+3351 5699 5718
+3351 5409 5699
+3351 5718 5417
+5417 5718 5706
+3747 5706 5719
+3747 5417 5706
\ No newline at end of file
diff --git a/simulations/anatomical_phantoms/util/cardiac/create_cardiac_masks/create_cardiac_masks.m b/simulations/anatomical_phantoms/util/cardiac/create_cardiac_masks/create_cardiac_masks.m
new file mode 100644
index 0000000..29a656e
--- /dev/null
+++ b/simulations/anatomical_phantoms/util/cardiac/create_cardiac_masks/create_cardiac_masks.m
@@ -0,0 +1,371 @@
+% ================
+% == READ ATLAS ==
+% ================
+function [pts, LV, RV, EPI] = read_atlas(stage, plot)
+ % ARGS:
+ % stage = either "ED" for end diastole or "ES" for end systole
+ % plot = logical flag to plot after reading
+ arguments
+ stage string {mustBeMember(stage, ["ED", "ES"])} = "ED"
+ plot logical = false
+ end
+
+ pc = h5read('UKBRVLV.h5', '/COEFF'); % read the principal components
+ ev = h5read('UKBRVLV.h5', '/LATENT'); % read the eigenvalues
+ mu = h5read('UKBRVLV.h5', '/MU'); % read the mean shape
+
+ deviations = rand([200,1]); % how many standard deviations to vary each pc
+ scaled_ev = deviations .* sqrt(ev); % scaled eigenvalues
+ variations = repmat(scaled_ev', [size(pc, 1), 1]) .* pc;
+ summed_variations = sum(variations,2)';
+
+ % generate the first principal mode
+ % with 1.5 times the standard deviation
+ S = mu + summed_variations;
+
+ % get ED & ES points, & convert to 3 columns matrix [x, y, z]
+ N = length(S);
+ if stage == "ED"
+ pts = reshape(S(1:N/2), 3, [])';
+ else
+ pts = reshape(S((N/2+1):end), 3, [])';
+ end
+
+ % only take some of the points
+ % these separations were from https://github.com/ComputationalPhysiology/ukb-atlas/blob/main/src/ukb/surface.py
+ % and i kinda trust them more than my own lol
+ LV = pts(1:1500, :);
+ RV = pts(cat(2, 1501:3224, 5730:5808), :);
+ EPI = pts(3225:5582, :);
+ everything_else = pts(5583:end, :);
+
+ if plot
+ % plot ED points in blue
+ % plot ES points in red
+ figure('Color', 'w');
+ hold on;
+ plot3(LV(:,1), LV(:,2), LV(:,3), 'r.');
+ plot3(RV(:,1), RV(:,2), RV(:,3), 'g.');
+ plot3(EPI(:,1), EPI(:,2), EPI(:,3), 'b.');
+ plot3(everything_else(:,1), everything_else(:,2), everything_else(:,3), 'y.');
+
+ axis vis3d
+ axis equal
+ end
+end
+
+% =======================
+% == READ CONNECTIVITY ==
+% =======================
+function connectivity = read_connectivity(path)
+ arguments
+ path string = 'connectivity.txt'
+ end
+ connectivity = readmatrix(path) + 1; % +1 to account for the fact that this came from python, and python uses 0-indexing
+ % tbh, that's the main reason why i wanted a wrapper function for this
+ % lol
+end
+
+% ===================
+% == PROJECT EDGES ==
+% ===================
+function slice = trace_surface(zlevel, slice_size, pts, faces, pt_idxs, face_idxs)
+ % ARGS:
+ % zlevel = z coordinate of slice
+ % slice_size = scalar of how big the slice should be
+ % pts = Nx3 array of points
+ % faces = Nx3 array of pt idxs that define triangles
+ % pt_idxs = 1xN array of idxs of all points to look at
+ % face_idxs = 1xN array of idxs of all faces to look at
+ % OUT:
+ % slice = 2d matrix slice with points and (most) lines
+
+ slice = zeros(slice_size);
+ offset = slice_size / 2;
+
+ for face_idx = face_idxs
+ face = faces(face_idx, :);
+ % if any point index in face isn't in pt_idxs, skip this face
+ % because i guess there's points in connectivity.txt that don't exist/aren't relevant to the parts we're looking at
+ if any(~ismember(face, pt_idxs))
+ continue
+ end
+
+ verts = pts(face, :);
+ n_verts = size(verts, 2); % i mean, this is gonna be 3 because everything is a triangle, but... NO MAGIC NUMBERS
+
+ % for each pair of vertices, find intersecting points
+ intersection_coords = {};
+ for vert_idx = 1:n_verts
+ vert1 = verts(vert_idx, :);
+ vert2 = verts(mod(vert_idx, n_verts) + 1, :);
+ % funny thing about this line: it's supposed to be something
+ % like vert2 = verts(mod(vert_idx + 1, 3), :), but because
+ % matlab uses 1-indexing, it turns into
+ % mod((vert_idx + 1) - 1, n_verts) + 1, so that's what that does
+ if (vert1(3) >= zlevel && vert2(3) <= zlevel) || ...
+ (vert1(3) <= zlevel && vert2(3) >= zlevel)
+ xy = find_plane_intersection(vert1, vert2, zlevel);
+ intersection_coords{numel(intersection_coords) + 1} = [round(xy(1)) + offset, round(xy(2)) + offset];
+ slice(round(xy(1)) + offset, round(xy(2)) + offset) = 1; % yes, it's code duplication, but i'm lazy
+ end
+
+ % if there's 2 intersection coordinates, draw a line between them
+ if numel(intersection_coords) == 2
+ x1 = intersection_coords{1}(1);
+ y1 = intersection_coords{1}(2);
+ x2 = intersection_coords{2}(1);
+ y2 = intersection_coords{2}(2);
+ slice = draw_line(slice, x1, y1, x2, y2);
+ end
+ end
+ end
+end
+
+% ======================
+% == HELPER FUNCTIONS ==
+% ======================
+function xy = find_plane_intersection(a, b, z)
+ % a and b are coordinates [x,y,z]
+ % z is the plane at z=z
+ % xy are the xy coordinates where line ab intersects z
+ xy = [...
+ a(1) + (((z - a(3)) * (b(1) - a(1))) / (b(3) - a(3))), ...
+ a(2) + (((z - a(3)) * (b(2) - a(2))) / (b(3) - a(3))) ...
+ ];
+end
+
+% quick wrapper function to draw a bresenham line
+function I_new = draw_line(I, x1, y1, x2, y2)
+ [x,y] = bresenham(x1, y1, x2, y2);
+ line_indices = sub2ind(size(I), x, y);
+ I_new = I;
+ I_new(line_indices) = 1;
+end
+
+function [new_endpt_x, new_endpt_y] = remove_erroneous_endpoints(I, endpt_x, endpt_y)
+ % removes pixels that could be considered offshoots
+ % this is a very "this just needs to work" kind of function
+ kernel = ones(5);
+ n_neighbors = conv2(I, kernel, 'same'); % includes the corner itself
+
+ new_endpt_x = [];
+ new_endpt_y = [];
+ for endpt_idx = 1:numel(endpt_x)
+ if n_neighbors(endpt_x(endpt_idx), endpt_y(endpt_idx)) <= 3
+ new_endpt_x(numel(new_endpt_x) + 1, 1) = endpt_x(endpt_idx);
+ new_endpt_y(numel(new_endpt_y) + 1, 1) = endpt_y(endpt_idx);
+ else
+ disp("removed erroneous endpoint")
+ end
+ end
+end
+
+function I = remove_blobs(I, blob_size)
+ % removes small blobs of isolated pixels. intended to work with even
+ kernel = ones(blob_size + 2) .* 100;
+ kernel(2:(blob_size + 1), 2:(blob_size + 1)) = 1;
+ conved = conv2(I, kernel, 'same');
+ blob_locations = conved < 100 & conved ~= 0;
+ if mod(blob_size, 2) == 0
+ new_kernel = zeros(blob_size + 1);
+ new_kernel(2:end, 2:end) = 1; % see, kernels with even dimensions are weird, so this manipulates the anchor of the kernel so it actually catches the right pixels
+ else
+ new_kernel = ones(blob_size);
+ end
+ to_remove = conv2(blob_locations, new_kernel, 'same');
+ I(to_remove ~= 0) = 0;
+end
+
+
+
+% =====================
+% == CLOSE BIG HOLES ==
+% =====================
+function bresenhamified = close_big_holes(I)
+ I = bwskel(logical(I));
+ I = remove_blobs(I, 5); % i think 5 is reasonable
+ bresenhamified = I;
+ % identify endpoints
+ kernel = [1 1 1; 1 0 1; 1 1 1];
+ surrounding_pixels = conv2(I, kernel, 'same');
+ endpoints = (surrounding_pixels == 1 & I == 1);
+ endpt_indices = find(endpoints);
+ n_endpts = numel(endpt_indices);
+ if n_endpts == 0
+ return
+ end
+
+ [endpt_x, endpt_y] = ind2sub(size(endpoints), endpt_indices);
+
+ if mod(numel(endpt_x), 2) == 1
+ figure; imshow(I);
+ error("there's a weird outcrop somewhere idk help")
+ end
+
+ % multiple gaps case
+ if numel(endpt_indices) > 2
+ distances = zeros(n_endpts);
+ for endpt_idx1 = 1:numel(endpt_indices)
+ for endpt_idx2 = 1:numel(endpt_indices)
+ % check if the points are connected
+ pt1 = [endpt_x(endpt_idx1), endpt_y(endpt_idx1)];
+ pt2 = [endpt_x(endpt_idx2), endpt_y(endpt_idx2)];
+ is_connected = check_connection(I, pt1, pt2);
+ % if not connected, set it to distance between 2 points
+ if ~is_connected
+ dx = pt1(1) - pt2(1);
+ dy = pt1(2) - pt2(2);
+ distances(endpt_idx1, endpt_idx2) = sqrt(dx.^2 + dy.^2);
+ end
+ end
+ end
+
+ remaining_endpts = 1:n_endpts;
+ while any(distances > 0, 'all')
+ % find minimum nonzero distance, fill that one in first
+ nonzero_min = min(distances(distances > 0));
+ [pt1_idx, pt2_idx] = ind2sub(size(distances), find(distances == nonzero_min, 1));
+ bresenhamified = draw_line(bresenhamified, endpt_x(pt1_idx), endpt_y(pt1_idx), endpt_x(pt2_idx), endpt_y(pt2_idx));
+
+ % set these guys to 0
+ distances(pt1_idx,:) = 0;
+ distances(:,pt1_idx) = 0;
+ distances(pt2_idx,:) = 0;
+ distances(:,pt2_idx) = 0;
+
+ % recheck connectivity
+ remaining_endpts(pt1_idx) = 0;
+ remaining_endpts(pt2_idx) = 0;
+ for endpt_idx1 = remaining_endpts(remaining_endpts > 0)
+ for endpt_idx2 = remaining_endpts(remaining_endpts > 0)
+ pt1 = [endpt_x(endpt_idx1), endpt_y(endpt_idx1)];
+ pt2 = [endpt_x(endpt_idx2), endpt_y(endpt_idx2)];
+ is_connected = check_connection(bresenhamified, pt1, pt2); % TODO: consider making a wrapper function for checking connectivity of a set of points
+ if is_connected
+ distances(endpt_idx1, endpt_idx2) = 0;
+ end
+ end
+ end
+ end
+ end
+
+
+ % now there should only be two endpoints
+ % re-skeletonize (in case some corners were introduced and endpoints
+ % can't be found)
+ bresenhamified = bwskel(logical(bresenhamified));
+ surrounding_pixels = conv2(bresenhamified, kernel, 'same');
+ endpoints = (surrounding_pixels == 1 & bresenhamified == 1);
+ endpt_indices = find(endpoints);
+ [endpt_x, endpt_y] = ind2sub(size(endpoints), endpt_indices);
+ if numel(endpt_x) ~= 2
+ warning('something looks awefully suspicious. double check this layer')
+ [endpt_x, endpt_y] = remove_erroneous_endpoints(bresenhamified, endpt_x, endpt_y);
+ end
+ bresenhamified = draw_line(bresenhamified, endpt_x(1), endpt_y(1), endpt_x(2), endpt_y(2));
+end
+
+
+% ================
+% == FLOOD-FILL ==
+% ================
+function filled = fill_outline(outline)
+ inverse_fill = imfill(outline, [1,1]);
+ filled = ~inverse_fill + outline;
+end
+
+% ============================
+% == distinguish myocardium ==
+% ============================
+function new_mask = separate_myocardium(og_layered)
+ % og_layered = row x col x slice, 1 = lv, 2 = rv, 3 = epi
+ % outputs a new layered mask where 1 = lv, 2 = rv, 3 = lvmy, 4 = rvmy
+ new_mask = og_layered;
+
+ % find distances
+ lv_dist = bwdist(new_mask == 1);
+
+ rv_dist = bwdist(new_mask == 2);
+
+ % for each voxel, see if a) it's epi, b) if it's closer
+ for row = 1:size(new_mask, 1)
+ for col = 1:size(new_mask, 2)
+ for slice = 1:size(new_mask, 3)
+ if new_mask(row,col,slice) == 3 && rv_dist(row,col,slice) < lv_dist(row,col,slice)
+ new_mask(row,col,slice) = 4;
+ end
+ end
+ end
+ end
+end
+
+
+function [filled, closed, traced] = create_one_slice(zlevel, slice_size, pts, connections, pt_idxs_to_use, face_idxs_to_use)
+ traced = trace_surface(zlevel, slice_size, pts, connections, pt_idxs_to_use, face_idxs_to_use);
+ closed = close_big_holes(traced);
+ filled = fill_outline(closed);
+end
+
+
+%%
+% ==========
+% == MAIN ==
+% ==========
+clear; close all;
+
+% read atlas and connectivity, declare ranges
+[pts, ~, ~, ~] = read_atlas("ED", false);
+connections = read_connectivity();
+
+LV_pts = 1:1500;
+RV_pts = 1501:3224;
+EPI_pts = 3225:5582;
+LV_faces = 1:3072;
+RV_faces = cat(2, 3073:4480, 4480:6752);
+EPI_faces = 6753:11616;
+
+% parameters for slices
+z_values = -40:2:50;
+slice_size = 150;
+
+% creating masks
+layered_masks = zeros(slice_size, slice_size, numel(z_values));
+traced_masks = zeros(slice_size, slice_size, numel(z_values));
+closed_masks = zeros(slice_size, slice_size, numel(z_values));
+
+for z_idx = 1:numel(z_values)
+ z = z_values(z_idx);
+ % generate each slice
+ [LV_slice, LV_closed, LV_traced] = create_one_slice(z, slice_size, pts, connections, LV_pts, LV_faces);
+ [RV_slice, RV_closed, RV_traced] = create_one_slice(z, slice_size, pts, connections, RV_pts, RV_faces);
+ [EPI_slice, EPI_closed, EPI_traced] = create_one_slice(z, slice_size, pts, connections, EPI_pts, EPI_faces);
+
+ % layer everything
+ layered_slice = EPI_slice .* 3;
+ layered_slice(LV_slice > 0) = 1;
+ layered_slice(RV_slice > 0) = 2;
+ layered_masks(:,:,z_idx) = layered_slice;
+
+ % also do the traced masks (for debugging purposes)
+ closed_masks(:,:,z_idx) = EPI_closed;
+ traced_masks(:,:,z_idx) = EPI_traced;
+ fprintf("z slice at %i (slice #%i) has been made\n", z, z_idx);
+end
+
+layered_masks = separate_myocardium(layered_masks);
+
+% separate out masks
+masks = zeros(slice_size, slice_size, numel(z_values), 4);
+masks(:,:,:,1) = layered_masks == 1;
+masks(:,:,:,2) = layered_masks == 2;
+masks(:,:,:,3) = layered_masks == 3;
+masks(:,:,:,4) = layered_masks == 4;
+
+%%
+for slice = 1:46
+ figure; imshow(layered_masks(:,:,slice), [0, max(layered_masks, [], 'all')]);
+end
+
+%%
+matlab.io.saveVariablesToScript('outputs/cardiac_mask_10.m', {'masks'})
diff --git a/simulations/metabolic_phantom/DEMO.m b/simulations/metabolic_shapes_phantom/DEMO.m
similarity index 100%
rename from simulations/metabolic_phantom/DEMO.m
rename to simulations/metabolic_shapes_phantom/DEMO.m
diff --git a/simulations/metabolic_phantom/README.md b/simulations/metabolic_shapes_phantom/README.md
similarity index 100%
rename from simulations/metabolic_phantom/README.md
rename to simulations/metabolic_shapes_phantom/README.md
diff --git a/simulations/metabolic_phantom/demo_metabolic_phantom_fit.m b/simulations/metabolic_shapes_phantom/demo_metabolic_phantom_fit.m
similarity index 100%
rename from simulations/metabolic_phantom/demo_metabolic_phantom_fit.m
rename to simulations/metabolic_shapes_phantom/demo_metabolic_phantom_fit.m
diff --git a/simulations/metabolic_phantom/kPL_16.png b/simulations/metabolic_shapes_phantom/kPL_16.png
similarity index 100%
rename from simulations/metabolic_phantom/kPL_16.png
rename to simulations/metabolic_shapes_phantom/kPL_16.png
diff --git a/simulations/metabolic_phantom/kPL_256.png b/simulations/metabolic_shapes_phantom/kPL_256.png
similarity index 100%
rename from simulations/metabolic_phantom/kPL_256.png
rename to simulations/metabolic_shapes_phantom/kPL_256.png
diff --git a/simulations/metabolic_phantom/kTRANS_16.png b/simulations/metabolic_shapes_phantom/kTRANS_16.png
similarity index 100%
rename from simulations/metabolic_phantom/kTRANS_16.png
rename to simulations/metabolic_shapes_phantom/kTRANS_16.png
diff --git a/simulations/metabolic_phantom/kTRANS_256.png b/simulations/metabolic_shapes_phantom/kTRANS_256.png
similarity index 100%
rename from simulations/metabolic_phantom/kTRANS_256.png
rename to simulations/metabolic_shapes_phantom/kTRANS_256.png
diff --git a/simulations/metabolic_phantom/metabolic_phantom.m b/simulations/metabolic_shapes_phantom/metabolic_phantom.m
similarity index 100%
rename from simulations/metabolic_phantom/metabolic_phantom.m
rename to simulations/metabolic_shapes_phantom/metabolic_phantom.m
diff --git a/simulations/metabolic_phantom/rectangle_shape.m b/simulations/metabolic_shapes_phantom/rectangle_shape.m
similarity index 100%
rename from simulations/metabolic_phantom/rectangle_shape.m
rename to simulations/metabolic_shapes_phantom/rectangle_shape.m
diff --git a/simulations/metabolic_phantom/sphere_fcn.m b/simulations/metabolic_shapes_phantom/sphere_fcn.m
similarity index 100%
rename from simulations/metabolic_phantom/sphere_fcn.m
rename to simulations/metabolic_shapes_phantom/sphere_fcn.m
diff --git a/simulations/HP_montecarlo_evaluation.m b/simulations/montecarlo_simulations/HP_montecarlo_evaluation.m
similarity index 100%
rename from simulations/HP_montecarlo_evaluation.m
rename to simulations/montecarlo_simulations/HP_montecarlo_evaluation.m
diff --git a/simulations/test_HP_montecarlo_evaluation.m b/simulations/montecarlo_simulations/test_HP_montecarlo_evaluation.m
similarity index 100%
rename from simulations/test_HP_montecarlo_evaluation.m
rename to simulations/montecarlo_simulations/test_HP_montecarlo_evaluation.m
diff --git a/simulations/realistic_input_function.m b/simulations/pk_models/realistic_input_function.m
similarity index 100%
rename from simulations/realistic_input_function.m
rename to simulations/pk_models/realistic_input_function.m
diff --git a/simulations/simulate_2site_model.m b/simulations/pk_models/simulate_2site_model.m
similarity index 100%
rename from simulations/simulate_2site_model.m
rename to simulations/pk_models/simulate_2site_model.m
diff --git a/simulations/simulate_Nsite_model.m b/simulations/pk_models/simulate_Nsite_model.m
similarity index 100%
rename from simulations/simulate_Nsite_model.m
rename to simulations/pk_models/simulate_Nsite_model.m
diff --git a/utilities/fire.m b/utilities/fire.m
new file mode 100644
index 0000000..28f409b
--- /dev/null
+++ b/utilities/fire.m
@@ -0,0 +1,300 @@
+function p = fire(m)
+%FIRE Blue-Purple Hot colormap
+%
+% FIRE(M) returns an M-by-3 matrix containing a "fire" colormap.
+% FIRE, by itself, is the same length as the current figure's
+% colormap. If no figure exists, MATLAB creates one.
+%
+% To add this colormap as a default map, use 'addpath' with the
+% directory containing 'fire.m'.
+%
+% To reset the colormap of the current figure use 'colormap(fire)'.
+%
+% see also: HSV, GRAY, HOT, COOL, BONE, COPPER, FLAG, PINK, COLORMAP,
+% RGBPLOT.
+%
+% To create any custom colormap, see the directions on line 23 of this
+% m-file.
+
+if nargin < 1
+ m = size(get(gcf,'colormap'),1);
+end
+
+%You can replace this M x 3 matrix with any matrix whose values range
+%between 0 and 1 to create a new colormap file. Use copy / paste to create
+%a matrix like the one below, you do not have to add these values
+%manually. To create a new colormap, change 'cmap_mat' to the desired
+%matrix, rename the function *and* the m-file from 'fire' to your desired
+%colormap name.
+
+cmap_mat=[
+ 0 0 0
+ 0 0 0.0275
+ 0 0 0.0588
+ 0 0 0.0863
+ 0 0 0.1176
+ 0 0 0.1490
+ 0 0 0.1765
+ 0 0 0.2078
+ 0 0 0.2392
+ 0 0 0.2549
+ 0 0 0.2706
+ 0 0 0.2902
+ 0 0 0.3059
+ 0 0 0.3216
+ 0 0 0.3412
+ 0 0 0.3569
+ 0.0039 0 0.3765
+ 0.0157 0 0.3922
+ 0.0275 0 0.4078
+ 0.0392 0 0.4235
+ 0.0510 0 0.4431
+ 0.0627 0 0.4588
+ 0.0745 0 0.4745
+ 0.0863 0 0.4902
+ 0.0980 0 0.5098
+ 0.1098 0 0.5255
+ 0.1216 0 0.5412
+ 0.1333 0 0.5608
+ 0.1451 0 0.5765
+ 0.1569 0 0.5922
+ 0.1686 0 0.6118
+ 0.1804 0 0.6275
+ 0.1922 0 0.6471
+ 0.2039 0 0.6588
+ 0.2157 0 0.6706
+ 0.2275 0 0.6863
+ 0.2392 0 0.6980
+ 0.2510 0 0.7098
+ 0.2627 0 0.7255
+ 0.2745 0 0.7373
+ 0.2863 0 0.7529
+ 0.2980 0 0.7647
+ 0.3098 0 0.7804
+ 0.3216 0 0.7922
+ 0.3333 0 0.8078
+ 0.3451 0 0.8196
+ 0.3569 0 0.8353
+ 0.3686 0 0.8471
+ 0.3843 0 0.8627
+ 0.3961 0 0.8627
+ 0.4078 0 0.8667
+ 0.4196 0 0.8706
+ 0.4314 0 0.8745
+ 0.4431 0 0.8784
+ 0.4549 0 0.8824
+ 0.4667 0 0.8863
+ 0.4784 0 0.8902
+ 0.4902 0 0.8784
+ 0.5020 0 0.8706
+ 0.5137 0 0.8627
+ 0.5255 0 0.8549
+ 0.5373 0 0.8471
+ 0.5490 0 0.8392
+ 0.5608 0 0.8314
+ 0.5725 0 0.8235
+ 0.5804 0 0.8078
+ 0.5882 0 0.7922
+ 0.5961 0 0.7804
+ 0.6039 0 0.7647
+ 0.6118 0 0.7490
+ 0.6196 0 0.7373
+ 0.6275 0 0.7216
+ 0.6353 0 0.7098
+ 0.6392 0 0.6941
+ 0.6431 0 0.6784
+ 0.6510 0 0.6627
+ 0.6549 0 0.6510
+ 0.6588 0 0.6353
+ 0.6667 0 0.6196
+ 0.6706 0 0.6039
+ 0.6784 0 0.5922
+ 0.6824 0 0.5765
+ 0.6863 0 0.5608
+ 0.6941 0 0.5490
+ 0.6980 0 0.5333
+ 0.7020 0 0.5176
+ 0.7098 0 0.5059
+ 0.7137 0 0.4902
+ 0.7216 0 0.4784
+ 0.7255 0 0.4627
+ 0.7294 0 0.4471
+ 0.7373 0 0.4353
+ 0.7412 0 0.4196
+ 0.7451 0 0.4039
+ 0.7529 0 0.3922
+ 0.7569 0 0.3765
+ 0.7647 0 0.3647
+ 0.7686 0.0039 0.3490
+ 0.7765 0.0118 0.3333
+ 0.7804 0.0196 0.3216
+ 0.7882 0.0275 0.3059
+ 0.7922 0.0314 0.2902
+ 0.8000 0.0392 0.2784
+ 0.8039 0.0471 0.2627
+ 0.8118 0.0549 0.2510
+ 0.8157 0.0627 0.2353
+ 0.8196 0.0745 0.2196
+ 0.8235 0.0824 0.2078
+ 0.8314 0.0941 0.1922
+ 0.8353 0.1059 0.1765
+ 0.8392 0.1137 0.1647
+ 0.8431 0.1255 0.1490
+ 0.8510 0.1373 0.1373
+ 0.8549 0.1451 0.1216
+ 0.8627 0.1569 0.1059
+ 0.8667 0.1686 0.0902
+ 0.8745 0.1804 0.0784
+ 0.8784 0.1882 0.0627
+ 0.8863 0.2000 0.0471
+ 0.8902 0.2118 0.0314
+ 0.8980 0.2235 0.0196
+ 0.9020 0.2314 0.0157
+ 0.9059 0.2431 0.0118
+ 0.9137 0.2549 0.0118
+ 0.9176 0.2667 0.0078
+ 0.9216 0.2745 0.0039
+ 0.9294 0.2863 0.0039
+ 0.9333 0.2980 0
+ 0.9412 0.3098 0
+ 0.9451 0.3176 0
+ 0.9529 0.3294 0
+ 0.9569 0.3412 0
+ 0.9647 0.3529 0
+ 0.9686 0.3608 0
+ 0.9765 0.3725 0
+ 0.9804 0.3843 0
+ 0.9882 0.3961 0
+ 0.9882 0.4039 0
+ 0.9882 0.4118 0
+ 0.9922 0.4196 0
+ 0.9922 0.4275 0
+ 0.9922 0.4353 0
+ 0.9961 0.4431 0
+ 0.9961 0.4510 0
+ 1.0000 0.4588 0
+ 1.0000 0.4667 0
+ 1.0000 0.4745 0
+ 1.0000 0.4824 0
+ 1.0000 0.4902 0
+ 1.0000 0.4980 0
+ 1.0000 0.5059 0
+ 1.0000 0.5137 0
+ 1.0000 0.5216 0
+ 1.0000 0.5255 0
+ 1.0000 0.5333 0
+ 1.0000 0.5412 0
+ 1.0000 0.5490 0
+ 1.0000 0.5529 0
+ 1.0000 0.5608 0
+ 1.0000 0.5686 0
+ 1.0000 0.5765 0
+ 1.0000 0.5804 0
+ 1.0000 0.5882 0
+ 1.0000 0.5961 0
+ 1.0000 0.6039 0
+ 1.0000 0.6078 0
+ 1.0000 0.6157 0
+ 1.0000 0.6235 0
+ 1.0000 0.6314 0
+ 1.0000 0.6353 0
+ 1.0000 0.6431 0
+ 1.0000 0.6510 0
+ 1.0000 0.6588 0
+ 1.0000 0.6627 0
+ 1.0000 0.6706 0
+ 1.0000 0.6784 0
+ 1.0000 0.6863 0
+ 1.0000 0.6902 0
+ 1.0000 0.6980 0
+ 1.0000 0.7059 0
+ 1.0000 0.7137 0
+ 1.0000 0.7216 0
+ 1.0000 0.7294 0
+ 1.0000 0.7373 0
+ 1.0000 0.7451 0
+ 1.0000 0.7490 0
+ 1.0000 0.7569 0
+ 1.0000 0.7647 0
+ 1.0000 0.7725 0
+ 1.0000 0.7804 0
+ 1.0000 0.7882 0
+ 1.0000 0.7961 0
+ 1.0000 0.8039 0
+ 1.0000 0.8078 0
+ 1.0000 0.8157 0
+ 1.0000 0.8235 0
+ 1.0000 0.8314 0
+ 1.0000 0.8353 0
+ 1.0000 0.8431 0
+ 1.0000 0.8510 0
+ 1.0000 0.8588 0
+ 1.0000 0.8627 0
+ 1.0000 0.8706 0
+ 1.0000 0.8784 0
+ 1.0000 0.8863 0
+ 1.0000 0.8941 0
+ 1.0000 0.9020 0
+ 1.0000 0.9098 0
+ 1.0000 0.9176 0
+ 1.0000 0.9216 0.0157
+ 1.0000 0.9294 0.0314
+ 1.0000 0.9373 0.0510
+ 1.0000 0.9451 0.0667
+ 1.0000 0.9490 0.0824
+ 1.0000 0.9569 0.1020
+ 1.0000 0.9647 0.1176
+ 1.0000 0.9725 0.1373
+ 1.0000 0.9725 0.1647
+ 1.0000 0.9765 0.1961
+ 1.0000 0.9804 0.2275
+ 1.0000 0.9843 0.2588
+ 1.0000 0.9882 0.2902
+ 1.0000 0.9922 0.3216
+ 1.0000 0.9961 0.3529
+ 1.0000 1.0000 0.3843
+ 1.0000 1.0000 0.4118
+ 1.0000 1.0000 0.4431
+ 1.0000 1.0000 0.4745
+ 1.0000 1.0000 0.5059
+ 1.0000 1.0000 0.5333
+ 1.0000 1.0000 0.5647
+ 1.0000 1.0000 0.5961
+ 1.0000 1.0000 0.6275
+ 1.0000 1.0000 0.6549
+ 1.0000 1.0000 0.6863
+ 1.0000 1.0000 0.7176
+ 1.0000 1.0000 0.7490
+ 1.0000 1.0000 0.7804
+ 1.0000 1.0000 0.8118
+ 1.0000 1.0000 0.8431
+ 1.0000 1.0000 0.8745
+ 1.0000 1.0000 0.8902
+ 1.0000 1.0000 0.9059
+ 1.0000 1.0000 0.9216
+ 1.0000 1.0000 0.9373
+ 1.0000 1.0000 0.9529
+ 1.0000 1.0000 0.9686
+ 1.0000 1.0000 0.9843
+ 1.0000 1.0000 1.0000
+ 1.0000 1.0000 1.0000
+ 1.0000 1.0000 1.0000
+ 1.0000 1.0000 1.0000
+ 1.0000 1.0000 1.0000
+ 1.0000 1.0000 1.0000
+ 1.0000 1.0000 1.0000
+ 1.0000 1.0000 1.0000
+ ];
+
+%interpolate values
+xin=linspace(0,1,m)';
+xorg=linspace(0,1,size(cmap_mat,1));
+
+p(:,1)=interp1(xorg,cmap_mat(:,1),xin,'linear');
+p(:,2)=interp1(xorg,cmap_mat(:,2),xin,'linear');
+p(:,3)=interp1(xorg,cmap_mat(:,3),xin,'linear');
+
+
+
+
+