public void Equals_RelativeTolerance_IsImplemented()
        {
            var v = RelativeHumidity.FromPercent(1);

            Assert.True(v.Equals(RelativeHumidity.FromPercent(1), PercentTolerance, ComparisonType.Relative));
            Assert.False(v.Equals(RelativeHumidity.Zero, PercentTolerance, ComparisonType.Relative));
        }
示例#2
0
文件: DhtSensor.cs 项目: mmalyska/iot
        private bool TryReadDhtInternal(int pinNumber, int dhtType, out Temperature temperature, out RelativeHumidity humidity)
        {
            temperature = default;
            humidity    = default;

            FirmataCommandSequence dhtCommandSequence = new();

            dhtCommandSequence.WriteByte((byte)FirmataSysexCommand.DHT_SENSOR_DATA_REQUEST);
            dhtCommandSequence.WriteByte((byte)dhtType);
            dhtCommandSequence.WriteByte((byte)pinNumber);
            dhtCommandSequence.WriteByte((byte)FirmataCommand.END_SYSEX);
            var reply = SendCommandAndWait(dhtCommandSequence);

            // Command, pin number and 2x2 bytes data (+ END_SYSEX byte)
            if (reply.Length < 7)
            {
                return(false);
            }

            if (reply[0] != (byte)FirmataSysexCommand.DHT_SENSOR_DATA_REQUEST && reply[1] != 0)
            {
                return(false);
            }

            int t = reply[3] | reply[4] << 7;
            int h = reply[5] | reply[6] << 7;

            temperature = Temperature.FromDegreesCelsius(t / 10.0);
            humidity    = RelativeHumidity.FromPercent(h / 10.0);

            return(true);
        }
        public void Equals_SameType_IsImplemented()
        {
            var a = RelativeHumidity.FromPercent(1);
            var b = RelativeHumidity.FromPercent(2);

            Assert.True(a.Equals(a));
            Assert.False(a.Equals(b));
        }
示例#4
0
 private RelativeHumidity GetActualHumidity(short humidityRaw)
 {
     // datasheet does not specify if calibration points are not changing
     // since this is almost no-op and max output data rate is 12.5Hz let's do it every time
     (short h0raw, short h1raw) = GetHumidityCalibrationPointsRaw();
     (byte h0x2rH, byte h1x2rH) = GetHumidityCalibrationPointsRH();
     return(RelativeHumidity.FromPercent(Lerp(humidityRaw, h0raw, h1raw, h0x2rH / 2.0f, h1x2rH / 2.0f)));
 }
示例#5
0
        [InlineData(27.8, 38.1, 20.0, 59.317)] // in data from BMP280 (in case), thermometer 1 meter away shows 20.0°, 57%
        public void GetRelativeHumidityFromActualAirTemperature(double inTemp, double inHumidity, double outTemp, double outHumidityExpected)
        {
            RelativeHumidity result = WeatherHelper.GetRelativeHumidityFromActualAirTemperature(
                Temperature.FromDegreesCelsius(inTemp),
                RelativeHumidity.FromPercent(inHumidity), Temperature.FromDegreesCelsius(outTemp));

            Assert.Equal(outHumidityExpected, result.Percent, 3);
        }
        public void CompareToIsImplemented()
        {
            RelativeHumidity percent = RelativeHumidity.FromPercent(1);

            Assert.Equal(0, percent.CompareTo(percent));
            Assert.True(percent.CompareTo(RelativeHumidity.Zero) > 0);
            Assert.True(RelativeHumidity.Zero.CompareTo(percent) < 0);
        }
        public void ToUnit()
        {
            var percent = RelativeHumidity.FromPercent(1);

            var percentQuantity = percent.ToUnit(RelativeHumidityUnit.Percent);

            AssertEx.EqualTolerance(PercentInOnePercent, (double)percentQuantity.Value, PercentTolerance);
            Assert.Equal(RelativeHumidityUnit.Percent, percentQuantity.Unit);
        }
        public void Equals_QuantityAsObject_IsImplemented()
        {
            object a = RelativeHumidity.FromPercent(1);
            object b = RelativeHumidity.FromPercent(2);

            Assert.True(a.Equals(a));
            Assert.False(a.Equals(b));
            Assert.False(a.Equals((object)null));
        }
示例#9
0
        /// <summary>
        /// Calculates a corrected relative humidity. This is useful if you have a temperature/humidity sensor that is
        /// placed in a location where the temperature is different from the real ambient temperature (like it sits inside a hot case)
        /// and another temperature-only sensor that gives more reasonable ambient temperature readings.
        /// Do note that the relative humidity is dependent on the temperature, because it depends on how much water a volume of air
        /// can contain, which increases with temperature.
        /// </summary>
        /// <param name="airTemperatureFromHumiditySensor">Temperature measured by the humidity sensor</param>
        /// <param name="relativeHumidityMeasured">Humidity measured</param>
        /// <param name="airTemperatureFromBetterPlacedSensor">Temperature measured by better placed sensor</param>
        /// <returns>A corrected humidity. The value will be lower than the input value if the better placed sensor is cooler than
        /// the "bad" sensor.</returns>
        public static RelativeHumidity GetRelativeHumidityFromActualAirTemperature(Temperature airTemperatureFromHumiditySensor,
                                                                                   RelativeHumidity relativeHumidityMeasured, Temperature airTemperatureFromBetterPlacedSensor)
        {
            Density absoluteHumidity =
                CalculateAbsoluteHumidity(airTemperatureFromHumiditySensor, relativeHumidityMeasured);
            double avp = absoluteHumidity.GramsPerCubicMeter * (airTemperatureFromBetterPlacedSensor.Kelvins * 461.5) / 1000;
            double ret = avp / CalculateSaturatedVaporPressureOverWater(airTemperatureFromBetterPlacedSensor).Hectopascals;

            return(RelativeHumidity.FromPercent(ret));
        }
示例#10
0
        /// <summary>
        /// Try to read relative humidity from sensor.
        /// </summary>
        /// <remarks>Range is 25 to 95 percent</remarks>
        /// <param name="humidity">Relative humidity if successful</param>
        /// <returns></returns>
        public bool TryReadRelativeHumidity(out RelativeHumidity humidity)
        {
            humidity = RelativeHumidity.MaxValue;
            if (ReadRegister(Register.ON_BOARD_SENSOR_ERROR).Equals((byte)RegisterStatusErrors.NO_ERROR))
            {
                humidity = RelativeHumidity.FromPercent(ReadRegister(Register.ON_BOARD_HUMIDITY_REG));
                return(true);
            }

            return(false);
        }
示例#11
0
 internal Readings(ApiWeatherResult apiWeatherResult)
 {
     Weather = new List <WeatherCondition>();
     foreach (var weather in apiWeatherResult.Weather)
     {
         Weather.Add(new WeatherCondition
         {
             ConditionId = weather.Id,
             Main        = weather.Main,
             Description = weather.Description,
             IconId      = weather.Icon
         });
     }
     Temperature        = Temperature.FromKelvins(apiWeatherResult.Main.Temp);
     FeelsLike          = Temperature.FromKelvins(apiWeatherResult.Main.FeelsLike);
     Pressure           = Pressure.FromHectopascals(apiWeatherResult.Main.Pressure);
     Humidity           = RelativeHumidity.FromPercent(apiWeatherResult.Main.Humidity);
     MinimumTemperature = Temperature.FromKelvins(apiWeatherResult.Main.TempMin);
     MaximumTemperature = Temperature.FromKelvins(apiWeatherResult.Main.TempMax);
     if (apiWeatherResult.Main.SeaLevel.HasValue)
     {
         SeaLevelPressure = Pressure.FromHectopascals(apiWeatherResult.Main.SeaLevel.Value);
     }
     if (apiWeatherResult.Main.GrndLevel.HasValue)
     {
         GroundLevelPressure = Pressure.FromHectopascals(apiWeatherResult.Main.GrndLevel.Value);
     }
     WindSpeed     = Speed.FromMetersPerSecond(apiWeatherResult.Wind.Speed);
     WindDirection = Angle.FromDegrees(apiWeatherResult.Wind.Deg);
     if (apiWeatherResult.Wind.Gust.HasValue)
     {
         WindGust = Speed.FromMetersPerSecond(apiWeatherResult.Wind.Gust.Value);
     }
     Cloudiness = Ratio.FromPercent(apiWeatherResult.Clouds.All);
     if (apiWeatherResult.Rain != null)
     {
         RainfallLastHour       = Length.FromMillimeters(apiWeatherResult.Rain.OneHour);
         RainfallLastThreeHours = Length.FromMillimeters(apiWeatherResult.Rain.ThreeHours);
     }
     if (apiWeatherResult.Snow != null)
     {
         SnowfallLastHour       = Length.FromMillimeters(apiWeatherResult.Snow.OneHour);
         SnowfallLastThreeHours = Length.FromMillimeters(apiWeatherResult.Snow.ThreeHours);
     }
     MeasuredTime   = DateTimeOffset.FromUnixTimeSeconds(apiWeatherResult.Dt).UtcDateTime;
     CountryCode    = apiWeatherResult.Sys.Country;
     Sunrise        = DateTimeOffset.FromUnixTimeSeconds(apiWeatherResult.Sys.Sunrise).UtcDateTime;
     Sunset         = DateTimeOffset.FromUnixTimeSeconds(apiWeatherResult.Sys.Sunset).UtcDateTime;
     TimeZoneOffset = TimeSpan.FromSeconds(apiWeatherResult.Timezone);
     CityId         = apiWeatherResult.Id;
     CityName       = apiWeatherResult.Name;
     FetchedTime    = DateTime.UtcNow;
 }
        public void ArithmeticOperators()
        {
            RelativeHumidity v = RelativeHumidity.FromPercent(1);

            AssertEx.EqualTolerance(-1, -v.Percent, PercentTolerance);
            AssertEx.EqualTolerance(2, (RelativeHumidity.FromPercent(3) - v).Percent, PercentTolerance);
            AssertEx.EqualTolerance(2, (v + v).Percent, PercentTolerance);
            AssertEx.EqualTolerance(10, (v * 10).Percent, PercentTolerance);
            AssertEx.EqualTolerance(10, (10 * v).Percent, PercentTolerance);
            AssertEx.EqualTolerance(2, (RelativeHumidity.FromPercent(10) / 5).Percent, PercentTolerance);
            AssertEx.EqualTolerance(2, RelativeHumidity.FromPercent(10) / RelativeHumidity.FromPercent(5), PercentTolerance);
        }
        public void To_UnitSystem_ThrowsArgumentExceptionIfNotSupported()
        {
            var percent = RelativeHumidity.FromPercent(1);

            Assert.Throws <ArgumentException>(() => percent.ToUnit(UnitSystem.SI));
            Assert.Throws <ArgumentException>(() => percent.ToUnit(UnitSystem.CGS));
            Assert.Throws <ArgumentException>(() => percent.ToUnit(UnitSystem.BI));
            Assert.Throws <ArgumentException>(() => percent.ToUnit(UnitSystem.EE));
            Assert.Throws <ArgumentException>(() => percent.ToUnit(UnitSystem.USC));
            Assert.Throws <ArgumentException>(() => percent.ToUnit(UnitSystem.FPS));
            Assert.Throws <ArgumentException>(() => percent.ToUnit(UnitSystem.Astronomical));
        }
        public void ComparisonOperators()
        {
            RelativeHumidity onePercent = RelativeHumidity.FromPercent(1);
            RelativeHumidity twoPercent = RelativeHumidity.FromPercent(2);

            Assert.True(onePercent < twoPercent);
            Assert.True(onePercent <= twoPercent);
            Assert.True(twoPercent > onePercent);
            Assert.True(twoPercent >= onePercent);

            Assert.False(onePercent > twoPercent);
            Assert.False(onePercent >= twoPercent);
            Assert.False(twoPercent < onePercent);
            Assert.False(twoPercent <= onePercent);
        }
        public void EqualityOperators()
        {
            var a = RelativeHumidity.FromPercent(1);
            var b = RelativeHumidity.FromPercent(2);

            // ReSharper disable EqualExpressionComparison

            Assert.True(a == a);
            Assert.False(a != a);

            Assert.True(a != b);
            Assert.False(a == b);

            Assert.False(a == null);
            Assert.False(null == a);

// ReSharper restore EqualExpressionComparison
        }
示例#16
0
文件: Shtc3.cs 项目: mauricio-bv/iot
        /// <summary>
        /// Try read Temperature and Humidity
        /// </summary>
        /// <param name="temperature">Temperature returned by sensor</param>
        /// <param name="relativeHumidity">Humidity return by sensor</param>
        /// <param name="lowPower">"true" measured in low power mode, "false"(default) measured in normal power mode</param>
        /// <param name="clockStretching">"true" allow clock stretching, "false" (default) without clock stretching</param>
        /// <returns>True if operation was successful</returns>
        public bool TryGetTemperatureAndHumidity(out Temperature temperature, out RelativeHumidity relativeHumidity, bool lowPower = false, bool clockStretching = false)
        {
            if (Status == Status.Sleep)
            {
                Wakeup();
            }

            Register cmd = GetMeasurementCmd(lowPower, clockStretching);

            if (!TryReadSensorData(cmd, out var st, out var srh))
            {
                temperature      = default(Temperature);
                relativeHumidity = default(RelativeHumidity);
                return(false);
            }

            // Details in the Datasheet P9
            temperature      = Temperature.FromDegreesCelsius(Math.Round(st * 175 / 65536.0 - 45, 1));
            relativeHumidity = RelativeHumidity.FromPercent(srh * 100.0 / 65536.0);
            return(true);
        }
        public void Convert_ChangeType_InvalidType_ThrowsInvalidCastException()
        {
            var quantity = RelativeHumidity.FromPercent(1.0);

            Assert.Throws <InvalidCastException>(() => Convert.ChangeType(quantity, typeof(QuantityFormatter)));
        }
        public void Convert_ChangeType_BaseDimensions_EqualsBaseDimensions()
        {
            var quantity = RelativeHumidity.FromPercent(1.0);

            Assert.Equal(RelativeHumidity.BaseDimensions, Convert.ChangeType(quantity, typeof(BaseDimensions)));
        }
        public void Convert_ChangeType_QuantityInfo_EqualsQuantityInfo()
        {
            var quantity = RelativeHumidity.FromPercent(1.0);

            Assert.Equal(RelativeHumidity.Info, Convert.ChangeType(quantity, typeof(QuantityInfo)));
        }
        public void Convert_ChangeType_UnitType_EqualsUnit()
        {
            var quantity = RelativeHumidity.FromPercent(1.0);

            Assert.Equal(quantity.Unit, Convert.ChangeType(quantity, typeof(RelativeHumidityUnit)));
        }
        public void Convert_ChangeType_SelfType_EqualsSelf()
        {
            var quantity = RelativeHumidity.FromPercent(1.0);

            Assert.Equal(quantity, Convert.ChangeType(quantity, typeof(RelativeHumidity)));
        }
示例#22
0
文件: Dht10.cs 项目: mmalyska/iot
        internal override RelativeHumidity GetHumidity(Span <byte> readBuff)
        {
            int raw = (((readBuff[1] << 8) | readBuff[2]) << 4) | readBuff[3] >> 4;

            return(RelativeHumidity.FromPercent(100.0 * raw / Math.Pow(2, 20)));
        }
        public void Convert_ToSingle_EqualsValueAsSameType()
        {
            var quantity = RelativeHumidity.FromPercent(1.0);

            Assert.Equal((float)quantity.Value, Convert.ToSingle(quantity));
        }
        public void Convert_ToInt32_EqualsValueAsSameType()
        {
            var quantity = RelativeHumidity.FromPercent(1.0);

            Assert.Equal((int)quantity.Value, Convert.ToInt32(quantity));
        }
        public void Convert_ToDecimal_EqualsValueAsSameType()
        {
            var quantity = RelativeHumidity.FromPercent(1.0);

            Assert.Equal((decimal)quantity.Value, Convert.ToDecimal(quantity));
        }
        public void GetHashCode_Equals()
        {
            var quantity = RelativeHumidity.FromPercent(1.0);

            Assert.Equal(new { RelativeHumidity.Info.Name, quantity.Value, quantity.Unit }.GetHashCode(), quantity.GetHashCode());
        }
        public void NegationOperator_ReturnsQuantity_WithNegatedValue(double value)
        {
            var quantity = RelativeHumidity.FromPercent(value);

            Assert.Equal(RelativeHumidity.FromPercent(-value), -quantity);
        }
        public void Convert_ToString_EqualsToString()
        {
            var quantity = RelativeHumidity.FromPercent(1.0);

            Assert.Equal(quantity.ToString(), Convert.ToString(quantity));
        }
        public void TestConcurrency()
        {
            int[] pitable   = new int[] { 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9819, 9478, 9150, 8833, 8528, 8234, 7950, 7678, 7415, 7162, 6918, 6683, 6456, 6237, 6026, 5822, 5625, 5435, 5252, 5076, 4905, 4741, 4582, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9943, 9598, 9265, 8945, 8636, 8338, 8051, 7774, 7507, 7250, 7001, 6761, 6532, 6310, 6096, 5890, 5691, 5499, 5314, 5135, 4963, 4797, 4636, 4481, 4331, 4187, 4048, 3913, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9719, 9382, 9058, 8745, 8443, 8153, 7872, 7602, 7341, 7090, 6847, 6613, 6388, 6171, 5960, 5758, 5564, 5376, 5196, 5021, 4853, 4690, 4533, 4382, 4236, 4095, 3959, 3828, 3701, 3579, 3460, 3346, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9842, 9501, 9173, 8856, 8550, 8256, 7972, 7698, 7434, 7179, 6934, 6697, 6469, 6248, 6036, 5831, 5633, 5443, 5259, 5081, 4910, 4745, 4587, 4433, 4286, 4143, 4005, 3872, 3744, 3620, 3501, 3385, 3274, 3166, 3062, 2962, 2865, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9967, 9622, 9289, 8968, 8659, 8361, 8073, 7796, 7529, 7271, 7022, 6782, 6551, 6328, 6113, 5905, 5705, 5512, 5325, 5145, 4972, 4805, 4643, 4487, 4337, 4192, 4052, 3918, 3788, 3663, 3542, 3425, 3312, 3203, 3098, 2996, 2898, 2804, 2712, 2624, 2538, 2456, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9743, 9406, 9082, 8769, 8467, 8176, 7895, 7624, 7363, 7112, 6869, 6634, 6408, 6191, 5980, 5777, 5582, 5393, 5211, 5035, 4866, 4702, 4544, 4392, 4245, 4103, 3966, 3834, 3706, 3583, 3465, 3351, 3240, 3134, 3031, 2932, 2836, 2743, 2654, 2568, 2484, 2404, 2326, 2251, 2178, 2108, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9865, 9525, 9196, 8879, 8574, 8279, 7995, 7721, 7457, 7202, 6956, 6719, 6490, 6269, 6057, 5851, 5653, 5462, 5277, 5099, 4928, 4762, 4602, 4448, 4299, 4155, 4016, 3882, 3753, 3628, 3508, 3392, 3280, 3171, 3067, 2966, 2869, 2775, 2685, 2597, 2513, 2431, 2353, 2277, 2203, 2132, 2063, 1997, 1933, 1871, 1811, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9989, 9644, 9312, 8991, 8682, 8383, 8096, 7818, 7551, 7293, 7044, 6804, 6572, 6349, 6134, 5926, 5725, 5532, 5345, 5165, 4991, 4823, 4661, 4504, 4354, 4208, 4067, 3932, 3801, 3675, 3553, 3435, 3321, 3211, 3105, 3003, 2904, 2809, 2717, 2628, 2542, 2460, 2380, 2303, 2228, 2157, 2087, 2020, 1955, 1892, 1832, 1773, 1717, 1662, 1609, 1558, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9766, 9429, 9104, 8791, 8489, 8198, 7917, 7646, 7385, 7133, 6890, 6656, 6429, 6211, 6001, 5798, 5602, 5413, 5230, 5054, 4884, 4720, 4562, 4409, 4262, 4120, 3982, 3850, 3722, 3598, 3479, 3363, 3252, 3145, 3041, 2941, 2844, 2751, 2661, 2574, 2490, 2409, 2330, 2254, 2182, 2111, 2043, 1978, 1914, 1853, 1794, 1736, 1681, 1628, 1576, 1526, 1478, 1431, 1386, 1342, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9888, 9547, 9219, 8902, 8596, 8301, 8017, 7743, 7478, 7223, 6977, 6740, 6511, 6290, 6077, 5871, 5673, 5481, 5297, 5118, 4946, 4780, 4620, 4466, 4316, 4172, 4033, 3899, 3769, 3644, 3523, 3406, 3294, 3185, 3080, 2979, 2881, 2786, 2695, 2606, 2521, 2439, 2360, 2283, 2209, 2137, 2068, 2001, 1936, 1874, 1814, 1756, 1700, 1646, 1594, 1543, 1494, 1447, 1401, 1357, 1314, 1273, 1233, 1195, 1157, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9666, 9333, 9013, 8704, 8405, 8118, 7840, 7573, 7314, 7065, 6825, 6593, 6369, 6154, 5945, 5744, 5551, 5364, 5183, 5009, 4841, 4679, 4522, 4371, 4225, 4084, 3948, 3817, 3691, 3568, 3450, 3336, 3226, 3119, 3017, 2918, 2822, 2729, 2640, 2553, 2470, 2390, 2312, 2237, 2164, 2094, 2026, 1961, 1897, 1836, 1777, 1720, 1665, 1612, 1561, 1511, 1464, 1417, 1373, 1329, 1287, 1247, 1208, 1170, 1134, 1098, 1064, 1031, 999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9784, 9448, 9124, 8811, 8509, 8218, 7938, 7667, 7406, 7154, 6911, 6676, 6450, 6231, 6021, 5817, 5621, 5432, 5249, 5072, 4902, 4738, 4579, 4426, 4279, 4136, 3999, 3866, 3737, 3614, 3494, 3379, 3267, 3159, 3055, 2955, 2858, 2764, 2674, 2586, 2502, 2420, 2341, 2265, 2192, 2121, 2052, 1986, 1921, 1860, 1800, 1742, 1686, 1632, 1580, 1530, 1481, 1434, 1388, 1345, 1302, 1261, 1222, 1183, 1146, 1111, 1076, 1042, 1010, 979, 948, 919, 891, 863, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9908, 9566, 9237, 8920, 8614, 8319, 8035, 7762, 7498, 7243, 6997, 6759, 6530, 6310, 6096, 5891, 5692, 5500, 5315, 5137, 4964, 4798, 4638, 4483, 4333, 4189, 4049, 3915, 3785, 3659, 3538, 3421, 3308, 3199, 3094, 2992, 2894, 2799, 2708, 2619, 2534, 2451, 2371, 2294, 2220, 2148, 2078, 2011, 1946, 1883, 1823, 1764, 1707, 1653, 1600, 1549, 1499, 1452, 1405, 1361, 1318, 1276, 1236, 1197, 1159, 1123, 1088, 1054, 1021, 990, 959, 929, 901, 873, 846, 820, 795, 771, 747, 9999, 9999, 9999, 9999, 9999, 9999, 9999, 9694, 9358, 9035, 8724, 8425, 8136, 7858, 7590, 7332, 7083, 6843, 6611, 6388, 6172, 5964, 5763, 5569, 5382, 5201, 5027, 4859, 4696, 4539, 4388, 4242, 4101, 3964, 3833, 3706, 3583, 3465, 3350, 3240, 3133, 3030, 2931, 2835, 2742, 2653, 2566, 2482, 2402, 2323, 2248, 2175, 2105, 2037, 1971, 1907, 1846, 1787, 1729, 1674, 1620, 1568, 1518, 1470, 1423, 1378, 1334, 1292, 1251, 1212, 1173, 1137, 1101, 1066, 1033, 1001, 970, 940, 911, 883, 855, 829, 804, 779, 755, 732, 710, 688, 667, 647, 9999, 9999, 9835, 9492, 9163, 8845, 8540, 8246, 7962, 7689, 7426, 7173, 6929, 6694, 6467, 6248, 6037, 5834, 5638, 5449, 5266, 5090, 4919, 4755, 4596, 4443, 4295, 4152, 4014, 3881, 3753, 3629, 3509, 3393, 3281, 3173, 3069, 2968, 2871, 2777, 2686, 2598, 2514, 2432, 2353, 2277, 2203, 2131, 2063, 1996, 1932, 1869, 1809, 1751, 1695, 1641, 1588, 1538, 1489, 1441, 1395, 1351, 1308, 1267, 1227, 1188, 1151, 1114, 1079, 1046, 1013, 981, 951, 921, 893, 865, 838, 813, 788, 764, 740, 718, 696, 675, 654, 634, 615, 596, 579, 561, 8981, 8668, 8367, 8078, 7799, 7530, 7272, 7023, 6783, 6552, 6329, 6114, 5908, 5708, 5516, 5331, 5152, 4980, 4814, 4653, 4498, 4349, 4204, 4065, 3930, 3800, 3674, 3553, 3436, 3323, 3213, 3108, 3006, 2907, 2812, 2720, 2631, 2546, 2463, 2383, 2305, 2231, 2158, 2089, 2021, 1956, 1893, 1832, 1774, 1717, 1662, 1609, 1557, 1508, 1460, 1413, 1368, 1325, 1283, 1242, 1203, 1165, 1128, 1093, 1059, 1026, 993, 962, 932, 903, 875, 848, 822, 797, 772, 748, 726, 703, 682, 661, 641, 622, 603, 585, 567, 550, 534, 518, 502, 487, 7647, 7382, 7127, 6882, 6646, 6418, 6199, 5988, 5785, 5589, 5400, 5218, 5043, 4874, 4711, 4554, 4402, 4256, 4115, 3979, 3847, 3720, 3597, 3479, 3364, 3254, 3147, 3044, 2944, 2848, 2755, 2665, 2578, 2494, 2413, 2335, 2259, 2186, 2115, 2047, 1981, 1917, 1855, 1796, 1738, 1683, 1629, 1577, 1527, 1478, 1431, 1386, 1342, 1299, 1258, 1218, 1180, 1143, 1107, 1072, 1039, 1006, 975, 944, 915, 886, 859, 832, 806, 781, 757, 734, 711, 690, 669, 648, 629, 610, 591, 573, 556, 539, 523, 507, 492, 478, 463, 450, 436, 423, 6519, 6294, 6078, 5870, 5670, 5477, 5291, 5112, 4940, 4774, 4613, 4459, 4310, 4167, 4028, 3895, 3766, 3642, 3522, 3406, 3294, 3186, 3082, 2981, 2883, 2789, 2698, 2610, 2525, 2443, 2364, 2287, 2213, 2142, 2073, 2006, 1941, 1879, 1819, 1760, 1704, 1650, 1597, 1546, 1497, 1449, 1403, 1359, 1316, 1274, 1234, 1195, 1157, 1121, 1086, 1052, 1019, 987, 956, 926, 897, 870, 843, 816, 791, 767, 743, 720, 698, 677, 656, 636, 617, 598, 580, 562, 545, 529, 513, 498, 483, 468, 454, 441, 428, 415, 403, 391, 379, 368, 5564, 5373, 5190, 5013, 4843, 4679, 4522, 4370, 4223, 4082, 3946, 3815, 3688, 3566, 3448, 3335, 3225, 3120, 3018, 2919, 2824, 2732, 2643, 2557, 2474, 2394, 2316, 2241, 2169, 2099, 2031, 1966, 1903, 1842, 1783, 1725, 1670, 1617, 1565, 1516, 1467, 1421, 1376, 1332, 1290, 1249, 1210, 1172, 1135, 1100, 1065, 1032, 999, 968, 938, 909, 881, 853, 827, 801, 776, 752, 729, 707, 685, 664, 644, 624, 605, 587, 569, 552, 535, 519, 503, 488, 473, 459, 446, 432, 419, 407, 395, 383, 372, 361, 350, 340, 330, 321, 4754, 4592, 4436, 4286, 4142, 4003, 3868, 3739, 3615, 3494, 3379, 3267, 3159, 3056, 2955, 2859, 2765, 2675, 2589, 2505, 2423, 2345, 2269, 2196, 2125, 2057, 1991, 1927, 1865, 1805, 1747, 1691, 1637, 1585, 1535, 1486, 1439, 1393, 1349, 1306, 1265, 1225, 1187, 1149, 1113, 1078, 1045, 1012, 980, 950, 920, 892, 864, 837, 811, 786, 762, 738, 716, 694, 672, 652, 632, 612, 594, 576, 558, 541, 525, 509, 494, 479, 464, 450, 437, 424, 411, 399, 387, 376, 365, 354, 344, 334, 324, 314, 305, 296, 288, 279, 4067, 3929, 3797, 3669, 3546, 3428, 3313, 3203, 3097, 2995, 2896, 2801, 2710, 2621, 2536, 2453, 2374, 2297, 2223, 2151, 2082, 2015, 1951, 1888, 1828, 1769, 1713, 1658, 1605, 1554, 1505, 1457, 1411, 1366, 1323, 1281, 1241, 1202, 1164, 1127, 1092, 1058, 1025, 993, 962, 932, 903, 875, 848, 822, 796, 772, 748, 725, 702, 681, 660, 640, 620, 601, 583, 565, 548, 531, 515, 500, 485, 470, 456, 442, 429, 416, 404, 392, 380, 369, 358, 347, 337, 327, 318, 308, 299, 291, 282, 274, 266, 259, 251, 244, 3484, 3366, 3253, 3144, 3040, 2939, 2841, 2747, 2657, 2570, 2486, 2405, 2327, 2251, 2178, 2108, 2040, 1975, 1911, 1850, 1791, 1734, 1679, 1625, 1573, 1524, 1475, 1428, 1383, 1339, 1297, 1256, 1217, 1178, 1141, 1106, 1071, 1038, 1005, 974, 943, 914, 886, 858, 832, 806, 781, 757, 734, 711, 689, 668, 648, 628, 609, 590, 572, 555, 538, 522, 506, 491, 476, 461, 448, 434, 421, 409, 396, 385, 373, 362, 351, 341, 331, 321, 312, 303, 294, 285, 277, 269, 261, 254, 246, 239, 232, 226, 219, 213, 2987, 2887, 2791, 2698, 2608, 2522, 2439, 2359, 2282, 2208, 2136, 2067, 2000, 1935, 1873, 1813, 1755, 1699, 1645, 1593, 1542, 1493, 1446, 1400, 1356, 1313, 1272, 1232, 1193, 1156, 1120, 1084, 1051, 1018, 986, 955, 926, 897, 869, 842, 816, 791, 767, 743, 720, 698, 677, 656, 636, 616, 598, 579, 562, 545, 528, 512, 497, 482, 467, 453, 440, 426, 414, 401, 389, 378, 366, 355, 345, 335, 325, 315, 306, 297, 288, 280, 272, 264, 256, 249, 242, 235, 228, 221, 215, 209, 203, 197, 192, 186, 2564, 2479, 2396, 2317, 2241, 2167, 2096, 2028, 1962, 1898, 1837, 1778, 1721, 1666, 1613, 1561, 1512, 1464, 1417, 1373, 1329, 1288, 1247, 1208, 1170, 1133, 1098, 1064, 1030, 998, 967, 937, 908, 880, 853, 826, 801, 776, 752, 729, 707, 685, 664, 644, 624, 605, 587, 569, 552, 535, 519, 503, 488, 473, 459, 445, 432, 419, 406, 394, 382, 371, 360, 349, 339, 329, 319, 310, 301, 292, 283, 275, 267, 259, 252, 244, 237, 230, 224, 217, 211, 205, 199, 194, 188, 183, 178, 173, 168, 163, 2204, 2131, 2060, 1992, 1927, 1864, 1804, 1745, 1689, 1634, 1582, 1531, 1483, 1435, 1390, 1346, 1303, 1262, 1223, 1184, 1147, 1111, 1077, 1043, 1011, 979, 949, 919, 891, 863, 837, 811, 786, 762, 738, 715, 693, 672, 652, 632, 613, 594, 576, 558, 541, 525, 509, 494, 479, 464, 451, 437, 424, 411, 399, 387, 375, 364, 353, 343, 333, 323, 313, 304, 295, 287, 278, 270, 262, 254, 247, 240, 233, 226, 220, 213, 207, 201, 196, 190, 185, 179, 174, 169, 165, 160, 155, 151, 147, 143, 1896, 1833, 1773, 1715, 1659, 1605, 1554, 1504, 1455, 1409, 1364, 1320, 1279, 1238, 1199, 1161, 1125, 1090, 1056, 1023, 991, 960, 931, 902, 874, 847, 821, 796, 771, 747, 724, 702, 681, 660, 640, 620, 601, 583, 565, 548, 531, 515, 500, 485, 470, 456, 442, 429, 416, 404, 392, 380, 369, 358, 347, 337, 327, 317, 308, 299, 290, 281, 273, 265, 257, 250, 243, 236, 229, 222, 216, 210, 203, 198, 192, 187, 181, 176, 171, 166, 162, 157, 153, 148, 144, 140, 136, 132, 129, 125, 1633, 1579, 1528, 1478, 1430, 1384, 1340, 1297, 1255, 1215, 1177, 1140, 1104, 1069, 1036, 1003, 972, 942, 913, 885, 857, 831, 805, 780, 756, 733, 711, 689, 668, 648, 628, 609, 590, 572, 555, 538, 522, 506, 491, 476, 462, 448, 434, 421, 409, 397, 385, 373, 362, 351, 341, 331, 321, 312, 302, 294, 285, 277, 268, 261, 253, 246, 238, 231, 225, 218, 212, 206, 200, 194, 189, 183, 178, 173, 168, 163, 159, 154, 150, 146, 142, 138, 134, 130, 126, 123, 120, 116, 113, 110, 1408, 1362, 1318, 1275, 1234, 1194, 1156, 1120, 1084, 1050, 1017, 985, 954, 924, 895, 868, 841, 815, 790, 766, 742, 719, 697, 676, 655, 636, 616, 597, 579, 562, 545, 528, 512, 497, 482, 467, 453, 440, 427, 414, 401, 389, 378, 367, 356, 345, 335, 325, 315, 306, 297, 288, 280, 272, 264, 256, 249, 241, 234, 227, 221, 214, 208, 202, 196, 191, 185, 180, 175, 170, 165, 160, 156, 151, 147, 143, 139, 135, 131, 128, 124, 121, 117, 114, 111, 108, 105, 102, 99, 97, 1215, 1176, 1138, 1101, 1066, 1032, 999, 968, 937, 908, 879, 852, 825, 800, 775, 751, 728, 706, 684, 663, 643, 624, 605, 586, 569, 551, 535, 519, 503, 488, 473, 459, 445, 432, 419, 406, 394, 382, 371, 360, 349, 339, 329, 319, 310, 301, 292, 283, 275, 267, 259, 252, 244, 237, 230, 224, 217, 211, 205, 199, 193, 188, 182, 177, 172, 167, 162, 158, 153, 149, 145, 140, 137, 133, 129, 125, 122, 119, 115, 112, 109, 106, 103, 100, 97, 95, 92, 90, 87, 85, 1050, 1016, 983, 952, 922, 892, 864, 837, 811, 786, 761, 738, 715, 693, 672, 651, 631, 612, 593, 575, 558, 541, 525, 509, 494, 479, 464, 451, 437, 424, 411, 399, 387, 376, 364, 354, 343, 333, 323, 314, 304, 295, 287, 278, 270, 262, 255, 247, 240, 233, 226, 220, 213, 207, 201, 195, 190, 184, 179, 174, 169, 164, 159, 155, 150, 146, 142, 138, 134, 130, 127, 123, 120, 116, 113, 110, 107, 104, 101, 98, 96, 93, 91, 88, 86, 83, 81, 79, 77, 75, 908, 879, 851, 824, 798, 773, 748, 725, 702, 681, 660, 639, 620, 601, 582, 565, 548, 531, 515, 500, 485, 470, 456, 442, 429, 416, 404, 392, 380, 369, 358, 347, 337, 327, 317, 308, 299, 290, 282, 273, 265, 258, 250, 243, 236, 229, 222, 216, 210, 204, 198, 192, 187, 181, 176, 171, 166, 161, 157, 152, 148, 144, 140, 136, 132, 128, 125, 121, 118, 114, 111, 108, 105, 102, 99, 97, 94, 91, 89, 87, 84, 82, 80, 78, 75, 73, 71, 70, 68, 66, 786, 761, 737, 714, 691, 670, 649, 629, 609, 590, 572, 555, 538, 521, 506, 490, 476, 461, 448, 434, 421, 409, 397, 385, 373, 362, 352, 341, 331, 321, 312, 303, 294, 285, 277, 269, 261, 253, 246, 239, 232, 225, 219, 212, 206, 200, 194, 189, 183, 178, 173, 168, 163, 159, 154, 150, 145, 141, 137, 133, 130, 126, 122, 119, 116, 112, 109, 106, 103, 100, 98, 95, 92, 90, 87, 85, 83, 80, 78, 76, 74, 72, 70, 68, 66, 65, 63, 61, 60, 58, 681, 660, 639, 619, 600, 581, 563, 546, 529, 513, 497, 482, 467, 453, 439, 426, 414, 401, 389, 378, 367, 356, 345, 335, 325, 316, 306, 297, 289, 280, 272, 264, 256, 249, 242, 235, 228, 221, 215, 209, 202, 197, 191, 186, 180, 175, 170, 165, 160, 156, 151, 147, 143, 139, 135, 131, 128, 124, 120, 117, 114, 111, 108, 105, 102, 99, 96, 93, 91, 88, 86, 84, 81, 79, 77, 75, 73, 71, 69, 67, 65, 64, 62, 60, 59, 57, 56, 54, 53, 51, 591, 573, 555, 537, 521, 504, 489, 474, 459, 445, 432, 419, 406, 394, 382, 371, 360, 349, 339, 329, 319, 310, 301, 292, 283, 275, 267, 259, 252, 244, 237, 230, 224, 217, 211, 205, 199, 193, 188, 182, 177, 172, 167, 162, 158, 153, 149, 145, 141, 137, 133, 129, 125, 122, 118, 115, 112, 109, 106, 103, 100, 97, 94, 92, 89, 87, 84, 82, 80, 78, 76, 74, 72, 70, 68, 66, 64, 62, 61, 59, 58, 56, 55, 53, 52, 50, 49, 48, 47, 45, 513, 497, 482, 467, 452, 439, 425, 412, 400, 388, 376, 365, 354, 343, 333, 323, 314, 304, 295, 287, 278, 270, 262, 255, 247, 240, 233, 226, 220, 214, 207, 201, 196, 190, 184, 179, 174, 169, 164, 160, 155, 151, 146, 142, 138, 134, 131, 127, 123, 120, 116, 113, 110, 107, 104, 101, 98, 96, 93, 90, 88, 85, 83, 81, 79, 76, 74, 72, 70, 68, 67, 65, 63, 61, 60, 58, 57, 55, 54, 52, 51, 49, 48, 47, 46, 45, 43, 42, 41, 40, 446, 432, 419, 406, 394, 382, 370, 359, 348, 337, 327, 318, 308, 299, 290, 282, 273, 265, 258, 250, 243, 236, 229, 222, 216, 210, 204, 198, 192, 187, 181, 176, 171, 166, 161, 157, 152, 148, 144, 140, 136, 132, 128, 125, 121, 118, 115, 111, 108, 105, 102, 99, 97, 94, 91, 89, 86, 84, 82, 79, 77, 75, 73, 71, 69, 67, 65, 64, 62, 60, 59, 57, 56, 54, 53, 51, 50, 49, 47, 46, 45, 44, 43, 42, 40, 39, 38, 37, 36, 35, 388, 376, 365, 354, 343, 332, 322, 313, 303, 294, 285, 277, 269, 261, 253, 246, 239, 232, 225, 219, 212, 206, 200, 194, 189, 183, 178, 173, 168, 163, 159, 154, 150, 146, 141, 137, 134, 130, 126, 123, 119, 116, 113, 109, 106, 103, 101, 98, 95, 92, 90, 87, 85, 83, 80, 78, 76, 74, 72, 70, 68, 66, 64, 63, 61, 59, 58, 56, 55, 53, 52, 50, 49, 48, 47, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 338, 328, 318, 308, 299, 290, 281, 273, 264, 257, 249, 242, 235, 228, 221, 215, 208, 202, 197, 191, 186, 180, 175, 170, 165, 161, 156, 152, 147, 143, 139, 135, 131, 128, 124, 121, 117, 114, 111, 108, 105, 102, 99, 96, 94, 91, 88, 86, 84, 81, 79, 77, 75, 73, 71, 69, 67, 65, 63, 62, 60, 58, 57, 55, 54, 52, 51, 50, 48, 47, 46, 45, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 33, 32, 31, 30, 29, 29, 28, 295, 286, 277, 269, 261, 253, 245, 238, 231, 224, 218, 211, 205, 199, 193, 188, 182, 177, 172, 167, 162, 158, 153, 149, 145, 141, 137, 133, 129, 125, 122, 119, 115, 112, 109, 106, 103, 100, 97, 95, 92, 89, 87, 85, 82, 80, 78, 76, 74, 72, 70, 68, 66, 64, 62, 61, 59, 57, 56, 54, 53, 52, 50, 49, 48, 46, 45, 44, 43, 42, 40, 39, 38, 37, 36, 35, 35, 34, 33, 32, 31, 30, 30, 29, 28, 27, 27, 26, 25, 25, 257, 250, 242, 235, 228, 221, 214, 208, 202, 196, 190, 185, 179, 174, 169, 164, 160, 155, 151, 146, 142, 138, 134, 131, 127, 123, 120, 117, 113, 110, 107, 104, 101, 98, 96, 93, 90, 88, 86, 83, 81, 79, 77, 74, 72, 70, 69, 67, 65, 63, 61, 60, 58, 57, 55, 54, 52, 51, 49, 48, 47, 46, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 31, 30, 29, 28, 28, 27, 26, 26, 25, 24, 24, 23, 23, 22, 225, 218, 211, 205, 199, 193, 187, 182, 177, 171, 166, 162, 157, 152, 148, 144, 140, 136, 132, 128, 125, 121, 118, 115, 111, 108, 105, 102, 100, 97, 94, 91, 89, 86, 84, 82, 80, 77, 75, 73, 71, 69, 67, 66, 64, 62, 60, 59, 57, 56, 54, 53, 51, 50, 49, 47, 46, 45, 44, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 33, 32, 31, 30, 29, 29, 28, 27, 26, 26, 25, 25, 24, 23, 23, 22, 22, 21, 21, 20, 20, 197, 191, 185, 179, 174, 169, 164, 159, 155, 150, 146, 142, 138, 134, 130, 126, 123, 119, 116, 113, 109, 106, 103, 101, 98, 95, 93, 90, 87, 85, 83, 80, 78, 76, 74, 72, 70, 68, 66, 64, 63, 61, 59, 58, 56, 55, 53, 52, 50, 49, 48, 47, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 30, 29, 28, 27, 27, 26, 25, 25, 24, 23, 23, 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, 17, 172, 167, 162, 157, 152, 148, 144, 140, 135, 132, 128, 124, 121, 117, 114, 111, 108, 105, 102, 99, 96, 94, 91, 88, 86, 84, 81, 79, 77, 75, 73, 71, 69, 67, 65, 63, 62, 60, 58, 57, 55, 54, 52, 51, 50, 48, 47, 46, 45, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 32, 31, 30, 29, 28, 28, 27, 26, 26, 25, 24, 24, 23, 23, 22, 21, 21, 20, 20, 19, 19, 18, 18, 18, 17, 17, 16, 16, 16, 151, 146, 142, 138, 134, 130, 126, 122, 119, 115, 112, 109, 106, 103, 100, 97, 95, 92, 89, 87, 85, 82, 80, 78, 76, 74, 72, 70, 68, 66, 64, 62, 61, 59, 58, 56, 54, 53, 52, 50, 49, 48, 46, 45, 44, 43, 42, 40, 39, 38, 37, 36, 35, 35, 34, 33, 32, 31, 30, 29, 29, 28, 27, 27, 26, 25, 25, 24, 23, 23, 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, 17, 17, 16, 16, 16, 15, 15, 15, 14, 14, 132, 128, 124, 121, 117, 114, 111, 107, 104, 101, 99, 96, 93, 90, 88, 86, 83, 81, 79, 77, 74, 72, 70, 69, 67, 65, 63, 61, 60, 58, 57, 55, 54, 52, 51, 49, 48, 47, 46, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 31, 30, 29, 28, 28, 27, 26, 25, 25, 24, 24, 23, 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, 17, 17, 17, 16, 16, 15, 15, 15, 14, 14, 14, 13, 13, 13, 12, 116, 113, 109, 106, 103, 100, 97, 94, 92, 89, 87, 84, 82, 80, 77, 75, 73, 71, 69, 67, 66, 64, 62, 60, 59, 57, 56, 54, 53, 51, 50, 49, 47, 46, 45, 44, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 33, 32, 31, 30, 29, 29, 28, 27, 26, 26, 25, 24, 24, 23, 23, 22, 21, 21, 20, 20, 19, 19, 18, 18, 18, 17, 17, 16, 16, 15, 15, 15, 14, 14, 14, 13, 13, 13, 12, 12, 12, 12, 11, 11, 102, 99, 96, 93, 91, 88, 85, 83, 81, 78, 76, 74, 72, 70, 68, 66, 64, 63, 61, 59, 58, 56, 55, 53, 52, 50, 49, 48, 47, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 30, 29, 28, 27, 27, 26, 25, 25, 24, 23, 23, 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, 17, 17, 16, 16, 16, 15, 15, 14, 14, 14, 13, 13, 13, 13, 12, 12, 12, 11, 11, 11, 11, 10, 10, 10, 90, 87, 84, 82, 80, 77, 75, 73, 71, 69, 67, 65, 63, 62, 60, 58, 57, 55, 54, 52, 51, 50, 48, 47, 46, 45, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 32, 31, 30, 29, 28, 28, 27, 26, 26, 25, 24, 24, 23, 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, 17, 17, 17, 16, 16, 15, 15, 15, 14, 14, 14, 13, 13, 13, 12, 12, 12, 11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9, 9, 79, 77, 74, 72, 70, 68, 66, 64, 63, 61, 59, 58, 56, 54, 53, 52, 50, 49, 48, 46, 45, 44, 43, 42, 40, 39, 38, 37, 36, 35, 35, 34, 33, 32, 31, 30, 29, 29, 28, 27, 27, 26, 25, 25, 24, 23, 23, 22, 22, 21, 21, 20, 19, 19, 19, 18, 18, 17, 17, 16, 16, 16, 15, 15, 14, 14, 14, 13, 13, 13, 12, 12, 12, 12, 11, 11, 11, 10, 10, 10, 10, 10, 9, 9, 9, 9, 8, 8, 8, 8, 69, 67, 65, 64, 62, 60, 58, 57, 55, 54, 52, 51, 49, 48, 47, 46, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 31, 30, 29, 28, 28, 27, 26, 25, 25, 24, 24, 23, 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, 17, 17, 16, 16, 16, 15, 15, 15, 14, 14, 13, 13, 13, 13, 12, 12, 12, 11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, 61, 59, 58, 56, 55, 53, 52, 50, 49, 47, 46, 45, 44, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 33, 32, 31, 30, 29, 29, 28, 27, 26, 26, 25, 24, 24, 23, 23, 22, 21, 21, 20, 20, 19, 19, 18, 18, 18, 17, 17, 16, 16, 15, 15, 15, 14, 14, 14, 13, 13, 13, 12, 12, 12, 11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 54, 52, 51, 50, 48, 47, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 30, 29, 28, 27, 27, 26, 25, 25, 24, 23, 23, 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, 17, 17, 16, 16, 16, 15, 15, 14, 14, 14, 13, 13, 13, 12, 12, 12, 12, 11, 11, 11, 10, 10, 10, 10, 10, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 48, 46, 45, 44, 43, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 32, 31, 30, 29, 28, 28, 27, 26, 26, 25, 24, 24, 23, 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, 17, 17, 17, 16, 16, 15, 15, 15, 14, 14, 14, 13, 13, 13, 12, 12, 12, 11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 29, 28, 27, 27, 26, 25, 25, 24, 23, 23, 22, 22, 21, 20, 20, 19, 19, 18, 18, 18, 17, 17, 16, 16, 15, 15, 15, 14, 14, 14, 13, 13, 13, 12, 12, 12, 11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 37, 36, 35, 34, 33, 32, 32, 31, 30, 29, 28, 28, 27, 26, 25, 25, 24, 24, 23, 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, 17, 17, 16, 16, 16, 15, 15, 15, 14, 14, 13, 13, 13, 12, 12, 12, 12, 11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 33, 32, 31, 30, 29, 29, 28, 27, 26, 26, 25, 24, 24, 23, 23, 22, 21, 21, 20, 20, 19, 19, 18, 18, 17, 17, 17, 16, 16, 15, 15, 15, 14, 14, 14, 13, 13, 13, 12, 12, 12, 11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 29, 28, 28, 27, 26, 25, 25, 24, 23, 23, 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, 17, 17, 16, 16, 16, 15, 15, 14, 14, 14, 13, 13, 13, 12, 12, 12, 12, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 26, 25, 25, 24, 23, 23, 22, 21, 21, 20, 20, 19, 19, 18, 18, 17, 17, 17, 16, 16, 15, 15, 15, 14, 14, 14, 13, 13, 13, 12, 12, 12, 11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 23, 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, 17, 17, 16, 16, 15, 15, 15, 14, 14, 14, 13, 13, 13, 12, 12, 12, 11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 20, 20, 19, 19, 18, 18, 17, 17, 16, 16, 16, 15, 15, 14, 14, 14, 13, 13, 13, 12, 12, 12, 12, 11, 11, 11, 10, 10, 10, 10, 10, 9, 9, 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 18, 18, 17, 17, 16, 16, 15, 15, 15, 14, 14, 14, 13, 13, 13, 12, 12, 12, 11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 16, 16, 15, 15, 15, 14, 14, 13, 13, 13, 12, 12, 12, 12, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 14, 14, 14, 13, 13, 13, 12, 12, 12, 11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 13, 12, 12, 12, 12, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 9, 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 21, 19, 18, 17, 16, 15, 14, 13, 12, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 15, 14, 13, 12, 11, 10, 10, 9, 9, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 12, 11, 10, 9, 9, 8, 8, 7, 7, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 11, 10, 9, 8, 8, 7, 7, 6, 6, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 10, 9, 8, 8, 7, 7, 6, 6, 5, 5, 5, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 12, 10, 9, 8, 7, 7, 6, 6, 5, 5, 5, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 12, 10, 9, 8, 7, 7, 6, 6, 5, 5, 5, 4, 4, 4, 4, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 13, 11, 10, 9, 8, 7, 6, 6, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 16, 14, 12, 10, 9, 8, 7, 6, 6, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 18, 15, 13, 11, 10, 8, 8, 7, 6, 5, 5, 5, 4, 4, 4, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 20, 17, 14, 12, 11, 9, 8, 7, 6, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 24, 20, 16, 14, 12, 10, 9, 8, 7, 6, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 3, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 35, 28, 23, 19, 16, 13, 11, 10, 9, 7, 7, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 3, 3, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 43, 34, 27, 22, 18, 15, 13, 11, 9, 8, 7, 6, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 71, 54, 42, 33, 26, 21, 18, 15, 12, 11, 9, 8, 7, 6, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 92, 69, 53, 41, 32, 26, 21, 17, 14, 12, 10, 9, 8, 7, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 123, 90, 67, 51, 40, 31, 25, 21, 17, 14, 12, 10, 9, 8, 7, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 0, 0, 0, 0, 0, 168, 121, 88, 66, 50, 39, 31, 25, 20, 17, 14, 12, 10, 9, 8, 7, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 0, 0, 0, 0, 236, 165, 119, 87, 65, 50, 38, 30, 24, 20, 16, 14, 11, 10, 8, 7, 6, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 0, 0, 0, 340, 232, 163, 117, 86, 64, 49, 38, 30, 24, 19, 16, 13, 11, 10, 8, 7, 6, 6, 5, 5, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 0, 0, 0, 335, 229, 161, 115, 85, 63, 48, 37, 30, 24, 19, 16, 13, 11, 10, 8, 7, 6, 6, 5, 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 0, 0, 498, 332, 227, 159, 114, 84, 63, 48, 37, 29, 23, 19, 16, 13, 11, 9, 8, 7, 6, 6, 5, 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 0, 763, 493, 328, 225, 157, 113, 83, 62, 47, 37, 29, 23, 19, 16, 13, 11, 9, 8, 7, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 0, 756, 489, 326, 223, 156, 112, 82, 61, 47, 36, 29, 23, 19, 15, 13, 11, 9, 8, 7, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 0, 751, 486, 323, 221, 155, 111, 81, 61, 46, 36, 28, 23, 19, 15, 13, 11, 9, 8, 7, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 0, 747, 483, 322, 220, 154, 111, 81, 61, 46, 36, 28, 23, 18, 15, 13, 11, 9, 8, 7, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 1186, 744, 481, 320, 219, 154, 110, 81, 60, 46, 36, 28, 23, 18, 15, 13, 11, 9, 8, 7, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 0, 742, 480, 320, 219, 153, 110, 81, 60, 46, 36, 28, 23, 18, 15, 13, 11, 9, 8, 7, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 0, 742, 480, 319, 218, 153, 110, 80, 60, 46, 36, 28, 23, 18, 15, 13, 11, 9, 8, 7, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 0, 742, 480, 320, 219, 153, 110, 81, 60, 46, 36, 28, 23, 18, 15, 13, 11, 9, 8, 7, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 0, 0, 482, 321, 219, 154, 110, 81, 60, 46, 36, 28, 23, 18, 15, 13, 11, 9, 8, 7, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 0, 0, 484, 322, 220, 154, 111, 81, 61, 46, 36, 28, 23, 18, 15, 13, 11, 9, 8, 7, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 0, 0, 0, 325, 222, 156, 112, 82, 61, 47, 36, 29, 23, 19, 15, 13, 11, 9, 8, 7, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 224, 157, 113, 83, 62, 47, 37, 29, 23, 19, 16, 13, 11, 9, 8, 7, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 160, 114, 84, 63, 48, 37, 29, 23, 19, 16, 13, 11, 9, 8, 7, 6, 6, 5, 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 86, 64, 49, 38, 30, 24, 19, 16, 13, 11, 10, 8, 7, 6, 6, 5, 5, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 66, 50, 39, 31, 25, 20, 16, 14, 12, 10, 9, 7, 7, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 32, 25, 21, 17, 14, 12, 10, 9, 8, 7, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 22, 18, 15, 13, 11, 9, 8, 7, 6, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 16, 14, 12, 10, 9, 8, 7, 6, 5, 5, 5, 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 11, 10, 9, 8, 7, 6, 6, 5, 5, 4, 4, 4, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 10, 9, 8, 7, 7, 6, 6, 5, 5, 4, 4, 4, 4, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 10, 9, 9, 8, 7, 7, 6, 6, 6, 5, 5, 5, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 21, 19, 18, 17, 16, 15, 14, 13, 12, 12 };
            int   minDays   = 99999;
            int   minDaysT  = 0;
            int   minDaysRH = 0;
            int   maxDays   = 0;
            int   maxDaysT  = 0;
            int   maxDaysRH = 0;

            for (int t = 2; t <= 45; t++)
            {
                for (int rh = 65; rh <= 100; rh++)
                {
                    Temperature      temperature      = Temperature.FromDegreesCelsius(t);
                    RelativeHumidity relativeHumidity = RelativeHumidity.FromPercent(rh);
                    var mold = (temperature.DegreesCelsius > 45 || temperature.DegreesCelsius < 2 || relativeHumidity.Percent < 65) ?
                               0 :
                               pitable[Convert.ToInt32(8010 + (Math.Round(temperature.DegreesCelsius, MidpointRounding.AwayFromZero) - 2) * 36 + Math.Round(relativeHumidity.Percent, MidpointRounding.AwayFromZero) - 65)];

                    if (mold < minDays && mold > 0)
                    {
                        minDays   = mold;
                        minDaysT  = t;
                        minDaysRH = rh;
                    }
                    else if (mold > maxDays)
                    {
                        maxDays   = mold;
                        maxDaysT  = t;
                        maxDaysRH = rh;
                    }
                }
            }

            var openWeatherMapCache = new OpenWeatherMapCache(apiKey, 10_000);
            int totalFromCache      = 0;
            int totalFromAPI        = 0;

            var result = Parallel.For(1, 101, (i, state) =>
            {
                var location = new Models.Location(48.6371, -122.1237);
                var readings = openWeatherMapCache.GetReadings(location);
                if (readings.IsFromCache)
                {
                    Interlocked.Increment(ref totalFromCache);
                }
                else
                {
                    Interlocked.Increment(ref totalFromAPI);
                }
            });

            while (totalFromCache + totalFromAPI < 100)
            {
            }

            Assert.Equal(99, totalFromCache);
            Assert.Equal(1, totalFromAPI);

            Thread.Sleep(10_001);

            result = Parallel.For(1, 101, (i, state) =>
            {
                var location = new Models.Location(1, 1);
                var readings = openWeatherMapCache.GetReadings(location);
                if (readings.IsFromCache)
                {
                    Interlocked.Increment(ref totalFromCache);
                }
                else
                {
                    Interlocked.Increment(ref totalFromAPI);
                }
            });

            while (totalFromCache + totalFromAPI < 200)
            {
            }

            Assert.Equal(198, totalFromCache);
            Assert.Equal(2, totalFromAPI);
        }
        public void Convert_ToUInt64_EqualsValueAsSameType()
        {
            var quantity = RelativeHumidity.FromPercent(1.0);

            Assert.Equal((ulong)quantity.Value, Convert.ToUInt64(quantity));
        }